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/obp5wqVSVDMiDTC414cR8/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/2ASoJGxS-D4w-vat00xMy/_buildManifest.js
similarity index 100%
rename from litellm/proxy/_experimental/out/_next/static/obp5wqVSVDMiDTC414cR8/_buildManifest.js
rename to litellm/proxy/_experimental/out/_next/static/2ASoJGxS-D4w-vat00xMy/_buildManifest.js
diff --git a/litellm/proxy/_experimental/out/_next/static/obp5wqVSVDMiDTC414cR8/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/2ASoJGxS-D4w-vat00xMy/_ssgManifest.js
similarity index 100%
rename from litellm/proxy/_experimental/out/_next/static/obp5wqVSVDMiDTC414cR8/_ssgManifest.js
rename to litellm/proxy/_experimental/out/_next/static/2ASoJGxS-D4w-vat00xMy/_ssgManifest.js
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-6a39771cacf75ea6.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-6a39771cacf75ea6.js
deleted file mode 100644
index 7d08a80c96..0000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-6a39771cacf75ea6.js
+++ /dev/null
@@ -1 +0,0 @@
-(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,t){Promise.resolve().then(t.bind(t,7926))},7926:function(e,l,t){"use strict";t.r(l),t.d(l,{default:function(){return lb}});var s,a,r=t(3827),n=t(64090),o=t(47907),i=t(8792),c=t(40491),d=t(65270),m=e=>{let{userID:l,userRole:t,userEmail:s,showSSOBanner:a}=e;console.log("User ID:",l),console.log("userEmail:",s),console.log("showSSOBanner:",a);let n=[{key:"1",label:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("p",{children:["Role: ",t]}),(0,r.jsxs)("p",{children:["ID: ",l]})]})}];return(0,r.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,r.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,r.jsx)("div",{className:"flex flex-col items-center",children:(0,r.jsx)(i.default,{href:"/",children:(0,r.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,r.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,r.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,r.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,r.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Request hosted proxy"})}):null,(0,r.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,r.jsx)(c.Z,{menu:{items:n},children:(0,r.jsx)(d.Z,{children:s})})})]})]})},u=t(80588);let h=async()=>{try{let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"),l=await e.json();return console.log("received data: ".concat(l)),l}catch(e){throw console.error("Failed to get model cost map:",e),e}},x=async(e,l)=>{try{let t=await fetch("/model/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model created successfully. Wait 60s and refresh on 'All Models' page"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,l)=>{console.log("model_id in model delete call: ".concat(l));try{let t=await fetch("/model/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({id:l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model deleted successfully. Restart server to see this."),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,l)=>{try{console.log("in keyDeleteCall:",l);let t=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[l]})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to delete key: "+e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},f=async(e,l)=>{try{console.log("in teamDeleteCall:",l);let t=await fetch("/team/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_ids:[l]})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to delete team: "+e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to delete key:",e),e}},Z=async function(e,l,t){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],a=arguments.length>4?arguments[4]:void 0,r=arguments.length>5?arguments[5]:void 0;try{let n="/user/info";"App Owner"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),"App User"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),console.log("in userInfoCall viewAll=",s),s&&r&&null!=a&&void 0!=a&&(n="".concat(n,"?view_all=true&page=").concat(a,"&page_size=").concat(r));let o=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let i=await o.json();return console.log("API Response:",i),i}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,l)=>{try{let t="/team/info";l&&(t="".concat(t,"?team_id=").concat(l)),console.log("in teamInfoCall");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let l=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},b=async(e,l,t)=>{try{let l=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log("modelInfoCall:",t),t}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,l,t,s,a,r)=>{try{let l="/model/metrics";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(a,"&endTime=").concat(r));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,l,t,s,a,r)=>{try{let l="/model/metrics/slow_responses";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(a,"&endTime=").concat(r));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,l,t,s,a,r)=>{try{let l="/model/metrics/exceptions";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(a,"&endTime=").concat(r));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},N=async(e,l,t)=>{try{let l=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},A=async e=>{try{let l="/global/spend/teams";console.log("in teamSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},E=async(e,l,t)=>{try{let s="/global/spend/tags";l&&t&&(s="".concat(s,"?start_date=").concat(l,"&end_date=").concat(t)),console.log("in tagsSpendLogsCall:",s);let a=await fetch("".concat(s),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let r=await a.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,l,t,s,a,r)=>{try{console.log("user role in spend logs call: ".concat(t));let l="/spend/logs";l="App Owner"==t?"".concat(l,"?user_id=").concat(s,"&start_date=").concat(a,"&end_date=").concat(r):"".concat(l,"?start_date=").concat(a,"&end_date=").concat(r);let n=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},C=async e=>{try{let l=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{let l=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,l,t,s)=>{try{let a="";a=l?JSON.stringify({api_key:l,startTime:t,endTime:s}):JSON.stringify({startTime:t,endTime:s});let r={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};r.body=a;let n=await fetch("/global/spend/end_users",r);if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},O=async e=>{try{let l=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},F=async(e,l)=>{try{let t=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},R=async(e,l)=>{try{let t="/user/get_users?role=".concat(l);console.log("in userGetAllUsersCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to delete key: "+e,10),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to get requested models:",e),e}},M=async(e,l)=>{try{console.log("Form Values in teamCreateCall:",l);let t=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},L=async(e,l)=>{try{console.log("Form Values in keyUpdateCall:",l);let t=await fetch("/key/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update key Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},U=async(e,l)=>{try{console.log("Form Values in teamUpateCall:",l);let t=await fetch("/team/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update team: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update Team Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},D=async(e,l)=>{try{console.log("Form Values in modelUpateCall:",l);let t=await fetch("/model/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update model: "+e,10),console.error("Error update from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update model Response:",s),s}catch(e){throw console.error("Failed to update model:",e),e}},K=async(e,l,t)=>{try{console.log("Form Values in teamMemberAddCall:",t);let s=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:l,member:t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},B=async(e,l,t)=>{try{console.log("Form Values in userUpdateUserCall:",l);let s={...l};null!==t&&(s.user_role=t),s=JSON.stringify(s);let a=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:s});if(!a.ok){let e=await a.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await a.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},z=async(e,l)=>{try{let t="/health/services?service=".concat(l);console.log("Checking Slack Budget Alerts service health");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed ".concat(l," service health check ")+e),Error(e)}let a=await s.json();return u.ZP.success("Test request to ".concat(l," made - check logs/alerts on ").concat(l," to verify")),a}catch(e){throw console.error("Failed to perform health check:",e),e}},q=async(e,l,t)=>{try{let l=await fetch("/get/config/callbacks",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},V=async(e,l)=>{try{let t=await fetch("/config/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to set callbacks:",e),e}},G=async e=>{try{let l=await fetch("/health",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to call /health:",e),e}};var Y=t(10384),W=t(46453),J=t(16450),H=t(52273),$=t(26780),X=t(15595),Q=t(6698),ee=t(71801),el=t(42440),et=t(42308),es=t(50670),ea=t(81583),er=t(99129),en=t(44839),eo=t(88707),ei=t(1861);let{Option:ec}=es.default;var ed=e=>{let{userID:l,team:t,userRole:s,accessToken:a,data:o,setData:i}=e,[c]=ea.Z.useForm(),[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(null),[p,g]=(0,n.useState)(null),[y,f]=(0,n.useState)([]),[Z,_]=(0,n.useState)([]),w=()=>{m(!1),c.resetFields()},b=()=>{m(!1),x(null),c.resetFields()};(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==a){let e=(await N(a,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),f(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,s]);let k=async e=>{try{var t,s,r;let n=null!==(t=null==e?void 0:e.key_alias)&&void 0!==t?t:"",d=null!==(s=null==e?void 0:e.team_id)&&void 0!==s?s:null;if((null!==(r=null==o?void 0:o.filter(e=>e.team_id===d).map(e=>e.key_alias))&&void 0!==r?r:[]).includes(n))throw Error("Key alias ".concat(n," already exists for team with ID ").concat(d,", please provide another key alias"));u.ZP.info("Making API Call"),m(!0);let h=await j(a,l,e);console.log("key create Response:",h),i(e=>e?[...e,h]:[h]),x(h.key),g(h.soft_budget),u.ZP.success("API Key Created"),c.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e),u.ZP.error("Error creating the key: ".concat(e),20)}};return(0,n.useEffect)(()=>{_(t&&t.models.length>0?t.models.includes("all-proxy-models")?y:t.models:y)},[t,y]),(0,r.jsxs)("div",{children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,r.jsx)(er.Z,{title:"Create Key",visible:d,width:800,footer:null,onOk:w,onCancel:b,children:(0,r.jsxs)(ea.Z,{form:c,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:t?t.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,r.jsx)(en.Z,{value:t?t.team_alias:"",disabled:!0})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&c.setFieldsValue({models:["all-team-models"]})},children:[(0,r.jsx)(ec,{value:"all-team-models",children:"All Team Models"},"all-team-models"),Z.map(e=>(0,r.jsx)(ec,{value:e,children:e},e))]})}),(0,r.jsxs)($.Z,{className:"mt-20 mb-8",children:[(0,r.jsx)(Q.Z,{children:(0,r.jsx)("b",{children:"Optional Settings"})}),(0,r.jsxs)(X.Z,{children:[(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(t.max_budget))}}],children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,r.jsxs)(es.default,{defaultValue:null,placeholder:"n/a",children:[(0,r.jsx)(es.default.Option,{value:"24h",children:"daily"}),(0,r.jsx)(es.default.Option,{value:"30d",children:"monthly"})]})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(en.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Create Key"})})]})}),h&&(0,r.jsx)(er.Z,{visible:d,onOk:w,onCancel:b,footer:null,children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(el.Z,{children:"Save your Key"}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,r.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:null!=h?(0,r.jsxs)("div",{children:[(0,r.jsx)(ee.Z,{className:"mt-3",children:"API Key:"}),(0,r.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,r.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:h})}),(0,r.jsx)(et.CopyToClipboard,{text:h,onCopy:()=>{u.ZP.success("API Key copied to clipboard")},children:(0,r.jsx)(J.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,r.jsx)(ee.Z,{children:"Key being created, this might take 30s"})})]})})]})},em=t(9454),eu=t(98941),eh=t(33393),ex=t(5),ep=t(13810),ej=t(61244),eg=t(10827),ey=t(3851),ef=t(2044),eZ=t(64167),e_=t(74480),ew=t(7178),eb=t(95093),ek=t(27166);let{Option:ev}=es.default;var eS=e=>{let{userID:l,userRole:t,accessToken:s,selectedTeam:a,data:o,setData:i,teams:c}=e,[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(!1),[p,j]=(0,n.useState)(null),[g,f]=(0,n.useState)(null),[Z,_]=(0,n.useState)(null),[w,b]=(0,n.useState)(""),[k,v]=(0,n.useState)(!1),[S,A]=(0,n.useState)(!1),[E,I]=(0,n.useState)(null),[C,P]=(0,n.useState)([]),T=new Set,[O,F]=(0,n.useState)(T);(0,n.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==s&&null!==t){let e=(await N(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),P(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[s,l,t]),(0,n.useEffect)(()=>{if(c){let e=new Set;c.forEach((l,t)=>{let s=l.team_id;e.add(s)}),F(e)}},[c]);let R=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),I(e),v(!0)},M=async e=>{if(null==s)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let t=await L(s,e);console.log("handleEditSubmit: newKeyValues",t),o&&i(o.map(e=>e.token===l?t:e)),u.ZP.success("Key updated successfully"),v(!1),I(null)},U=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=o&&(j(e.token),localStorage.removeItem("userData"+l),x(!0))},D=async()=>{if(null!=p&&null!=o){try{await y(s,p);let e=o.filter(e=>e.token!==p);i(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),j(null)}};if(null!=o)return console.log("RERENDER TRIGGERED"),(0,r.jsxs)("div",{children:[(0,r.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,r.jsxs)(eg.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Key Alias"}),(0,r.jsx)(e_.Z,{children:"Secret Key"}),(0,r.jsx)(e_.Z,{children:"Spend (USD)"}),(0,r.jsx)(e_.Z,{children:"Budget (USD)"}),(0,r.jsx)(e_.Z,{children:"Models"}),(0,r.jsx)(e_.Z,{children:"TPM / RPM Limits"})]})}),(0,r.jsx)(ey.Z,{children:o.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(a){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(O.has(e.team_id),", selectedTeam id: ").concat(a.team_id)),(null!=a.team_id||null===e.team_id||O.has(e.team_id))&&e.team_id!=a.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,r.jsx)(ee.Z,{children:e.key_alias}):(0,r.jsx)(ee.Z,{children:"Not Set"})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:e.key_name})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,r.jsx)(ef.Z,{children:null!=e.max_budget?(0,r.jsx)(ee.Z,{children:e.max_budget}):(0,r.jsx)(ee.Z,{children:"Unlimited"})}),(0,r.jsx)(ef.Z,{children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(r.Fragment,{children:a&&a.models&&a.models.length>0?a.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Team Models"})},l):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Team Models"})},l):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(ef.Z,{children:(0,r.jsxs)(ee.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{onClick:()=>{I(e),A(!0)},icon:em.Z,size:"sm"}),(0,r.jsx)(er.Z,{open:S,onCancel:()=>{A(!1),I(null)},footer:null,width:800,children:E&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-8",children:[(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat(E.spend).toFixed(4)}catch(e){return E.spend}})()})})]}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.max_budget?(0,r.jsx)(r.Fragment,{children:E.max_budget}):(0,r.jsx)(r.Fragment,{children:"Unlimited"})})})]},e.name),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.expires?(0,r.jsx)(r.Fragment,{children:new Date(E.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,r.jsx)(r.Fragment,{children:"Never"})})})]},e.name)]}),(0,r.jsxs)(ep.Z,{className:"my-4",children:[(0,r.jsx)(el.Z,{children:"Token Name"}),(0,r.jsx)(ee.Z,{className:"my-1",children:E.key_alias?E.key_alias:E.key_name}),(0,r.jsx)(el.Z,{children:"Token ID"}),(0,r.jsx)(ee.Z,{className:"my-1 text-[12px]",children:E.token}),(0,r.jsx)(el.Z,{children:"Metadata"}),(0,r.jsx)(ee.Z,{className:"my-1",children:(0,r.jsxs)("pre",{children:[JSON.stringify(E.metadata)," "]})})]}),(0,r.jsx)(J.Z,{className:"mx-auto flex items-center",onClick:()=>{A(!1),I(null)},children:"Close"})]})}),(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>R(e)}),(0,r.jsx)(ej.Z,{onClick:()=>U(e),icon:eh.Z,size:"sm"})]})]},e.token)})})]}),h&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:""}),(0,r.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(J.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(J.Z,{onClick:()=>{x(!1),j(null)},children:"Cancel"})]})]})]})})]}),E&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,token:s,onSubmit:o}=e,[i]=ea.Z.useForm(),[d,m]=(0,n.useState)(a),[u,h]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1);return(0,r.jsx)(er.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{i.validateFields().then(e=>{i.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(ea.Z,{form:i,onFinish:M,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)(en.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let t=l.filter(e=>!d.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!d.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(t)),t.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(t,"Team models: ").concat(d.models)):Promise.resolve()}}],children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(ev,{value:"all-team-models",children:"All Team Models"},"all-team-models"),d&&d.models?d.models.includes("all-proxy-models")?C.filter(e=>"all-proxy-models"!==e).map(e=>(0,r.jsx)(ev,{value:e,children:e},e)):d.models.map(e=>(0,r.jsx)(ev,{value:e,children:e},e)):C.map(e=>(0,r.jsx)(ev,{value:e,children:e},e))]})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==d?void 0:d.max_budget)!==null&&(null==d?void 0:d.max_budget)!==void 0?null==d?void 0:d.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&d&&null!==d.max_budget&&l>d.max_budget)throw console.log("keyTeam.max_budget: ".concat(d.max_budget)),Error("Budget cannot exceed team max budget: $".concat(d.max_budget))}}],children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{label:"token",name:"token",hidden:!0}),(0,r.jsx)(ea.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,r.jsx)(eb.Z,{value:s.team_alias,children:null==c?void 0:c.map((e,l)=>(0,r.jsx)(ek.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:k,onCancel:()=>{v(!1),I(null)},token:E,onSubmit:M})]})},eN=t(76032),eA=t(35152),eE=e=>{let{userID:l,userRole:t,accessToken:s,userSpend:a,selectedTeam:o}=e;console.log("userSpend: ".concat(a));let[i,c]=(0,n.useState)(null!==a?a:0),[d,m]=(0,n.useState)(0),[u,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=async()=>{if(s&&l&&t&&"Admin"===t&&null==a)try{let e=await w(s);e&&(e.spend?c(e.spend):c(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===t)return;if(null!==s){let e=(await N(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),h(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,s,l]),(0,n.useEffect)(()=>{null!==a&&c(a)},[a]);let x=[];o&&o.models&&(x=o.models),x&&x.includes("all-proxy-models")?(console.log("user models:",u),x=u):x&&x.includes("all-team-models")?x=o.models:x&&0===x.length&&(x=u);let p=void 0!==i?i.toFixed(4):null;return console.log("spend in view user spend: ".concat(i)),(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsxs)("div",{children:[(0,r.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,r.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",p]})]}),(0,r.jsx)("div",{className:"ml-auto",children:(0,r.jsxs)($.Z,{children:[(0,r.jsx)(Q.Z,{children:(0,r.jsx)(ee.Z,{children:"Team Models"})}),(0,r.jsx)(X.Z,{className:"absolute right-0 z-10 bg-white p-2 shadow-lg max-w-xs",children:(0,r.jsx)(eN.Z,{children:x.map(e=>(0,r.jsx)(eA.Z,{children:(0,r.jsx)(ee.Z,{children:e})},e))})})]})})]})},eI=e=>{let{userID:l,userRole:t,selectedTeam:s,accessToken:a}=e,[o,i]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==a){let e=(await N(a,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),i(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,t]);let c=[];return s&&s.models&&(c=s.models),c&&c.includes("all-proxy-models")&&(console.log("user models:",o),c=o),(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("div",{className:"mb-5",children:(0,r.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==s?void 0:s.team_alias})})})},eC=e=>{let l,{teams:t,setSelectedTeam:s,userRole:a}=e,o={models:[],team_id:null,team_alias:"Default Team"},[i,c]=(0,n.useState)(o);return(l="App User"===a?t:t?[...t,o]:[o],"App User"===a)?null:(0,r.jsxs)("div",{className:"mt-5 mb-5",children:[(0,r.jsx)(el.Z,{children:"Select Team"}),(0,r.jsx)(ee.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,r.jsxs)(ee.Z,{className:"mt-3 mb-3",children:[(0,r.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,r.jsx)(eb.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(ek.Z,{value:String(l),onClick:()=>s(e),children:e.team_alias},l))}):(0,r.jsxs)(ee.Z,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]})},eP=t(37963),eT=t(36083);console.log("isLocal:",!1);var eO=e=>{let{userID:l,userRole:t,teams:s,keys:a,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:m,setKeys:u}=e,[h,x]=(0,n.useState)(null),p=(0,o.useSearchParams)();p.get("viewSpend"),(0,o.useRouter)();let j=p.get("token"),[g,y]=(0,n.useState)(null),[f,_]=(0,n.useState)(null),[b,k]=(0,n.useState)([]),v={models:[],team_alias:"Default Team",team_id:null},[S,A]=(0,n.useState)(s?s[0]:v);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(j){let e=(0,eP.o)(j);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),y(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),i(l)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&g&&t&&!a&&!h){let e=sessionStorage.getItem("userModels"+l);e?k(JSON.parse(e)):(async()=>{try{let e=await Z(g,l,t,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==t){let e=await w(g);x(e),console.log("globalSpend:",e)}else x(e.user_info);u(e.keys),m(e.teams);let s=[...e.teams];s.length>0?(console.log("response['teams']: ".concat(s)),A(s[0])):A(v),sessionStorage.setItem("userData"+l,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(e.user_info));let a=(await N(g,l,t)).data.map(e=>e.id);console.log("available_model_names:",a),k(a),console.log("userModels:",b),sessionStorage.setItem("userModels"+l,JSON.stringify(a))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,j,g,a,t]),(0,n.useEffect)(()=>{if(null!==a&&null!=S){let e=0;for(let l of a)S.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===S.team_id&&(e+=l.spend);_(e)}else if(null!==a){let e=0;for(let l of a)e+=l.spend;_(e)}},[S]),null==l||null==j){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==g)return null;if(null==t&&i("App Owner"),t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=eT.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",S),console.log("teamSpend: ".concat(f)),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsx)(W.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(eI,{userID:l,userRole:t,selectedTeam:S||null,accessToken:g}),(0,r.jsx)(eE,{userID:l,userRole:t,accessToken:g,userSpend:f,selectedTeam:S||null}),(0,r.jsx)(eS,{userID:l,userRole:t,accessToken:g,selectedTeam:S||null,data:a,setData:u,teams:s}),(0,r.jsx)(ed,{userID:l,team:S||null,userRole:t,accessToken:g,data:a,setData:u},S?S.team_id:null),(0,r.jsx)(eC,{teams:s,setSelectedTeam:A,userRole:t})]})})})},eF=t(35087),eR=t(92836),eM=t(26734),eL=t(41608),eU=t(32126),eD=t(23682),eK=t(47047),eB=t(76628),ez=t(57750),eq=t(44041),eV=t(38302),eG=t(28683),eY=t(1460),eW=t(78578),eJ=t(63954),eH=t(90252),e$=t(7905),eX=e=>{let{modelID:l,accessToken:t}=e,[s,a]=(0,n.useState)(!1),o=async()=>{try{u.ZP.info("Making API Call"),a(!0);let e=await p(t,l);console.log("model delete Response:",e),u.ZP.success("Model ".concat(l," deleted successfully")),a(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(ej.Z,{onClick:()=>a(!0),icon:eh.Z,size:"sm"}),(0,r.jsx)(er.Z,{open:s,onOk:o,okType:"danger",onCancel:()=>a(!1),children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(el.Z,{children:"Delete Model"}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Model ID: ",(0,r.jsx)("b",{children:l})]})})]})})]})},eQ=t(97766),e0=t(46495);let{Title:e1,Link:e2}=eT.default;(s=a||(a={})).OpenAI="OpenAI",s.Azure="Azure",s.Anthropic="Anthropic",s.Google_AI_Studio="Gemini (Google AI Studio)",s.Bedrock="Amazon Bedrock",s.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",s.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)";let e4={OpenAI:"openai",Azure:"azure",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai"},e8={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},e5=async(e,l,t)=>{try{let s=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(s)),console.log("received type of deployments: ".concat(typeof s)),s.forEach(async t=>{console.log("litellm_model: ".concat(t));let s={},a={};s.model=t;let r="";for(let[l,t]of Object.entries(e))if(""!==t){if("model_name"==l)r+=t;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)a[l]=t;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",t);let e={};if(t&&void 0!=t){try{e=JSON.parse(t)}catch(e){throw u.ZP.error("Failed to parse LiteLLM Extra Params: "+e,10),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))s[l]=t}}else s[l]=t}let n={model_name:r,litellm_params:s,model_info:a},o=await x(l,n);console.log("response for model create call: ".concat(o.data))}),t.resetFields()}catch(e){u.ZP.error("Failed to create model: "+e,10)}};var e3=e=>{var l,t,s;let{accessToken:o,token:i,userRole:c,userID:d,modelData:m={data:[]},setModelData:x}=e,[p,j]=(0,n.useState)([]),[g]=ea.Z.useForm(),[y,f]=(0,n.useState)(null),[Z,_]=(0,n.useState)(""),[w,N]=(0,n.useState)([]),A=Object.values(a).filter(e=>isNaN(Number(e))),[E,I]=(0,n.useState)("OpenAI"),[C,P]=(0,n.useState)(""),[T,O]=(0,n.useState)(!1),[F,R]=(0,n.useState)(null),[M,L]=(0,n.useState)([]),[U,K]=(0,n.useState)(null),[B,z]=(0,n.useState)([]),[Y,et]=(0,n.useState)([]),[es,en]=(0,n.useState)([]),[ec,ed]=(0,n.useState)([]),[em,eh]=(0,n.useState)([]),[ev,eS]=(0,n.useState)([]),[eN,eA]=(0,n.useState)([]),[eE,eI]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[eC,eP]=(0,n.useState)(null),[eO,e3]=(0,n.useState)(0),e6=e=>{R(e),O(!0)},e7=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},t=null;for(let[s,a]of Object.entries(e))"model_id"!==s?l[s]=a:t=a;let s={litellm_params:l,model_info:{id:t}};console.log("handleEditSubmit payload:",s);try{await D(o,s),u.ZP.success("Model updated successfully, restart server to see updates"),O(!1),R(null)}catch(e){console.log("Error occurred")}},e9=()=>{_(new Date().toLocaleString())},le=async()=>{if(!o){console.error("Access token is missing");return}console.log("new modelGroupRetryPolicy:",eC);try{await V(o,{router_settings:{model_group_retry_policy:eC}}),u.ZP.success("Retry settings saved successfully")}catch(e){console.error("Failed to save retry settings:",e),u.ZP.error("Failed to save retry settings")}};if((0,n.useEffect)(()=>{if(!o||!i||!c||!d)return;let e=async()=>{try{var e,l,t,s,a,r;let n=await b(o,d,c);console.log("Model data response:",n.data),x(n);let i=new Set;for(let e=0;e0&&(u=m[m.length-1],console.log("_initial_model_group:",u),K(u)),console.log("selectedModelGroup:",U);let h=await k(o,d,c,u,null===(e=eE.from)||void 0===e?void 0:e.toISOString(),null===(l=eE.to)||void 0===l?void 0:l.toISOString());console.log("Model metrics response:",h),et(h.data),en(h.all_api_bases);let p=await S(o,d,c,u,null===(t=eE.from)||void 0===t?void 0:t.toISOString(),null===(s=eE.to)||void 0===s?void 0:s.toISOString());console.log("Model exceptions response:",p),ed(p.data),eh(p.exception_types);let j=await v(o,d,c,u,null===(a=eE.from)||void 0===a?void 0:a.toISOString(),null===(r=eE.to)||void 0===r?void 0:r.toISOString());console.log("slowResponses:",j),eA(j);let g=(await q(o,d,c)).router_settings;console.log("routerSettingsInfo:",g);let y=g.model_group_retry_policy,f=g.num_retries;console.log("model_group_retry_policy:",y),console.log("default_retries:",f),eP(y),e3(f)}catch(e){console.error("There was an error fetching the model data",e)}};o&&i&&c&&d&&e();let l=async()=>{let e=await h();console.log("received model cost map data: ".concat(Object.keys(e))),f(e)};null==y&&l(),e9()},[o,i,c,d,y,Z]),!m||!o||!i||!c||!d)return(0,r.jsx)("div",{children:"Loading..."});let ll=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(y)),null!=y&&"object"==typeof y&&e in y)?y[e].litellm_provider:"openai";if(a){let e=a.split("/"),l=e[0];n=1===e.length?u(a):l}else n="openai";r&&(o=null==r?void 0:r.input_cost_per_token,i=null==r?void 0:r.output_cost_per_token,c=null==r?void 0:r.max_tokens),(null==s?void 0:s.litellm_params)&&(d=Object.fromEntries(Object.entries(null==s?void 0:s.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),m.data[e].provider=n,m.data[e].input_cost=o,m.data[e].output_cost=i,m.data[e].max_tokens=c,m.data[e].api_base=null==s?void 0:null===(t=s.litellm_params)||void 0===t?void 0:t.api_base,m.data[e].cleanedLitellmParams=d,ll.push(s.model_name),console.log(m.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=eT.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let lt=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(a).find(l=>a[l]===e);if(l){let e=e4[l];console.log("mappingResult: ".concat(e));let t=[];"object"==typeof y&&Object.entries(y).forEach(l=>{let[s,a]=l;null!==a&&"object"==typeof a&&"litellm_provider"in a&&(a.litellm_provider===e||a.litellm_provider.includes(e))&&t.push(s)}),N(t),console.log("providerModels: ".concat(w))}},ls=async()=>{try{u.ZP.info("Running health check..."),P("");let e=await G(o);P(e)}catch(e){console.error("Error running health check:",e),P("Error running health check")}},la=async(e,l,t)=>{if(console.log("Updating model metrics for group:",e),o&&d&&c&&l&&t){console.log("inside updateModelMetrics - startTime:",l,"endTime:",t),K(e);try{let s=await k(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model metrics response:",s),et(s.data),en(s.all_api_bases);let a=await S(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model exceptions response:",a),ed(a.data),eh(a.exception_types);let r=await v(o,d,c,e,l.toISOString(),t.toISOString());console.log("slowResponses:",r),eA(r)}catch(e){console.error("Failed to fetch model metrics",e)}}};return console.log("selectedProvider: ".concat(E)),console.log("providerModels.length: ".concat(w.length)),(0,r.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,r.jsxs)(eM.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(eL.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)(eR.Z,{children:"All Models"}),(0,r.jsx)(eR.Z,{children:"Add Model"}),(0,r.jsx)(eR.Z,{children:(0,r.jsx)("pre",{children:"/health Models"})}),(0,r.jsx)(eR.Z,{children:"Model Analytics"}),(0,r.jsx)(eR.Z,{children:"Model Retry Settings"})]}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[Z&&(0,r.jsxs)(ee.Z,{children:["Last Refreshed: ",Z]}),(0,r.jsx)(ej.Z,{icon:eJ.Z,variant:"shadow",size:"xs",className:"self-center",onClick:e9})]})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)(W.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(ee.Z,{children:"Filter by Public Model Name"}),(0,r.jsxs)(eb.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:"all",onValueChange:e=>K("all"===e?"all":e),children:[(0,r.jsx)(ek.Z,{value:"all",children:"All Models"}),M.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>K(e),children:e},l))]})]}),(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eg.Z,{className:"mt-5",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Public Model Name "}),(0,r.jsx)(e_.Z,{children:"Provider"}),"Admin"===c&&(0,r.jsx)(e_.Z,{children:"API Base"}),(0,r.jsx)(e_.Z,{children:"Extra litellm Params"}),(0,r.jsx)(e_.Z,{children:"Input Price per token ($)"}),(0,r.jsx)(e_.Z,{children:"Output Price per token ($)"}),(0,r.jsx)(e_.Z,{children:"Max Tokens"}),(0,r.jsx)(e_.Z,{children:"Status"})]})}),(0,r.jsx)(ey.Z,{children:m.data.filter(e=>"all"===U||e.model_name===U||null==U||""===U).map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:e.model_name})}),(0,r.jsx)(ef.Z,{children:e.provider}),"Admin"===c&&(0,r.jsx)(ef.Z,{children:e.api_base}),(0,r.jsx)(ef.Z,{children:(0,r.jsxs)($.Z,{children:[(0,r.jsx)(Q.Z,{children:(0,r.jsx)(ee.Z,{children:"Litellm params"})}),(0,r.jsx)(X.Z,{children:(0,r.jsx)("pre",{children:JSON.stringify(e.cleanedLitellmParams,null,2)})})]})}),(0,r.jsx)(ef.Z,{children:e.input_cost||e.litellm_params.input_cost_per_token||null}),(0,r.jsx)(ef.Z,{children:e.output_cost||e.litellm_params.output_cost_per_token||null}),(0,r.jsx)(ef.Z,{children:e.max_tokens}),(0,r.jsx)(ef.Z,{children:e.model_info.db_model?(0,r.jsx)(ex.Z,{icon:eH.Z,className:"text-white",children:"DB Model"}):(0,r.jsx)(ex.Z,{icon:e$.Z,className:"text-black",children:"Config Model"})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>e6(e)}),(0,r.jsx)(eX,{modelID:e.model_info.id,accessToken:o})]})]},l))})]})})]}),(0,r.jsx)(e=>{let{visible:l,onCancel:t,model:s,onSubmit:a}=e,[n]=ea.Z.useForm(),o={},i="",c="";if(s){o=s.litellm_params,i=s.model_name;let e=s.model_info;e&&(c=e.id,console.log("model_id: ".concat(c)),o.model_id=c)}return(0,r.jsx)(er.Z,{title:"Edit Model "+i,visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a(e),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(ea.Z,{form:n,onFinish:e7,initialValues:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,r.jsx)(H.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"max_retries",name:"max_retries",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"input_cost_per_token",name:"input_cost_per_token",tooltip:"float (optional) - Input cost per token",children:(0,r.jsx)(eo.Z,{min:0,step:1e-4})}),(0,r.jsx)(ea.Z.Item,{label:"output_cost_per_token",name:"output_cost_per_token",tooltip:"float (optional) - Output cost per token",children:(0,r.jsx)(eo.Z,{min:0,step:1e-4})}),(0,r.jsx)(ea.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:T,onCancel:()=>{O(!1),R(null)},model:F,onSubmit:e7})]}),(0,r.jsxs)(eU.Z,{className:"h-full",children:[(0,r.jsx)(e1,{level:2,children:"Add new model"}),(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(ea.Z,{form:g,onFinish:()=>{g.validateFields().then(e=>{e5(e,o,g)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eb.Z,{value:E.toString(),children:A.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>{lt(e),I(e)},children:e},l))})}),(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,r.jsx)(H.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(s=E.toString())?"gemini-pro":"Anthropic"==s?"claude-3-opus":"Amazon Bedrock"==s?"claude-3-opus":"Gemini (Google AI Studio)"==s?"gemini-pro":"gpt-3.5-turbo"})}),(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsx)(ee.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===E?(0,r.jsx)(H.Z,{placeholder:"Enter model name"}):w.length>0?(0,r.jsx)(eK.Z,{value:w,children:w.map((e,l)=>(0,r.jsx)(eB.Z,{value:e,children:e},l))}):(0,r.jsx)(H.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsxs)(ee.Z,{className:"mb-3 mt-1",children:["Actual model name used for making ",(0,r.jsx)(e2,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll ",(0,r.jsx)(e2,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," models with the same 'public name'"]})})]}),"Amazon Bedrock"!=E&&"Vertex AI (Anthropic, Gemini, etc.)"!=E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,r.jsx)(H.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==E&&(0,r.jsx)(ea.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,r.jsx)(H.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,r.jsx)(H.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,r.jsx)(H.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,r.jsx)(e0.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;g.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?u.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&u.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,r.jsx)(ei.ZP,{icon:(0,r.jsx)(eQ.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsx)(ee.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==E||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==E)&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,r.jsx)(H.Z,{placeholder:"https://..."})}),"Azure"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,r.jsx)(H.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==E&&(0,r.jsxs)(ea.Z.Item,{label:"Base Model",name:"base_model",children:[(0,r.jsx)(H.Z,{placeholder:"azure/gpt-3.5-turbo"}),(0,r.jsxs)(ee.Z,{children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from ",(0,r.jsx)(e2,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})]}),"Amazon Bedrock"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)(H.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)(H.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)(H.Z,{placeholder:"us-east-1"})}),(0,r.jsx)(ea.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,r.jsx)(eW.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsxs)(ee.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params ",(0,r.jsx)(e2,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,r.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add Model"})}),(0,r.jsx)(eY.Z,{title:"Get help on our github",children:(0,r.jsx)(eT.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(ee.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,r.jsx)(J.Z,{onClick:ls,children:"Run `/health`"}),C&&(0,r.jsx)("pre",{children:JSON.stringify(C,null,2)})]})}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)(W.Z,{numItems:2,className:"mt-2",children:[(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Time Range"}),(0,r.jsx)(eF.Z,{enableSelect:!0,value:eE,onValueChange:e=>{eI(e),la(U,e.from,e.to)}})]}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Model Group"}),(0,r.jsx)(eb.Z,{className:"mb-4 mt-2",defaultValue:U||M[0],value:U||M[0],children:M.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>la(e,eE.from,eE.to),children:e},l))})]})]}),(0,r.jsxs)(W.Z,{numItems:2,children:[(0,r.jsx)(eG.Z,{children:(0,r.jsxs)(ep.Z,{className:"mr-2 max-h-[400px] min-h-[400px]",children:[(0,r.jsx)(el.Z,{children:"Avg Latency per Token"}),(0,r.jsx)("p",{className:"text-gray-500 italic",children:" (seconds/token)"}),(0,r.jsx)(ee.Z,{className:"text-gray-500 italic mt-1 mb-1",children:"average Latency for successfull requests divided by the total tokens"}),Y&&es&&(0,r.jsx)(ez.Z,{title:"Model Latency",className:"h-72",data:Y,showLegend:!1,index:"date",categories:es,connectNulls:!0,customTooltip:e=>{var l,t;let{payload:s,active:a}=e;if(!a||!s)return null;let n=null===(t=s[0])||void 0===t?void 0:null===(l=t.payload)||void 0===l?void 0:l.date,o=s.sort((e,l)=>l.value-e.value);if(o.length>5){let e=o.length-5;(o=o.slice(0,5)).push({dataKey:"".concat(e," other deployments"),value:s.slice(5).reduce((e,l)=>e+l.value,0),color:"gray"})}return(0,r.jsxs)("div",{className:"w-150 rounded-tremor-default border border-tremor-border bg-tremor-background p-2 text-tremor-default shadow-tremor-dropdown",children:[n&&(0,r.jsxs)("p",{className:"text-tremor-content-emphasis mb-2",children:["Date: ",n]}),o.map((e,l)=>{let t=parseFloat(e.value.toFixed(5)),s=0===t&&e.value>0?"<0.00001":t.toFixed(5);return(0,r.jsxs)("div",{className:"flex justify-between",children:[(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)("div",{className:"w-2 h-2 mt-1 rounded-full bg-".concat(e.color,"-500")}),(0,r.jsx)("p",{className:"text-tremor-content",children:e.dataKey})]}),(0,r.jsx)("p",{className:"font-medium text-tremor-content-emphasis text-righ ml-2",children:s})]},l)})]})}})]})}),(0,r.jsx)(eG.Z,{children:(0,r.jsx)(ep.Z,{className:"ml-2 max-h-[400px] min-h-[400px] overflow-y-auto",children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Deployment"}),(0,r.jsx)(e_.Z,{children:"Success Responses"}),(0,r.jsxs)(e_.Z,{children:["Slow Responses ",(0,r.jsx)("p",{children:"Success Responses taking 600+s"})]})]})}),(0,r.jsx)(ey.Z,{children:eN.map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.api_base}),(0,r.jsx)(ef.Z,{children:e.total_count}),(0,r.jsx)(ef.Z,{children:e.slow_count})]},l))})]})})})]}),(0,r.jsxs)(ep.Z,{className:"mt-4",children:[(0,r.jsx)(el.Z,{children:"Exceptions per Model"}),(0,r.jsx)(eq.Z,{className:"h-72",data:ec,index:"model",categories:em,stack:!0,colors:["indigo-300","rose-200","#ffcc33"],yAxisWidth:30})]})]}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(ee.Z,{children:"Filter by Public Model Name"}),(0,r.jsx)(eb.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:U||M[0],value:U||M[0],onValueChange:e=>K(e),children:M.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>K(e),children:e},l))})]}),(0,r.jsxs)(el.Z,{children:["Retry Policy for ",U]}),(0,r.jsx)(ee.Z,{className:"mb-6",children:"How many retries should be attempted based on the Exception"}),e8&&(0,r.jsx)("table",{children:(0,r.jsx)("tbody",{children:Object.entries(e8).map((e,l)=>{var t;let[s,a]=e,n=null==eC?void 0:null===(t=eC[U])||void 0===t?void 0:t[a];return null==n&&(n=eO),(0,r.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,r.jsx)("td",{children:(0,r.jsx)(ee.Z,{children:s})}),(0,r.jsx)("td",{children:(0,r.jsx)(eo.Z,{className:"ml-5",value:n,min:0,step:1,onChange:e=>{eP(l=>{var t;let s=null!==(t=null==l?void 0:l[U])&&void 0!==t?t:{};return{...null!=l?l:{},[U]:{...s,[a]:e}}})}})})]},l)})})}),(0,r.jsx)(J.Z,{className:"mt-6 mr-8",onClick:le,children:"Save"})]})]})]})})};let{Option:e6}=es.default;var e7=e=>{let{userID:l,accessToken:t,teams:s}=e,[a]=ea.Z.useForm(),[o,i]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[m,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await N(t,l,"any"),s=[];for(let l=0;l{i(!1),a.resetFields()},p=()=>{i(!1),d(null),a.resetFields()},j=async e=>{try{u.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let s=await g(t,null,e);console.log("user create Response:",s),d(s.key),u.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Invite User"}),(0,r.jsxs)(er.Z,{title:"Invite User",visible:o,width:800,footer:null,onOk:x,onCancel:p,children:[(0,r.jsx)(ee.Z,{className:"mb-1",children:"Invite a user to login to the Admin UI and create Keys"}),(0,r.jsx)(ee.Z,{className:"mb-6",children:(0,r.jsx)("b",{children:"Note: SSO Setup Required for this"})}),(0,r.jsxs)(ea.Z,{form:a,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsx)(ea.Z.Item,{label:"User Email",name:"user_email",children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Team ID",name:"team_id",children:(0,r.jsx)(es.default,{placeholder:"Select Team ID",style:{width:"100%"},children:s?s.map(e=>(0,r.jsx)(e6,{value:e.team_id,children:e.team_alias},e.team_id)):(0,r.jsx)(e6,{value:null,children:"Default Team"},"default")})}),(0,r.jsx)(ea.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(en.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Create User"})})]})]}),c&&(0,r.jsxs)(er.Z,{title:"User Created Successfully",visible:o,onOk:x,onCancel:p,footer:null,children:[(0,r.jsx)("p",{children:"User has been created to access your proxy. Please Ask them to Log In."}),(0,r.jsx)("br",{}),(0,r.jsx)("p",{children:(0,r.jsx)("b",{children:"Note: This Feature is only supported through SSO on the Admin UI"})})]})]})},e9=e=>{let{accessToken:l,token:t,keys:s,userRole:a,userID:o,teams:i,setKeys:c}=e,[d,m]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(0),[j,g]=n.useState(null),[y,f]=(0,n.useState)(null);return((0,n.useEffect)(()=>{if(!l||!t||!a||!o)return;let e=async()=>{try{let e=await Z(l,null,a,!0,x,25);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};l&&t&&a&&o&&e()},[l,t,a,o,x]),d&&l&&t&&a&&o)?(0,r.jsx)("div",{style:{width:"100%"},children:(0,r.jsxs)(W.Z,{className:"gap-2 p-2 h-[80vh] w-full mt-8",children:[(0,r.jsx)(e7,{userID:o,accessToken:l,teams:i}),(0,r.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[80vh] mb-4",children:[(0,r.jsx)("div",{className:"mb-4 mt-1",children:(0,r.jsx)(ee.Z,{children:"These are Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM"})}),(0,r.jsx)(eM.Z,{children:(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(eg.Z,{className:"mt-5",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"User ID"}),(0,r.jsx)(e_.Z,{children:"User Email"}),(0,r.jsx)(e_.Z,{children:"User Models"}),(0,r.jsx)(e_.Z,{children:"User Spend ($ USD)"}),(0,r.jsx)(e_.Z,{children:"User Max Budget ($ USD)"}),(0,r.jsx)(e_.Z,{children:"User API Key Aliases"})]})}),(0,r.jsx)(ey.Z,{children:d.map(e=>{var l;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.user_id}),(0,r.jsx)(ef.Z,{children:e.user_email}),(0,r.jsx)(ef.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,r.jsx)(ef.Z,{children:e.spend?null===(l=e.spend)||void 0===l?void 0:l.toFixed(2):0}),(0,r.jsx)(ef.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(W.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,r.jsx)(ex.Z,{size:"xs",color:"indigo",children:e.key_aliases.filter(e=>null!==e).join(", ")}):(0,r.jsx)(ex.Z,{size:"xs",color:"gray",children:"No Keys"})})})]},e.user_id)})})]})}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("div",{className:"flex-1"}),(0,r.jsx)("div",{className:"flex-1 flex justify-between items-center"})]})})]})})]}),function(){if(!d)return null;let e=Math.ceil(d.length/25);return(0,r.jsxs)("div",{className:"flex justify-between items-center",children:[(0,r.jsxs)("div",{children:["Showing Page ",x+1," of ",e]}),(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===x,onClick:()=>p(x-1),children:"← Prev"}),(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{p(x+1)},children:"Next →"})]})]})}()]})}):(0,r.jsx)("div",{children:"Loading..."})},le=e=>{let{teams:l,searchParams:t,accessToken:s,setTeams:a,userID:o,userRole:i}=e,[c]=ea.Z.useForm(),[d]=ea.Z.useForm(),{Title:m,Paragraph:h}=eT.default,[x,p]=(0,n.useState)(""),[j,g]=(0,n.useState)(!1),[y,Z]=(0,n.useState)(l?l[0]:null),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1),[S,A]=(0,n.useState)([]),[E,I]=(0,n.useState)(!1),[C,P]=(0,n.useState)(null),[T,O]=(0,n.useState)({}),F=e=>{Z(e),g(!0)},R=async e=>{let t=e.team_id;if(console.log("handleEditSubmit:",e),null==s)return;let r=await U(s,e);l&&a(l.map(e=>e.team_id===t?r.data:e)),u.ZP.success("Team updated successfully"),g(!1),Z(null)},L=async e=>{P(e),I(!0)},D=async()=>{if(null!=C&&null!=l&&null!=s){try{await f(s,C);let e=l.filter(e=>e.team_id!==C);a(e)}catch(e){console.error("Error deleting the team:",e)}I(!1),P(null)}};(0,n.useEffect)(()=>{let e=async()=>{try{if(null===o||null===i||null===s||null===l)return;console.log("fetching team info:");let e={};for(let t=0;t<(null==l?void 0:l.length);t++){let a=l[t].team_id,r=await _(s,a);console.log("teamInfo response:",r),null!==r&&(e={...e,[a]:r})}O(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===o||null===i)return;if(null!==s){let e=(await N(s,o,i)).data.map(e=>e.id);console.log("available_model_names:",e),A(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,o,i,l]);let B=async e=>{try{if(null!=s){var t;let r=null==e?void 0:e.team_alias;if((null!==(t=null==l?void 0:l.map(e=>e.team_alias))&&void 0!==t?t:[]).includes(r))throw Error("Team alias ".concat(r," already exists, please pick another alias"));u.ZP.info("Creating Team");let n=await M(s,e);null!==l?a([...l,n]):a([n]),console.log("response for team create call: ".concat(n)),u.ZP.success("Team created"),b(!1)}}catch(e){console.error("Error creating the team:",e),u.ZP.error("Error creating the team: "+e,20)}},z=async e=>{try{if(null!=s&&null!=l){u.ZP.info("Adding Member");let t={role:"user",user_email:e.user_email,user_id:e.user_id},r=await K(s,y.team_id,t);console.log("response for team create call: ".concat(r.data));let n=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(r.data.team_id)),e.team_id===r.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...l];e[n]=r.data,a(e),Z(r.data)}v(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(JSON.stringify(l))),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"All Teams"}),(0,r.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Team Name"}),(0,r.jsx)(e_.Z,{children:"Spend (USD)"}),(0,r.jsx)(e_.Z,{children:"Budget (USD)"}),(0,r.jsx)(e_.Z,{children:"Models"}),(0,r.jsx)(e_.Z,{children:"TPM / RPM Limits"}),(0,r.jsx)(e_.Z,{children:"Info"})]})}),(0,r.jsx)(ey.Z,{children:l&&l.length>0?l.map(e=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,r.jsx)(ef.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})},l):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,r.jsxs)(ee.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsxs)(ee.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].keys&&T[e.team_id].keys.length," ","Keys"]}),(0,r.jsxs)(ee.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].team_info&&T[e.team_id].team_info.members_with_roles&&T[e.team_id].team_info.members_with_roles.length," ","Members"]})]}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>F(e)}),(0,r.jsx)(ej.Z,{onClick:()=>L(e.team_id),icon:eh.Z,size:"sm"})]})]},e.team_id)):null})]}),E&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:""}),(0,r.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(J.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(J.Z,{onClick:()=>{I(!1),P(null)},children:"Cancel"})]})]})]})})]})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>b(!0),children:"+ Create New Team"}),(0,r.jsx)(er.Z,{title:"Create Team",visible:w,width:800,footer:null,onOk:()=>{b(!1),c.resetFields()},onCancel:()=>{b(!1),c.resetFields()},children:(0,r.jsxs)(ea.Z,{form:c,onFinish:B,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(es.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S.map(e=>(0,r.jsx)(es.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(ea.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"Team Members"}),(0,r.jsx)(h,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,r.jsx)(eb.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(ek.Z,{value:String(l),onClick:()=>{Z(e)},children:e.team_alias},l))}):(0,r.jsxs)(h,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Member Name"}),(0,r.jsx)(e_.Z,{children:"Role"})]})}),(0,r.jsx)(ey.Z,{children:y?y.members_with_roles.map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(ef.Z,{children:e.role})]},l)):null})]})}),y&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,team:s,onSubmit:a}=e,[n]=ea.Z.useForm();return(0,r.jsx)(er.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a({...e,team_id:s.team_id}),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(ea.Z,{form:n,onFinish:R,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)(H.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(es.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S&&S.map(e=>(0,r.jsx)(es.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(ea.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:j,onCancel:()=>{g(!1),Z(null)},team:y,onSubmit:R})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(J.Z,{className:"mx-auto mb-5",onClick:()=>v(!0),children:"+ Add member"}),(0,r.jsx)(er.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{v(!1),d.resetFields()},onCancel:()=>{v(!1),d.resetFields()},children:(0,r.jsxs)(ea.Z,{form:c,onFinish:z,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(ea.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ll=t(18190),lt=e=>{let l,{searchParams:t,accessToken:s,showSSOBanner:a}=e,[o]=ea.Z.useForm(),[i]=ea.Z.useForm(),{Title:c,Paragraph:d}=eT.default,[m,h]=(0,n.useState)(""),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)(!1),[y,f]=(0,n.useState)(!1),[Z,_]=(0,n.useState)(!1),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1);try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let S=()=>{v(!1)},N=["proxy_admin","proxy_admin_viewer"];(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],l=await R(s,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let t=await R(s,"proxy_admin");t.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(t)),console.log("combinedList: ".concat(e)),p(e)}})()},[s]);let A=()=>{_(!1),i.resetFields()},E=()=>{_(!1),i.resetFields()},I=e=>(0,r.jsxs)(ea.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(ea.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add member"})})]}),C=(e,l,t)=>(0,r.jsxs)(ea.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eb.Z,{value:l,children:N.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,children:e},l))})}),(0,r.jsx)(ea.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:t,valuePropName:"user_id",className:"mt-8",children:(0,r.jsx)(en.Z,{value:t,disabled:!0})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Update role"})})]}),P=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,null);console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),u.ZP.success("Refresh tab to see updated user role"),_(!1)}}catch(e){console.error("Error creating the key:",e)}},T=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),g(!1)}}catch(e){console.error("Error creating the key:",e)}},O=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call"),e.user_email,e.user_id;let l=await B(s,e,"proxy_admin");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),f(!1)}}catch(e){console.error("Error creating the key:",e)}},F=async e=>{null!=s&&V(s,{environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}})};return console.log("admins: ".concat(null==x?void 0:x.length)),(0,r.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,r.jsx)(c,{level:4,children:"Admin Access "}),(0,r.jsxs)(d,{children:[a&&(0,r.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc. ",(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsx)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Member Name"}),(0,r.jsx)(e_.Z,{children:"Role"})]})}),(0,r.jsx)(ey.Z,{children:x?x.map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(ef.Z,{children:e.user_role}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>_(!0)}),(0,r.jsx)(er.Z,{title:"Update role",visible:Z,width:800,footer:null,onOk:A,onCancel:E,children:C(P,e.user_role,e.user_id)})]})]},l)):null})]})})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)("div",{className:"flex justify-start",children:[(0,r.jsx)(J.Z,{className:"mr-4 mb-5",onClick:()=>f(!0),children:"+ Add admin"}),(0,r.jsx)(er.Z,{title:"Add admin",visible:y,width:800,footer:null,onOk:()=>{f(!1),i.resetFields()},onCancel:()=>{f(!1),i.resetFields()},children:I(O)}),(0,r.jsx)(J.Z,{className:"mb-5",onClick:()=>g(!0),children:"+ Add viewer"}),(0,r.jsx)(er.Z,{title:"Add viewer",visible:j,width:800,footer:null,onOk:()=>{g(!1),i.resetFields()},onCancel:()=>{g(!1),i.resetFields()},children:I(T)})]})})]}),(0,r.jsxs)(W.Z,{children:[(0,r.jsx)(c,{level:4,children:"Add SSO"}),(0,r.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,r.jsx)(J.Z,{onClick:()=>b(!0),children:"Add SSO"}),(0,r.jsx)(er.Z,{title:"Add SSO",visible:w,width:800,footer:null,onOk:()=>{b(!1),o.resetFields()},onCancel:()=>{b(!1),o.resetFields()},children:(0,r.jsxs)(ea.Z,{form:o,onFinish:e=>{O(e),F(e),b(!1),v(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,r.jsx)(en.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,r.jsx)(en.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,r.jsx)(en.Z.Password,{})}),(0,r.jsx)(ea.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,r.jsx)(en.Z.Password,{})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,r.jsxs)(er.Z,{title:"SSO Setup Instructions",visible:k,width:800,footer:null,onOk:S,onCancel:()=>{v(!1)},children:[(0,r.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{onClick:S,children:"Done"})})]})]}),(0,r.jsxs)(ll.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access ",(0,r.jsxs)("a",{href:l,target:"_blank",children:[(0,r.jsx)("b",{children:l})," "]})]})]})]})},ls=t(42556);let la=[{name:"slack",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"langfuse",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"openmeter",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}}];var lr=e=>{let{accessToken:l,userRole:t,userID:s}=e,[a,o]=(0,n.useState)(la),[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)(!1),[h]=ea.Z.useForm(),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)([]),[y,f]=(0,n.useState)(""),[Z,_]=(0,n.useState)({}),[w,b]=(0,n.useState)([]),k=e=>{w.includes(e)?b(w.filter(l=>l!==e)):b([...w,e])},v={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)",daily_reports:"Weekly/Monthly Spend Reports"};(0,n.useEffect)(()=>{l&&t&&s&&q(l,s,t).then(e=>{console.log("callbacks",e);let l=la;o(l=l.map(l=>{let t=e.callbacks.find(e=>e.name===l.name);return t?{...l,variables:{...l.variables,...t.variables}}:l}));let t=e.alerts;if(console.log("alerts_data",t),t&&t.length>0){let e=t[0];console.log("_alert_info",e);let l=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",l),b(e.active_alerts),f(l),_(e.alerts_to_webhook)}c(t)})},[l,t,s]);let S=e=>w&&w.includes(e),N=e=>{if(!l)return;let t=Object.fromEntries(Object.entries(e.variables).map(e=>{var l;let[t,s]=e;return[t,(null===(l=document.querySelector('input[name="'.concat(t,'"]')))||void 0===l?void 0:l.value)||s]}));console.log("updatedVariables",t),console.log("updateAlertTypes",j);let s={environment_variables:t,litellm_settings:{success_callback:[e.name]}};try{V(l,s)}catch(e){u.ZP.error("Failed to update callback: "+e,20)}u.ZP.success("Callback updated successfully")},A=()=>{l&&h.validateFields().then(e=>{if(console.log("Form values:",e),"langfuse"===e.callback){V(l,{environment_variables:{LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey,OPENMETER_API_KEY:null}};o(a?[...a,t]:[t])}else if("slack"===e.callback){console.log("values.slackWebhookUrl: ".concat(e.slackWebhookUrl)),V(l,{general_settings:{alerting:["slack"],alerting_threshold:300},environment_variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl}}),console.log("values.callback: ".concat(e.callback));let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null}};o(a?[...a,t]:[t])}else if("openmeter"==e.callback){console.log("values.openMeterApiKey: ".concat(e.openMeterApiKey)),V(l,{environment_variables:{OPENMETER_API_KEY:e.openMeterApiKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:e.openMeterAPIKey}};o(a?[...a,t]:[t])}m(!1),h.resetFields(),p(null)})};return l?(console.log("callbacks: ".concat(a)),(0,r.jsxs)("div",{className:"w-full mx-4",children:[(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,r.jsx)(ll.Z,{title:"[UI] Presidio PII + Guardrails Coming Soon. https://docs.litellm.ai/docs/proxy/pii_masking",color:"sky"}),(0,r.jsxs)(eM.Z,{children:[(0,r.jsxs)(eL.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eR.Z,{value:"1",children:"Logging Callbacks"}),(0,r.jsx)(eR.Z,{value:"2",children:"Alerting"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Callback"}),(0,r.jsx)(e_.Z,{children:"Callback Env Vars"})]})}),(0,r.jsx)(ey.Z,{children:a.filter(e=>"slack"!==e.name).map((e,t)=>{var s;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ex.Z,{color:"emerald",children:e.name})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)("ul",{children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).filter(l=>{let[t,s]=l;return t.toLowerCase().includes(e.name)}).map(e=>{let[l,t]=e;return(0,r.jsxs)("li",{children:[(0,r.jsx)(ee.Z,{className:"mt-2",children:l}),"LANGFUSE_HOST"===l?(0,r.jsx)("p",{children:"default value=https://cloud.langfuse.com"}):(0,r.jsx)("div",{}),(0,r.jsx)(H.Z,{name:l,defaultValue:t,type:"password"})]},l)})}),(0,r.jsx)(J.Z,{className:"mt-2",onClick:()=>N(e),children:"Save Changes"}),(0,r.jsx)(J.Z,{onClick:()=>z(l,e.name),className:"mx-2",children:"Test Callback"})]})]},t)})})]})})}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsxs)(ee.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from ",(0,r.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{}),(0,r.jsx)(e_.Z,{}),(0,r.jsx)(e_.Z,{children:"Slack Webhook URL"})]})}),(0,r.jsx)(ey.Z,{children:Object.entries(v).map((e,l)=>{let[t,s]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ls.Z,{id:"switch",name:"switch",checked:S(t),onChange:()=>k(t)})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:s})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(H.Z,{name:t,type:"password",defaultValue:Z&&Z[t]?Z[t]:y})})]},l)})})]}),(0,r.jsx)(J.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(v).forEach(l=>{let[t,s]=l,a=document.querySelector('input[name="'.concat(t,'"]'));console.log("key",t),console.log("webhookInput",a);let r=(null==a?void 0:a.value)||"";console.log("newWebhookValue",r),e[t]=r}),console.log("updatedAlertToWebhooks",e);let t={general_settings:{alert_to_webhook_url:e,alert_types:w}};console.log("payload",t);try{V(l,t)}catch(e){u.ZP.error("Failed to update alerts: "+e,20)}u.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,r.jsx)(J.Z,{onClick:()=>z(l,"slack"),className:"mx-2",children:"Test Alerts"})]})})]})]})]}),(0,r.jsx)(er.Z,{title:"Add Callback",visible:d,onOk:A,width:800,onCancel:()=>{m(!1),h.resetFields(),p(null)},footer:null,children:(0,r.jsxs)(ea.Z,{form:h,layout:"vertical",onFinish:A,children:[(0,r.jsx)(ea.Z.Item,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,r.jsxs)(es.default,{onChange:e=>{p(e)},children:[(0,r.jsx)(es.default.Option,{value:"langfuse",children:"langfuse"}),(0,r.jsx)(es.default.Option,{value:"openmeter",children:"openmeter"})]})}),"langfuse"===x&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"LANGFUSE_PUBLIC_KEY",name:"langfusePublicKey",rules:[{required:!0,message:"Please enter the public key"}],children:(0,r.jsx)(H.Z,{type:"password"})}),(0,r.jsx)(ea.Z.Item,{label:"LANGFUSE_PRIVATE_KEY",name:"langfusePrivateKey",rules:[{required:!0,message:"Please enter the private key"}],children:(0,r.jsx)(H.Z,{type:"password"})})]}),"openmeter"==x&&(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(ea.Z.Item,{label:"OPENMETER_API_KEY",name:"openMeterApiKey",rules:[{required:!0,message:"Please enter the openmeter api key"}],children:(0,r.jsx)(H.Z,{type:"password"})})}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:ln}=es.default;var lo=e=>{let{models:l,accessToken:t,routerSettings:s,setRouterSettings:a}=e,[o]=ea.Z.useForm(),[i,c]=(0,n.useState)(!1),[d,m]=(0,n.useState)("");return(0,r.jsxs)("div",{children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>c(!0),children:"+ Add Fallbacks"}),(0,r.jsx)(er.Z,{title:"Add Fallbacks",visible:i,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),o.resetFields()},children:(0,r.jsxs)(ea.Z,{form:o,onFinish:e=>{console.log(e);let{model_name:l,models:r}=e,n=[...s.fallbacks||[],{[l]:r}],i={...s,fallbacks:n};console.log(i);try{V(t,{router_settings:i}),a(i)}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully"),c(!1),o.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,r.jsx)(eb.Z,{defaultValue:d,children:l&&l.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,r.jsx)(ea.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsx)(eK.Z,{value:l,children:l&&l.filter(e=>e!=d).map(e=>(0,r.jsx)(eB.Z,{value:e,children:e},e))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},li=t(12968);async function lc(e,l){console.log("isLocal:",!1);let t=window.location.origin,s=new li.ZP.OpenAI({apiKey:l,baseURL:t,dangerouslyAllowBrowser:!0});try{let l=await s.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});u.ZP.success((0,r.jsxs)("span",{children:["Test model=",(0,r.jsx)("strong",{children:e}),", received model=",(0,r.jsx)("strong",{children:l.model}),". See ",(0,r.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}let ld={ttl:3600,lowest_latency_buffer:0},lm=e=>{let{selectedStrategy:l,strategyArgs:t,paramExplanation:s}=e;return(0,r.jsxs)($.Z,{children:[(0,r.jsx)(Q.Z,{className:"text-sm font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong",children:"Routing Strategy Specific Args"}),(0,r.jsx)(X.Z,{children:"latency-based-routing"==l?(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Setting"}),(0,r.jsx)(e_.Z,{children:"Value"})]})}),(0,r.jsx)(ey.Z,{children:Object.entries(t).map(e=>{let[l,t]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ee.Z,{children:l}),(0,r.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:s[l]})]}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(H.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]})}):(0,r.jsx)(ee.Z,{children:"No specific settings"})})]})};var lu=e=>{let{accessToken:l,userRole:t,userID:s,modelData:a}=e,[o,i]=(0,n.useState)({}),[c,d]=(0,n.useState)(!1),[m]=ea.Z.useForm(),[h,x]=(0,n.useState)(null),[p,j]=(0,n.useState)(null),[g,y]=(0,n.useState)(null),f={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request",ttl:"(int) Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"(float) Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};(0,n.useEffect)(()=>{l&&t&&s&&q(l,s,t).then(e=>{console.log("callbacks",e),i(e.router_settings)})},[l,t,s]);let Z=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(o.fallbacks)),o.fallbacks.map(l=>(e in l&&delete l[e],l));try{await V(l,{router_settings:o}),i({...o}),j(o.routing_strategy),u.ZP.success("Router settings updated successfully")}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}}},_=e=>{if(!l)return;console.log("router_settings",e);let t=Object.fromEntries(Object.entries(e).map(e=>{let[l,t]=e;if("routing_strategy_args"!==l&&"routing_strategy"!==l){var s;return[l,(null===(s=document.querySelector('input[name="'.concat(l,'"]')))||void 0===s?void 0:s.value)||t]}if("routing_strategy"==l)return[l,p];if("routing_strategy_args"==l&&"latency-based-routing"==p){let e={},l=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]');return(null==l?void 0:l.value)&&(e.lowest_latency_buffer=Number(l.value)),(null==t?void 0:t.value)&&(e.ttl=Number(t.value)),console.log("setRoutingStrategyArgs: ".concat(e)),["routing_strategy_args",e]}return null}).filter(e=>null!=e));console.log("updatedVariables",t);try{V(l,{router_settings:t})}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully")};return l?(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(eM.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(eL.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eR.Z,{value:"1",children:"General Settings"}),(0,r.jsx)(eR.Z,{value:"2",children:"Fallbacks"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,r.jsx)(el.Z,{children:"Router Settings"}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Setting"}),(0,r.jsx)(e_.Z,{children:"Value"})]})}),(0,r.jsx)(ey.Z,{children:Object.entries(o).filter(e=>{let[l,t]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l&&"routing_strategy_args"!=l}).map(e=>{let[l,t]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ee.Z,{children:l}),(0,r.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:f[l]})]}),(0,r.jsx)(ef.Z,{children:"routing_strategy"==l?(0,r.jsxs)(eb.Z,{defaultValue:t,className:"w-full max-w-md",onValueChange:j,children:[(0,r.jsx)(ek.Z,{value:"usage-based-routing",children:"usage-based-routing"}),(0,r.jsx)(ek.Z,{value:"latency-based-routing",children:"latency-based-routing"}),(0,r.jsx)(ek.Z,{value:"simple-shuffle",children:"simple-shuffle"})]}):(0,r.jsx)(H.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]}),(0,r.jsx)(lm,{selectedStrategy:p,strategyArgs:o&&o.routing_strategy_args&&Object.keys(o.routing_strategy_args).length>0?o.routing_strategy_args:ld,paramExplanation:f})]}),(0,r.jsx)(Y.Z,{children:(0,r.jsx)(J.Z,{className:"mt-2",onClick:()=>_(o),children:"Save Changes"})})]})}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Model Name"}),(0,r.jsx)(e_.Z,{children:"Fallbacks"})]})}),(0,r.jsx)(ey.Z,{children:o.fallbacks&&o.fallbacks.map((e,t)=>Object.entries(e).map(e=>{let[s,a]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:s}),(0,r.jsx)(ef.Z,{children:Array.isArray(a)?a.join(", "):a}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(J.Z,{onClick:()=>lc(s,l),children:"Test Fallback"})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ej.Z,{icon:eh.Z,size:"sm",onClick:()=>Z(s)})})]},t.toString()+s)}))})]}),(0,r.jsx)(lo,{models:(null==a?void 0:a.data)?a.data.map(e=>e.model_name):[],accessToken:l,routerSettings:o,setRouterSettings:i})]})]})]})}):null},lh=t(67951),lx=e=>{let{}=e;return(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(W.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsxs)("div",{className:"mb-5",children:[(0,r.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,r.jsx)(ee.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,r.jsxs)(eM.Z,{children:[(0,r.jsxs)(eL.Z,{children:[(0,r.jsx)(eR.Z,{children:"OpenAI Python SDK"}),(0,r.jsx)(eR.Z,{children:"LlamaIndex"}),(0,r.jsx)(eR.Z,{children:"Langchain Py"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsx)(lh.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n '})}),(0,r.jsx)(eU.Z,{children:(0,r.jsx)(lh.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n '})}),(0,r.jsx)(eU.Z,{children:(0,r.jsx)(lh.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})]})})})};async function lp(e,l,t,s){console.log("isLocal:",!1);let a=window.location.origin,r=new li.ZP.OpenAI({apiKey:s,baseURL:a,dangerouslyAllowBrowser:!0});try{for await(let s of(await r.chat.completions.create({model:t,stream:!0,messages:[{role:"user",content:e}]})))console.log(s),s.choices[0].delta.content&&l(s.choices[0].delta.content)}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lj=e=>{let{accessToken:l,token:t,userRole:s,userID:a}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)(""),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)(void 0),[p,j]=(0,n.useState)([]);(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{let e=await N(l,a,s);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));console.log(l),j(l),x(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,a,s]);let g=(e,l)=>{u(t=>{let s=t[t.length-1];return s&&s.role===e?[...t.slice(0,t.length-1),{role:e,content:s.content+l}]:[...t,{role:e,content:l}]})},y=async()=>{if(""!==c.trim()&&o&&t&&s&&a){u(e=>[...e,{role:"user",content:c}]);try{h&&await lp(c,e=>g("assistant",e),h,o)}catch(e){console.error("Error fetching model response",e),g("assistant","Error fetching model response")}d("")}};if(s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=eT.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,r.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,r.jsx)(W.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eM.Z,{children:[(0,r.jsx)(eL.Z,{children:(0,r.jsx)(eR.Z,{children:"Chat"})}),(0,r.jsx)(eD.Z,{children:(0,r.jsxs)(eU.Z,{children:[(0,r.jsx)("div",{className:"sm:max-w-2xl",children:(0,r.jsxs)(W.Z,{numItems:2,children:[(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(ee.Z,{children:"API Key"}),(0,r.jsx)(H.Z,{placeholder:"Type API Key here",type:"password",onValueChange:i,value:o})]}),(0,r.jsxs)(Y.Z,{className:"mx-2",children:[(0,r.jsx)(ee.Z,{children:"Select Model:"}),(0,r.jsx)(es.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),x(e)},options:p,style:{width:"200px"}})]})]})}),(0,r.jsxs)(eg.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsx)(ew.Z,{children:(0,r.jsx)(ef.Z,{})})}),(0,r.jsx)(ey.Z,{children:m.map((e,l)=>(0,r.jsx)(ew.Z,{children:(0,r.jsx)(ef.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,r.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)(H.Z,{type:"text",value:c,onChange:e=>d(e.target.value),placeholder:"Type your message..."}),(0,r.jsx)(J.Z,{onClick:y,className:"ml-2",children:"Send"})]})})]})})]})})})})},lg=t(33509),ly=t(95781);let{Sider:lf}=lg.default;var lZ=e=>{let{setPage:l,userRole:t,defaultSelectedKey:s}=e;return"Admin Viewer"==t?(0,r.jsx)(lg.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,r.jsx)(lf,{width:120,children:(0,r.jsxs)(ly.Z,{mode:"inline",defaultSelectedKeys:s||["4"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(ly.Z.Item,{onClick:()=>l("api-keys"),children:"API Keys"},"4"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("models"),children:"Models"},"2"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("llm-playground"),children:"Chat UI"},"3"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")]})})}):(0,r.jsx)(lg.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,r.jsx)(lf,{width:145,children:(0,r.jsxs)(ly.Z,{mode:"inline",defaultSelectedKeys:s||["1"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(ly.Z.Item,{onClick:()=>l("api-keys"),children:(0,r.jsx)(ee.Z,{children:"API Keys"})},"1"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("llm-playground"),children:(0,r.jsx)(ee.Z,{children:"Test Key"})},"3"),"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("models"),children:(0,r.jsx)(ee.Z,{children:"Models"})},"2"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("usage"),children:(0,r.jsx)(ee.Z,{children:"Usage"})},"4"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("teams"),children:(0,r.jsx)(ee.Z,{children:"Teams"})},"6"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("users"),children:(0,r.jsx)(ee.Z,{children:"Users"})},"5"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("settings"),children:(0,r.jsx)(ee.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("general-settings"),children:(0,r.jsx)(ee.Z,{children:"Router Settings"})},"9"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("admin-panel"),children:(0,r.jsx)(ee.Z,{children:"Admin"})},"7"):null,(0,r.jsx)(ly.Z.Item,{onClick:()=>l("api_ref"),children:(0,r.jsx)(ee.Z,{children:"API Reference"})},"11")]})})})},l_=t(67989),lw=e=>{let{accessToken:l,token:t,userRole:s,userID:a,keys:o}=e,i=new Date,[c,d]=(0,n.useState)([]),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)([]),[p,j]=(0,n.useState)([]),[g,y]=(0,n.useState)([]),[f,Z]=(0,n.useState)([]),[_,w]=(0,n.useState)([]),[b,k]=(0,n.useState)([]),[v,S]=(0,n.useState)(""),[N,R]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),M=new Date(i.getFullYear(),i.getMonth(),1),L=new Date(i.getFullYear(),i.getMonth()+1,0),U=z(M),D=z(L);console.log("keys in usage",o);let K=async(e,t,s)=>{if(!e||!t||!l)return;console.log("uiSelectedKey",s);let a=await T(l,s,e.toISOString(),t.toISOString());console.log("End user data updated successfully",a),j(a)},B=async(e,t)=>{e&&t&&l&&(Z((await E(l,e.toISOString(),t.toISOString())).spend_per_tag),console.log("Tag spend data updated successfully"))};function z(e){let l=e.getFullYear(),t=e.getMonth()+1,s=e.getDate();return"".concat(l,"-").concat(t<10?"0"+t:t,"-").concat(s<10?"0"+s:s)}return console.log("Start date is ".concat(U)),console.log("End date is ".concat(D)),(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{if(console.log("user role: ".concat(s)),"Admin"==s||"Admin Viewer"==s){var e,r;let t=await C(l);d(t);let s=(await P(l)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,10),spend:e.total_spend}));u(s);let a=(await O(l)).map(e=>({key:e.model,spend:e.total_spend}));x(a);let n=await A(l);console.log("teamSpend",n),y(n.daily_spend),w(n.teams);let o=n.total_spend_per_team;o=o.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e)),k(o);let i=await E(l,null===(e=N.from)||void 0===e?void 0:e.toISOString(),null===(r=N.to)||void 0===r?void 0:r.toISOString());Z(i.spend_per_tag);let c=await T(l,null,void 0,void 0);j(c),console.log("spend/user result",c)}else"App Owner"==s&&await I(l,t,s,a,U,D).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),d(l);let t=e.top_api_keys;u(t)}else{let t=(await F(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[t,s]=e;"spend"!==t&&"startTime"!==t&&"models"!==t&&"users"!==t&&l.push({key:t,spend:s})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let t=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(t[0]))),t}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));u(t),d(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[l,t,s,a,U,D]),(0,r.jsxs)("div",{style:{width:"100%"},className:"p-8",children:[(0,r.jsx)(eE,{userID:a,userRole:s,accessToken:l,userSpend:null,selectedTeam:null}),(0,r.jsxs)(eM.Z,{children:[(0,r.jsxs)(eL.Z,{className:"mt-2",children:[(0,r.jsx)(eR.Z,{children:"All Up"}),(0,r.jsx)(eR.Z,{children:"Team Based Usage"}),(0,r.jsx)(eR.Z,{children:"End User Usage"}),(0,r.jsx)(eR.Z,{children:"Tag Based Usage"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsx)(Y.Z,{numColSpan:2,children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Monthly Spend"}),(0,r.jsx)(eq.Z,{data:c,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Top API Keys"}),(0,r.jsx)(eq.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Top Models"}),(0,r.jsx)(eq.Z,{className:"mt-4 h-40",data:h,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,r.jsx)(Y.Z,{numColSpan:1})]})}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsxs)(Y.Z,{numColSpan:2,children:[(0,r.jsxs)(ep.Z,{className:"mb-2",children:[(0,r.jsx)(el.Z,{children:"Total Spend Per Team"}),(0,r.jsx)(l_.Z,{data:b})]}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Daily Spend Per Team"}),(0,r.jsx)(eq.Z,{className:"h-72",data:g,showLegend:!0,index:"date",categories:_,yAxisWidth:80,colors:["blue","green","yellow","red","purple"],stack:!0})]})]}),(0,r.jsx)(Y.Z,{numColSpan:2})]})}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:["End-Users of your LLM API calls. Tracked when a `user` param is passed in your LLM calls ",(0,r.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/users",target:"_blank",children:"docs here"})]}),(0,r.jsxs)(W.Z,{numItems:2,children:[(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Time Range"}),(0,r.jsx)(eF.Z,{enableSelect:!0,value:N,onValueChange:e=>{R(e),K(e.from,e.to,null)}})]}),(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Key"}),(0,r.jsxs)(eb.Z,{defaultValue:"all-keys",children:[(0,r.jsx)(ek.Z,{value:"all-keys",onClick:()=>{K(N.from,N.to,null)},children:"All Keys"},"all-keys"),null==o?void 0:o.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,r.jsx)(ek.Z,{value:String(l),onClick:()=>{K(N.from,N.to,e.token)},children:e.key_alias},l):null)]})]})]}),(0,r.jsx)(ep.Z,{className:"mt-4",children:(0,r.jsxs)(eg.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"End User"}),(0,r.jsx)(e_.Z,{children:"Spend"}),(0,r.jsx)(e_.Z,{children:"Total Events"})]})}),(0,r.jsx)(ey.Z,{children:null==p?void 0:p.map((e,l)=>{var t;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.end_user}),(0,r.jsx)(ef.Z,{children:null===(t=e.total_spend)||void 0===t?void 0:t.toFixed(4)}),(0,r.jsx)(ef.Z,{children:e.total_count})]},l)})})]})})]}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,r.jsxs)(Y.Z,{numColSpan:2,children:[(0,r.jsx)(eF.Z,{className:"mb-4",enableSelect:!0,value:N,onValueChange:e=>{R(e),B(e.from,e.to)}}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Spend Per Tag"}),(0,r.jsxs)(ee.Z,{children:["Get Started Tracking cost per tag ",(0,r.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags",target:"_blank",children:"here"})]}),(0,r.jsx)(eq.Z,{className:"h-72",data:f,index:"name",categories:["spend"],colors:["blue"]})]})]}),(0,r.jsx)(Y.Z,{numColSpan:2})]})})]})]})]})},lb=()=>{let{Title:e,Paragraph:l}=eT.default,[t,s]=(0,n.useState)(""),[a,i]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,o.useSearchParams)(),[g,y]=(0,n.useState)({data:[]}),f=j.get("userID"),Z=j.get("token"),[_,w]=(0,n.useState)("api-keys"),[b,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,eP.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),s(l),"Admin Viewer"==l&&w("usage")}else console.log("User role not defined");e.user_email?i(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[Z]),(0,r.jsx)(n.Suspense,{fallback:(0,r.jsx)("div",{children:"Loading..."}),children:(0,r.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,r.jsx)(m,{userID:f,userRole:t,userEmail:a,showSSOBanner:x}),(0,r.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,r.jsx)("div",{className:"mt-8",children:(0,r.jsx)(lZ,{setPage:w,userRole:t,defaultSelectedKey:null})}),"api-keys"==_?(0,r.jsx)(eO,{userID:f,userRole:t,teams:c,keys:u,setUserRole:s,userEmail:a,setUserEmail:i,setTeams:d,setKeys:h}):"models"==_?(0,r.jsx)(e3,{userID:f,userRole:t,token:Z,accessToken:b,modelData:g,setModelData:y}):"llm-playground"==_?(0,r.jsx)(lj,{userID:f,userRole:t,token:Z,accessToken:b}):"users"==_?(0,r.jsx)(e9,{userID:f,userRole:t,token:Z,keys:u,teams:c,accessToken:b,setKeys:h}):"teams"==_?(0,r.jsx)(le,{teams:c,setTeams:d,searchParams:j,accessToken:b,userID:f,userRole:t}):"admin-panel"==_?(0,r.jsx)(lt,{setTeams:d,searchParams:j,accessToken:b,showSSOBanner:x}):"api_ref"==_?(0,r.jsx)(lx,{}):"settings"==_?(0,r.jsx)(lr,{userID:f,userRole:t,accessToken:b}):"general-settings"==_?(0,r.jsx)(lu,{userID:f,userRole:t,accessToken:b,modelData:g}):(0,r.jsx)(lw,{userID:f,userRole:t,token:Z,accessToken:b,keys:u})]})]})})}}},function(e){e.O(0,[936,884,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/app/page-c35c14c9afd091ec.js b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-c35c14c9afd091ec.js
new file mode 100644
index 0000000000..e8b5c33a1c
--- /dev/null
+++ b/litellm/proxy/_experimental/out/_next/static/chunks/app/page-c35c14c9afd091ec.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,4858))},4858:function(e,l,t){"use strict";t.r(l),t.d(l,{default:function(){return lS}});var s,r,a=t(3827),n=t(64090),o=t(47907),i=t(8792),c=t(40491),d=t(65270),m=e=>{let{userID:l,userRole:t,userEmail:s,showSSOBanner:r}=e;console.log("User ID:",l),console.log("userEmail:",s),console.log("showSSOBanner:",r);let n=[{key:"1",label:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("p",{children:["Role: ",t]}),(0,a.jsxs)("p",{children:["ID: ",l]})]})}];return(0,a.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,a.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,a.jsx)("div",{className:"flex flex-col items-center",children:(0,a.jsx)(i.default,{href:"/",children:(0,a.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,a.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,a.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[r?(0,a.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,a.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Request hosted proxy"})}):null,(0,a.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,a.jsx)(c.Z,{menu:{items:n},children:(0,a.jsx)(d.Z,{children:s})})})]})]})},u=t(80588);let h=async()=>{try{let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"),l=await e.json();return console.log("received data: ".concat(l)),l}catch(e){throw console.error("Failed to get model cost map:",e),e}},x=async(e,l)=>{try{let t=await fetch("/model/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model created successfully. Wait 60s and refresh on 'All Models' page"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,l)=>{console.log("model_id in model delete call: ".concat(l));try{let t=await fetch("/model/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({id:l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model deleted successfully. Restart server to see this."),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},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 u.ZP.error("Failed to delete key: "+e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},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 u.ZP.error("Failed to delete team: "+e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to delete key:",e),e}},Z=async function(e,l,t){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],r=arguments.length>4?arguments[4]:void 0,a=arguments.length>5?arguments[5]:void 0;try{let n="/user/info";"App Owner"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),"App User"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),console.log("in userInfoCall viewAll=",s),s&&a&&null!=r&&void 0!=r&&(n="".concat(n,"?view_all=true&page=").concat(r,"&page_size=").concat(a));let o=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let i=await o.json();return console.log("API Response:",i),i}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,l)=>{try{let t="/team/info";l&&(t="".concat(t,"?team_id=").concat(l)),console.log("in teamInfoCall");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let l=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},b=async(e,l,t)=>{try{let l=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log("modelInfoCall:",t),t}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,l,t,s,r,a)=>{try{let l="/model/metrics";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(r,"&endTime=").concat(a));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,l,t,s,r,a)=>{try{let l="/model/metrics/slow_responses";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(r,"&endTime=").concat(a));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,l,t,s,r,a)=>{try{let l="/model/metrics/exceptions";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(r,"&endTime=").concat(a));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},N=async(e,l,t)=>{try{let l=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},A=async e=>{try{let l="/global/spend/teams";console.log("in teamSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},E=async(e,l,t)=>{try{let s="/global/spend/tags";l&&t&&(s="".concat(s,"?start_date=").concat(l,"&end_date=").concat(t)),console.log("in tagsSpendLogsCall:",s);let r=await fetch("".concat(s),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!r.ok){let e=await r.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let a=await r.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,l,t,s,r,a)=>{try{console.log("user role in spend logs call: ".concat(t));let l="/spend/logs";l="App Owner"==t?"".concat(l,"?user_id=").concat(s,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(l,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},C=async e=>{try{let l=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{let l=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,l,t,s)=>{try{let r="";r=l?JSON.stringify({api_key:l,startTime:t,endTime:s}):JSON.stringify({startTime:t,endTime:s});let a={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};a.body=r;let n=await fetch("/global/spend/end_users",a);if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},O=async e=>{try{let l=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},F=async(e,l)=>{try{let t=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},R=async(e,l)=>{try{let t="/user/get_users?role=".concat(l);console.log("in userGetAllUsersCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to delete key: "+e,10),Error("Network response was not ok")}let r=await s.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},M=async(e,l)=>{try{console.log("Form Values in teamCreateCall:",l);let t=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},L=async(e,l)=>{try{console.log("Form Values in keyUpdateCall:",l);let t=await fetch("/key/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update key Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},U=async(e,l)=>{try{console.log("Form Values in teamUpateCall:",l);let t=await fetch("/team/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update team: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update Team Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},D=async(e,l)=>{try{console.log("Form Values in modelUpateCall:",l);let t=await fetch("/model/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update model: "+e,10),console.error("Error update from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update model Response:",s),s}catch(e){throw console.error("Failed to update model:",e),e}},K=async(e,l,t)=>{try{console.log("Form Values in teamMemberAddCall:",t);let s=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:l,member:t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},B=async(e,l,t)=>{try{console.log("Form Values in userUpdateUserCall:",l);let s={...l};null!==t&&(s.user_role=t),s=JSON.stringify(s);let r=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:s});if(!r.ok){let e=await r.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await r.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},z=async(e,l)=>{try{let t="/health/services?service=".concat(l);console.log("Checking Slack Budget Alerts service health");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed ".concat(l," service health check ")+e),Error(e)}let r=await s.json();return u.ZP.success("Test request to ".concat(l," made - check logs/alerts on ").concat(l," to verify")),r}catch(e){throw console.error("Failed to perform health check:",e),e}},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 u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},q=async e=>{try{let l=await fetch("/config/list?config_type=general_settings",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},G=async(e,l,t)=>{try{let s=await fetch("/config/field/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({field_name:l,field_value:t,config_type:"general_settings"})});if(!s.ok){let e=await s.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let r=await s.json();return u.ZP.success("Successfully updated value!"),r}catch(e){throw console.error("Failed to set callbacks:",e),e}},Y=async(e,l)=>{try{let t=await fetch("/config/field/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({field_name:l,config_type:"general_settings"})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let s=await t.json();return u.ZP.success("Field reset on proxy"),s}catch(e){throw console.error("Failed to get callbacks:",e),e}},W=async(e,l)=>{try{let t=await fetch("/config/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to set callbacks:",e),e}},J=async e=>{try{let l=await fetch("/health",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to call /health:",e),e}};var H=t(10384),$=t(46453),X=t(16450),Q=t(52273),ee=t(26780),el=t(15595),et=t(6698),es=t(71801),er=t(42440),ea=t(42308),en=t(50670),eo=t(81583),ei=t(99129),ec=t(44839),ed=t(88707),em=t(1861);let{Option:eu}=en.default;var eh=e=>{let{userID:l,team:t,userRole:s,accessToken:r,data:o,setData:i}=e,[c]=eo.Z.useForm(),[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(null),[p,g]=(0,n.useState)(null),[f,y]=(0,n.useState)([]),[Z,_]=(0,n.useState)([]),w=()=>{m(!1),c.resetFields()},b=()=>{m(!1),x(null),c.resetFields()};(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==r){let e=(await N(r,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),y(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[r,l,s]);let k=async e=>{try{var t,s,a;let n=null!==(t=null==e?void 0:e.key_alias)&&void 0!==t?t:"",d=null!==(s=null==e?void 0:e.team_id)&&void 0!==s?s:null;if((null!==(a=null==o?void 0:o.filter(e=>e.team_id===d).map(e=>e.key_alias))&&void 0!==a?a:[]).includes(n))throw Error("Key alias ".concat(n," already exists for team with ID ").concat(d,", please provide another key alias"));u.ZP.info("Making API Call"),m(!0);let h=await j(r,l,e);console.log("key create Response:",h),i(e=>e?[...e,h]:[h]),x(h.key),g(h.soft_budget),u.ZP.success("API Key Created"),c.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e),u.ZP.error("Error creating the key: ".concat(e),20)}};return(0,n.useEffect)(()=>{_(t&&t.models.length>0?t.models.includes("all-proxy-models")?f:t.models:f)},[t,f]),(0,a.jsxs)("div",{children:[(0,a.jsx)(X.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,a.jsx)(ei.Z,{title:"Create Key",visible:d,width:800,footer:null,onOk:w,onCancel:b,children:(0,a.jsxs)(eo.Z,{form:c,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(Q.Z,{placeholder:""})}),(0,a.jsx)(eo.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:t?t.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,a.jsx)(ec.Z,{value:t?t.team_alias:"",disabled:!0})}),(0,a.jsx)(eo.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsxs)(en.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&c.setFieldsValue({models:["all-team-models"]})},children:[(0,a.jsx)(eu,{value:"all-team-models",children:"All Team Models"},"all-team-models"),Z.map(e=>(0,a.jsx)(eu,{value:e,children:e},e))]})}),(0,a.jsxs)(ee.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(et.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(el.Z,{children:[(0,a.jsx)(eo.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(t.max_budget))}}],children:(0,a.jsx)(ed.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(eo.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,a.jsxs)(en.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(en.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(en.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(eo.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,a.jsx)(ed.Z,{step:1,width:400})}),(0,a.jsx)(eo.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,a.jsx)(ed.Z,{step:1,width:400})}),(0,a.jsx)(eo.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,a.jsx)(Q.Z,{placeholder:""})}),(0,a.jsx)(eo.Z.Item,{label:"Metadata",name:"metadata",children:(0,a.jsx)(ec.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Create Key"})})]})}),h&&(0,a.jsx)(ei.Z,{visible:d,onOk:w,onCancel:b,footer:null,children:(0,a.jsxs)($.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(er.Z,{children:"Save your Key"}),(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,a.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,a.jsx)(H.Z,{numColSpan:1,children:null!=h?(0,a.jsxs)("div",{children:[(0,a.jsx)(es.Z,{className:"mt-3",children:"API Key:"}),(0,a.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,a.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:h})}),(0,a.jsx)(ea.CopyToClipboard,{text:h,onCopy:()=>{u.ZP.success("API Key copied to clipboard")},children:(0,a.jsx)(X.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,a.jsx)(es.Z,{children:"Key being created, this might take 30s"})})]})})]})},ex=t(9454),ep=t(98941),ej=t(33393),eg=t(5),ef=t(13810),ey=t(61244),eZ=t(10827),e_=t(3851),ew=t(2044),eb=t(64167),ek=t(74480),ev=t(7178),eS=t(95093),eN=t(27166);let{Option:eA}=en.default;var eE=e=>{let{userID:l,userRole:t,accessToken:s,selectedTeam:r,data:o,setData:i,teams:c}=e,[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(!1),[p,j]=(0,n.useState)(null),[g,y]=(0,n.useState)(null),[Z,_]=(0,n.useState)(null),[w,b]=(0,n.useState)(""),[k,v]=(0,n.useState)(!1),[S,A]=(0,n.useState)(!1),[E,I]=(0,n.useState)(null),[C,P]=(0,n.useState)([]),T=new Set,[O,F]=(0,n.useState)(T);(0,n.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==s&&null!==t){let e=(await N(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),P(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[s,l,t]),(0,n.useEffect)(()=>{if(c){let e=new Set;c.forEach((l,t)=>{let s=l.team_id;e.add(s)}),F(e)}},[c]);let R=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),I(e),v(!0)},M=async e=>{if(null==s)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let t=await L(s,e);console.log("handleEditSubmit: newKeyValues",t),o&&i(o.map(e=>e.token===l?t:e)),u.ZP.success("Key updated successfully"),v(!1),I(null)},U=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=o&&(j(e.token),localStorage.removeItem("userData"+l),x(!0))},D=async()=>{if(null!=p&&null!=o){try{await 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,a.jsxs)("div",{children:[(0,a.jsxs)(ef.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,a.jsxs)(eZ.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Key Alias"}),(0,a.jsx)(ek.Z,{children:"Secret Key"}),(0,a.jsx)(ek.Z,{children:"Spend (USD)"}),(0,a.jsx)(ek.Z,{children:"Budget (USD)"}),(0,a.jsx)(ek.Z,{children:"Models"}),(0,a.jsx)(ek.Z,{children:"TPM / RPM Limits"})]})}),(0,a.jsx)(e_.Z,{children:o.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(r){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(O.has(e.team_id),", selectedTeam id: ").concat(r.team_id)),(null!=r.team_id||null===e.team_id||O.has(e.team_id))&&e.team_id!=r.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,a.jsx)(es.Z,{children:e.key_alias}):(0,a.jsx)(es.Z,{children:"Not Set"})}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(es.Z,{children:e.key_name})}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(es.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,a.jsx)(ew.Z,{children:null!=e.max_budget?(0,a.jsx)(es.Z,{children:e.max_budget}):(0,a.jsx)(es.Z,{children:"Unlimited"})}),(0,a.jsx)(ew.Z,{children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(a.Fragment,{children:r&&r.models&&r.models.length>0?r.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(es.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(es.Z,{children:"All Team Models"})},l):(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(es.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(es.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(es.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(es.Z,{children:"All Team Models"})},l):(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(es.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(ew.Z,{children:(0,a.jsxs)(es.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ey.Z,{onClick:()=>{I(e),A(!0)},icon:ex.Z,size:"sm"}),(0,a.jsx)(ei.Z,{open:S,onCancel:()=>{A(!1),I(null)},footer:null,width:800,children:E&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-8",children:[(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat(E.spend).toFixed(4)}catch(e){return E.spend}})()})})]}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.max_budget?(0,a.jsx)(a.Fragment,{children:E.max_budget}):(0,a.jsx)(a.Fragment,{children:"Unlimited"})})})]},e.name),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.expires?(0,a.jsx)(a.Fragment,{children:new Date(E.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,a.jsx)(a.Fragment,{children:"Never"})})})]},e.name)]}),(0,a.jsxs)(ef.Z,{className:"my-4",children:[(0,a.jsx)(er.Z,{children:"Token Name"}),(0,a.jsx)(es.Z,{className:"my-1",children:E.key_alias?E.key_alias:E.key_name}),(0,a.jsx)(er.Z,{children:"Token ID"}),(0,a.jsx)(es.Z,{className:"my-1 text-[12px]",children:E.token}),(0,a.jsx)(er.Z,{children:"Metadata"}),(0,a.jsx)(es.Z,{className:"my-1",children:(0,a.jsxs)("pre",{children:[JSON.stringify(E.metadata)," "]})})]}),(0,a.jsx)(X.Z,{className:"mx-auto flex items-center",onClick:()=>{A(!1),I(null)},children:"Close"})]})}),(0,a.jsx)(ey.Z,{icon:ep.Z,size:"sm",onClick:()=>R(e)}),(0,a.jsx)(ey.Z,{onClick:()=>U(e),icon:ej.Z,size:"sm"})]})]},e.token)})})]}),h&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:""}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(X.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(X.Z,{onClick:()=>{x(!1),j(null)},children:"Cancel"})]})]})]})})]}),E&&(0,a.jsx)(e=>{let{visible:l,onCancel:t,token:s,onSubmit:o}=e,[i]=eo.Z.useForm(),[d,m]=(0,n.useState)(r),[u,h]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1);return(0,a.jsx)(ei.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{i.validateFields().then(e=>{i.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,a.jsxs)(eo.Z,{form:i,onFinish:M,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(ec.Z,{})}),(0,a.jsx)(eo.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let t=l.filter(e=>!d.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!d.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(t)),t.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(t,"Team models: ").concat(d.models)):Promise.resolve()}}],children:(0,a.jsxs)(en.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(eA,{value:"all-team-models",children:"All Team Models"},"all-team-models"),d&&d.models?d.models.includes("all-proxy-models")?C.filter(e=>"all-proxy-models"!==e).map(e=>(0,a.jsx)(eA,{value:e,children:e},e)):d.models.map(e=>(0,a.jsx)(eA,{value:e,children:e},e)):C.map(e=>(0,a.jsx)(eA,{value:e,children:e},e))]})}),(0,a.jsx)(eo.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==d?void 0:d.max_budget)!==null&&(null==d?void 0:d.max_budget)!==void 0?null==d?void 0:d.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&d&&null!==d.max_budget&&l>d.max_budget)throw console.log("keyTeam.max_budget: ".concat(d.max_budget)),Error("Budget cannot exceed team max budget: $".concat(d.max_budget))}}],children:(0,a.jsx)(ed.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(eo.Z.Item,{label:"token",name:"token",hidden:!0}),(0,a.jsx)(eo.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,a.jsx)(eS.Z,{value:s.team_alias,children:null==c?void 0:c.map((e,l)=>(0,a.jsx)(eN.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:k,onCancel:()=>{v(!1),I(null)},token:E,onSubmit:M})]})},eI=t(76032),eC=t(35152),eP=e=>{let{userID:l,userRole:t,accessToken:s,userSpend:r,selectedTeam:o}=e;console.log("userSpend: ".concat(r));let[i,c]=(0,n.useState)(null!==r?r:0),[d,m]=(0,n.useState)(0),[u,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=async()=>{if(s&&l&&t&&"Admin"===t&&null==r)try{let e=await w(s);e&&(e.spend?c(e.spend):c(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===t)return;if(null!==s){let e=(await N(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),h(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,s,l]),(0,n.useEffect)(()=>{null!==r&&c(r)},[r]);let x=[];o&&o.models&&(x=o.models),x&&x.includes("all-proxy-models")?(console.log("user models:",u),x=u):x&&x.includes("all-team-models")?x=o.models:x&&0===x.length&&(x=u);let p=void 0!==i?i.toFixed(4):null;return console.log("spend in view user spend: ".concat(i)),(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,a.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",p]})]}),(0,a.jsx)("div",{className:"ml-auto",children:(0,a.jsxs)(ee.Z,{children:[(0,a.jsx)(et.Z,{children:(0,a.jsx)(es.Z,{children:"Team Models"})}),(0,a.jsx)(el.Z,{className:"absolute right-0 z-10 bg-white p-2 shadow-lg max-w-xs",children:(0,a.jsx)(eI.Z,{children:x.map(e=>(0,a.jsx)(eC.Z,{children:(0,a.jsx)(es.Z,{children:e})},e))})})]})})]})},eT=e=>{let{userID:l,userRole:t,selectedTeam:s,accessToken:r}=e,[o,i]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==r){let e=(await N(r,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),i(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[r,l,t]);let c=[];return s&&s.models&&(c=s.models),c&&c.includes("all-proxy-models")&&(console.log("user models:",o),c=o),(0,a.jsx)(a.Fragment,{children:(0,a.jsx)("div",{className:"mb-5",children:(0,a.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==s?void 0:s.team_alias})})})},eO=e=>{let l,{teams:t,setSelectedTeam:s,userRole:r}=e,o={models:[],team_id:null,team_alias:"Default Team"},[i,c]=(0,n.useState)(o);return(l="App User"===r?t:t?[...t,o]:[o],"App User"===r)?null:(0,a.jsxs)("div",{className:"mt-5 mb-5",children:[(0,a.jsx)(er.Z,{children:"Select Team"}),(0,a.jsx)(es.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,a.jsxs)(es.Z,{className:"mt-3 mb-3",children:[(0,a.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,a.jsx)(eS.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(eN.Z,{value:String(l),onClick:()=>s(e),children:e.team_alias},l))}):(0,a.jsxs)(es.Z,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]})},eF=t(37963),eR=t(36083);console.log("isLocal:",!1);var eM=e=>{let{userID:l,userRole:t,teams:s,keys:r,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:m,setKeys:u}=e,[h,x]=(0,n.useState)(null),p=(0,o.useSearchParams)();p.get("viewSpend"),(0,o.useRouter)();let j=p.get("token"),[g,f]=(0,n.useState)(null),[y,_]=(0,n.useState)(null),[b,k]=(0,n.useState)([]),v={models:[],team_alias:"Default Team",team_id:null},[S,A]=(0,n.useState)(s?s[0]:v);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(j){let e=(0,eF.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&&!r&&!h){let e=sessionStorage.getItem("userModels"+l);e?k(JSON.parse(e)):(async()=>{try{let e=await Z(g,l,t,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==t){let e=await w(g);x(e),console.log("globalSpend:",e)}else x(e.user_info);u(e.keys),m(e.teams);let s=[...e.teams];s.length>0?(console.log("response['teams']: ".concat(s)),A(s[0])):A(v),sessionStorage.setItem("userData"+l,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(e.user_info));let r=(await N(g,l,t)).data.map(e=>e.id);console.log("available_model_names:",r),k(r),console.log("userModels:",b),sessionStorage.setItem("userModels"+l,JSON.stringify(r))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,j,g,r,t]),(0,n.useEffect)(()=>{if(null!==r&&null!=S){let e=0;for(let l of r)S.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===S.team_id&&(e+=l.spend);_(e)}else if(null!==r){let e=0;for(let l of r)e+=l.spend;_(e)}},[S]),null==l||null==j){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==g)return null;if(null==t&&i("App Owner"),t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=eR.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",S),console.log("teamSpend: ".concat(y)),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsx)($.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,a.jsxs)(H.Z,{numColSpan:1,children:[(0,a.jsx)(eT,{userID:l,userRole:t,selectedTeam:S||null,accessToken:g}),(0,a.jsx)(eP,{userID:l,userRole:t,accessToken:g,userSpend:y,selectedTeam:S||null}),(0,a.jsx)(eE,{userID:l,userRole:t,accessToken:g,selectedTeam:S||null,data:r,setData:u,teams:s}),(0,a.jsx)(eh,{userID:l,team:S||null,userRole:t,accessToken:g,data:r,setData:u},S?S.team_id:null),(0,a.jsx)(eO,{teams:s,setSelectedTeam:A,userRole:t})]})})})},eL=t(35087),eU=t(92836),eD=t(26734),eK=t(41608),eB=t(32126),ez=t(23682),eV=t(47047),eq=t(76628),eG=t(57750),eY=t(44041),eW=t(38302),eJ=t(28683),eH=t(1460),e$=t(78578),eX=t(63954),eQ=t(90252),e0=t(7905),e1=e=>{let{modelID:l,accessToken:t}=e,[s,r]=(0,n.useState)(!1),o=async()=>{try{u.ZP.info("Making API Call"),r(!0);let e=await p(t,l);console.log("model delete Response:",e),u.ZP.success("Model ".concat(l," deleted successfully")),r(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(ey.Z,{onClick:()=>r(!0),icon:ej.Z,size:"sm"}),(0,a.jsx)(ei.Z,{open:s,onOk:o,okType:"danger",onCancel:()=>r(!1),children:(0,a.jsxs)($.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(er.Z,{children:"Delete Model"}),(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Model ID: ",(0,a.jsx)("b",{children:l})]})})]})})]})},e2=t(97766),e4=t(46495);let{Title:e8,Link:e5}=eR.default;(s=r||(r={})).OpenAI="OpenAI",s.Azure="Azure",s.Anthropic="Anthropic",s.Google_AI_Studio="Gemini (Google AI Studio)",s.Bedrock="Amazon Bedrock",s.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",s.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)";let e3={OpenAI:"openai",Azure:"azure",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai"},e6={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},e7=async(e,l,t)=>{try{let s=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(s)),console.log("received type of deployments: ".concat(typeof s)),s.forEach(async t=>{console.log("litellm_model: ".concat(t));let s={},r={};s.model=t;let a="";for(let[l,t]of Object.entries(e))if(""!==t){if("model_name"==l)a+=t;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)r[l]=t;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",t);let e={};if(t&&void 0!=t){try{e=JSON.parse(t)}catch(e){throw u.ZP.error("Failed to parse LiteLLM Extra Params: "+e,10),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))s[l]=t}}else s[l]=t}let n={model_name:a,litellm_params:s,model_info:r},o=await x(l,n);console.log("response for model create call: ".concat(o.data))}),t.resetFields()}catch(e){u.ZP.error("Failed to create model: "+e,10)}};var e9=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]=eo.Z.useForm(),[f,y]=(0,n.useState)(null),[Z,_]=(0,n.useState)(""),[w,N]=(0,n.useState)([]),A=Object.values(r).filter(e=>isNaN(Number(e))),[E,I]=(0,n.useState)("OpenAI"),[C,P]=(0,n.useState)(""),[T,O]=(0,n.useState)(!1),[F,R]=(0,n.useState)(null),[M,L]=(0,n.useState)([]),[U,K]=(0,n.useState)(null),[B,z]=(0,n.useState)([]),[q,G]=(0,n.useState)([]),[Y,H]=(0,n.useState)([]),[ea,en]=(0,n.useState)([]),[ec,eu]=(0,n.useState)([]),[eh,ex]=(0,n.useState)([]),[ej,eA]=(0,n.useState)([]),[eE,eI]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[eC,eP]=(0,n.useState)(null),[eT,eO]=(0,n.useState)(0),eF=e=>{R(e),O(!0)},eM=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},t=null;for(let[s,r]of Object.entries(e))"model_id"!==s?l[s]=r:t=r;let s={litellm_params:l,model_info:{id:t}};console.log("handleEditSubmit payload:",s);try{await D(o,s),u.ZP.success("Model updated successfully, restart server to see updates"),O(!1),R(null)}catch(e){console.log("Error occurred")}},e9=()=>{_(new Date().toLocaleString())},le=async()=>{if(!o){console.error("Access token is missing");return}console.log("new modelGroupRetryPolicy:",eC);try{await W(o,{router_settings:{model_group_retry_policy:eC}}),u.ZP.success("Retry settings saved successfully")}catch(e){console.error("Failed to save retry settings:",e),u.ZP.error("Failed to save retry settings")}};if((0,n.useEffect)(()=>{if(!o||!i||!c||!d)return;let e=async()=>{try{var e,l,t,s,r,a;let n=await b(o,d,c);console.log("Model data response:",n.data),x(n);let i=new Set;for(let e=0;e0&&(u=m[m.length-1],console.log("_initial_model_group:",u),K(u)),console.log("selectedModelGroup:",U);let h=await k(o,d,c,u,null===(e=eE.from)||void 0===e?void 0:e.toISOString(),null===(l=eE.to)||void 0===l?void 0:l.toISOString());console.log("Model metrics response:",h),G(h.data),H(h.all_api_bases);let p=await S(o,d,c,u,null===(t=eE.from)||void 0===t?void 0:t.toISOString(),null===(s=eE.to)||void 0===s?void 0:s.toISOString());console.log("Model exceptions response:",p),en(p.data),eu(p.exception_types);let j=await v(o,d,c,u,null===(r=eE.from)||void 0===r?void 0:r.toISOString(),null===(a=eE.to)||void 0===a?void 0:a.toISOString());console.log("slowResponses:",j),eA(j);let g=(await V(o,d,c)).router_settings;console.log("routerSettingsInfo:",g);let f=g.model_group_retry_policy,y=g.num_retries;console.log("model_group_retry_policy:",f),console.log("default_retries:",y),eP(f),eO(y)}catch(e){console.error("There was an error fetching the model data",e)}};o&&i&&c&&d&&e();let l=async()=>{let e=await h();console.log("received model cost map data: ".concat(Object.keys(e))),y(e)};null==f&&l(),e9()},[o,i,c,d,f,Z]),!m||!o||!i||!c||!d)return(0,a.jsx)("div",{children:"Loading..."});let ll=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(f)),null!=f&&"object"==typeof f&&e in f)?f[e].litellm_provider:"openai";if(r){let e=r.split("/"),l=e[0];n=1===e.length?u(r):l}else n="openai";a&&(o=null==a?void 0:a.input_cost_per_token,i=null==a?void 0:a.output_cost_per_token,c=null==a?void 0:a.max_tokens),(null==s?void 0:s.litellm_params)&&(d=Object.fromEntries(Object.entries(null==s?void 0:s.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),m.data[e].provider=n,m.data[e].input_cost=o,m.data[e].output_cost=i,m.data[e].max_tokens=c,m.data[e].api_base=null==s?void 0:null===(t=s.litellm_params)||void 0===t?void 0:t.api_base,m.data[e].cleanedLitellmParams=d,ll.push(s.model_name),console.log(m.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=eR.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let lt=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(r).find(l=>r[l]===e);if(l){let e=e3[l];console.log("mappingResult: ".concat(e));let t=[];"object"==typeof f&&Object.entries(f).forEach(l=>{let[s,r]=l;null!==r&&"object"==typeof r&&"litellm_provider"in r&&(r.litellm_provider===e||r.litellm_provider.includes(e))&&t.push(s)}),N(t),console.log("providerModels: ".concat(w))}},ls=async()=>{try{u.ZP.info("Running health check..."),P("");let e=await J(o);P(e)}catch(e){console.error("Error running health check:",e),P("Error running health check")}},lr=async(e,l,t)=>{if(console.log("Updating model metrics for group:",e),o&&d&&c&&l&&t){console.log("inside updateModelMetrics - startTime:",l,"endTime:",t),K(e);try{let s=await k(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model metrics response:",s),G(s.data),H(s.all_api_bases);let r=await S(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model exceptions response:",r),en(r.data),eu(r.exception_types);let a=await v(o,d,c,e,l.toISOString(),t.toISOString());console.log("slowResponses:",a),eA(a)}catch(e){console.error("Failed to fetch model metrics",e)}}};return console.log("selectedProvider: ".concat(E)),console.log("providerModels.length: ".concat(w.length)),(0,a.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,a.jsxs)(eD.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(eK.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(eU.Z,{children:"All Models"}),(0,a.jsx)(eU.Z,{children:"Add Model"}),(0,a.jsx)(eU.Z,{children:(0,a.jsx)("pre",{children:"/health Models"})}),(0,a.jsx)(eU.Z,{children:"Model Analytics"}),(0,a.jsx)(eU.Z,{children:"Model Retry Settings"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[Z&&(0,a.jsxs)(es.Z,{children:["Last Refreshed: ",Z]}),(0,a.jsx)(ey.Z,{icon:eX.Z,variant:"shadow",size:"xs",className:"self-center",onClick:e9})]})]}),(0,a.jsxs)(ez.Z,{children:[(0,a.jsxs)(eB.Z,{children:[(0,a.jsxs)($.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(es.Z,{children:"Filter by Public Model Name"}),(0,a.jsxs)(eS.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:"all",onValueChange:e=>K("all"===e?"all":e),children:[(0,a.jsx)(eN.Z,{value:"all",children:"All Models"}),M.map((e,l)=>(0,a.jsx)(eN.Z,{value:e,onClick:()=>K(e),children:e},l))]})]}),(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(eZ.Z,{className:"mt-5",children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Public Model Name "}),(0,a.jsx)(ek.Z,{children:"Provider"}),"Admin"===c&&(0,a.jsx)(ek.Z,{children:"API Base"}),(0,a.jsx)(ek.Z,{children:"Extra litellm Params"}),(0,a.jsx)(ek.Z,{children:"Input Price per token ($)"}),(0,a.jsx)(ek.Z,{children:"Output Price per token ($)"}),(0,a.jsx)(ek.Z,{children:"Max Tokens"}),(0,a.jsx)(ek.Z,{children:"Status"})]})}),(0,a.jsx)(e_.Z,{children:m.data.filter(e=>"all"===U||e.model_name===U||null==U||""===U).map((e,l)=>(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:(0,a.jsx)(es.Z,{children:e.model_name})}),(0,a.jsx)(ew.Z,{children:e.provider}),"Admin"===c&&(0,a.jsx)(ew.Z,{children:e.api_base}),(0,a.jsx)(ew.Z,{children:(0,a.jsxs)(ee.Z,{children:[(0,a.jsx)(et.Z,{children:(0,a.jsx)(es.Z,{children:"Litellm params"})}),(0,a.jsx)(el.Z,{children:(0,a.jsx)("pre",{children:JSON.stringify(e.cleanedLitellmParams,null,2)})})]})}),(0,a.jsx)(ew.Z,{children:e.input_cost||e.litellm_params.input_cost_per_token||null}),(0,a.jsx)(ew.Z,{children:e.output_cost||e.litellm_params.output_cost_per_token||null}),(0,a.jsx)(ew.Z,{children:e.max_tokens}),(0,a.jsx)(ew.Z,{children:e.model_info.db_model?(0,a.jsx)(eg.Z,{icon:eQ.Z,className:"text-white",children:"DB Model"}):(0,a.jsx)(eg.Z,{icon:e0.Z,className:"text-black",children:"Config Model"})}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ey.Z,{icon:ep.Z,size:"sm",onClick:()=>eF(e)}),(0,a.jsx)(e1,{modelID:e.model_info.id,accessToken:o})]})]},l))})]})})]}),(0,a.jsx)(e=>{let{visible:l,onCancel:t,model:s,onSubmit:r}=e,[n]=eo.Z.useForm(),o={},i="",c="";if(s){o=s.litellm_params,i=s.model_name;let e=s.model_info;e&&(c=e.id,console.log("model_id: ".concat(c)),o.model_id=c)}return(0,a.jsx)(ei.Z,{title:"Edit Model "+i,visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{r(e),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,a.jsxs)(eo.Z,{form:n,onFinish:eM,initialValues:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,a.jsx)(Q.Z,{})}),(0,a.jsx)(eo.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,a.jsx)(ed.Z,{min:0,step:1})}),(0,a.jsx)(eo.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,a.jsx)(ed.Z,{min:0,step:1})}),(0,a.jsx)(eo.Z.Item,{label:"max_retries",name:"max_retries",children:(0,a.jsx)(ed.Z,{min:0,step:1})}),(0,a.jsx)(eo.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,a.jsx)(ed.Z,{min:0,step:1})}),(0,a.jsx)(eo.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,a.jsx)(ed.Z,{min:0,step:1})}),(0,a.jsx)(eo.Z.Item,{label:"input_cost_per_token",name:"input_cost_per_token",tooltip:"float (optional) - Input cost per token",children:(0,a.jsx)(ed.Z,{min:0,step:1e-4})}),(0,a.jsx)(eo.Z.Item,{label:"output_cost_per_token",name:"output_cost_per_token",tooltip:"float (optional) - Output cost per token",children:(0,a.jsx)(ed.Z,{min:0,step:1e-4})}),(0,a.jsx)(eo.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:T,onCancel:()=>{O(!1),R(null)},model:F,onSubmit:eM})]}),(0,a.jsxs)(eB.Z,{className:"h-full",children:[(0,a.jsx)(e8,{level:2,children:"Add new model"}),(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(eo.Z,{form:g,onFinish:()=>{g.validateFields().then(e=>{e7(e,o,g)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(eS.Z,{value:E.toString(),children:A.map((e,l)=>(0,a.jsx)(eN.Z,{value:e,onClick:()=>{lt(e),I(e)},children:e},l))})}),(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,a.jsx)(Q.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(s=E.toString())?"gemini-pro":"Anthropic"==s?"claude-3-opus":"Amazon Bedrock"==s?"claude-3-opus":"Gemini (Google AI Studio)"==s?"gemini-pro":"gpt-3.5-turbo"})}),(0,a.jsxs)(eW.Z,{children:[(0,a.jsx)(eJ.Z,{span:10}),(0,a.jsx)(eJ.Z,{span:10,children:(0,a.jsx)(es.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===E?(0,a.jsx)(Q.Z,{placeholder:"Enter model name"}):w.length>0?(0,a.jsx)(eV.Z,{value:w,children:w.map((e,l)=>(0,a.jsx)(eq.Z,{value:e,children:e},l))}):(0,a.jsx)(Q.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,a.jsxs)(eW.Z,{children:[(0,a.jsx)(eJ.Z,{span:10}),(0,a.jsx)(eJ.Z,{span:10,children:(0,a.jsxs)(es.Z,{className:"mb-3 mt-1",children:["Actual model name used for making ",(0,a.jsx)(e5,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll ",(0,a.jsx)(e5,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," models with the same 'public name'"]})})]}),"Amazon Bedrock"!=E&&"Vertex AI (Anthropic, Gemini, etc.)"!=E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,a.jsx)(Q.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==E&&(0,a.jsx)(eo.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,a.jsx)(Q.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,a.jsx)(Q.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,a.jsx)(Q.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,a.jsx)(e4.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;g.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?u.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&u.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,a.jsx)(em.ZP,{icon:(0,a.jsx)(e2.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsxs)(eW.Z,{children:[(0,a.jsx)(eJ.Z,{span:10}),(0,a.jsx)(eJ.Z,{span:10,children:(0,a.jsx)(es.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==E||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==E)&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,a.jsx)(Q.Z,{placeholder:"https://..."})}),"Azure"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,a.jsx)(Q.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==E&&(0,a.jsxs)(eo.Z.Item,{label:"Base Model",name:"base_model",children:[(0,a.jsx)(Q.Z,{placeholder:"azure/gpt-3.5-turbo"}),(0,a.jsxs)(es.Z,{children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from ",(0,a.jsx)(e5,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})]}),"Amazon Bedrock"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(Q.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(Q.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(Q.Z,{placeholder:"us-east-1"})}),(0,a.jsx)(eo.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,a.jsx)(e$.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,a.jsxs)(eW.Z,{children:[(0,a.jsx)(eJ.Z,{span:10}),(0,a.jsx)(eJ.Z,{span:10,children:(0,a.jsxs)(es.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params ",(0,a.jsx)(e5,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,a.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Add Model"})}),(0,a.jsx)(eH.Z,{title:"Get help on our github",children:(0,a.jsx)(eR.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,a.jsx)(eB.Z,{children:(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(es.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,a.jsx)(X.Z,{onClick:ls,children:"Run `/health`"}),C&&(0,a.jsx)("pre",{children:JSON.stringify(C,null,2)})]})}),(0,a.jsxs)(eB.Z,{children:[(0,a.jsxs)($.Z,{numItems:2,className:"mt-2",children:[(0,a.jsxs)(eJ.Z,{children:[(0,a.jsx)(es.Z,{children:"Select Time Range"}),(0,a.jsx)(eL.Z,{enableSelect:!0,value:eE,onValueChange:e=>{eI(e),lr(U,e.from,e.to)}})]}),(0,a.jsxs)(eJ.Z,{children:[(0,a.jsx)(es.Z,{children:"Select Model Group"}),(0,a.jsx)(eS.Z,{className:"mb-4 mt-2",defaultValue:U||M[0],value:U||M[0],children:M.map((e,l)=>(0,a.jsx)(eN.Z,{value:e,onClick:()=>lr(e,eE.from,eE.to),children:e},l))})]})]}),(0,a.jsxs)($.Z,{numItems:2,children:[(0,a.jsx)(eJ.Z,{children:(0,a.jsxs)(ef.Z,{className:"mr-2 max-h-[400px] min-h-[400px]",children:[(0,a.jsx)(er.Z,{children:"Avg Latency per Token"}),(0,a.jsx)("p",{className:"text-gray-500 italic",children:" (seconds/token)"}),(0,a.jsx)(es.Z,{className:"text-gray-500 italic mt-1 mb-1",children:"average Latency for successfull requests divided by the total tokens"}),q&&Y&&(0,a.jsx)(eG.Z,{title:"Model Latency",className:"h-72",data:q,showLegend:!1,index:"date",categories:Y,connectNulls:!0,customTooltip:e=>{var l,t;let{payload:s,active:r}=e;if(!r||!s)return null;let n=null===(t=s[0])||void 0===t?void 0:null===(l=t.payload)||void 0===l?void 0:l.date,o=s.sort((e,l)=>l.value-e.value);if(o.length>5){let e=o.length-5;(o=o.slice(0,5)).push({dataKey:"".concat(e," other deployments"),value:s.slice(5).reduce((e,l)=>e+l.value,0),color:"gray"})}return(0,a.jsxs)("div",{className:"w-150 rounded-tremor-default border border-tremor-border bg-tremor-background p-2 text-tremor-default shadow-tremor-dropdown",children:[n&&(0,a.jsxs)("p",{className:"text-tremor-content-emphasis mb-2",children:["Date: ",n]}),o.map((e,l)=>{let t=parseFloat(e.value.toFixed(5)),s=0===t&&e.value>0?"<0.00001":t.toFixed(5);return(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)("div",{className:"w-2 h-2 mt-1 rounded-full bg-".concat(e.color,"-500")}),(0,a.jsx)("p",{className:"text-tremor-content",children:e.dataKey})]}),(0,a.jsx)("p",{className:"font-medium text-tremor-content-emphasis text-righ ml-2",children:s})]},l)})]})}})]})}),(0,a.jsx)(eJ.Z,{children:(0,a.jsx)(ef.Z,{className:"ml-2 max-h-[400px] min-h-[400px] overflow-y-auto",children:(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Deployment"}),(0,a.jsx)(ek.Z,{children:"Success Responses"}),(0,a.jsxs)(ek.Z,{children:["Slow Responses ",(0,a.jsx)("p",{children:"Success Responses taking 600+s"})]})]})}),(0,a.jsx)(e_.Z,{children:ej.map((e,l)=>(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:e.api_base}),(0,a.jsx)(ew.Z,{children:e.total_count}),(0,a.jsx)(ew.Z,{children:e.slow_count})]},l))})]})})})]}),(0,a.jsxs)(ef.Z,{className:"mt-4",children:[(0,a.jsx)(er.Z,{children:"Exceptions per Model"}),(0,a.jsx)(eY.Z,{className:"h-72",data:ea,index:"model",categories:ec,stack:!0,colors:["indigo-300","rose-200","#ffcc33"],yAxisWidth:30})]})]}),(0,a.jsxs)(eB.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(es.Z,{children:"Filter by Public Model Name"}),(0,a.jsx)(eS.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:U||M[0],value:U||M[0],onValueChange:e=>K(e),children:M.map((e,l)=>(0,a.jsx)(eN.Z,{value:e,onClick:()=>K(e),children:e},l))})]}),(0,a.jsxs)(er.Z,{children:["Retry Policy for ",U]}),(0,a.jsx)(es.Z,{className:"mb-6",children:"How many retries should be attempted based on the Exception"}),e6&&(0,a.jsx)("table",{children:(0,a.jsx)("tbody",{children:Object.entries(e6).map((e,l)=>{var t;let[s,r]=e,n=null==eC?void 0:null===(t=eC[U])||void 0===t?void 0:t[r];return null==n&&(n=eT),(0,a.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,a.jsx)("td",{children:(0,a.jsx)(es.Z,{children:s})}),(0,a.jsx)("td",{children:(0,a.jsx)(ed.Z,{className:"ml-5",value:n,min:0,step:1,onChange:e=>{eP(l=>{var t;let s=null!==(t=null==l?void 0:l[U])&&void 0!==t?t:{};return{...null!=l?l:{},[U]:{...s,[r]:e}}})}})})]},l)})})}),(0,a.jsx)(X.Z,{className:"mt-6 mr-8",onClick:le,children:"Save"})]})]})]})})};let{Option:le}=en.default;var ll=e=>{let{userID:l,accessToken:t,teams:s}=e,[r]=eo.Z.useForm(),[o,i]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[m,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await N(t,l,"any"),s=[];for(let l=0;l{i(!1),r.resetFields()},p=()=>{i(!1),d(null),r.resetFields()},j=async e=>{try{u.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let s=await g(t,null,e);console.log("user create Response:",s),d(s.key),u.ZP.success("API user Created"),r.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(X.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Invite User"}),(0,a.jsxs)(ei.Z,{title:"Invite User",visible:o,width:800,footer:null,onOk:x,onCancel:p,children:[(0,a.jsx)(es.Z,{className:"mb-1",children:"Invite a user to login to the Admin UI and create Keys"}),(0,a.jsx)(es.Z,{className:"mb-6",children:(0,a.jsx)("b",{children:"Note: SSO Setup Required for this"})}),(0,a.jsxs)(eo.Z,{form:r,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(eo.Z.Item,{label:"User Email",name:"user_email",children:(0,a.jsx)(Q.Z,{placeholder:""})}),(0,a.jsx)(eo.Z.Item,{label:"Team ID",name:"team_id",children:(0,a.jsx)(en.default,{placeholder:"Select Team ID",style:{width:"100%"},children:s?s.map(e=>(0,a.jsx)(le,{value:e.team_id,children:e.team_alias},e.team_id)):(0,a.jsx)(le,{value:null,children:"Default Team"},"default")})}),(0,a.jsx)(eo.Z.Item,{label:"Metadata",name:"metadata",children:(0,a.jsx)(ec.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Create User"})})]})]}),c&&(0,a.jsxs)(ei.Z,{title:"User Created Successfully",visible:o,onOk:x,onCancel:p,footer:null,children:[(0,a.jsx)("p",{children:"User has been created to access your proxy. Please Ask them to Log In."}),(0,a.jsx)("br",{}),(0,a.jsx)("p",{children:(0,a.jsx)("b",{children:"Note: This Feature is only supported through SSO on the Admin UI"})})]})]})},lt=e=>{let{accessToken:l,token:t,keys:s,userRole:r,userID:o,teams:i,setKeys:c}=e,[d,m]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(0),[j,g]=n.useState(null),[f,y]=(0,n.useState)(null);return((0,n.useEffect)(()=>{if(!l||!t||!r||!o)return;let e=async()=>{try{let e=await Z(l,null,r,!0,x,25);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};l&&t&&r&&o&&e()},[l,t,r,o,x]),d&&l&&t&&r&&o)?(0,a.jsx)("div",{style:{width:"100%"},children:(0,a.jsxs)($.Z,{className:"gap-2 p-2 h-[80vh] w-full mt-8",children:[(0,a.jsx)(ll,{userID:o,accessToken:l,teams:i}),(0,a.jsxs)(ef.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[80vh] mb-4",children:[(0,a.jsx)("div",{className:"mb-4 mt-1",children:(0,a.jsx)(es.Z,{children:"These are Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM"})}),(0,a.jsx)(eD.Z,{children:(0,a.jsxs)(ez.Z,{children:[(0,a.jsx)(eB.Z,{children:(0,a.jsxs)(eZ.Z,{className:"mt-5",children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"User ID"}),(0,a.jsx)(ek.Z,{children:"User Email"}),(0,a.jsx)(ek.Z,{children:"User Models"}),(0,a.jsx)(ek.Z,{children:"User Spend ($ USD)"}),(0,a.jsx)(ek.Z,{children:"User Max Budget ($ USD)"}),(0,a.jsx)(ek.Z,{children:"User API Key Aliases"})]})}),(0,a.jsx)(e_.Z,{children:d.map(e=>{var l;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:e.user_id}),(0,a.jsx)(ew.Z,{children:e.user_email}),(0,a.jsx)(ew.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,a.jsx)(ew.Z,{children:e.spend?null===(l=e.spend)||void 0===l?void 0:l.toFixed(2):0}),(0,a.jsx)(ew.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)($.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,a.jsx)(eg.Z,{size:"xs",color:"indigo",children:e.key_aliases.filter(e=>null!==e).join(", ")}):(0,a.jsx)(eg.Z,{size:"xs",color:"gray",children:"No Keys"})})})]},e.user_id)})})]})}),(0,a.jsx)(eB.Z,{children:(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("div",{className:"flex-1 flex justify-between items-center"})]})})]})})]}),function(){if(!d)return null;let e=Math.ceil(d.length/25);return(0,a.jsxs)("div",{className:"flex justify-between items-center",children:[(0,a.jsxs)("div",{children:["Showing Page ",x+1," of ",e]}),(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===x,onClick:()=>p(x-1),children:"← Prev"}),(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{p(x+1)},children:"Next →"})]})]})}()]})}):(0,a.jsx)("div",{children:"Loading..."})},ls=e=>{let{teams:l,searchParams:t,accessToken:s,setTeams:r,userID:o,userRole:i}=e,[c]=eo.Z.useForm(),[d]=eo.Z.useForm(),{Title:m,Paragraph:h}=eR.default,[x,p]=(0,n.useState)(""),[j,g]=(0,n.useState)(!1),[f,Z]=(0,n.useState)(l?l[0]:null),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1),[S,A]=(0,n.useState)([]),[E,I]=(0,n.useState)(!1),[C,P]=(0,n.useState)(null),[T,O]=(0,n.useState)({}),F=e=>{Z(e),g(!0)},R=async e=>{let t=e.team_id;if(console.log("handleEditSubmit:",e),null==s)return;let a=await U(s,e);l&&r(l.map(e=>e.team_id===t?a.data:e)),u.ZP.success("Team updated successfully"),g(!1),Z(null)},L=async e=>{P(e),I(!0)},D=async()=>{if(null!=C&&null!=l&&null!=s){try{await y(s,C);let e=l.filter(e=>e.team_id!==C);r(e)}catch(e){console.error("Error deleting the team:",e)}I(!1),P(null)}};(0,n.useEffect)(()=>{let e=async()=>{try{if(null===o||null===i||null===s||null===l)return;console.log("fetching team info:");let e={};for(let t=0;t<(null==l?void 0:l.length);t++){let r=l[t].team_id,a=await _(s,r);console.log("teamInfo response:",a),null!==a&&(e={...e,[r]:a})}O(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===o||null===i)return;if(null!==s){let e=(await N(s,o,i)).data.map(e=>e.id);console.log("available_model_names:",e),A(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,o,i,l]);let B=async e=>{try{if(null!=s){var t;let a=null==e?void 0:e.team_alias;if((null!==(t=null==l?void 0:l.map(e=>e.team_alias))&&void 0!==t?t:[]).includes(a))throw Error("Team alias ".concat(a," already exists, please pick another alias"));u.ZP.info("Creating Team");let n=await M(s,e);null!==l?r([...l,n]):r([n]),console.log("response for team create call: ".concat(n)),u.ZP.success("Team created"),b(!1)}}catch(e){console.error("Error creating the team:",e),u.ZP.error("Error creating the team: "+e,20)}},z=async e=>{try{if(null!=s&&null!=l){u.ZP.info("Adding Member");let t={role:"user",user_email:e.user_email,user_id:e.user_id},a=await K(s,f.team_id,t);console.log("response for team create call: ".concat(a.data));let n=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(a.data.team_id)),e.team_id===a.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...l];e[n]=a.data,r(e),Z(a.data)}v(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(JSON.stringify(l))),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)($.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(H.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"All Teams"}),(0,a.jsxs)(ef.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Team Name"}),(0,a.jsx)(ek.Z,{children:"Spend (USD)"}),(0,a.jsx)(ek.Z,{children:"Budget (USD)"}),(0,a.jsx)(ek.Z,{children:"Models"}),(0,a.jsx)(ek.Z,{children:"TPM / RPM Limits"}),(0,a.jsx)(ek.Z,{children:"Info"})]})}),(0,a.jsx)(e_.Z,{children:l&&l.length>0?l.map(e=>(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,a.jsx)(ew.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,a.jsx)(ew.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,a.jsx)(ew.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(es.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(es.Z,{children:"All Proxy Models"})},l):(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(es.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(ew.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,a.jsxs)(es.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsxs)(es.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].keys&&T[e.team_id].keys.length," ","Keys"]}),(0,a.jsxs)(es.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].team_info&&T[e.team_id].team_info.members_with_roles&&T[e.team_id].team_info.members_with_roles.length," ","Members"]})]}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ey.Z,{icon:ep.Z,size:"sm",onClick:()=>F(e)}),(0,a.jsx)(ey.Z,{onClick:()=>L(e.team_id),icon:ej.Z,size:"sm"})]})]},e.team_id)):null})]}),E&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:""}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(X.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(X.Z,{onClick:()=>{I(!1),P(null)},children:"Cancel"})]})]})]})})]})]}),(0,a.jsxs)(H.Z,{numColSpan:1,children:[(0,a.jsx)(X.Z,{className:"mx-auto",onClick:()=>b(!0),children:"+ Create New Team"}),(0,a.jsx)(ei.Z,{title:"Create Team",visible:w,width:800,footer:null,onOk:()=>{b(!1),c.resetFields()},onCancel:()=>{b(!1),c.resetFields()},children:(0,a.jsxs)(eo.Z,{form:c,onFinish:B,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(Q.Z,{placeholder:""})}),(0,a.jsx)(eo.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(en.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(en.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S.map(e=>(0,a.jsx)(en.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(eo.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(ed.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(eo.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(ed.Z,{step:1,width:400})}),(0,a.jsx)(eo.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(ed.Z,{step:1,width:400})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,a.jsxs)(H.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"Team Members"}),(0,a.jsx)(h,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,a.jsx)(eS.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(eN.Z,{value:String(l),onClick:()=>{Z(e)},children:e.team_alias},l))}):(0,a.jsxs)(h,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,a.jsxs)(H.Z,{numColSpan:1,children:[(0,a.jsx)(ef.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Member Name"}),(0,a.jsx)(ek.Z,{children:"Role"})]})}),(0,a.jsx)(e_.Z,{children:f?f.members_with_roles.map((e,l)=>(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsx)(ew.Z,{children:e.role})]},l)):null})]})}),f&&(0,a.jsx)(e=>{let{visible:l,onCancel:t,team:s,onSubmit:r}=e,[n]=eo.Z.useForm();return(0,a.jsx)(ei.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{r({...e,team_id:s.team_id}),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,a.jsxs)(eo.Z,{form:n,onFinish:R,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(Q.Z,{})}),(0,a.jsx)(eo.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(en.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(en.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S&&S.map(e=>(0,a.jsx)(en.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(eo.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(ed.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(eo.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(ed.Z,{step:1,width:400})}),(0,a.jsx)(eo.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(ed.Z,{step:1,width:400})}),(0,a.jsx)(eo.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:j,onCancel:()=>{g(!1),Z(null)},team:f,onSubmit:R})]}),(0,a.jsxs)(H.Z,{numColSpan:1,children:[(0,a.jsx)(X.Z,{className:"mx-auto mb-5",onClick:()=>v(!0),children:"+ Add member"}),(0,a.jsx)(ei.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{v(!1),d.resetFields()},onCancel:()=>{v(!1),d.resetFields()},children:(0,a.jsxs)(eo.Z,{form:c,onFinish:z,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,a.jsx)(ec.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,a.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,a.jsx)(eo.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,a.jsx)(ec.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},lr=t(18190),la=e=>{let l,{searchParams:t,accessToken:s,showSSOBanner:r}=e,[o]=eo.Z.useForm(),[i]=eo.Z.useForm(),{Title:c,Paragraph:d}=eR.default,[m,h]=(0,n.useState)(""),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)(!1),[f,y]=(0,n.useState)(!1),[Z,_]=(0,n.useState)(!1),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1);try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let S=()=>{v(!1)},N=["proxy_admin","proxy_admin_viewer"];(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],l=await R(s,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let t=await R(s,"proxy_admin");t.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(t)),console.log("combinedList: ".concat(e)),p(e)}})()},[s]);let A=()=>{_(!1),i.resetFields()},E=()=>{_(!1),i.resetFields()},I=e=>(0,a.jsxs)(eo.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,a.jsx)(ec.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,a.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,a.jsx)(eo.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,a.jsx)(ec.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Add member"})})]}),C=(e,l,t)=>(0,a.jsxs)(eo.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(eS.Z,{value:l,children:N.map((e,l)=>(0,a.jsx)(eN.Z,{value:e,children:e},l))})}),(0,a.jsx)(eo.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:t,valuePropName:"user_id",className:"mt-8",children:(0,a.jsx)(ec.Z,{value:t,disabled:!0})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Update role"})})]}),P=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,null);console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),u.ZP.success("Refresh tab to see updated user role"),_(!1)}}catch(e){console.error("Error creating the key:",e)}},T=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),g(!1)}}catch(e){console.error("Error creating the key:",e)}},O=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call"),e.user_email,e.user_id;let l=await B(s,e,"proxy_admin");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),y(!1)}}catch(e){console.error("Error creating the key:",e)}},F=async e=>{null!=s&&W(s,{environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}})};return console.log("admins: ".concat(null==x?void 0:x.length)),(0,a.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,a.jsx)(c,{level:4,children:"Admin Access "}),(0,a.jsxs)(d,{children:[r&&(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc. ",(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,a.jsxs)($.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsx)(ef.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Member Name"}),(0,a.jsx)(ek.Z,{children:"Role"})]})}),(0,a.jsx)(e_.Z,{children:x?x.map((e,l)=>(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsx)(ew.Z,{children:e.user_role}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ey.Z,{icon:ep.Z,size:"sm",onClick:()=>_(!0)}),(0,a.jsx)(ei.Z,{title:"Update role",visible:Z,width:800,footer:null,onOk:A,onCancel:E,children:C(P,e.user_role,e.user_id)})]})]},l)):null})]})})}),(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsxs)("div",{className:"flex justify-start",children:[(0,a.jsx)(X.Z,{className:"mr-4 mb-5",onClick:()=>y(!0),children:"+ Add admin"}),(0,a.jsx)(ei.Z,{title:"Add admin",visible:f,width:800,footer:null,onOk:()=>{y(!1),i.resetFields()},onCancel:()=>{y(!1),i.resetFields()},children:I(O)}),(0,a.jsx)(X.Z,{className:"mb-5",onClick:()=>g(!0),children:"+ Add viewer"}),(0,a.jsx)(ei.Z,{title:"Add viewer",visible:j,width:800,footer:null,onOk:()=>{g(!1),i.resetFields()},onCancel:()=>{g(!1),i.resetFields()},children:I(T)})]})})]}),(0,a.jsxs)($.Z,{children:[(0,a.jsx)(c,{level:4,children:"Add SSO"}),(0,a.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,a.jsx)(X.Z,{onClick:()=>b(!0),children:"Add SSO"}),(0,a.jsx)(ei.Z,{title:"Add SSO",visible:w,width:800,footer:null,onOk:()=>{b(!1),o.resetFields()},onCancel:()=>{b(!1),o.resetFields()},children:(0,a.jsxs)(eo.Z,{form:o,onFinish:e=>{O(e),F(e),b(!1),v(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,a.jsx)(ec.Z,{})}),(0,a.jsx)(eo.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,a.jsx)(ec.Z,{})}),(0,a.jsx)(eo.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,a.jsx)(ec.Z.Password,{})}),(0,a.jsx)(eo.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,a.jsx)(ec.Z.Password,{})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,a.jsxs)(ei.Z,{title:"SSO Setup Instructions",visible:k,width:800,footer:null,onOk:S,onCancel:()=>{v(!1)},children:[(0,a.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,a.jsx)(es.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,a.jsx)(es.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,a.jsx)(es.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,a.jsx)(es.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{onClick:S,children:"Done"})})]})]}),(0,a.jsxs)(lr.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access ",(0,a.jsxs)("a",{href:l,target:"_blank",children:[(0,a.jsx)("b",{children:l})," "]})]})]})]})},ln=t(42556);let lo=[{name:"slack",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"langfuse",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"openmeter",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}}];var li=e=>{let{accessToken:l,userRole:t,userID:s}=e,[r,o]=(0,n.useState)(lo),[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)(!1),[h]=eo.Z.useForm(),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)([]),[f,y]=(0,n.useState)(""),[Z,_]=(0,n.useState)({}),[w,b]=(0,n.useState)([]),k=e=>{w.includes(e)?b(w.filter(l=>l!==e)):b([...w,e])},v={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)",daily_reports:"Weekly/Monthly Spend Reports"};(0,n.useEffect)(()=>{l&&t&&s&&V(l,s,t).then(e=>{console.log("callbacks",e);let l=lo;o(l=l.map(l=>{let t=e.callbacks.find(e=>e.name===l.name);return t?{...l,variables:{...l.variables,...t.variables}}:l}));let t=e.alerts;if(console.log("alerts_data",t),t&&t.length>0){let e=t[0];console.log("_alert_info",e);let l=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",l),b(e.active_alerts),y(l),_(e.alerts_to_webhook)}c(t)})},[l,t,s]);let S=e=>w&&w.includes(e),N=e=>{if(!l)return;let t=Object.fromEntries(Object.entries(e.variables).map(e=>{var l;let[t,s]=e;return[t,(null===(l=document.querySelector('input[name="'.concat(t,'"]')))||void 0===l?void 0:l.value)||s]}));console.log("updatedVariables",t),console.log("updateAlertTypes",j);let s={environment_variables:t,litellm_settings:{success_callback:[e.name]}};try{W(l,s)}catch(e){u.ZP.error("Failed to update callback: "+e,20)}u.ZP.success("Callback updated successfully")},A=()=>{l&&h.validateFields().then(e=>{if(console.log("Form values:",e),"langfuse"===e.callback){W(l,{environment_variables:{LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey,OPENMETER_API_KEY:null}};o(r?[...r,t]:[t])}else if("slack"===e.callback){console.log("values.slackWebhookUrl: ".concat(e.slackWebhookUrl)),W(l,{general_settings:{alerting:["slack"],alerting_threshold:300},environment_variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl}}),console.log("values.callback: ".concat(e.callback));let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null}};o(r?[...r,t]:[t])}else if("openmeter"==e.callback){console.log("values.openMeterApiKey: ".concat(e.openMeterApiKey)),W(l,{environment_variables:{OPENMETER_API_KEY:e.openMeterApiKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:e.openMeterAPIKey}};o(r?[...r,t]:[t])}m(!1),h.resetFields(),p(null)})};return l?(console.log("callbacks: ".concat(r)),(0,a.jsxs)("div",{className:"w-full mx-4",children:[(0,a.jsxs)($.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,a.jsx)(lr.Z,{title:"[UI] Presidio PII + Guardrails Coming Soon. https://docs.litellm.ai/docs/proxy/pii_masking",color:"sky"}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsxs)(eK.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(eU.Z,{value:"1",children:"Logging Callbacks"}),(0,a.jsx)(eU.Z,{value:"2",children:"Alerting"})]}),(0,a.jsxs)(ez.Z,{children:[(0,a.jsx)(eB.Z,{children:(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Callback"}),(0,a.jsx)(ek.Z,{children:"Callback Env Vars"})]})}),(0,a.jsx)(e_.Z,{children:r.filter(e=>"slack"!==e.name).map((e,t)=>{var s;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:(0,a.jsx)(eg.Z,{color:"emerald",children:e.name})}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)("ul",{children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).filter(l=>{let[t,s]=l;return t.toLowerCase().includes(e.name)}).map(e=>{let[l,t]=e;return(0,a.jsxs)("li",{children:[(0,a.jsx)(es.Z,{className:"mt-2",children:l}),"LANGFUSE_HOST"===l?(0,a.jsx)("p",{children:"default value=https://cloud.langfuse.com"}):(0,a.jsx)("div",{}),(0,a.jsx)(Q.Z,{name:l,defaultValue:t,type:"password"})]},l)})}),(0,a.jsx)(X.Z,{className:"mt-2",onClick:()=>N(e),children:"Save Changes"}),(0,a.jsx)(X.Z,{onClick:()=>z(l,e.name),className:"mx-2",children:"Test Callback"})]})]},t)})})]})})}),(0,a.jsx)(eB.Z,{children:(0,a.jsxs)(ef.Z,{children:[(0,a.jsxs)(es.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from ",(0,a.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{}),(0,a.jsx)(ek.Z,{}),(0,a.jsx)(ek.Z,{children:"Slack Webhook URL"})]})}),(0,a.jsx)(e_.Z,{children:Object.entries(v).map((e,l)=>{let[t,s]=e;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:(0,a.jsx)(ln.Z,{id:"switch",name:"switch",checked:S(t),onChange:()=>k(t)})}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(es.Z,{children:s})}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(Q.Z,{name:t,type:"password",defaultValue:Z&&Z[t]?Z[t]:f})})]},l)})})]}),(0,a.jsx)(X.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(v).forEach(l=>{let[t,s]=l,r=document.querySelector('input[name="'.concat(t,'"]'));console.log("key",t),console.log("webhookInput",r);let a=(null==r?void 0:r.value)||"";console.log("newWebhookValue",a),e[t]=a}),console.log("updatedAlertToWebhooks",e);let t={general_settings:{alert_to_webhook_url:e,alert_types:w}};console.log("payload",t);try{W(l,t)}catch(e){u.ZP.error("Failed to update alerts: "+e,20)}u.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,a.jsx)(X.Z,{onClick:()=>z(l,"slack"),className:"mx-2",children:"Test Alerts"})]})})]})]})]}),(0,a.jsx)(ei.Z,{title:"Add Callback",visible:d,onOk:A,width:800,onCancel:()=>{m(!1),h.resetFields(),p(null)},footer:null,children:(0,a.jsxs)(eo.Z,{form:h,layout:"vertical",onFinish:A,children:[(0,a.jsx)(eo.Z.Item,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,a.jsxs)(en.default,{onChange:e=>{p(e)},children:[(0,a.jsx)(en.default.Option,{value:"langfuse",children:"langfuse"}),(0,a.jsx)(en.default.Option,{value:"openmeter",children:"openmeter"})]})}),"langfuse"===x&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"LANGFUSE_PUBLIC_KEY",name:"langfusePublicKey",rules:[{required:!0,message:"Please enter the public key"}],children:(0,a.jsx)(Q.Z,{type:"password"})}),(0,a.jsx)(eo.Z.Item,{label:"LANGFUSE_PRIVATE_KEY",name:"langfusePrivateKey",rules:[{required:!0,message:"Please enter the private key"}],children:(0,a.jsx)(Q.Z,{type:"password"})})]}),"openmeter"==x&&(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(eo.Z.Item,{label:"OPENMETER_API_KEY",name:"openMeterApiKey",rules:[{required:!0,message:"Please enter the openmeter api key"}],children:(0,a.jsx)(Q.Z,{type:"password"})})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:lc}=en.default;var ld=e=>{let{models:l,accessToken:t,routerSettings:s,setRouterSettings:r}=e,[o]=eo.Z.useForm(),[i,c]=(0,n.useState)(!1),[d,m]=(0,n.useState)("");return(0,a.jsxs)("div",{children:[(0,a.jsx)(X.Z,{className:"mx-auto",onClick:()=>c(!0),children:"+ Add Fallbacks"}),(0,a.jsx)(ei.Z,{title:"Add Fallbacks",visible:i,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),o.resetFields()},children:(0,a.jsxs)(eo.Z,{form:o,onFinish:e=>{console.log(e);let{model_name:l,models:a}=e,n=[...s.fallbacks||[],{[l]:a}],i={...s,fallbacks:n};console.log(i);try{W(t,{router_settings:i}),r(i)}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully"),c(!1),o.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,a.jsx)(eS.Z,{defaultValue:d,children:l&&l.map((e,l)=>(0,a.jsx)(eN.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,a.jsx)(eo.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsx)(eV.Z,{value:l,children:l&&l.filter(e=>e!=d).map(e=>(0,a.jsx)(eq.Z,{value:e,children:e},e))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},lm=t(12968);async function lu(e,l){console.log("isLocal:",!1);let t=window.location.origin,s=new lm.ZP.OpenAI({apiKey:l,baseURL:t,dangerouslyAllowBrowser:!0});try{let l=await s.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});u.ZP.success((0,a.jsxs)("span",{children:["Test model=",(0,a.jsx)("strong",{children:e}),", received model=",(0,a.jsx)("strong",{children:l.model}),". See"," ",(0,a.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}let lh={ttl:3600,lowest_latency_buffer:0},lx=e=>{let{selectedStrategy:l,strategyArgs:t,paramExplanation:s}=e;return(0,a.jsxs)(ee.Z,{children:[(0,a.jsx)(et.Z,{className:"text-sm font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong",children:"Routing Strategy Specific Args"}),(0,a.jsx)(el.Z,{children:"latency-based-routing"==l?(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Setting"}),(0,a.jsx)(ek.Z,{children:"Value"})]})}),(0,a.jsx)(e_.Z,{children:Object.entries(t).map(e=>{let[l,t]=e;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(es.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:s[l]})]}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(Q.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]})}):(0,a.jsx)(es.Z,{children:"No specific settings"})})]})};var lp=e=>{let{accessToken:l,userRole:t,userID:s,modelData:r}=e,[o,i]=(0,n.useState)({}),[c,d]=(0,n.useState)({}),[m,h]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1),[j]=eo.Z.useForm(),[g,f]=(0,n.useState)(null),[y,Z]=(0,n.useState)(null),[_,w]=(0,n.useState)(null),b={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request",ttl:"(int) Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"(float) Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};(0,n.useEffect)(()=>{l&&t&&s&&(V(l,s,t).then(e=>{console.log("callbacks",e),i(e.router_settings)}),q(l).then(e=>{h(e)}))},[l,t,s]);let k=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 W(l,{router_settings:o}),i({...o}),Z(o.routing_strategy),u.ZP.success("Router settings updated successfully")}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}}},v=(e,l)=>{h(m.map(t=>t.field_name===e?{...t,field_value:l}:t))},S=(e,t)=>{if(!l)return;let s=m[t].field_value;if(null!=s&&void 0!=s)try{G(l,e,s);let t=m.map(l=>l.field_name===e?{...l,stored_in_db:!0}:l);h(t)}catch(e){}},N=(e,t)=>{if(l)try{Y(l,e);let t=m.map(l=>l.field_name===e?{...l,stored_in_db:null,field_value:null}:l);h(t)}catch(e){}},A=e=>{if(!l)return;console.log("router_settings",e);let t=Object.fromEntries(Object.entries(e).map(e=>{let[l,t]=e;if("routing_strategy_args"!==l&&"routing_strategy"!==l){var s;return[l,(null===(s=document.querySelector('input[name="'.concat(l,'"]')))||void 0===s?void 0:s.value)||t]}if("routing_strategy"==l)return[l,y];if("routing_strategy_args"==l&&"latency-based-routing"==y){let e={},l=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]');return(null==l?void 0:l.value)&&(e.lowest_latency_buffer=Number(l.value)),(null==t?void 0:t.value)&&(e.ttl=Number(t.value)),console.log("setRoutingStrategyArgs: ".concat(e)),["routing_strategy_args",e]}return null}).filter(e=>null!=e));console.log("updatedVariables",t);try{W(l,{router_settings:t})}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully")};return l?(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(eD.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(eK.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(eU.Z,{value:"1",children:"Loadbalancing"}),(0,a.jsx)(eU.Z,{value:"2",children:"Fallbacks"}),(0,a.jsx)(eU.Z,{value:"3",children:"General"})]}),(0,a.jsxs)(ez.Z,{children:[(0,a.jsx)(eB.Z,{children:(0,a.jsxs)($.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,a.jsx)(er.Z,{children:"Router Settings"}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Setting"}),(0,a.jsx)(ek.Z,{children:"Value"})]})}),(0,a.jsx)(e_.Z,{children:Object.entries(o).filter(e=>{let[l,t]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l&&"routing_strategy_args"!=l}).map(e=>{let[l,t]=e;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(es.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:b[l]})]}),(0,a.jsx)(ew.Z,{children:"routing_strategy"==l?(0,a.jsxs)(eS.Z,{defaultValue:t,className:"w-full max-w-md",onValueChange:Z,children:[(0,a.jsx)(eN.Z,{value:"usage-based-routing",children:"usage-based-routing"}),(0,a.jsx)(eN.Z,{value:"latency-based-routing",children:"latency-based-routing"}),(0,a.jsx)(eN.Z,{value:"simple-shuffle",children:"simple-shuffle"})]}):(0,a.jsx)(Q.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]}),(0,a.jsx)(lx,{selectedStrategy:y,strategyArgs:o&&o.routing_strategy_args&&Object.keys(o.routing_strategy_args).length>0?o.routing_strategy_args:lh,paramExplanation:b})]}),(0,a.jsx)(H.Z,{children:(0,a.jsx)(X.Z,{className:"mt-2",onClick:()=>A(o),children:"Save Changes"})})]})}),(0,a.jsxs)(eB.Z,{children:[(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Model Name"}),(0,a.jsx)(ek.Z,{children:"Fallbacks"})]})}),(0,a.jsx)(e_.Z,{children:o.fallbacks&&o.fallbacks.map((e,t)=>Object.entries(e).map(e=>{let[s,r]=e;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:s}),(0,a.jsx)(ew.Z,{children:Array.isArray(r)?r.join(", "):r}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(X.Z,{onClick:()=>lu(s,l),children:"Test Fallback"})}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(ey.Z,{icon:ej.Z,size:"sm",onClick:()=>k(s)})})]},t.toString()+s)}))})]}),(0,a.jsx)(ld,{models:(null==r?void 0:r.data)?r.data.map(e=>e.model_name):[],accessToken:l,routerSettings:o,setRouterSettings:i})]}),(0,a.jsx)(eB.Z,{children:(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Setting"}),(0,a.jsx)(ek.Z,{children:"Value"}),(0,a.jsx)(ek.Z,{children:"Status"}),(0,a.jsx)(ek.Z,{children:"Action"})]})}),(0,a.jsx)(e_.Z,{children:m.map((e,l)=>(0,a.jsxs)(ev.Z,{children:[(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(es.Z,{children:e.field_name}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:e.field_description})]}),(0,a.jsx)(ew.Z,{children:"Integer"==e.field_type?(0,a.jsx)(ed.Z,{step:1,value:e.field_value,onChange:l=>v(e.field_name,l)}):null}),(0,a.jsx)(ew.Z,{children:!0==e.stored_in_db?(0,a.jsx)(eg.Z,{icon:eQ.Z,className:"text-white",children:"In DB"}):!1==e.stored_in_db?(0,a.jsx)(eg.Z,{className:"text-gray bg-white outline",children:"In Config"}):(0,a.jsx)(eg.Z,{className:"text-gray bg-white outline",children:"Not Set"})}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(X.Z,{onClick:()=>S(e.field_name,l),children:"Update"}),(0,a.jsx)(ey.Z,{icon:ej.Z,color:"red",onClick:()=>N(e.field_name,l),children:"Reset"})]})]},l))})]})})})]})]})}):null},lj=t(67951),lg=e=>{let{}=e;return(0,a.jsx)(a.Fragment,{children:(0,a.jsx)($.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsxs)("div",{className:"mb-5",children:[(0,a.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,a.jsx)(es.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsxs)(eK.Z,{children:[(0,a.jsx)(eU.Z,{children:"OpenAI Python SDK"}),(0,a.jsx)(eU.Z,{children:"LlamaIndex"}),(0,a.jsx)(eU.Z,{children:"Langchain Py"})]}),(0,a.jsxs)(ez.Z,{children:[(0,a.jsx)(eB.Z,{children:(0,a.jsx)(lj.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n '})}),(0,a.jsx)(eB.Z,{children:(0,a.jsx)(lj.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n '})}),(0,a.jsx)(eB.Z,{children:(0,a.jsx)(lj.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 lf(e,l,t,s){console.log("isLocal:",!1);let r=window.location.origin,a=new lm.ZP.OpenAI({apiKey:s,baseURL:r,dangerouslyAllowBrowser:!0});try{for await(let s of(await a.chat.completions.create({model:t,stream:!0,messages:[{role:"user",content:e}]})))console.log(s),s.choices[0].delta.content&&l(s.choices[0].delta.content)}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var ly=e=>{let{accessToken:l,token:t,userRole:s,userID:r}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)(""),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)(void 0),[p,j]=(0,n.useState)([]);(0,n.useEffect)(()=>{l&&t&&s&&r&&(async()=>{try{let e=await N(l,r,s);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));console.log(l),j(l),x(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,r,s]);let g=(e,l)=>{u(t=>{let s=t[t.length-1];return s&&s.role===e?[...t.slice(0,t.length-1),{role:e,content:s.content+l}]:[...t,{role:e,content:l}]})},f=async()=>{if(""!==c.trim()&&o&&t&&s&&r){u(e=>[...e,{role:"user",content:c}]);try{h&&await lf(c,e=>g("assistant",e),h,o)}catch(e){console.error("Error fetching model response",e),g("assistant","Error fetching model response")}d("")}};if(s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=eR.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,a.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,a.jsx)($.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(eD.Z,{children:[(0,a.jsx)(eK.Z,{children:(0,a.jsx)(eU.Z,{children:"Chat"})}),(0,a.jsx)(ez.Z,{children:(0,a.jsxs)(eB.Z,{children:[(0,a.jsx)("div",{className:"sm:max-w-2xl",children:(0,a.jsxs)($.Z,{numItems:2,children:[(0,a.jsxs)(H.Z,{children:[(0,a.jsx)(es.Z,{children:"API Key"}),(0,a.jsx)(Q.Z,{placeholder:"Type API Key here",type:"password",onValueChange:i,value:o})]}),(0,a.jsxs)(H.Z,{className:"mx-2",children:[(0,a.jsx)(es.Z,{children:"Select Model:"}),(0,a.jsx)(en.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),x(e)},options:p,style:{width:"200px"}})]})]})}),(0,a.jsxs)(eZ.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,a.jsx)(eb.Z,{children:(0,a.jsx)(ev.Z,{children:(0,a.jsx)(ew.Z,{})})}),(0,a.jsx)(e_.Z,{children:m.map((e,l)=>(0,a.jsx)(ev.Z,{children:(0,a.jsx)(ew.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,a.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(Q.Z,{type:"text",value:c,onChange:e=>d(e.target.value),placeholder:"Type your message..."}),(0,a.jsx)(X.Z,{onClick:f,className:"ml-2",children:"Send"})]})})]})})]})})})})},lZ=t(33509),l_=t(95781);let{Sider:lw}=lZ.default;var lb=e=>{let{setPage:l,userRole:t,defaultSelectedKey:s}=e;return"Admin Viewer"==t?(0,a.jsx)(lZ.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,a.jsx)(lw,{width:120,children:(0,a.jsxs)(l_.Z,{mode:"inline",defaultSelectedKeys:s||["4"],style:{height:"100%",borderRight:0},children:[(0,a.jsx)(l_.Z.Item,{onClick:()=>l("api-keys"),children:"API Keys"},"4"),(0,a.jsx)(l_.Z.Item,{onClick:()=>l("models"),children:"Models"},"2"),(0,a.jsx)(l_.Z.Item,{onClick:()=>l("llm-playground"),children:"Chat UI"},"3"),(0,a.jsx)(l_.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")]})})}):(0,a.jsx)(lZ.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,a.jsx)(lw,{width:145,children:(0,a.jsxs)(l_.Z,{mode:"inline",defaultSelectedKeys:s||["1"],style:{height:"100%",borderRight:0},children:[(0,a.jsx)(l_.Z.Item,{onClick:()=>l("api-keys"),children:(0,a.jsx)(es.Z,{children:"API Keys"})},"1"),(0,a.jsx)(l_.Z.Item,{onClick:()=>l("llm-playground"),children:(0,a.jsx)(es.Z,{children:"Test Key"})},"3"),"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("models"),children:(0,a.jsx)(es.Z,{children:"Models"})},"2"):null,"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("usage"),children:(0,a.jsx)(es.Z,{children:"Usage"})},"4"):null,"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("teams"),children:(0,a.jsx)(es.Z,{children:"Teams"})},"6"):null,"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("users"),children:(0,a.jsx)(es.Z,{children:"Users"})},"5"):null,"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("settings"),children:(0,a.jsx)(es.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("general-settings"),children:(0,a.jsx)(es.Z,{children:"Router Settings"})},"9"):null,"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("admin-panel"),children:(0,a.jsx)(es.Z,{children:"Admin"})},"7"):null,(0,a.jsx)(l_.Z.Item,{onClick:()=>l("api_ref"),children:(0,a.jsx)(es.Z,{children:"API Reference"})},"11")]})})})},lk=t(67989),lv=e=>{let{accessToken:l,token:t,userRole:s,userID:r,keys:o}=e,i=new Date,[c,d]=(0,n.useState)([]),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)([]),[p,j]=(0,n.useState)([]),[g,f]=(0,n.useState)([]),[y,Z]=(0,n.useState)([]),[_,w]=(0,n.useState)([]),[b,k]=(0,n.useState)([]),[v,S]=(0,n.useState)(""),[N,R]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),M=new Date(i.getFullYear(),i.getMonth(),1),L=new Date(i.getFullYear(),i.getMonth()+1,0),U=z(M),D=z(L);console.log("keys in usage",o);let K=async(e,t,s)=>{if(!e||!t||!l)return;console.log("uiSelectedKey",s);let r=await T(l,s,e.toISOString(),t.toISOString());console.log("End user data updated successfully",r),j(r)},B=async(e,t)=>{e&&t&&l&&(Z((await E(l,e.toISOString(),t.toISOString())).spend_per_tag),console.log("Tag spend data updated successfully"))};function z(e){let l=e.getFullYear(),t=e.getMonth()+1,s=e.getDate();return"".concat(l,"-").concat(t<10?"0"+t:t,"-").concat(s<10?"0"+s:s)}return console.log("Start date is ".concat(U)),console.log("End date is ".concat(D)),(0,n.useEffect)(()=>{l&&t&&s&&r&&(async()=>{try{if(console.log("user role: ".concat(s)),"Admin"==s||"Admin Viewer"==s){var e,a;let t=await C(l);d(t);let s=(await P(l)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,10),spend:e.total_spend}));u(s);let r=(await O(l)).map(e=>({key:e.model,spend:e.total_spend}));x(r);let n=await A(l);console.log("teamSpend",n),f(n.daily_spend),w(n.teams);let o=n.total_spend_per_team;o=o.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e)),k(o);let i=await E(l,null===(e=N.from)||void 0===e?void 0:e.toISOString(),null===(a=N.to)||void 0===a?void 0:a.toISOString());Z(i.spend_per_tag);let c=await T(l,null,void 0,void 0);j(c),console.log("spend/user result",c)}else"App Owner"==s&&await I(l,t,s,r,U,D).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),d(l);let t=e.top_api_keys;u(t)}else{let t=(await F(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[t,s]=e;"spend"!==t&&"startTime"!==t&&"models"!==t&&"users"!==t&&l.push({key:t,spend:s})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let t=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(t[0]))),t}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));u(t),d(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[l,t,s,r,U,D]),(0,a.jsxs)("div",{style:{width:"100%"},className:"p-8",children:[(0,a.jsx)(eP,{userID:r,userRole:s,accessToken:l,userSpend:null,selectedTeam:null}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsxs)(eK.Z,{className:"mt-2",children:[(0,a.jsx)(eU.Z,{children:"All Up"}),(0,a.jsx)(eU.Z,{children:"Team Based Usage"}),(0,a.jsx)(eU.Z,{children:"End User Usage"}),(0,a.jsx)(eU.Z,{children:"Tag Based Usage"})]}),(0,a.jsxs)(ez.Z,{children:[(0,a.jsx)(eB.Z,{children:(0,a.jsxs)($.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsx)(H.Z,{numColSpan:2,children:(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(er.Z,{children:"Monthly Spend"}),(0,a.jsx)(eY.Z,{data:c,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(er.Z,{children:"Top API Keys"}),(0,a.jsx)(eY.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(er.Z,{children:"Top Models"}),(0,a.jsx)(eY.Z,{className:"mt-4 h-40",data:h,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(H.Z,{numColSpan:1})]})}),(0,a.jsx)(eB.Z,{children:(0,a.jsxs)($.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsxs)(H.Z,{numColSpan:2,children:[(0,a.jsxs)(ef.Z,{className:"mb-2",children:[(0,a.jsx)(er.Z,{children:"Total Spend Per Team"}),(0,a.jsx)(lk.Z,{data:b})]}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(er.Z,{children:"Daily Spend Per Team"}),(0,a.jsx)(eY.Z,{className:"h-72",data:g,showLegend:!0,index:"date",categories:_,yAxisWidth:80,colors:["blue","green","yellow","red","purple"],stack:!0})]})]}),(0,a.jsx)(H.Z,{numColSpan:2})]})}),(0,a.jsxs)(eB.Z,{children:[(0,a.jsxs)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:["End-Users of your LLM API calls. Tracked when a `user` param is passed in your LLM calls ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/users",target:"_blank",children:"docs here"})]}),(0,a.jsxs)($.Z,{numItems:2,children:[(0,a.jsxs)(H.Z,{children:[(0,a.jsx)(es.Z,{children:"Select Time Range"}),(0,a.jsx)(eL.Z,{enableSelect:!0,value:N,onValueChange:e=>{R(e),K(e.from,e.to,null)}})]}),(0,a.jsxs)(H.Z,{children:[(0,a.jsx)(es.Z,{children:"Select Key"}),(0,a.jsxs)(eS.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(eN.Z,{value:"all-keys",onClick:()=>{K(N.from,N.to,null)},children:"All Keys"},"all-keys"),null==o?void 0:o.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsx)(eN.Z,{value:String(l),onClick:()=>{K(N.from,N.to,e.token)},children:e.key_alias},l):null)]})]})]}),(0,a.jsx)(ef.Z,{className:"mt-4",children:(0,a.jsxs)(eZ.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"End User"}),(0,a.jsx)(ek.Z,{children:"Spend"}),(0,a.jsx)(ek.Z,{children:"Total Events"})]})}),(0,a.jsx)(e_.Z,{children:null==p?void 0:p.map((e,l)=>{var t;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:e.end_user}),(0,a.jsx)(ew.Z,{children:null===(t=e.total_spend)||void 0===t?void 0:t.toFixed(4)}),(0,a.jsx)(ew.Z,{children:e.total_count})]},l)})})]})})]}),(0,a.jsx)(eB.Z,{children:(0,a.jsxs)($.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,a.jsxs)(H.Z,{numColSpan:2,children:[(0,a.jsx)(eL.Z,{className:"mb-4",enableSelect:!0,value:N,onValueChange:e=>{R(e),B(e.from,e.to)}}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(er.Z,{children:"Spend Per Tag"}),(0,a.jsxs)(es.Z,{children:["Get Started Tracking cost per tag ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags",target:"_blank",children:"here"})]}),(0,a.jsx)(eY.Z,{className:"h-72",data:y,index:"name",categories:["spend"],colors:["blue"]})]})]}),(0,a.jsx)(H.Z,{numColSpan:2})]})})]})]})]})},lS=()=>{let{Title:e,Paragraph:l}=eR.default,[t,s]=(0,n.useState)(""),[r,i]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,o.useSearchParams)(),[g,f]=(0,n.useState)({data:[]}),y=j.get("userID"),Z=j.get("token"),[_,w]=(0,n.useState)("api-keys"),[b,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,eF.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),s(l),"Admin Viewer"==l&&w("usage")}else console.log("User role not defined");e.user_email?i(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[Z]),(0,a.jsx)(n.Suspense,{fallback:(0,a.jsx)("div",{children:"Loading..."}),children:(0,a.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,a.jsx)(m,{userID:y,userRole:t,userEmail:r,showSSOBanner:x}),(0,a.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,a.jsx)("div",{className:"mt-8",children:(0,a.jsx)(lb,{setPage:w,userRole:t,defaultSelectedKey:null})}),"api-keys"==_?(0,a.jsx)(eM,{userID:y,userRole:t,teams:c,keys:u,setUserRole:s,userEmail:r,setUserEmail:i,setTeams:d,setKeys:h}):"models"==_?(0,a.jsx)(e9,{userID:y,userRole:t,token:Z,accessToken:b,modelData:g,setModelData:f}):"llm-playground"==_?(0,a.jsx)(ly,{userID:y,userRole:t,token:Z,accessToken:b}):"users"==_?(0,a.jsx)(lt,{userID:y,userRole:t,token:Z,keys:u,teams:c,accessToken:b,setKeys:h}):"teams"==_?(0,a.jsx)(ls,{teams:c,setTeams:d,searchParams:j,accessToken:b,userID:y,userRole:t}):"admin-panel"==_?(0,a.jsx)(la,{setTeams:d,searchParams:j,accessToken:b,showSSOBanner:x}):"api_ref"==_?(0,a.jsx)(lg,{}):"settings"==_?(0,a.jsx)(li,{userID:y,userRole:t,accessToken:b}):"general-settings"==_?(0,a.jsx)(lp,{userID:y,userRole:t,accessToken:b,modelData:g}):(0,a.jsx)(lv,{userID:y,userRole:t,token:Z,accessToken:b,keys:u})]})]})})}}},function(e){e.O(0,[936,884,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/index.html b/litellm/proxy/_experimental/out/index.html
index 930018e005..011bb7fc76 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 d67a480b37..ce4099b2cd 100644
--- a/litellm/proxy/_experimental/out/index.txt
+++ b/litellm/proxy/_experimental/out/index.txt
@@ -1,7 +1,7 @@
2:I[77831,[],""]
-3:I[7926,["936","static/chunks/2f6dbc85-052c4579f80d66ae.js","884","static/chunks/884-7576ee407a2ecbe6.js","931","static/chunks/app/page-6a39771cacf75ea6.js"],""]
+3:I[4858,["936","static/chunks/2f6dbc85-052c4579f80d66ae.js","884","static/chunks/884-7576ee407a2ecbe6.js","931","static/chunks/app/page-c35c14c9afd091ec.js"],""]
4:I[5613,[],""]
5:I[31778,[],""]
-0:["obp5wqVSVDMiDTC414cR8",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_c23dc8","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/f04e46b02318b660.css","precedence":"next","crossOrigin":""}]],"$L6"]]]]
+0:["2ASoJGxS-D4w-vat00xMy",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_c23dc8","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/f04e46b02318b660.css","precedence":"next","crossOrigin":""}]],"$L6"]]]]
6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]]
1:null
diff --git a/litellm/proxy/_super_secret_config.yaml b/litellm/proxy/_super_secret_config.yaml
index 0e9e43bc99..8d3e4f5e14 100644
--- a/litellm/proxy/_super_secret_config.yaml
+++ b/litellm/proxy/_super_secret_config.yaml
@@ -18,11 +18,6 @@ model_list:
model: azure/chatgpt-v-2
api_key: os.environ/AZURE_API_KEY
api_base: os.environ/AZURE_API_BASE
- input_cost_per_token: 0.0
- output_cost_per_token: 0.0
-- model_name: gpt-3.5-turbo
- litellm_params:
- model: gpt-4o
- model_name: bert-classifier
litellm_params:
model: huggingface/text-classification/shahrukhx01/question-vs-statement-classifier
@@ -34,14 +29,17 @@ router_settings:
enable_pre_call_checks: true
litellm_settings:
- set_verbose: True
- fallbacks: [{"gpt-3.5-turbo-012": ["gpt-3.5-turbo-0125-preview"]}]
+ fallbacks: [{"gpt-3.5-turbo-012": ["azure-gpt-3.5-turbo"]}]
# service_callback: ["prometheus_system"]
# success_callback: ["prometheus"]
# failure_callback: ["prometheus"]
general_settings:
enable_jwt_auth: True
+ litellm_jwtauth:
+ team_id_default: "1234"
+ user_id_jwt_field:
+ user_id_upsert: True
disable_reset_budget: True
proxy_batch_write_at: 10 # 👈 Frequency of batch writing logs to server (in seconds)
routing_strategy: simple-shuffle # Literal["simple-shuffle", "least-busy", "usage-based-routing","latency-based-routing"], default="simple-shuffle"
diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py
index b1af153e81..d6bf49dca6 100644
--- a/litellm/proxy/_types.py
+++ b/litellm/proxy/_types.py
@@ -1,37 +1,11 @@
-from pydantic import ConfigDict, BaseModel, Field, root_validator, Json, VERSION
+from pydantic import BaseModel, Extra, Field, root_validator, Json, validator
+from dataclasses import fields
import enum
from typing import Optional, List, Union, Dict, Literal, Any
from datetime import datetime
-import uuid
-import json
+import uuid, json, sys, os
from litellm.types.router import UpdateRouterConfig
-try:
- from pydantic import model_validator # type: ignore
-except ImportError:
- from pydantic import root_validator # pydantic v1
-
- def model_validator(mode): # type: ignore
- pre = mode == "before"
- return root_validator(pre=pre)
-
-
-# Function to get Pydantic version
-def is_pydantic_v2() -> int:
- return int(VERSION.split(".")[0])
-
-
-def get_model_config(arbitrary_types_allowed: bool = False) -> ConfigDict:
- # Version-specific configuration
- if is_pydantic_v2() >= 2:
- model_config = ConfigDict(extra="allow", arbitrary_types_allowed=arbitrary_types_allowed, protected_namespaces=()) # type: ignore
- else:
- from pydantic import Extra
-
- model_config = ConfigDict(extra=Extra.allow, arbitrary_types_allowed=arbitrary_types_allowed) # type: ignore
-
- return model_config
-
def hash_token(token: str):
import hashlib
@@ -61,7 +35,8 @@ class LiteLLMBase(BaseModel):
# if using pydantic v1
return self.__fields_set__
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class LiteLLM_UpperboundKeyGenerateParams(LiteLLMBase):
@@ -104,11 +79,6 @@ class LiteLLMRoutes(enum.Enum):
"/v1/models",
]
- # NOTE: ROUTES ONLY FOR MASTER KEY - only the Master Key should be able to Reset Spend
- master_key_only_routes: List = [
- "/global/spend/reset",
- ]
-
info_routes: List = [
"/key/info",
"/team/info",
@@ -119,6 +89,11 @@ class LiteLLMRoutes(enum.Enum):
"/v2/key/info",
]
+ # NOTE: ROUTES ONLY FOR MASTER KEY - only the Master Key should be able to Reset Spend
+ master_key_only_routes: List = [
+ "/global/spend/reset",
+ ]
+
sso_only_routes: List = [
"/key/generate",
"/key/update",
@@ -227,13 +202,19 @@ class LiteLLM_JWTAuth(LiteLLMBase):
"global_spend_tracking_routes",
"info_routes",
]
- team_jwt_scope: str = "litellm_team"
- team_id_jwt_field: str = "client_id"
+ team_id_jwt_field: Optional[str] = None
team_allowed_routes: List[
Literal["openai_routes", "info_routes", "management_routes"]
] = ["openai_routes", "info_routes"]
+ team_id_default: Optional[str] = Field(
+ default=None,
+ description="If no team_id given, default permissions/spend-tracking to this team.s",
+ )
org_id_jwt_field: Optional[str] = None
user_id_jwt_field: Optional[str] = None
+ user_id_upsert: bool = Field(
+ default=False, description="If user doesn't exist, upsert them into the db."
+ )
end_user_id_jwt_field: Optional[str] = None
public_key_ttl: float = 600
@@ -259,7 +240,7 @@ class LiteLLMPromptInjectionParams(LiteLLMBase):
llm_api_system_prompt: Optional[str] = None
llm_api_fail_call_string: Optional[str] = None
- @model_validator(mode="before")
+ @root_validator(pre=True)
def check_llm_api_params(cls, values):
llm_api_check = values.get("llm_api_check")
if llm_api_check is True:
@@ -317,7 +298,8 @@ class ProxyChatCompletionRequest(LiteLLMBase):
deployment_id: Optional[str] = None
request_timeout: Optional[int] = None
- model_config = get_model_config()
+ class Config:
+ extra = "allow" # allow params not defined here, these fall in litellm.completion(**kwargs)
class ModelInfoDelete(LiteLLMBase):
@@ -344,9 +326,11 @@ class ModelInfo(LiteLLMBase):
]
]
- model_config = get_model_config()
+ class Config:
+ extra = Extra.allow # Allow extra fields
+ protected_namespaces = ()
- @model_validator(mode="before")
+ @root_validator(pre=True)
def set_model_info(cls, values):
if values.get("id") is None:
values.update({"id": str(uuid.uuid4())})
@@ -372,9 +356,10 @@ class ModelParams(LiteLLMBase):
litellm_params: dict
model_info: ModelInfo
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
- @model_validator(mode="before")
+ @root_validator(pre=True)
def set_model_info(cls, values):
if values.get("model_info") is None:
values.update({"model_info": ModelInfo()})
@@ -410,7 +395,8 @@ class GenerateKeyRequest(GenerateRequestBase):
{}
) # {"gpt-4": 5.0, "gpt-3.5-turbo": 5.0}, defaults to {}
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class GenerateKeyResponse(GenerateKeyRequest):
@@ -420,7 +406,7 @@ class GenerateKeyResponse(GenerateKeyRequest):
user_id: Optional[str] = None
token_id: Optional[str] = None
- @model_validator(mode="before")
+ @root_validator(pre=True)
def set_model_info(cls, values):
if values.get("token") is not None:
values.update({"key": values.get("token")})
@@ -460,7 +446,8 @@ class LiteLLM_ModelTable(LiteLLMBase):
created_by: str
updated_by: str
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class NewUserRequest(GenerateKeyRequest):
@@ -488,7 +475,7 @@ class UpdateUserRequest(GenerateRequestBase):
user_role: Optional[str] = None
max_budget: Optional[float] = None
- @model_validator(mode="before")
+ @root_validator(pre=True)
def check_user_info(cls, values):
if values.get("user_id") is None and values.get("user_email") is None:
raise ValueError("Either user id or user email must be provided")
@@ -508,7 +495,7 @@ class NewEndUserRequest(LiteLLMBase):
None # if no equivalent model in allowed region - default all requests to this model
)
- @model_validator(mode="before")
+ @root_validator(pre=True)
def check_user_info(cls, values):
if values.get("max_budget") is not None and values.get("budget_id") is not None:
raise ValueError("Set either 'max_budget' or 'budget_id', not both.")
@@ -521,7 +508,7 @@ class Member(LiteLLMBase):
user_id: Optional[str] = None
user_email: Optional[str] = None
- @model_validator(mode="before")
+ @root_validator(pre=True)
def check_user_info(cls, values):
if values.get("user_id") is None and values.get("user_email") is None:
raise ValueError("Either user id or user email must be provided")
@@ -546,7 +533,8 @@ class TeamBase(LiteLLMBase):
class NewTeamRequest(TeamBase):
model_aliases: Optional[dict] = None
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class GlobalEndUsersSpend(LiteLLMBase):
@@ -565,7 +553,7 @@ class TeamMemberDeleteRequest(LiteLLMBase):
user_id: Optional[str] = None
user_email: Optional[str] = None
- @model_validator(mode="before")
+ @root_validator(pre=True)
def check_user_info(cls, values):
if values.get("user_id") is None and values.get("user_email") is None:
raise ValueError("Either user id or user email must be provided")
@@ -599,9 +587,10 @@ class LiteLLM_TeamTable(TeamBase):
budget_reset_at: Optional[datetime] = None
model_id: Optional[int] = None
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
- @model_validator(mode="before")
+ @root_validator(pre=True)
def set_model_info(cls, values):
dict_fields = [
"metadata",
@@ -637,7 +626,8 @@ class LiteLLM_BudgetTable(LiteLLMBase):
model_max_budget: Optional[dict] = None
budget_duration: Optional[str] = None
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class NewOrganizationRequest(LiteLLM_BudgetTable):
@@ -687,7 +677,8 @@ class KeyManagementSettings(LiteLLMBase):
class TeamDefaultSettings(LiteLLMBase):
team_id: str
- model_config = get_model_config()
+ class Config:
+ extra = "allow" # allow params not defined here, these fall in litellm.completion(**kwargs)
class DynamoDBArgs(LiteLLMBase):
@@ -711,6 +702,25 @@ class DynamoDBArgs(LiteLLMBase):
assume_role_aws_session_name: Optional[str] = None
+class ConfigFieldUpdate(LiteLLMBase):
+ field_name: str
+ field_value: Any
+ config_type: Literal["general_settings"]
+
+
+class ConfigFieldDelete(LiteLLMBase):
+ config_type: Literal["general_settings"]
+ field_name: str
+
+
+class ConfigList(LiteLLMBase):
+ field_name: str
+ field_type: str
+ field_description: str
+ field_value: Any
+ stored_in_db: Optional[bool]
+
+
class ConfigGeneralSettings(LiteLLMBase):
"""
Documents all the fields supported by `general_settings` in config.yaml
@@ -758,7 +768,11 @@ class ConfigGeneralSettings(LiteLLMBase):
description="override user_api_key_auth with your own auth script - https://docs.litellm.ai/docs/proxy/virtual_keys#custom-auth",
)
max_parallel_requests: Optional[int] = Field(
- None, description="maximum parallel requests for each api key"
+ None,
+ description="maximum parallel requests for each api key",
+ )
+ global_max_parallel_requests: Optional[int] = Field(
+ None, description="global max parallel requests to allow for a proxy instance."
)
infer_model_from_keys: Optional[bool] = Field(
None,
@@ -828,7 +842,8 @@ class ConfigYAML(LiteLLMBase):
description="litellm router object settings. See router.py __init__ for all, example router.num_retries=5, router.timeout=5, router.max_retries=5, router.retry_after=5",
)
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class LiteLLM_VerificationToken(LiteLLMBase):
@@ -862,7 +877,8 @@ class LiteLLM_VerificationToken(LiteLLMBase):
user_id_rate_limits: Optional[dict] = None
team_id_rate_limits: Optional[dict] = None
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class LiteLLM_VerificationTokenView(LiteLLM_VerificationToken):
@@ -892,7 +908,7 @@ class UserAPIKeyAuth(
user_role: Optional[Literal["proxy_admin", "app_owner", "app_user"]] = None
allowed_model_region: Optional[Literal["eu"]] = None
- @model_validator(mode="before")
+ @root_validator(pre=True)
def check_api_key(cls, values):
if values.get("api_key") is not None:
values.update({"token": hash_token(values.get("api_key"))})
@@ -919,7 +935,7 @@ class LiteLLM_UserTable(LiteLLMBase):
tpm_limit: Optional[int] = None
rpm_limit: Optional[int] = None
- @model_validator(mode="before")
+ @root_validator(pre=True)
def set_model_info(cls, values):
if values.get("spend") is None:
values.update({"spend": 0.0})
@@ -927,7 +943,8 @@ class LiteLLM_UserTable(LiteLLMBase):
values.update({"models": []})
return values
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class LiteLLM_EndUserTable(LiteLLMBase):
@@ -939,13 +956,14 @@ class LiteLLM_EndUserTable(LiteLLMBase):
default_model: Optional[str] = None
litellm_budget_table: Optional[LiteLLM_BudgetTable] = None
- @model_validator(mode="before")
+ @root_validator(pre=True)
def set_model_info(cls, values):
if values.get("spend") is None:
values.update({"spend": 0.0})
return values
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class LiteLLM_SpendLogs(LiteLLMBase):
diff --git a/litellm/proxy/auth/auth_checks.py b/litellm/proxy/auth/auth_checks.py
index 62e5eba013..08da25556d 100644
--- a/litellm/proxy/auth/auth_checks.py
+++ b/litellm/proxy/auth/auth_checks.py
@@ -26,7 +26,7 @@ all_routes = LiteLLMRoutes.openai_routes.value + LiteLLMRoutes.management_routes
def common_checks(
request_body: dict,
- team_object: LiteLLM_TeamTable,
+ team_object: Optional[LiteLLM_TeamTable],
user_object: Optional[LiteLLM_UserTable],
end_user_object: Optional[LiteLLM_EndUserTable],
global_proxy_spend: Optional[float],
@@ -45,13 +45,14 @@ def common_checks(
6. [OPTIONAL] If 'litellm.max_budget' is set (>0), is proxy under budget
"""
_model = request_body.get("model", None)
- if team_object.blocked == True:
+ if team_object is not None and team_object.blocked == True:
raise Exception(
f"Team={team_object.team_id} is blocked. Update via `/team/unblock` if your admin."
)
# 2. If user can call model
if (
_model is not None
+ and team_object is not None
and len(team_object.models) > 0
and _model not in team_object.models
):
@@ -65,7 +66,8 @@ def common_checks(
)
# 3. If team is in budget
if (
- team_object.max_budget is not None
+ team_object is not None
+ and team_object.max_budget is not None
and team_object.spend is not None
and team_object.spend > team_object.max_budget
):
@@ -239,6 +241,7 @@ async def get_user_object(
user_id: str,
prisma_client: Optional[PrismaClient],
user_api_key_cache: DualCache,
+ user_id_upsert: bool,
) -> Optional[LiteLLM_UserTable]:
"""
- Check if user id in proxy User Table
@@ -252,7 +255,7 @@ async def get_user_object(
return None
# check if in cache
- cached_user_obj = user_api_key_cache.async_get_cache(key=user_id)
+ cached_user_obj = await user_api_key_cache.async_get_cache(key=user_id)
if cached_user_obj is not None:
if isinstance(cached_user_obj, dict):
return LiteLLM_UserTable(**cached_user_obj)
@@ -260,16 +263,27 @@ async def get_user_object(
return cached_user_obj
# else, check db
try:
+
response = await prisma_client.db.litellm_usertable.find_unique(
where={"user_id": user_id}
)
if response is None:
- raise Exception
+ if user_id_upsert:
+ response = await prisma_client.db.litellm_usertable.create(
+ data={"user_id": user_id}
+ )
+ else:
+ raise Exception
- return LiteLLM_UserTable(**response.dict())
- except Exception as e: # if end-user not in db
- raise Exception(
+ _response = LiteLLM_UserTable(**dict(response))
+
+ # save the user object to cache
+ await user_api_key_cache.async_set_cache(key=user_id, value=_response)
+
+ return _response
+ except Exception as e: # if user not in db
+ raise ValueError(
f"User doesn't exist in db. 'user_id'={user_id}. Create user via `/user/new` call."
)
@@ -290,7 +304,7 @@ async def get_team_object(
)
# check if in cache
- cached_team_obj = user_api_key_cache.async_get_cache(key=team_id)
+ cached_team_obj = await user_api_key_cache.async_get_cache(key=team_id)
if cached_team_obj is not None:
if isinstance(cached_team_obj, dict):
return LiteLLM_TeamTable(**cached_team_obj)
@@ -305,7 +319,11 @@ async def get_team_object(
if response is None:
raise Exception
- return LiteLLM_TeamTable(**response.dict())
+ _response = LiteLLM_TeamTable(**response.dict())
+ # save the team object to cache
+ await user_api_key_cache.async_set_cache(key=response.team_id, value=_response)
+
+ return _response
except Exception as e:
raise Exception(
f"Team doesn't exist in db. Team={team_id}. Create team via `/team/new` call."
diff --git a/litellm/proxy/auth/handle_jwt.py b/litellm/proxy/auth/handle_jwt.py
index 18c0d7b2ce..0a186d7dde 100644
--- a/litellm/proxy/auth/handle_jwt.py
+++ b/litellm/proxy/auth/handle_jwt.py
@@ -55,12 +55,9 @@ class JWTHandler:
return True
return False
- def is_team(self, scopes: list) -> bool:
- if self.litellm_jwtauth.team_jwt_scope in scopes:
- return True
- return False
-
- def get_end_user_id(self, token: dict, default_value: Optional[str]) -> str:
+ def get_end_user_id(
+ self, token: dict, default_value: Optional[str]
+ ) -> Optional[str]:
try:
if self.litellm_jwtauth.end_user_id_jwt_field is not None:
user_id = token[self.litellm_jwtauth.end_user_id_jwt_field]
@@ -70,13 +67,36 @@ class JWTHandler:
user_id = default_value
return user_id
+ def is_required_team_id(self) -> bool:
+ """
+ Returns:
+ - True: if 'team_id_jwt_field' is set
+ - False: if not
+ """
+ if self.litellm_jwtauth.team_id_jwt_field is None:
+ return False
+ return True
+
def get_team_id(self, token: dict, default_value: Optional[str]) -> Optional[str]:
try:
- team_id = token[self.litellm_jwtauth.team_id_jwt_field]
+ if self.litellm_jwtauth.team_id_jwt_field is not None:
+ team_id = token[self.litellm_jwtauth.team_id_jwt_field]
+ elif self.litellm_jwtauth.team_id_default is not None:
+ team_id = self.litellm_jwtauth.team_id_default
+ else:
+ team_id = None
except KeyError:
team_id = default_value
return team_id
+ def is_upsert_user_id(self) -> bool:
+ """
+ Returns:
+ - True: if 'user_id_upsert' is set
+ - False: if not
+ """
+ return self.litellm_jwtauth.user_id_upsert
+
def get_user_id(self, token: dict, default_value: Optional[str]) -> Optional[str]:
try:
if self.litellm_jwtauth.user_id_jwt_field is not None:
@@ -165,7 +185,7 @@ class JWTHandler:
decode_options = None
if audience is None:
decode_options = {"verify_aud": False}
-
+
from jwt.algorithms import RSAAlgorithm
header = jwt.get_unverified_header(token)
@@ -207,12 +227,14 @@ class JWTHandler:
raise Exception(f"Validation fails: {str(e)}")
elif public_key is not None and isinstance(public_key, str):
try:
- cert = x509.load_pem_x509_certificate(public_key.encode(), default_backend())
+ cert = x509.load_pem_x509_certificate(
+ public_key.encode(), default_backend()
+ )
# Extract public key
key = cert.public_key().public_bytes(
serialization.Encoding.PEM,
- serialization.PublicFormat.SubjectPublicKeyInfo
+ serialization.PublicFormat.SubjectPublicKeyInfo,
)
# decode the token using the public key
@@ -221,7 +243,7 @@ class JWTHandler:
key,
algorithms=algorithms,
audience=audience,
- options=decode_options
+ options=decode_options,
)
return payload
diff --git a/litellm/proxy/hooks/parallel_request_limiter.py b/litellm/proxy/hooks/parallel_request_limiter.py
index 28e6d1853f..26238b6c08 100644
--- a/litellm/proxy/hooks/parallel_request_limiter.py
+++ b/litellm/proxy/hooks/parallel_request_limiter.py
@@ -79,6 +79,9 @@ class _PROXY_MaxParallelRequestsHandler(CustomLogger):
max_parallel_requests = user_api_key_dict.max_parallel_requests
if max_parallel_requests is None:
max_parallel_requests = sys.maxsize
+ global_max_parallel_requests = data.get("metadata", {}).get(
+ "global_max_parallel_requests", None
+ )
tpm_limit = getattr(user_api_key_dict, "tpm_limit", sys.maxsize)
if tpm_limit is None:
tpm_limit = sys.maxsize
@@ -91,6 +94,24 @@ class _PROXY_MaxParallelRequestsHandler(CustomLogger):
# Setup values
# ------------
+ if global_max_parallel_requests is not None:
+ # get value from cache
+ _key = "global_max_parallel_requests"
+ current_global_requests = await cache.async_get_cache(
+ key=_key, local_only=True
+ )
+ # check if below limit
+ if current_global_requests is None:
+ current_global_requests = 1
+ # if above -> raise error
+ if current_global_requests >= global_max_parallel_requests:
+ raise HTTPException(
+ status_code=429, detail="Max parallel request limit reached."
+ )
+ # if below -> increment
+ else:
+ await cache.async_increment_cache(key=_key, value=1, local_only=True)
+
current_date = datetime.now().strftime("%Y-%m-%d")
current_hour = datetime.now().strftime("%H")
current_minute = datetime.now().strftime("%M")
@@ -207,6 +228,9 @@ class _PROXY_MaxParallelRequestsHandler(CustomLogger):
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time):
try:
self.print_verbose(f"INSIDE parallel request limiter ASYNC SUCCESS LOGGING")
+ global_max_parallel_requests = kwargs["litellm_params"]["metadata"].get(
+ "global_max_parallel_requests", None
+ )
user_api_key = kwargs["litellm_params"]["metadata"]["user_api_key"]
user_api_key_user_id = kwargs["litellm_params"]["metadata"].get(
"user_api_key_user_id", None
@@ -222,6 +246,14 @@ class _PROXY_MaxParallelRequestsHandler(CustomLogger):
# Setup values
# ------------
+ if global_max_parallel_requests is not None:
+ # get value from cache
+ _key = "global_max_parallel_requests"
+ # decrement
+ await self.user_api_key_cache.async_increment_cache(
+ key=_key, value=-1, local_only=True
+ )
+
current_date = datetime.now().strftime("%Y-%m-%d")
current_hour = datetime.now().strftime("%H")
current_minute = datetime.now().strftime("%M")
@@ -336,6 +368,9 @@ class _PROXY_MaxParallelRequestsHandler(CustomLogger):
async def async_log_failure_event(self, kwargs, response_obj, start_time, end_time):
try:
self.print_verbose(f"Inside Max Parallel Request Failure Hook")
+ global_max_parallel_requests = kwargs["litellm_params"]["metadata"].get(
+ "global_max_parallel_requests", None
+ )
user_api_key = (
kwargs["litellm_params"].get("metadata", {}).get("user_api_key", None)
)
@@ -347,17 +382,26 @@ class _PROXY_MaxParallelRequestsHandler(CustomLogger):
return
## decrement call count if call failed
- if (
- hasattr(kwargs["exception"], "status_code")
- and kwargs["exception"].status_code == 429
- and "Max parallel request limit reached" in str(kwargs["exception"])
- ):
+ if "Max parallel request limit reached" in str(kwargs["exception"]):
pass # ignore failed calls due to max limit being reached
else:
# ------------
# Setup values
# ------------
+ if global_max_parallel_requests is not None:
+ # get value from cache
+ _key = "global_max_parallel_requests"
+ current_global_requests = (
+ await self.user_api_key_cache.async_get_cache(
+ key=_key, local_only=True
+ )
+ )
+ # decrement
+ await self.user_api_key_cache.async_increment_cache(
+ key=_key, value=-1, local_only=True
+ )
+
current_date = datetime.now().strftime("%Y-%m-%d")
current_hour = datetime.now().strftime("%H")
current_minute = datetime.now().strftime("%M")
diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py
index 9192198453..83da986f6d 100644
--- a/litellm/proxy/proxy_server.py
+++ b/litellm/proxy/proxy_server.py
@@ -234,6 +234,7 @@ class SpecialModelNames(enum.Enum):
class CommonProxyErrors(enum.Enum):
db_not_connected_error = "DB not connected"
no_llm_router = "No models configured on proxy"
+ not_allowed_access = "Admin-only endpoint. Not allowed to access this."
@app.exception_handler(ProxyException)
@@ -440,29 +441,32 @@ async def user_api_key_auth(
# get team id
team_id = jwt_handler.get_team_id(token=valid_token, default_value=None)
- if team_id is None:
+ if team_id is None and jwt_handler.is_required_team_id() == True:
raise Exception(
f"No team id passed in. Field checked in jwt token - '{jwt_handler.litellm_jwtauth.team_id_jwt_field}'"
)
- # check allowed team routes
- is_allowed = allowed_routes_check(
- user_role="team",
- user_route=route,
- litellm_proxy_roles=jwt_handler.litellm_jwtauth,
- )
- if is_allowed == False:
- allowed_routes = jwt_handler.litellm_jwtauth.team_allowed_routes # type: ignore
- actual_routes = get_actual_routes(allowed_routes=allowed_routes)
- raise Exception(
- f"Team not allowed to access this route. Route={route}, Allowed Routes={actual_routes}"
- )
- # check if team in db
- team_object = await get_team_object(
- team_id=team_id,
- prisma_client=prisma_client,
- user_api_key_cache=user_api_key_cache,
- )
+ team_object: Optional[LiteLLM_TeamTable] = None
+ if team_id is not None:
+ # check allowed team routes
+ is_allowed = allowed_routes_check(
+ user_role="team",
+ user_route=route,
+ litellm_proxy_roles=jwt_handler.litellm_jwtauth,
+ )
+ if is_allowed == False:
+ allowed_routes = jwt_handler.litellm_jwtauth.team_allowed_routes # type: ignore
+ actual_routes = get_actual_routes(allowed_routes=allowed_routes)
+ raise Exception(
+ f"Team not allowed to access this route. Route={route}, Allowed Routes={actual_routes}"
+ )
+
+ # check if team in db
+ team_object = await get_team_object(
+ team_id=team_id,
+ prisma_client=prisma_client,
+ user_api_key_cache=user_api_key_cache,
+ )
# [OPTIONAL] track spend for an org id - `LiteLLM_OrganizationTable`
org_id = jwt_handler.get_org_id(token=valid_token, default_value=None)
@@ -481,11 +485,9 @@ async def user_api_key_auth(
user_id=user_id,
prisma_client=prisma_client,
user_api_key_cache=user_api_key_cache,
+ user_id_upsert=jwt_handler.is_upsert_user_id(),
)
- # save the user object to cache
- await user_api_key_cache.async_set_cache(
- key=user_id, value=user_object
- )
+
# [OPTIONAL] track spend against an external user - `LiteLLM_EndUserTable`
end_user_object = None
end_user_id = jwt_handler.get_end_user_id(
@@ -547,18 +549,18 @@ async def user_api_key_auth(
global_proxy_spend=global_proxy_spend,
route=route,
)
- # save team object in cache
- await user_api_key_cache.async_set_cache(
- key=team_object.team_id, value=team_object
- )
# return UserAPIKeyAuth object
return UserAPIKeyAuth(
api_key=None,
- team_id=team_object.team_id,
- team_tpm_limit=team_object.tpm_limit,
- team_rpm_limit=team_object.rpm_limit,
- team_models=team_object.models,
+ team_id=team_object.team_id if team_object is not None else None,
+ team_tpm_limit=(
+ team_object.tpm_limit if team_object is not None else None
+ ),
+ team_rpm_limit=(
+ team_object.rpm_limit if team_object is not None else None
+ ),
+ team_models=team_object.models if team_object is not None else [],
user_role="app_owner",
user_id=user_id,
org_id=org_id,
@@ -566,9 +568,9 @@ async def user_api_key_auth(
#### ELSE ####
if master_key is None:
if isinstance(api_key, str):
- return UserAPIKeyAuth(api_key=api_key)
+ return UserAPIKeyAuth(api_key=api_key, user_role="proxy_admin")
else:
- return UserAPIKeyAuth()
+ return UserAPIKeyAuth(user_role="proxy_admin")
elif api_key is None: # only require api key if master key is set
raise Exception("No api key passed in.")
elif api_key == "":
@@ -659,6 +661,7 @@ async def user_api_key_auth(
verbose_proxy_logger.debug("Token from db: %s", valid_token)
elif valid_token is not None:
verbose_proxy_logger.debug("API Key Cache Hit!")
+
user_id_information = None
if valid_token:
# Got Valid Token from Cache, DB
@@ -1187,7 +1190,18 @@ async def user_api_key_auth(
# No token was found when looking up in the DB
raise Exception("Invalid token passed")
if valid_token_dict is not None:
- return UserAPIKeyAuth(api_key=api_key, **valid_token_dict)
+ if user_id_information is not None and _is_user_proxy_admin(
+ user_id_information
+ ):
+ return UserAPIKeyAuth(
+ api_key=api_key, user_role="proxy_admin", **valid_token_dict
+ )
+ elif _has_user_setup_sso() and route in LiteLLMRoutes.sso_only_routes.value:
+ return UserAPIKeyAuth(
+ api_key=api_key, user_role="app_owner", **valid_token_dict
+ )
+ else:
+ return UserAPIKeyAuth(api_key=api_key, **valid_token_dict)
else:
raise Exception()
except Exception as e:
@@ -2684,7 +2698,19 @@ class ProxyConfig:
"Error setting env variable: %s - %s", k, str(e)
)
- # general_settings
+ # router settings
+ if llm_router is not None and prisma_client is not None:
+ db_router_settings = await prisma_client.db.litellm_config.find_first(
+ where={"param_name": "router_settings"}
+ )
+ if (
+ db_router_settings is not None
+ and db_router_settings.param_value is not None
+ ):
+ _router_settings = db_router_settings.param_value
+ llm_router.update_settings(**_router_settings)
+
+ ## ALERTING ## [TODO] move this to the _update_general_settings() block
_general_settings = config_data.get("general_settings", {})
if "alerting" in _general_settings:
general_settings["alerting"] = _general_settings["alerting"]
@@ -2708,17 +2734,24 @@ class ProxyConfig:
alert_to_webhook_url=general_settings["alert_to_webhook_url"]
)
- # router settings
- if llm_router is not None and prisma_client is not None:
- db_router_settings = await prisma_client.db.litellm_config.find_first(
- where={"param_name": "router_settings"}
- )
- if (
- db_router_settings is not None
- and db_router_settings.param_value is not None
- ):
- _router_settings = db_router_settings.param_value
- llm_router.update_settings(**_router_settings)
+ async def _update_general_settings(self, db_general_settings: Optional[Json]):
+ """
+ Pull from DB, read general settings value
+ """
+ global general_settings
+ if db_general_settings is None:
+ return
+ _general_settings = dict(db_general_settings)
+ ## MAX PARALLEL REQUESTS ##
+ if "max_parallel_requests" in _general_settings:
+ general_settings["max_parallel_requests"] = _general_settings[
+ "max_parallel_requests"
+ ]
+
+ if "global_max_parallel_requests" in _general_settings:
+ general_settings["global_max_parallel_requests"] = _general_settings[
+ "global_max_parallel_requests"
+ ]
async def add_deployment(
self,
@@ -2726,7 +2759,7 @@ class ProxyConfig:
proxy_logging_obj: ProxyLogging,
):
"""
- - Check db for new models (last 10 most recently updated)
+ - Check db for new models
- Check if model id's in router already
- If not, add to router
"""
@@ -2739,9 +2772,21 @@ class ProxyConfig:
)
verbose_proxy_logger.debug(f"llm_router: {llm_router}")
new_models = await prisma_client.db.litellm_proxymodeltable.find_many()
+ # update llm router
await self._update_llm_router(
new_models=new_models, proxy_logging_obj=proxy_logging_obj
)
+
+ db_general_settings = await prisma_client.db.litellm_config.find_first(
+ where={"param_name": "general_settings"}
+ )
+
+ # update general settings
+ if db_general_settings is not None:
+ await self._update_general_settings(
+ db_general_settings=db_general_settings.param_value,
+ )
+
except Exception as e:
verbose_proxy_logger.error(
"{}\nTraceback:{}".format(str(e), traceback.format_exc())
@@ -2941,27 +2986,6 @@ async def generate_key_helper_fn(
data=key_data, table_name="key"
)
key_data["token_id"] = getattr(create_key_response, "token", None)
- elif custom_db_client is not None:
- if table_name is None or table_name == "user":
- ## CREATE USER (If necessary)
- verbose_proxy_logger.debug(
- "CustomDBClient: Creating User= %s", user_data
- )
- user_row = await custom_db_client.insert_data(
- value=user_data, table_name="user"
- )
- if user_row is None:
- # GET USER ROW
- user_row = await custom_db_client.get_data(
- key=user_id, table_name="user" # type: ignore
- )
-
- ## use default user model list if no key-specific model list provided
- if len(user_row.models) > 0 and len(key_data["models"]) == 0: # type: ignore
- key_data["models"] = user_row.models
- ## CREATE KEY
- verbose_proxy_logger.debug("CustomDBClient: Creating Key= %s", key_data)
- await custom_db_client.insert_data(value=key_data, table_name="key")
except Exception as e:
traceback.print_exc()
if isinstance(e, HTTPException):
@@ -3557,6 +3581,9 @@ async def chat_completion(
data["metadata"]["user_api_key_alias"] = getattr(
user_api_key_dict, "key_alias", None
)
+ data["metadata"]["global_max_parallel_requests"] = general_settings.get(
+ "global_max_parallel_requests", None
+ )
data["metadata"]["user_api_key_user_id"] = user_api_key_dict.user_id
data["metadata"]["user_api_key_org_id"] = user_api_key_dict.org_id
data["metadata"]["user_api_key_team_id"] = getattr(
@@ -3746,8 +3773,11 @@ async def chat_completion(
await proxy_logging_obj.post_call_failure_hook(
user_api_key_dict=user_api_key_dict, original_exception=e, request_data=data
)
+ litellm_debug_info = getattr(e, "litellm_debug_info", "")
verbose_proxy_logger.debug(
- f"\033[1;31mAn error occurred: {e}\n\n Debug this by setting `--debug`, e.g. `litellm --model gpt-3.5-turbo --debug`"
+ "\033[1;31mAn error occurred: %s %s\n\n Debug this by setting `--debug`, e.g. `litellm --model gpt-3.5-turbo --debug`",
+ e,
+ litellm_debug_info,
)
router_model_names = llm_router.model_names if llm_router is not None else []
if user_debug:
@@ -3795,6 +3825,7 @@ async def completion(
user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
):
global user_temperature, user_request_timeout, user_max_tokens, user_api_base
+ data = {}
check_request_disconnected = None
try:
body = await request.body()
@@ -3824,6 +3855,9 @@ async def completion(
data["metadata"]["user_api_key_team_id"] = getattr(
user_api_key_dict, "team_id", None
)
+ data["metadata"]["global_max_parallel_requests"] = general_settings.get(
+ "global_max_parallel_requests", None
+ )
data["metadata"]["user_api_key_team_alias"] = getattr(
user_api_key_dict, "team_alias", None
)
@@ -3904,6 +3938,9 @@ async def completion(
cache_key = hidden_params.get("cache_key", None) or ""
api_base = hidden_params.get("api_base", None) or ""
+ ### ALERTING ###
+ data["litellm_status"] = "success" # used for alerting
+
verbose_proxy_logger.debug("final response: %s", response)
if (
"stream" in data and data["stream"] == True
@@ -3934,10 +3971,15 @@ async def completion(
return response
except Exception as e:
data["litellm_status"] = "fail" # used for alerting
+ await proxy_logging_obj.post_call_failure_hook(
+ user_api_key_dict=user_api_key_dict, original_exception=e, request_data=data
+ )
verbose_proxy_logger.debug("EXCEPTION RAISED IN PROXY MAIN.PY")
+ litellm_debug_info = getattr(e, "litellm_debug_info", "")
verbose_proxy_logger.debug(
- "\033[1;31mAn error occurred: %s\n\n Debug this by setting `--debug`, e.g. `litellm --model gpt-3.5-turbo --debug`",
+ "\033[1;31mAn error occurred: %s %s\n\n Debug this by setting `--debug`, e.g. `litellm --model gpt-3.5-turbo --debug`",
e,
+ litellm_debug_info,
)
traceback.print_exc()
error_traceback = traceback.format_exc()
@@ -4015,6 +4057,9 @@ async def embeddings(
data["metadata"]["user_api_key_alias"] = getattr(
user_api_key_dict, "key_alias", None
)
+ data["metadata"]["global_max_parallel_requests"] = general_settings.get(
+ "global_max_parallel_requests", None
+ )
data["metadata"]["user_api_key_user_id"] = user_api_key_dict.user_id
data["metadata"]["user_api_key_team_id"] = getattr(
user_api_key_dict, "team_id", None
@@ -4140,6 +4185,12 @@ async def embeddings(
await proxy_logging_obj.post_call_failure_hook(
user_api_key_dict=user_api_key_dict, original_exception=e, request_data=data
)
+ litellm_debug_info = getattr(e, "litellm_debug_info", "")
+ verbose_proxy_logger.debug(
+ "\033[1;31mAn error occurred: %s %s\n\n Debug this by setting `--debug`, e.g. `litellm --model gpt-3.5-turbo --debug`",
+ e,
+ litellm_debug_info,
+ )
traceback.print_exc()
if isinstance(e, HTTPException):
raise ProxyException(
@@ -4213,6 +4264,9 @@ async def image_generation(
data["metadata"]["user_api_key_alias"] = getattr(
user_api_key_dict, "key_alias", None
)
+ data["metadata"]["global_max_parallel_requests"] = general_settings.get(
+ "global_max_parallel_requests", None
+ )
data["metadata"]["user_api_key_user_id"] = user_api_key_dict.user_id
data["metadata"]["user_api_key_team_id"] = getattr(
user_api_key_dict, "team_id", None
@@ -4393,6 +4447,9 @@ async def audio_transcriptions(
data["metadata"]["user_api_key_team_id"] = getattr(
user_api_key_dict, "team_id", None
)
+ data["metadata"]["global_max_parallel_requests"] = general_settings.get(
+ "global_max_parallel_requests", None
+ )
data["metadata"]["user_api_key_team_alias"] = getattr(
user_api_key_dict, "team_alias", None
)
@@ -4590,6 +4647,9 @@ async def moderations(
"authorization", None
) # do not store the original `sk-..` api key in the db
data["metadata"]["headers"] = _headers
+ data["metadata"]["global_max_parallel_requests"] = general_settings.get(
+ "global_max_parallel_requests", None
+ )
data["metadata"]["user_api_key_alias"] = getattr(
user_api_key_dict, "key_alias", None
)
@@ -7697,7 +7757,12 @@ async def new_organization(
If none provided, create one based on provided values
"""
- budget_row = LiteLLM_BudgetTable(**data.json(exclude_none=True))
+ budget_params = LiteLLM_BudgetTable.model_fields.keys()
+
+ # Only include Budget Params when creating an entry in litellm_budgettable
+ _json_data = data.json(exclude_none=True)
+ _budget_data = {k: v for k, v in _json_data.items() if k in budget_params}
+ budget_row = LiteLLM_BudgetTable(**_budget_data)
new_budget = prisma_client.jsonify_object(budget_row.json(exclude_none=True))
@@ -9288,7 +9353,7 @@ async def auth_callback(request: Request):
return RedirectResponse(url=litellm_dashboard_ui)
-#### BASIC ENDPOINTS ####
+#### CONFIG MANAGEMENT ####
@router.post(
"/config/update",
tags=["config.yaml"],
@@ -9424,6 +9489,299 @@ async def update_config(config_info: ConfigYAML):
)
+### CONFIG GENERAL SETTINGS
+"""
+- Update config settings
+- Get config settings
+
+Keep it more precise, to prevent overwrite other values unintentially
+"""
+
+
+@router.post(
+ "/config/field/update",
+ tags=["config.yaml"],
+ dependencies=[Depends(user_api_key_auth)],
+)
+async def update_config_general_settings(
+ data: ConfigFieldUpdate,
+ user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
+):
+ """
+ Update a specific field in litellm general settings
+ """
+ global prisma_client
+ ## VALIDATION ##
+ """
+ - Check if prisma_client is None
+ - Check if user allowed to call this endpoint (admin-only)
+ - Check if param in general settings
+ - Check if config value is valid type
+ """
+
+ if prisma_client is None:
+ raise HTTPException(
+ status_code=400,
+ detail={"error": CommonProxyErrors.db_not_connected_error.value},
+ )
+
+ if user_api_key_dict.user_role != "proxy_admin":
+ raise HTTPException(
+ status_code=400,
+ detail={"error": CommonProxyErrors.not_allowed_access.value},
+ )
+
+ if data.field_name not in ConfigGeneralSettings.model_fields:
+ raise HTTPException(
+ status_code=400,
+ detail={"error": "Invalid field={} passed in.".format(data.field_name)},
+ )
+
+ try:
+ cgs = ConfigGeneralSettings(**{data.field_name: data.field_value})
+ except:
+ raise HTTPException(
+ status_code=400,
+ detail={
+ "error": "Invalid type of field value={} passed in.".format(
+ type(data.field_value),
+ )
+ },
+ )
+
+ ## get general settings from db
+ db_general_settings = await prisma_client.db.litellm_config.find_first(
+ where={"param_name": "general_settings"}
+ )
+ ### update value
+
+ if db_general_settings is None or db_general_settings.param_value is None:
+ general_settings = {}
+ else:
+ general_settings = dict(db_general_settings.param_value)
+
+ ## update db
+
+ general_settings[data.field_name] = data.field_value
+
+ response = await prisma_client.db.litellm_config.upsert(
+ where={"param_name": "general_settings"},
+ data={
+ "create": {"param_name": "general_settings", "param_value": json.dumps(general_settings)}, # type: ignore
+ "update": {"param_value": json.dumps(general_settings)}, # type: ignore
+ },
+ )
+
+ return response
+
+
+@router.get(
+ "/config/field/info",
+ tags=["config.yaml"],
+ dependencies=[Depends(user_api_key_auth)],
+)
+async def get_config_general_settings(
+ field_name: str,
+ user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
+):
+ global prisma_client
+
+ ## VALIDATION ##
+ """
+ - Check if prisma_client is None
+ - Check if user allowed to call this endpoint (admin-only)
+ - Check if param in general settings
+ """
+ if prisma_client is None:
+ raise HTTPException(
+ status_code=400,
+ detail={"error": CommonProxyErrors.db_not_connected_error.value},
+ )
+
+ if user_api_key_dict.user_role != "proxy_admin":
+ raise HTTPException(
+ status_code=400,
+ detail={"error": CommonProxyErrors.not_allowed_access.value},
+ )
+
+ if field_name not in ConfigGeneralSettings.model_fields:
+ raise HTTPException(
+ status_code=400,
+ detail={"error": "Invalid field={} passed in.".format(field_name)},
+ )
+
+ ## get general settings from db
+ db_general_settings = await prisma_client.db.litellm_config.find_first(
+ where={"param_name": "general_settings"}
+ )
+ ### pop the value
+
+ if db_general_settings is None or db_general_settings.param_value is None:
+ raise HTTPException(
+ status_code=400,
+ detail={"error": "Field name={} not in DB".format(field_name)},
+ )
+ else:
+ general_settings = dict(db_general_settings.param_value)
+
+ if field_name in general_settings:
+ return {
+ "field_name": field_name,
+ "field_value": general_settings[field_name],
+ }
+ else:
+ raise HTTPException(
+ status_code=400,
+ detail={"error": "Field name={} not in DB".format(field_name)},
+ )
+
+
+@router.get(
+ "/config/list",
+ tags=["config.yaml"],
+ dependencies=[Depends(user_api_key_auth)],
+)
+async def get_config_list(
+ config_type: Literal["general_settings"],
+ user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
+) -> List[ConfigList]:
+ """
+ List the available fields + current values for a given type of setting (currently just 'general_settings'user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),)
+ """
+ global prisma_client, general_settings
+
+ ## VALIDATION ##
+ """
+ - Check if prisma_client is None
+ - Check if user allowed to call this endpoint (admin-only)
+ - Check if param in general settings
+ """
+ if prisma_client is None:
+ raise HTTPException(
+ status_code=400,
+ detail={"error": CommonProxyErrors.db_not_connected_error.value},
+ )
+
+ if user_api_key_dict.user_role != "proxy_admin":
+ raise HTTPException(
+ status_code=400,
+ detail={
+ "error": "{}, your role={}".format(
+ CommonProxyErrors.not_allowed_access.value,
+ user_api_key_dict.user_role,
+ )
+ },
+ )
+
+ ## get general settings from db
+ db_general_settings = await prisma_client.db.litellm_config.find_first(
+ where={"param_name": "general_settings"}
+ )
+
+ if db_general_settings is not None and db_general_settings.param_value is not None:
+ db_general_settings_dict = dict(db_general_settings.param_value)
+ else:
+ db_general_settings_dict = {}
+
+ allowed_args = {
+ "max_parallel_requests": {"type": "Integer"},
+ "global_max_parallel_requests": {"type": "Integer"},
+ }
+
+ return_val = []
+
+ for field_name, field_info in ConfigGeneralSettings.model_fields.items():
+ if field_name in allowed_args:
+
+ _stored_in_db = None
+ if field_name in db_general_settings_dict:
+ _stored_in_db = True
+ elif field_name in general_settings:
+ _stored_in_db = False
+
+ _response_obj = ConfigList(
+ field_name=field_name,
+ field_type=allowed_args[field_name]["type"],
+ field_description=field_info.description or "",
+ field_value=general_settings.get(field_name, None),
+ stored_in_db=_stored_in_db,
+ )
+ return_val.append(_response_obj)
+
+ return return_val
+
+
+@router.post(
+ "/config/field/delete",
+ tags=["config.yaml"],
+ dependencies=[Depends(user_api_key_auth)],
+)
+async def delete_config_general_settings(
+ data: ConfigFieldDelete,
+ user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),
+):
+ """
+ Delete the db value of this field in litellm general settings. Resets it to it's initial default value on litellm.
+ """
+ global prisma_client
+ ## VALIDATION ##
+ """
+ - Check if prisma_client is None
+ - Check if user allowed to call this endpoint (admin-only)
+ - Check if param in general settings
+ """
+ if prisma_client is None:
+ raise HTTPException(
+ status_code=400,
+ detail={"error": CommonProxyErrors.db_not_connected_error.value},
+ )
+
+ if user_api_key_dict.user_role != "proxy_admin":
+ raise HTTPException(
+ status_code=400,
+ detail={
+ "error": "{}, your role={}".format(
+ CommonProxyErrors.not_allowed_access.value,
+ user_api_key_dict.user_role,
+ )
+ },
+ )
+
+ if data.field_name not in ConfigGeneralSettings.model_fields:
+ raise HTTPException(
+ status_code=400,
+ detail={"error": "Invalid field={} passed in.".format(data.field_name)},
+ )
+
+ ## get general settings from db
+ db_general_settings = await prisma_client.db.litellm_config.find_first(
+ where={"param_name": "general_settings"}
+ )
+ ### pop the value
+
+ if db_general_settings is None or db_general_settings.param_value is None:
+ raise HTTPException(
+ status_code=400,
+ detail={"error": "Field name={} not in config".format(data.field_name)},
+ )
+ else:
+ general_settings = dict(db_general_settings.param_value)
+
+ ## update db
+
+ general_settings.pop(data.field_name, None)
+
+ response = await prisma_client.db.litellm_config.upsert(
+ where={"param_name": "general_settings"},
+ data={
+ "create": {"param_name": "general_settings", "param_value": json.dumps(general_settings)}, # type: ignore
+ "update": {"param_value": json.dumps(general_settings)}, # type: ignore
+ },
+ )
+
+ return response
+
+
@router.get(
"/get/config/callbacks",
tags=["config.yaml"],
@@ -9591,6 +9949,7 @@ async def config_yaml_endpoint(config_info: ConfigYAML):
return {"hello": "world"}
+#### BASIC ENDPOINTS ####
@router.get(
"/test",
tags=["health"],
diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py
index 33127e957a..d1210a504f 100644
--- a/litellm/proxy/utils.py
+++ b/litellm/proxy/utils.py
@@ -252,8 +252,8 @@ class ProxyLogging:
"""
Runs the CustomLogger's async_moderation_hook()
"""
+ new_data = copy.deepcopy(data)
for callback in litellm.callbacks:
- new_data = copy.deepcopy(data)
try:
if isinstance(callback, CustomLogger):
await callback.async_moderation_hook(
@@ -418,9 +418,14 @@ class ProxyLogging:
Related issue - https://github.com/BerriAI/litellm/issues/3395
"""
+ litellm_debug_info = getattr(original_exception, "litellm_debug_info", None)
+ exception_str = str(original_exception)
+ if litellm_debug_info is not None:
+ exception_str += litellm_debug_info
+
asyncio.create_task(
self.alerting_handler(
- message=f"LLM API call failed: {str(original_exception)}",
+ message=f"LLM API call failed: {exception_str}",
level="High",
alert_type="llm_exceptions",
request_data=request_data,
diff --git a/litellm/router.py b/litellm/router.py
index ec7df1124c..08576f78e1 100644
--- a/litellm/router.py
+++ b/litellm/router.py
@@ -262,13 +262,22 @@ class Router:
self.retry_after = retry_after
self.routing_strategy = routing_strategy
- self.fallbacks = fallbacks or litellm.fallbacks
+
+ ## SETTING FALLBACKS ##
+ ### validate if it's set + in correct format
+ _fallbacks = fallbacks or litellm.fallbacks
+
+ self.validate_fallbacks(fallback_param=_fallbacks)
+ ### set fallbacks
+ self.fallbacks = _fallbacks
+
if default_fallbacks is not None or litellm.default_fallbacks is not None:
_fallbacks = default_fallbacks or litellm.default_fallbacks
if self.fallbacks is not None:
self.fallbacks.append({"*": _fallbacks})
else:
self.fallbacks = [{"*": _fallbacks}]
+
self.context_window_fallbacks = (
context_window_fallbacks or litellm.context_window_fallbacks
)
@@ -336,6 +345,21 @@ class Router:
if self.alerting_config is not None:
self._initialize_alerting()
+ def validate_fallbacks(self, fallback_param: Optional[List]):
+ if fallback_param is None:
+ return
+ if len(fallback_param) > 0: # if set
+ ## for dictionary in list, check if only 1 key in dict
+ for _dict in fallback_param:
+ assert isinstance(_dict, dict), "Item={}, not a dictionary".format(
+ _dict
+ )
+ assert (
+ len(_dict.keys()) == 1
+ ), "Only 1 key allows in dictionary. You set={} for dict={}".format(
+ len(_dict.keys()), _dict
+ )
+
def routing_strategy_init(self, routing_strategy: str, routing_strategy_args: dict):
if routing_strategy == "least-busy":
self.leastbusy_logger = LeastBusyLoggingHandler(
@@ -1962,6 +1986,45 @@ class Router:
key=rpm_key, value=request_count, local_only=True
) # don't change existing ttl
+ def _is_cooldown_required(self, exception_status: Union[str, int]):
+ """
+ A function to determine if a cooldown is required based on the exception status.
+
+ Parameters:
+ exception_status (Union[str, int]): The status of the exception.
+
+ Returns:
+ bool: True if a cooldown is required, False otherwise.
+ """
+ try:
+
+ if isinstance(exception_status, str):
+ exception_status = int(exception_status)
+
+ if exception_status >= 400 and exception_status < 500:
+ if exception_status == 429:
+ # Cool down 429 Rate Limit Errors
+ return True
+
+ elif exception_status == 401:
+ # Cool down 401 Auth Errors
+ return True
+
+ elif exception_status == 408:
+ return True
+
+ else:
+ # Do NOT cool down all other 4XX Errors
+ return False
+
+ else:
+ # should cool down for all other errors
+ return True
+
+ except:
+ # Catch all - if any exceptions default to cooling down
+ return True
+
def _set_cooldown_deployments(
self, exception_status: Union[str, int], deployment: Optional[str] = None
):
@@ -1975,6 +2038,9 @@ class Router:
if deployment is None:
return
+ if self._is_cooldown_required(exception_status=exception_status) == False:
+ return
+
dt = get_utc_datetime()
current_minute = dt.strftime("%H-%M")
# get current fails for deployment
diff --git a/litellm/router_strategy/lowest_latency.py b/litellm/router_strategy/lowest_latency.py
index 81a0133a90..c56db83f0b 100644
--- a/litellm/router_strategy/lowest_latency.py
+++ b/litellm/router_strategy/lowest_latency.py
@@ -27,7 +27,7 @@ class LiteLLMBase(BaseModel):
class RoutingArgs(LiteLLMBase):
- ttl: int = 1 * 60 * 60 # 1 hour
+ ttl: float = 1 * 60 * 60 # 1 hour
lowest_latency_buffer: float = 0
max_latency_list_size: int = 10
diff --git a/litellm/tests/test_amazing_vertex_completion.py b/litellm/tests/test_amazing_vertex_completion.py
index ad3fb3cc3e..b747ca8803 100644
--- a/litellm/tests/test_amazing_vertex_completion.py
+++ b/litellm/tests/test_amazing_vertex_completion.py
@@ -376,9 +376,8 @@ def test_vertex_ai_stream():
print("making request", model)
response = completion(
model=model,
- messages=[
- {"role": "user", "content": "write 10 line code code for saying hi"}
- ],
+ messages=[{"role": "user", "content": "hello tell me a short story"}],
+ max_tokens=15,
stream=True,
)
completed_str = ""
diff --git a/litellm/tests/test_completion.py b/litellm/tests/test_completion.py
index 2bc167ed09..120a65acbf 100644
--- a/litellm/tests/test_completion.py
+++ b/litellm/tests/test_completion.py
@@ -38,7 +38,7 @@ def reset_callbacks():
@pytest.mark.skip(reason="Local test")
def test_response_model_none():
"""
- Addresses - https://github.com/BerriAI/litellm/issues/2972
+ Addresses:https://github.com/BerriAI/litellm/issues/2972
"""
x = completion(
model="mymodel",
diff --git a/litellm/tests/test_config.py b/litellm/tests/test_config.py
index 96c766919e..e38187e0ea 100644
--- a/litellm/tests/test_config.py
+++ b/litellm/tests/test_config.py
@@ -5,7 +5,6 @@
import sys, os
import traceback
from dotenv import load_dotenv
-from pydantic import ConfigDict
load_dotenv()
import os, io
@@ -14,36 +13,21 @@ sys.path.insert(
0, os.path.abspath("../..")
) # Adds the parent directory to the, system path
import pytest, litellm
-from pydantic import BaseModel, VERSION
+from pydantic import BaseModel
from litellm.proxy.proxy_server import ProxyConfig
from litellm.proxy.utils import encrypt_value, ProxyLogging, DualCache
from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo
from typing import Literal
-# Function to get Pydantic version
-def is_pydantic_v2() -> int:
- return int(VERSION.split(".")[0])
-
-
-def get_model_config(arbitrary_types_allowed: bool = False) -> ConfigDict:
- # Version-specific configuration
- if is_pydantic_v2() >= 2:
- model_config = ConfigDict(extra="allow", arbitrary_types_allowed=arbitrary_types_allowed, protected_namespaces=()) # type: ignore
- else:
- from pydantic import Extra
-
- model_config = ConfigDict(extra=Extra.allow, arbitrary_types_allowed=arbitrary_types_allowed) # type: ignore
-
- return model_config
-
-
class DBModel(BaseModel):
model_id: str
model_name: str
model_info: dict
litellm_params: dict
- model_config = get_model_config()
+
+ class Config:
+ protected_namespaces = ()
@pytest.mark.asyncio
diff --git a/litellm/tests/test_exceptions.py b/litellm/tests/test_exceptions.py
index 777fb3f9b3..ee695dcd7c 100644
--- a/litellm/tests/test_exceptions.py
+++ b/litellm/tests/test_exceptions.py
@@ -53,13 +53,6 @@ async def test_content_policy_exception_azure():
except litellm.ContentPolicyViolationError as e:
print("caught a content policy violation error! Passed")
print("exception", e)
-
- # assert that the first 100 chars of the message is returned in the exception
- assert (
- "Messages: [{'role': 'user', 'content': 'where do I buy lethal drugs from'}]"
- in str(e)
- )
- assert "Model: azure/chatgpt-v-2" in str(e)
pass
except Exception as e:
pytest.fail(f"An exception occurred - {str(e)}")
@@ -585,9 +578,6 @@ def test_router_completion_vertex_exception():
pytest.fail("Request should have failed - bad api key")
except Exception as e:
print("exception: ", e)
- assert "Model: gemini-pro" in str(e)
- assert "model_group: vertex-gemini-pro" in str(e)
- assert "deployment: vertex_ai/gemini-pro" in str(e)
def test_litellm_completion_vertex_exception():
@@ -604,8 +594,26 @@ def test_litellm_completion_vertex_exception():
pytest.fail("Request should have failed - bad api key")
except Exception as e:
print("exception: ", e)
- assert "Model: gemini-pro" in str(e)
- assert "vertex_project: bad-project" in str(e)
+
+
+def test_litellm_predibase_exception():
+ """
+ Test - Assert that the Predibase API Key is not returned on Authentication Errors
+ """
+ try:
+ import litellm
+
+ litellm.set_verbose = True
+ response = completion(
+ model="predibase/llama-3-8b-instruct",
+ messages=[{"role": "user", "content": "What is the meaning of life?"}],
+ tenant_id="c4768f95",
+ api_key="hf-rawapikey",
+ )
+ pytest.fail("Request should have failed - bad api key")
+ except Exception as e:
+ assert "hf-rawapikey" not in str(e)
+ print("exception: ", e)
# # test_invalid_request_error(model="command-nightly")
diff --git a/litellm/tests/test_function_calling.py b/litellm/tests/test_function_calling.py
index 0d0a593d53..6e4e9d3e86 100644
--- a/litellm/tests/test_function_calling.py
+++ b/litellm/tests/test_function_calling.py
@@ -105,6 +105,9 @@ def test_parallel_function_call(model):
# Step 4: send the info for each function call and function response to the model
for tool_call in tool_calls:
function_name = tool_call.function.name
+ if function_name not in available_functions:
+ # the model called a function that does not exist in available_functions - don't try calling anything
+ return
function_to_call = available_functions[function_name]
function_args = json.loads(tool_call.function.arguments)
function_response = function_to_call(
@@ -124,7 +127,6 @@ def test_parallel_function_call(model):
model=model, messages=messages, temperature=0.2, seed=22
) # get a new response from the model where it can see the function response
print("second response\n", second_response)
- return second_response
except Exception as e:
pytest.fail(f"Error occurred: {e}")
diff --git a/litellm/tests/test_jwt.py b/litellm/tests/test_jwt.py
index b3af9913f6..45f4616290 100644
--- a/litellm/tests/test_jwt.py
+++ b/litellm/tests/test_jwt.py
@@ -1,7 +1,7 @@
#### What this tests ####
# Unit tests for JWT-Auth
-import sys, os, asyncio, time, random
+import sys, os, asyncio, time, random, uuid
import traceback
from dotenv import load_dotenv
@@ -24,6 +24,7 @@ public_key = {
"alg": "RS256",
}
+
def test_load_config_with_custom_role_names():
config = {
"general_settings": {
@@ -77,7 +78,8 @@ async def test_token_single_public_key():
== "qIgOQfEVrrErJC0E7gsHXi6rs_V0nyFY5qPFui2-tv0o4CwpwDzgfBtLO7o_wLiguq0lnu54sMT2eLNoRiiPuLvv6bg7Iy1H9yc5_4Jf5oYEOrqN5o9ZBOoYp1q68Pv0oNJYyZdGu5ZJfd7V4y953vB2XfEKgXCsAkhVhlvIUMiDNKWoMDWsyb2xela5tRURZ2mJAXcHfSC_sYdZxIA2YYrIHfoevq_vTlaz0qVSe_uOKjEpgOAS08UUrgda4CQL11nzICiIQzc6qmjIQt2cjzB2D_9zb4BYndzEtfl0kwAT0z_I85S3mkwTqHU-1BvKe_4MG4VG3dAAeffLPXJyXQ"
)
-@pytest.mark.parametrize('audience', [None, "litellm-proxy"])
+
+@pytest.mark.parametrize("audience", [None, "litellm-proxy"])
@pytest.mark.asyncio
async def test_valid_invalid_token(audience):
"""
@@ -90,7 +92,7 @@ async def test_valid_invalid_token(audience):
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
- os.environ.pop('JWT_AUDIENCE', None)
+ os.environ.pop("JWT_AUDIENCE", None)
if audience:
os.environ["JWT_AUDIENCE"] = audience
@@ -138,7 +140,7 @@ async def test_valid_invalid_token(audience):
"sub": "user123",
"exp": expiration_time, # set the token to expire in 10 minutes
"scope": "litellm-proxy-admin",
- "aud": audience
+ "aud": audience,
}
# Generate the JWT token
@@ -166,7 +168,7 @@ async def test_valid_invalid_token(audience):
"sub": "user123",
"exp": expiration_time, # set the token to expire in 10 minutes
"scope": "litellm-NO-SCOPE",
- "aud": audience
+ "aud": audience,
}
# Generate the JWT token
@@ -183,6 +185,7 @@ async def test_valid_invalid_token(audience):
except Exception as e:
pytest.fail(f"An exception occurred - {str(e)}")
+
@pytest.fixture
def prisma_client():
import litellm
@@ -205,7 +208,7 @@ def prisma_client():
return prisma_client
-@pytest.mark.parametrize('audience', [None, "litellm-proxy"])
+@pytest.mark.parametrize("audience", [None, "litellm-proxy"])
@pytest.mark.asyncio
async def test_team_token_output(prisma_client, audience):
import jwt, json
@@ -222,7 +225,7 @@ async def test_team_token_output(prisma_client, audience):
setattr(litellm.proxy.proxy_server, "prisma_client", prisma_client)
await litellm.proxy.proxy_server.prisma_client.connect()
- os.environ.pop('JWT_AUDIENCE', None)
+ os.environ.pop("JWT_AUDIENCE", None)
if audience:
os.environ["JWT_AUDIENCE"] = audience
@@ -261,7 +264,7 @@ async def test_team_token_output(prisma_client, audience):
jwt_handler.user_api_key_cache = cache
- jwt_handler.litellm_jwtauth = LiteLLM_JWTAuth()
+ jwt_handler.litellm_jwtauth = LiteLLM_JWTAuth(team_id_jwt_field="client_id")
# VALID TOKEN
## GENERATE A TOKEN
@@ -274,7 +277,7 @@ async def test_team_token_output(prisma_client, audience):
"exp": expiration_time, # set the token to expire in 10 minutes
"scope": "litellm_team",
"client_id": team_id,
- "aud": audience
+ "aud": audience,
}
# Generate the JWT token
@@ -289,7 +292,7 @@ async def test_team_token_output(prisma_client, audience):
"sub": "user123",
"exp": expiration_time, # set the token to expire in 10 minutes
"scope": "litellm_proxy_admin",
- "aud": audience
+ "aud": audience,
}
admin_token = jwt.encode(payload, private_key_str, algorithm="RS256")
@@ -315,7 +318,13 @@ async def test_team_token_output(prisma_client, audience):
## 1. INITIAL TEAM CALL - should fail
# use generated key to auth in
- setattr(litellm.proxy.proxy_server, "general_settings", {"enable_jwt_auth": True})
+ setattr(
+ litellm.proxy.proxy_server,
+ "general_settings",
+ {
+ "enable_jwt_auth": True,
+ },
+ )
setattr(litellm.proxy.proxy_server, "jwt_handler", jwt_handler)
try:
result = await user_api_key_auth(request=request, api_key=bearer_token)
@@ -358,9 +367,22 @@ async def test_team_token_output(prisma_client, audience):
assert team_result.team_models == ["gpt-3.5-turbo", "gpt-4"]
-@pytest.mark.parametrize('audience', [None, "litellm-proxy"])
+@pytest.mark.parametrize("audience", [None, "litellm-proxy"])
+@pytest.mark.parametrize(
+ "team_id_set, default_team_id",
+ [(True, False), (False, True)],
+)
+@pytest.mark.parametrize("user_id_upsert", [True, False])
@pytest.mark.asyncio
-async def test_user_token_output(prisma_client, audience):
+async def test_user_token_output(
+ prisma_client, audience, team_id_set, default_team_id, user_id_upsert
+):
+ import uuid
+
+ args = locals()
+ print(f"received args - {args}")
+ if default_team_id:
+ default_team_id = "team_id_12344_{}".format(uuid.uuid4())
"""
- If user required, check if it exists
- fail initial request (when user doesn't exist)
@@ -373,7 +395,12 @@ async def test_user_token_output(prisma_client, audience):
from cryptography.hazmat.backends import default_backend
from fastapi import Request
from starlette.datastructures import URL
- from litellm.proxy.proxy_server import user_api_key_auth, new_team, new_user
+ from litellm.proxy.proxy_server import (
+ user_api_key_auth,
+ new_team,
+ new_user,
+ user_info,
+ )
from litellm.proxy._types import NewTeamRequest, UserAPIKeyAuth, NewUserRequest
import litellm
import uuid
@@ -381,7 +408,7 @@ async def test_user_token_output(prisma_client, audience):
setattr(litellm.proxy.proxy_server, "prisma_client", prisma_client)
await litellm.proxy.proxy_server.prisma_client.connect()
- os.environ.pop('JWT_AUDIENCE', None)
+ os.environ.pop("JWT_AUDIENCE", None)
if audience:
os.environ["JWT_AUDIENCE"] = audience
@@ -423,6 +450,11 @@ async def test_user_token_output(prisma_client, audience):
jwt_handler.litellm_jwtauth = LiteLLM_JWTAuth()
jwt_handler.litellm_jwtauth.user_id_jwt_field = "sub"
+ jwt_handler.litellm_jwtauth.team_id_default = default_team_id
+ jwt_handler.litellm_jwtauth.user_id_upsert = user_id_upsert
+
+ if team_id_set:
+ jwt_handler.litellm_jwtauth.team_id_jwt_field = "client_id"
# VALID TOKEN
## GENERATE A TOKEN
@@ -436,7 +468,7 @@ async def test_user_token_output(prisma_client, audience):
"exp": expiration_time, # set the token to expire in 10 minutes
"scope": "litellm_team",
"client_id": team_id,
- "aud": audience
+ "aud": audience,
}
# Generate the JWT token
@@ -451,7 +483,7 @@ async def test_user_token_output(prisma_client, audience):
"sub": user_id,
"exp": expiration_time, # set the token to expire in 10 minutes
"scope": "litellm_proxy_admin",
- "aud": audience
+ "aud": audience,
}
admin_token = jwt.encode(payload, private_key_str, algorithm="RS256")
@@ -503,6 +535,16 @@ async def test_user_token_output(prisma_client, audience):
),
user_api_key_dict=result,
)
+ if default_team_id:
+ await new_team(
+ data=NewTeamRequest(
+ team_id=default_team_id,
+ tpm_limit=100,
+ rpm_limit=99,
+ models=["gpt-3.5-turbo", "gpt-4"],
+ ),
+ user_api_key_dict=result,
+ )
except Exception as e:
pytest.fail(f"This should not fail - {str(e)}")
@@ -513,23 +555,35 @@ async def test_user_token_output(prisma_client, audience):
team_result: UserAPIKeyAuth = await user_api_key_auth(
request=request, api_key=bearer_token
)
- pytest.fail(f"User doesn't exist. this should fail")
+ if user_id_upsert == False:
+ pytest.fail(f"User doesn't exist. this should fail")
except Exception as e:
pass
## 4. Create user
- try:
- bearer_token = "Bearer " + admin_token
+ if user_id_upsert:
+ ## check if user already exists
+ try:
+ bearer_token = "Bearer " + admin_token
- request._url = URL(url="/team/new")
- result = await user_api_key_auth(request=request, api_key=bearer_token)
- await new_user(
- data=NewUserRequest(
- user_id=user_id,
- ),
- )
- except Exception as e:
- pytest.fail(f"This should not fail - {str(e)}")
+ request._url = URL(url="/team/new")
+ result = await user_api_key_auth(request=request, api_key=bearer_token)
+ await user_info(user_id=user_id)
+ except Exception as e:
+ pytest.fail(f"This should not fail - {str(e)}")
+ else:
+ try:
+ bearer_token = "Bearer " + admin_token
+
+ request._url = URL(url="/team/new")
+ result = await user_api_key_auth(request=request, api_key=bearer_token)
+ await new_user(
+ data=NewUserRequest(
+ user_id=user_id,
+ ),
+ )
+ except Exception as e:
+ pytest.fail(f"This should not fail - {str(e)}")
## 5. 3rd call w/ same team, same user -> call should succeed
bearer_token = "Bearer " + token
@@ -543,7 +597,8 @@ async def test_user_token_output(prisma_client, audience):
## 6. ASSERT USER_API_KEY_AUTH format (used for tpm/rpm limiting in parallel_request_limiter.py AND cost tracking)
- assert team_result.team_tpm_limit == 100
- assert team_result.team_rpm_limit == 99
- assert team_result.team_models == ["gpt-3.5-turbo", "gpt-4"]
+ if team_id_set or default_team_id is not None:
+ assert team_result.team_tpm_limit == 100
+ assert team_result.team_rpm_limit == 99
+ assert team_result.team_models == ["gpt-3.5-turbo", "gpt-4"]
assert team_result.user_id == user_id
diff --git a/litellm/tests/test_lowest_latency_routing.py b/litellm/tests/test_lowest_latency_routing.py
index 4da8792087..3d79e5c8f7 100644
--- a/litellm/tests/test_lowest_latency_routing.py
+++ b/litellm/tests/test_lowest_latency_routing.py
@@ -705,7 +705,7 @@ async def test_lowest_latency_routing_first_pick():
) # type: ignore
deployments = {}
- for _ in range(5):
+ for _ in range(10):
response = await router.acompletion(
model="azure-model", messages=[{"role": "user", "content": "hello"}]
)
diff --git a/litellm/tests/test_parallel_request_limiter.py b/litellm/tests/test_parallel_request_limiter.py
index d0a28926e8..00da199d99 100644
--- a/litellm/tests/test_parallel_request_limiter.py
+++ b/litellm/tests/test_parallel_request_limiter.py
@@ -28,6 +28,37 @@ from datetime import datetime
## On Request failure
+@pytest.mark.asyncio
+async def test_global_max_parallel_requests():
+ """
+ Test if ParallelRequestHandler respects 'global_max_parallel_requests'
+
+ data["metadata"]["global_max_parallel_requests"]
+ """
+ global_max_parallel_requests = 0
+ _api_key = "sk-12345"
+ _api_key = hash_token("sk-12345")
+ user_api_key_dict = UserAPIKeyAuth(api_key=_api_key, max_parallel_requests=100)
+ local_cache = DualCache()
+ parallel_request_handler = MaxParallelRequestsHandler()
+
+ for _ in range(3):
+ try:
+ await parallel_request_handler.async_pre_call_hook(
+ user_api_key_dict=user_api_key_dict,
+ cache=local_cache,
+ data={
+ "metadata": {
+ "global_max_parallel_requests": global_max_parallel_requests
+ }
+ },
+ call_type="",
+ )
+ pytest.fail("Expected call to fail")
+ except Exception as e:
+ pass
+
+
@pytest.mark.asyncio
async def test_pre_call_hook():
"""
diff --git a/litellm/tests/test_router_cooldowns.py b/litellm/tests/test_router_cooldowns.py
new file mode 100644
index 0000000000..35095bb2cf
--- /dev/null
+++ b/litellm/tests/test_router_cooldowns.py
@@ -0,0 +1,64 @@
+#### What this tests ####
+# This tests calling router with fallback models
+
+import sys, os, time
+import traceback, asyncio
+import pytest
+
+sys.path.insert(
+ 0, os.path.abspath("../..")
+) # Adds the parent directory to the system path
+
+import litellm
+from litellm import Router
+from litellm.integrations.custom_logger import CustomLogger
+import openai, httpx
+
+
+@pytest.mark.asyncio
+async def test_cooldown_badrequest_error():
+ """
+ Test 1. It SHOULD NOT cooldown a deployment on a BadRequestError
+ """
+
+ router = litellm.Router(
+ model_list=[
+ {
+ "model_name": "gpt-3.5-turbo",
+ "litellm_params": {
+ "model": "azure/chatgpt-v-2",
+ "api_key": os.getenv("AZURE_API_KEY"),
+ "api_version": os.getenv("AZURE_API_VERSION"),
+ "api_base": os.getenv("AZURE_API_BASE"),
+ },
+ }
+ ],
+ debug_level="DEBUG",
+ set_verbose=True,
+ cooldown_time=300,
+ num_retries=0,
+ allowed_fails=0,
+ )
+
+ # Act & Assert
+ try:
+
+ response = await router.acompletion(
+ model="gpt-3.5-turbo",
+ messages=[{"role": "user", "content": "gm"}],
+ bad_param=200,
+ )
+ except:
+ pass
+
+ await asyncio.sleep(3) # wait for deployment to get cooled-down
+
+ response = await router.acompletion(
+ model="gpt-3.5-turbo",
+ messages=[{"role": "user", "content": "gm"}],
+ mock_response="hello",
+ )
+
+ assert response is not None
+
+ print(response)
diff --git a/litellm/tests/test_router_debug_logs.py b/litellm/tests/test_router_debug_logs.py
index 1d908abe81..cde9a8edd1 100644
--- a/litellm/tests/test_router_debug_logs.py
+++ b/litellm/tests/test_router_debug_logs.py
@@ -82,7 +82,7 @@ def test_async_fallbacks(caplog):
# Define the expected log messages
# - error request, falling back notice, success notice
expected_logs = [
- "litellm.acompletion(model=gpt-3.5-turbo)\x1b[31m Exception OpenAIException - Error code: 401 - {'error': {'message': 'Incorrect API key provided: bad-key. You can find your API key at https://platform.openai.com/account/api-keys.', 'type': 'invalid_request_error', 'param': None, 'code': 'invalid_api_key'}} \nModel: gpt-3.5-turbo\nAPI Base: https://api.openai.com\nMessages: [{'content': 'Hello, how are you?', 'role': 'user'}]\nmodel_group: gpt-3.5-turbo\n\ndeployment: gpt-3.5-turbo\n\x1b[0m",
+ "litellm.acompletion(model=gpt-3.5-turbo)\x1b[31m Exception OpenAIException - Error code: 401 - {'error': {'message': 'Incorrect API key provided: bad-key. You can find your API key at https://platform.openai.com/account/api-keys.', 'type': 'invalid_request_error', 'param': None, 'code': 'invalid_api_key'}}\x1b[0m",
"Falling back to model_group = azure/gpt-3.5-turbo",
"litellm.acompletion(model=azure/chatgpt-v-2)\x1b[32m 200 OK\x1b[0m",
"Successful fallback b/w models.",
diff --git a/litellm/types/completion.py b/litellm/types/completion.py
index 87a7629daf..78af7667ba 100644
--- a/litellm/types/completion.py
+++ b/litellm/types/completion.py
@@ -1,27 +1,10 @@
-from typing import List, Optional, Union, Iterable, cast
+from typing import List, Optional, Union, Iterable
-from pydantic import ConfigDict, BaseModel, validator, VERSION
+from pydantic import BaseModel, validator
from typing_extensions import Literal, Required, TypedDict
-# Function to get Pydantic version
-def is_pydantic_v2() -> int:
- return int(VERSION.split(".")[0])
-
-
-def get_model_config() -> ConfigDict:
- # Version-specific configuration
- if is_pydantic_v2() >= 2:
- model_config = ConfigDict(extra="allow", protected_namespaces=()) # type: ignore
- else:
- from pydantic import Extra
-
- model_config = ConfigDict(extra=Extra.allow) # type: ignore
-
- return model_config
-
-
class ChatCompletionSystemMessageParam(TypedDict, total=False):
content: Required[str]
"""The contents of the system message."""
@@ -208,4 +191,6 @@ class CompletionRequest(BaseModel):
api_key: Optional[str] = None
model_list: Optional[List[str]] = None
- model_config = get_model_config()
+ class Config:
+ extra = "allow"
+ protected_namespaces = ()
diff --git a/litellm/types/embedding.py b/litellm/types/embedding.py
index 831c4266c3..9db0ef2907 100644
--- a/litellm/types/embedding.py
+++ b/litellm/types/embedding.py
@@ -1,23 +1,6 @@
from typing import List, Optional, Union
-from pydantic import ConfigDict, BaseModel, validator, VERSION
-
-
-# Function to get Pydantic version
-def is_pydantic_v2() -> int:
- return int(VERSION.split(".")[0])
-
-
-def get_model_config(arbitrary_types_allowed: bool = False) -> ConfigDict:
- # Version-specific configuration
- if is_pydantic_v2() >= 2:
- model_config = ConfigDict(extra="allow", arbitrary_types_allowed=arbitrary_types_allowed, protected_namespaces=()) # type: ignore
- else:
- from pydantic import Extra
-
- model_config = ConfigDict(extra=Extra.allow, arbitrary_types_allowed=arbitrary_types_allowed) # type: ignore
-
- return model_config
+from pydantic import BaseModel, validator
class EmbeddingRequest(BaseModel):
@@ -34,4 +17,7 @@ class EmbeddingRequest(BaseModel):
litellm_call_id: Optional[str] = None
litellm_logging_obj: Optional[dict] = None
logger_fn: Optional[str] = None
- model_config = get_model_config()
+
+ class Config:
+ # allow kwargs
+ extra = "allow"
diff --git a/litellm/types/router.py b/litellm/types/router.py
index 0cc84d8c30..68ee387fea 100644
--- a/litellm/types/router.py
+++ b/litellm/types/router.py
@@ -1,42 +1,19 @@
from typing import List, Optional, Union, Dict, Tuple, Literal, TypedDict
import httpx
-from pydantic import (
- ConfigDict,
- BaseModel,
- validator,
- Field,
- __version__ as pydantic_version,
- VERSION,
-)
+from pydantic import BaseModel, validator, Field
from .completion import CompletionRequest
from .embedding import EmbeddingRequest
import uuid, enum
-# Function to get Pydantic version
-def is_pydantic_v2() -> int:
- return int(VERSION.split(".")[0])
-
-
-def get_model_config(arbitrary_types_allowed: bool = False) -> ConfigDict:
- # Version-specific configuration
- if is_pydantic_v2() >= 2:
- model_config = ConfigDict(extra="allow", arbitrary_types_allowed=arbitrary_types_allowed, protected_namespaces=()) # type: ignore
- else:
- from pydantic import Extra
-
- model_config = ConfigDict(extra=Extra.allow, arbitrary_types_allowed=arbitrary_types_allowed) # type: ignore
-
- return model_config
-
-
class ModelConfig(BaseModel):
model_name: str
litellm_params: Union[CompletionRequest, EmbeddingRequest]
tpm: int
rpm: int
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class RouterConfig(BaseModel):
@@ -67,7 +44,8 @@ class RouterConfig(BaseModel):
"latency-based-routing",
] = "simple-shuffle"
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class UpdateRouterConfig(BaseModel):
@@ -87,7 +65,8 @@ class UpdateRouterConfig(BaseModel):
fallbacks: Optional[List[dict]] = None
context_window_fallbacks: Optional[List[dict]] = None
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class ModelInfo(BaseModel):
@@ -105,7 +84,8 @@ class ModelInfo(BaseModel):
id = str(id)
super().__init__(id=id, **params)
- model_config = get_model_config()
+ class Config:
+ extra = "allow"
def __contains__(self, key):
# Define custom behavior for the 'in' operator
@@ -200,15 +180,9 @@ class GenericLiteLLMParams(BaseModel):
max_retries = int(max_retries) # cast to int
super().__init__(max_retries=max_retries, **args, **params)
- model_config = get_model_config(arbitrary_types_allowed=True)
- if pydantic_version.startswith("1"):
- # pydantic v2 warns about using a Config class.
- # But without this, pydantic v1 will raise an error:
- # RuntimeError: no validator found for ,
- # see `arbitrary_types_allowed` in Config
- # Putting arbitrary_types_allowed = True in the ConfigDict doesn't work in pydantic v1.
- class Config:
- arbitrary_types_allowed = True
+ class Config:
+ extra = "allow"
+ arbitrary_types_allowed = True
def __contains__(self, key):
# Define custom behavior for the 'in' operator
@@ -267,16 +241,9 @@ class LiteLLM_Params(GenericLiteLLMParams):
max_retries = int(max_retries) # cast to int
super().__init__(max_retries=max_retries, **args, **params)
- model_config = get_model_config(arbitrary_types_allowed=True)
-
- if pydantic_version.startswith("1"):
- # pydantic v2 warns about using a Config class.
- # But without this, pydantic v1 will raise an error:
- # RuntimeError: no validator found for ,
- # see `arbitrary_types_allowed` in Config
- # Putting arbitrary_types_allowed = True in the ConfigDict doesn't work in pydantic v1.
- class Config:
- arbitrary_types_allowed = True
+ class Config:
+ extra = "allow"
+ arbitrary_types_allowed = True
def __contains__(self, key):
# Define custom behavior for the 'in' operator
@@ -306,7 +273,8 @@ class updateDeployment(BaseModel):
litellm_params: Optional[updateLiteLLMParams] = None
model_info: Optional[ModelInfo] = None
- model_config = get_model_config()
+ class Config:
+ protected_namespaces = ()
class LiteLLMParamsTypedDict(TypedDict, total=False):
@@ -380,7 +348,9 @@ class Deployment(BaseModel):
# if using pydantic v1
return self.dict(**kwargs)
- model_config = get_model_config()
+ class Config:
+ extra = "allow"
+ protected_namespaces = ()
def __contains__(self, key):
# Define custom behavior for the 'in' operator
diff --git a/litellm/utils.py b/litellm/utils.py
index 7df79f3736..36f4ad481f 100644
--- a/litellm/utils.py
+++ b/litellm/utils.py
@@ -19,7 +19,7 @@ from functools import wraps, lru_cache
import datetime, time
import tiktoken
import uuid
-from pydantic import ConfigDict, BaseModel, VERSION
+from pydantic import BaseModel
import aiohttp
import textwrap
import logging
@@ -185,23 +185,6 @@ last_fetched_at_keys = None
# }
-# Function to get Pydantic version
-def is_pydantic_v2() -> int:
- return int(VERSION.split(".")[0])
-
-
-def get_model_config(arbitrary_types_allowed: bool = False) -> ConfigDict:
- # Version-specific configuration
- if is_pydantic_v2() >= 2:
- model_config = ConfigDict(extra="allow", arbitrary_types_allowed=arbitrary_types_allowed, protected_namespaces=()) # type: ignore
- else:
- from pydantic import Extra
-
- model_config = ConfigDict(extra=Extra.allow, arbitrary_types_allowed=arbitrary_types_allowed) # type: ignore
-
- return model_config
-
-
class UnsupportedParamsError(Exception):
def __init__(self, status_code, message):
self.status_code = status_code
@@ -348,7 +331,10 @@ class HiddenParams(OpenAIObject):
original_response: Optional[str] = None
model_id: Optional[str] = None # used in Router for individual deployments
api_base: Optional[str] = None # returns api base used for making completion call
- model_config = get_model_config()
+
+ class Config:
+ extra = "allow"
+ protected_namespaces = ()
def get(self, key, default=None):
# Custom .get() method to access attributes with a default value if the attribute doesn't exist
@@ -2579,7 +2565,7 @@ class Logging:
response_obj=result,
start_time=start_time,
end_time=end_time,
- )
+ ) # type: ignore
if callable(callback): # custom logger functions
await customLogger.async_log_event(
kwargs=self.model_call_details,
@@ -6778,7 +6764,7 @@ def get_max_tokens(model: str):
raise Exception()
except:
raise Exception(
- "This model isn't mapped yet. Add it here - https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json"
+ f"Model {model} isn't mapped yet. Add it here - https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json"
)
@@ -8155,33 +8141,39 @@ def exception_type(
# Common Extra information needed for all providers
# We pass num retries, api_base, vertex_deployment etc to the exception here
################################################################################
+ extra_information = ""
+ try:
+ _api_base = litellm.get_api_base(
+ model=model, optional_params=extra_kwargs
+ )
+ messages = litellm.get_first_chars_messages(kwargs=completion_kwargs)
+ _vertex_project = extra_kwargs.get("vertex_project")
+ _vertex_location = extra_kwargs.get("vertex_location")
+ _metadata = extra_kwargs.get("metadata", {}) or {}
+ _model_group = _metadata.get("model_group")
+ _deployment = _metadata.get("deployment")
+ extra_information = f"\nModel: {model}"
+ if _api_base:
+ extra_information += f"\nAPI Base: {_api_base}"
+ if messages and len(messages) > 0:
+ extra_information += f"\nMessages: {messages}"
- _api_base = litellm.get_api_base(model=model, optional_params=extra_kwargs)
- messages = litellm.get_first_chars_messages(kwargs=completion_kwargs)
- _vertex_project = extra_kwargs.get("vertex_project")
- _vertex_location = extra_kwargs.get("vertex_location")
- _metadata = extra_kwargs.get("metadata", {}) or {}
- _model_group = _metadata.get("model_group")
- _deployment = _metadata.get("deployment")
- extra_information = f"\nModel: {model}"
- if _api_base:
- extra_information += f"\nAPI Base: {_api_base}"
- if messages and len(messages) > 0:
- extra_information += f"\nMessages: {messages}"
+ if _model_group is not None:
+ extra_information += f"\nmodel_group: {_model_group}\n"
+ if _deployment is not None:
+ extra_information += f"\ndeployment: {_deployment}\n"
+ if _vertex_project is not None:
+ extra_information += f"\nvertex_project: {_vertex_project}\n"
+ if _vertex_location is not None:
+ extra_information += f"\nvertex_location: {_vertex_location}\n"
- if _model_group is not None:
- extra_information += f"\nmodel_group: {_model_group}\n"
- if _deployment is not None:
- extra_information += f"\ndeployment: {_deployment}\n"
- if _vertex_project is not None:
- extra_information += f"\nvertex_project: {_vertex_project}\n"
- if _vertex_location is not None:
- extra_information += f"\nvertex_location: {_vertex_location}\n"
-
- # on litellm proxy add key name + team to exceptions
- extra_information = _add_key_name_and_team_to_alert(
- request_info=extra_information, metadata=_metadata
- )
+ # on litellm proxy add key name + team to exceptions
+ extra_information = _add_key_name_and_team_to_alert(
+ request_info=extra_information, metadata=_metadata
+ )
+ except:
+ # DO NOT LET this Block raising the original exception
+ pass
################################################################################
# End of Common Extra information Needed for all providers
@@ -8194,9 +8186,10 @@ def exception_type(
if "Request Timeout Error" in error_str or "Request timed out" in error_str:
exception_mapping_worked = True
raise Timeout(
- message=f"APITimeoutError - Request timed out. {extra_information} \n error_str: {error_str}",
+ message=f"APITimeoutError - Request timed out. \nerror_str: {error_str}",
model=model,
llm_provider=custom_llm_provider,
+ litellm_debug_info=extra_information,
)
if (
@@ -8226,10 +8219,11 @@ def exception_type(
if "This model's maximum context length is" in error_str:
exception_mapping_worked = True
raise ContextWindowExceededError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
llm_provider=custom_llm_provider,
model=model,
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif (
"invalid_request_error" in error_str
@@ -8237,10 +8231,11 @@ def exception_type(
):
exception_mapping_worked = True
raise NotFoundError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
llm_provider=custom_llm_provider,
model=model,
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif (
"invalid_request_error" in error_str
@@ -8248,10 +8243,11 @@ def exception_type(
):
exception_mapping_worked = True
raise ContentPolicyViolationError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
llm_provider=custom_llm_provider,
model=model,
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif (
"invalid_request_error" in error_str
@@ -8259,17 +8255,19 @@ def exception_type(
):
exception_mapping_worked = True
raise BadRequestError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
llm_provider=custom_llm_provider,
model=model,
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif "Request too large" in error_str:
raise RateLimitError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
model=model,
llm_provider=custom_llm_provider,
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif (
"The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_API_KEY environment variable"
@@ -8277,10 +8275,11 @@ def exception_type(
):
exception_mapping_worked = True
raise AuthenticationError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
llm_provider=custom_llm_provider,
model=model,
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif "Mistral API raised a streaming error" in error_str:
exception_mapping_worked = True
@@ -8289,82 +8288,92 @@ def exception_type(
)
raise APIError(
status_code=500,
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
llm_provider=custom_llm_provider,
model=model,
request=_request,
+ litellm_debug_info=extra_information,
)
elif hasattr(original_exception, "status_code"):
exception_mapping_worked = True
if original_exception.status_code == 401:
exception_mapping_worked = True
raise AuthenticationError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
llm_provider=custom_llm_provider,
model=model,
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif original_exception.status_code == 404:
exception_mapping_worked = True
raise NotFoundError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
model=model,
llm_provider=custom_llm_provider,
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif original_exception.status_code == 408:
exception_mapping_worked = True
raise Timeout(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
model=model,
llm_provider=custom_llm_provider,
+ litellm_debug_info=extra_information,
)
elif original_exception.status_code == 422:
exception_mapping_worked = True
raise BadRequestError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
model=model,
llm_provider=custom_llm_provider,
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif original_exception.status_code == 429:
exception_mapping_worked = True
raise RateLimitError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
model=model,
llm_provider=custom_llm_provider,
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif original_exception.status_code == 503:
exception_mapping_worked = True
raise ServiceUnavailableError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
model=model,
llm_provider=custom_llm_provider,
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif original_exception.status_code == 504: # gateway timeout error
exception_mapping_worked = True
raise Timeout(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
model=model,
llm_provider=custom_llm_provider,
+ litellm_debug_info=extra_information,
)
else:
exception_mapping_worked = True
raise APIError(
status_code=original_exception.status_code,
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
llm_provider=custom_llm_provider,
model=model,
request=original_exception.request,
+ litellm_debug_info=extra_information,
)
else:
# if no status code then it is an APIConnectionError: https://github.com/openai/openai-python#handling-errors
raise APIConnectionError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
llm_provider=custom_llm_provider,
model=model,
+ litellm_debug_info=extra_information,
request=httpx.Request(
method="POST", url="https://api.openai.com/v1/"
),
@@ -8529,6 +8538,28 @@ def exception_type(
model=model,
response=original_exception.response,
)
+ elif custom_llm_provider == "predibase":
+ if "authorization denied for" in error_str:
+ exception_mapping_worked = True
+
+ # Predibase returns the raw API Key in the response - this block ensures it's not returned in the exception
+ if (
+ error_str is not None
+ and isinstance(error_str, str)
+ and "bearer" in error_str.lower()
+ ):
+ # only keep the first 10 chars after the occurnence of "bearer"
+ _bearer_token_start_index = error_str.lower().find("bearer")
+ error_str = error_str[: _bearer_token_start_index + 14]
+ error_str += "XXXXXXX" + '"'
+
+ raise AuthenticationError(
+ message=f"PredibaseException: Authentication Error - {error_str}",
+ llm_provider="predibase",
+ model=model,
+ response=original_exception.response,
+ litellm_debug_info=extra_information,
+ )
elif custom_llm_provider == "bedrock":
if (
"too many tokens" in error_str
@@ -8666,10 +8697,11 @@ def exception_type(
):
exception_mapping_worked = True
raise BadRequestError(
- message=f"VertexAIException - {error_str} {extra_information}",
+ message=f"VertexAIException - {error_str}",
model=model,
llm_provider="vertex_ai",
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif (
"None Unknown Error." in error_str
@@ -8677,26 +8709,29 @@ def exception_type(
):
exception_mapping_worked = True
raise APIError(
- message=f"VertexAIException - {error_str} {extra_information}",
+ message=f"VertexAIException - {error_str}",
status_code=500,
model=model,
llm_provider="vertex_ai",
request=original_exception.request,
+ litellm_debug_info=extra_information,
)
elif "403" in error_str:
exception_mapping_worked = True
raise BadRequestError(
- message=f"VertexAIException - {error_str} {extra_information}",
+ message=f"VertexAIException - {error_str}",
model=model,
llm_provider="vertex_ai",
response=original_exception.response,
+ litellm_debug_info=extra_information,
)
elif "The response was blocked." in error_str:
exception_mapping_worked = True
raise UnprocessableEntityError(
- message=f"VertexAIException - {error_str} {extra_information}",
+ message=f"VertexAIException - {error_str}",
model=model,
llm_provider="vertex_ai",
+ litellm_debug_info=extra_information,
response=httpx.Response(
status_code=429,
request=httpx.Request(
@@ -8713,9 +8748,10 @@ def exception_type(
):
exception_mapping_worked = True
raise RateLimitError(
- message=f"VertexAIException - {error_str} {extra_information}",
+ message=f"VertexAIException - {error_str}",
model=model,
llm_provider="vertex_ai",
+ litellm_debug_info=extra_information,
response=httpx.Response(
status_code=429,
request=httpx.Request(
@@ -8728,18 +8764,20 @@ def exception_type(
if original_exception.status_code == 400:
exception_mapping_worked = True
raise BadRequestError(
- message=f"VertexAIException - {error_str} {extra_information}",
+ message=f"VertexAIException - {error_str}",
model=model,
llm_provider="vertex_ai",
+ litellm_debug_info=extra_information,
response=original_exception.response,
)
if original_exception.status_code == 500:
exception_mapping_worked = True
raise APIError(
- message=f"VertexAIException - {error_str} {extra_information}",
+ message=f"VertexAIException - {error_str}",
status_code=500,
model=model,
llm_provider="vertex_ai",
+ litellm_debug_info=extra_information,
request=original_exception.request,
)
elif custom_llm_provider == "palm" or custom_llm_provider == "gemini":
@@ -9340,25 +9378,28 @@ def exception_type(
exception_mapping_worked = True
raise APIError(
status_code=500,
- message=f"AzureException - {original_exception.message} {extra_information}",
+ message=f"AzureException - {original_exception.message}",
llm_provider="azure",
model=model,
+ litellm_debug_info=extra_information,
request=httpx.Request(method="POST", url="https://openai.com/"),
)
elif "This model's maximum context length is" in error_str:
exception_mapping_worked = True
raise ContextWindowExceededError(
- message=f"AzureException - {original_exception.message} {extra_information}",
+ message=f"AzureException - {original_exception.message}",
llm_provider="azure",
model=model,
+ litellm_debug_info=extra_information,
response=original_exception.response,
)
elif "DeploymentNotFound" in error_str:
exception_mapping_worked = True
raise NotFoundError(
- message=f"AzureException - {original_exception.message} {extra_information}",
+ message=f"AzureException - {original_exception.message}",
llm_provider="azure",
model=model,
+ litellm_debug_info=extra_information,
response=original_exception.response,
)
elif (
@@ -9370,17 +9411,19 @@ def exception_type(
):
exception_mapping_worked = True
raise ContentPolicyViolationError(
- message=f"AzureException - {original_exception.message} {extra_information}",
+ message=f"AzureException - {original_exception.message}",
llm_provider="azure",
model=model,
+ litellm_debug_info=extra_information,
response=original_exception.response,
)
elif "invalid_request_error" in error_str:
exception_mapping_worked = True
raise BadRequestError(
- message=f"AzureException - {original_exception.message} {extra_information}",
+ message=f"AzureException - {original_exception.message}",
llm_provider="azure",
model=model,
+ litellm_debug_info=extra_information,
response=original_exception.response,
)
elif (
@@ -9389,9 +9432,10 @@ def exception_type(
):
exception_mapping_worked = True
raise AuthenticationError(
- message=f"{exception_provider} - {original_exception.message} {extra_information}",
+ message=f"{exception_provider} - {original_exception.message}",
llm_provider=custom_llm_provider,
model=model,
+ litellm_debug_info=extra_information,
response=original_exception.response,
)
elif hasattr(original_exception, "status_code"):
@@ -9399,55 +9443,62 @@ def exception_type(
if original_exception.status_code == 401:
exception_mapping_worked = True
raise AuthenticationError(
- message=f"AzureException - {original_exception.message} {extra_information}",
+ message=f"AzureException - {original_exception.message}",
llm_provider="azure",
model=model,
+ litellm_debug_info=extra_information,
response=original_exception.response,
)
elif original_exception.status_code == 408:
exception_mapping_worked = True
raise Timeout(
- message=f"AzureException - {original_exception.message} {extra_information}",
+ message=f"AzureException - {original_exception.message}",
model=model,
+ litellm_debug_info=extra_information,
llm_provider="azure",
)
if original_exception.status_code == 422:
exception_mapping_worked = True
raise BadRequestError(
- message=f"AzureException - {original_exception.message} {extra_information}",
+ message=f"AzureException - {original_exception.message}",
model=model,
llm_provider="azure",
+ litellm_debug_info=extra_information,
response=original_exception.response,
)
elif original_exception.status_code == 429:
exception_mapping_worked = True
raise RateLimitError(
- message=f"AzureException - {original_exception.message} {extra_information}",
+ message=f"AzureException - {original_exception.message}",
model=model,
llm_provider="azure",
+ litellm_debug_info=extra_information,
response=original_exception.response,
)
elif original_exception.status_code == 503:
exception_mapping_worked = True
raise ServiceUnavailableError(
- message=f"AzureException - {original_exception.message} {extra_information}",
+ message=f"AzureException - {original_exception.message}",
model=model,
llm_provider="azure",
+ litellm_debug_info=extra_information,
response=original_exception.response,
)
elif original_exception.status_code == 504: # gateway timeout error
exception_mapping_worked = True
raise Timeout(
- message=f"AzureException - {original_exception.message} {extra_information}",
+ message=f"AzureException - {original_exception.message}",
model=model,
+ litellm_debug_info=extra_information,
llm_provider="azure",
)
else:
exception_mapping_worked = True
raise APIError(
status_code=original_exception.status_code,
- message=f"AzureException - {original_exception.message} {extra_information}",
+ message=f"AzureException - {original_exception.message}",
llm_provider="azure",
+ litellm_debug_info=extra_information,
model=model,
request=httpx.Request(
method="POST", url="https://openai.com/"
@@ -9456,9 +9507,10 @@ def exception_type(
else:
# if no status code then it is an APIConnectionError: https://github.com/openai/openai-python#handling-errors
raise APIConnectionError(
- message=f"{exception_provider} - {message} {extra_information}",
+ message=f"{exception_provider} - {message}",
llm_provider="azure",
model=model,
+ litellm_debug_info=extra_information,
request=httpx.Request(method="POST", url="https://openai.com/"),
)
if (
diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json
index a88d6875ca..ff9194578c 100644
--- a/model_prices_and_context_window.json
+++ b/model_prices_and_context_window.json
@@ -1744,6 +1744,30 @@
"litellm_provider": "openrouter",
"mode": "chat"
},
+ "openrouter/openai/gpt-4o": {
+ "max_tokens": 4096,
+ "max_input_tokens": 128000,
+ "max_output_tokens": 4096,
+ "input_cost_per_token": 0.000005,
+ "output_cost_per_token": 0.000015,
+ "litellm_provider": "openrouter",
+ "mode": "chat",
+ "supports_function_calling": true,
+ "supports_parallel_function_calling": true,
+ "supports_vision": true
+ },
+ "openrouter/openai/gpt-4o-2024-05-13": {
+ "max_tokens": 4096,
+ "max_input_tokens": 128000,
+ "max_output_tokens": 4096,
+ "input_cost_per_token": 0.000005,
+ "output_cost_per_token": 0.000015,
+ "litellm_provider": "openrouter",
+ "mode": "chat",
+ "supports_function_calling": true,
+ "supports_parallel_function_calling": true,
+ "supports_vision": true
+ },
"openrouter/openai/gpt-4-vision-preview": {
"max_tokens": 130000,
"input_cost_per_token": 0.00001,
@@ -2943,6 +2967,24 @@
"litellm_provider": "ollama",
"mode": "completion"
},
+ "ollama/llama3": {
+ "max_tokens": 8192,
+ "max_input_tokens": 8192,
+ "max_output_tokens": 8192,
+ "input_cost_per_token": 0.0,
+ "output_cost_per_token": 0.0,
+ "litellm_provider": "ollama",
+ "mode": "chat"
+ },
+ "ollama/llama3:70b": {
+ "max_tokens": 8192,
+ "max_input_tokens": 8192,
+ "max_output_tokens": 8192,
+ "input_cost_per_token": 0.0,
+ "output_cost_per_token": 0.0,
+ "litellm_provider": "ollama",
+ "mode": "chat"
+ },
"ollama/mistral": {
"max_tokens": 8192,
"max_input_tokens": 8192,
@@ -2952,6 +2994,42 @@
"litellm_provider": "ollama",
"mode": "completion"
},
+ "ollama/mistral-7B-Instruct-v0.1": {
+ "max_tokens": 8192,
+ "max_input_tokens": 8192,
+ "max_output_tokens": 8192,
+ "input_cost_per_token": 0.0,
+ "output_cost_per_token": 0.0,
+ "litellm_provider": "ollama",
+ "mode": "chat"
+ },
+ "ollama/mistral-7B-Instruct-v0.2": {
+ "max_tokens": 32768,
+ "max_input_tokens": 32768,
+ "max_output_tokens": 32768,
+ "input_cost_per_token": 0.0,
+ "output_cost_per_token": 0.0,
+ "litellm_provider": "ollama",
+ "mode": "chat"
+ },
+ "ollama/mixtral-8x7B-Instruct-v0.1": {
+ "max_tokens": 32768,
+ "max_input_tokens": 32768,
+ "max_output_tokens": 32768,
+ "input_cost_per_token": 0.0,
+ "output_cost_per_token": 0.0,
+ "litellm_provider": "ollama",
+ "mode": "chat"
+ },
+ "ollama/mixtral-8x22B-Instruct-v0.1": {
+ "max_tokens": 65536,
+ "max_input_tokens": 65536,
+ "max_output_tokens": 65536,
+ "input_cost_per_token": 0.0,
+ "output_cost_per_token": 0.0,
+ "litellm_provider": "ollama",
+ "mode": "chat"
+ },
"ollama/codellama": {
"max_tokens": 4096,
"max_input_tokens": 4096,
diff --git a/pyproject.toml b/pyproject.toml
index 3250eed82f..55e88c30a2 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "litellm"
-version = "1.37.10"
+version = "1.37.12"
description = "Library to easily interface with LLM API providers"
authors = ["BerriAI"]
license = "MIT"
@@ -79,7 +79,7 @@ requires = ["poetry-core", "wheel"]
build-backend = "poetry.core.masonry.api"
[tool.commitizen]
-version = "1.37.10"
+version = "1.37.12"
version_files = [
"pyproject.toml:^version"
]
diff --git a/ui/litellm-dashboard/out/404.html b/ui/litellm-dashboard/out/404.html
index b70559084d..b0b75d094b 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/obp5wqVSVDMiDTC414cR8/_buildManifest.js b/ui/litellm-dashboard/out/_next/static/2ASoJGxS-D4w-vat00xMy/_buildManifest.js
similarity index 100%
rename from ui/litellm-dashboard/out/_next/static/obp5wqVSVDMiDTC414cR8/_buildManifest.js
rename to ui/litellm-dashboard/out/_next/static/2ASoJGxS-D4w-vat00xMy/_buildManifest.js
diff --git a/ui/litellm-dashboard/out/_next/static/obp5wqVSVDMiDTC414cR8/_ssgManifest.js b/ui/litellm-dashboard/out/_next/static/2ASoJGxS-D4w-vat00xMy/_ssgManifest.js
similarity index 100%
rename from ui/litellm-dashboard/out/_next/static/obp5wqVSVDMiDTC414cR8/_ssgManifest.js
rename to ui/litellm-dashboard/out/_next/static/2ASoJGxS-D4w-vat00xMy/_ssgManifest.js
diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/page-6a39771cacf75ea6.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-6a39771cacf75ea6.js
deleted file mode 100644
index 7d08a80c96..0000000000
--- a/ui/litellm-dashboard/out/_next/static/chunks/app/page-6a39771cacf75ea6.js
+++ /dev/null
@@ -1 +0,0 @@
-(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{20661:function(e,l,t){Promise.resolve().then(t.bind(t,7926))},7926:function(e,l,t){"use strict";t.r(l),t.d(l,{default:function(){return lb}});var s,a,r=t(3827),n=t(64090),o=t(47907),i=t(8792),c=t(40491),d=t(65270),m=e=>{let{userID:l,userRole:t,userEmail:s,showSSOBanner:a}=e;console.log("User ID:",l),console.log("userEmail:",s),console.log("showSSOBanner:",a);let n=[{key:"1",label:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("p",{children:["Role: ",t]}),(0,r.jsxs)("p",{children:["ID: ",l]})]})}];return(0,r.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,r.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,r.jsx)("div",{className:"flex flex-col items-center",children:(0,r.jsx)(i.default,{href:"/",children:(0,r.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,r.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,r.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[a?(0,r.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,r.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Request hosted proxy"})}):null,(0,r.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,r.jsx)(c.Z,{menu:{items:n},children:(0,r.jsx)(d.Z,{children:s})})})]})]})},u=t(80588);let h=async()=>{try{let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"),l=await e.json();return console.log("received data: ".concat(l)),l}catch(e){throw console.error("Failed to get model cost map:",e),e}},x=async(e,l)=>{try{let t=await fetch("/model/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model created successfully. Wait 60s and refresh on 'All Models' page"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,l)=>{console.log("model_id in model delete call: ".concat(l));try{let t=await fetch("/model/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({id:l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model deleted successfully. Restart server to see this."),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},y=async(e,l)=>{try{console.log("in keyDeleteCall:",l);let t=await fetch("/key/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:[l]})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to delete key: "+e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},f=async(e,l)=>{try{console.log("in teamDeleteCall:",l);let t=await fetch("/team/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_ids:[l]})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to delete team: "+e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to delete key:",e),e}},Z=async function(e,l,t){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],a=arguments.length>4?arguments[4]:void 0,r=arguments.length>5?arguments[5]:void 0;try{let n="/user/info";"App Owner"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),"App User"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),console.log("in userInfoCall viewAll=",s),s&&r&&null!=a&&void 0!=a&&(n="".concat(n,"?view_all=true&page=").concat(a,"&page_size=").concat(r));let o=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let i=await o.json();return console.log("API Response:",i),i}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,l)=>{try{let t="/team/info";l&&(t="".concat(t,"?team_id=").concat(l)),console.log("in teamInfoCall");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let l=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},b=async(e,l,t)=>{try{let l=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log("modelInfoCall:",t),t}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,l,t,s,a,r)=>{try{let l="/model/metrics";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(a,"&endTime=").concat(r));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,l,t,s,a,r)=>{try{let l="/model/metrics/slow_responses";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(a,"&endTime=").concat(r));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,l,t,s,a,r)=>{try{let l="/model/metrics/exceptions";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(a,"&endTime=").concat(r));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},N=async(e,l,t)=>{try{let l=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},A=async e=>{try{let l="/global/spend/teams";console.log("in teamSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},E=async(e,l,t)=>{try{let s="/global/spend/tags";l&&t&&(s="".concat(s,"?start_date=").concat(l,"&end_date=").concat(t)),console.log("in tagsSpendLogsCall:",s);let a=await fetch("".concat(s),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!a.ok){let e=await a.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let r=await a.json();return console.log(r),r}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,l,t,s,a,r)=>{try{console.log("user role in spend logs call: ".concat(t));let l="/spend/logs";l="App Owner"==t?"".concat(l,"?user_id=").concat(s,"&start_date=").concat(a,"&end_date=").concat(r):"".concat(l,"?start_date=").concat(a,"&end_date=").concat(r);let n=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},C=async e=>{try{let l=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{let l=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,l,t,s)=>{try{let a="";a=l?JSON.stringify({api_key:l,startTime:t,endTime:s}):JSON.stringify({startTime:t,endTime:s});let r={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};r.body=a;let n=await fetch("/global/spend/end_users",r);if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},O=async e=>{try{let l=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},F=async(e,l)=>{try{let t=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},R=async(e,l)=>{try{let t="/user/get_users?role=".concat(l);console.log("in userGetAllUsersCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to delete key: "+e,10),Error("Network response was not ok")}let a=await s.json();return console.log(a),a}catch(e){throw console.error("Failed to get requested models:",e),e}},M=async(e,l)=>{try{console.log("Form Values in teamCreateCall:",l);let t=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},L=async(e,l)=>{try{console.log("Form Values in keyUpdateCall:",l);let t=await fetch("/key/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update key Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},U=async(e,l)=>{try{console.log("Form Values in teamUpateCall:",l);let t=await fetch("/team/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update team: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update Team Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},D=async(e,l)=>{try{console.log("Form Values in modelUpateCall:",l);let t=await fetch("/model/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update model: "+e,10),console.error("Error update from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update model Response:",s),s}catch(e){throw console.error("Failed to update model:",e),e}},K=async(e,l,t)=>{try{console.log("Form Values in teamMemberAddCall:",t);let s=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:l,member:t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await s.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},B=async(e,l,t)=>{try{console.log("Form Values in userUpdateUserCall:",l);let s={...l};null!==t&&(s.user_role=t),s=JSON.stringify(s);let a=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:s});if(!a.ok){let e=await a.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await a.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},z=async(e,l)=>{try{let t="/health/services?service=".concat(l);console.log("Checking Slack Budget Alerts service health");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed ".concat(l," service health check ")+e),Error(e)}let a=await s.json();return u.ZP.success("Test request to ".concat(l," made - check logs/alerts on ").concat(l," to verify")),a}catch(e){throw console.error("Failed to perform health check:",e),e}},q=async(e,l,t)=>{try{let l=await fetch("/get/config/callbacks",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},V=async(e,l)=>{try{let t=await fetch("/config/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to set callbacks:",e),e}},G=async e=>{try{let l=await fetch("/health",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to call /health:",e),e}};var Y=t(10384),W=t(46453),J=t(16450),H=t(52273),$=t(26780),X=t(15595),Q=t(6698),ee=t(71801),el=t(42440),et=t(42308),es=t(50670),ea=t(81583),er=t(99129),en=t(44839),eo=t(88707),ei=t(1861);let{Option:ec}=es.default;var ed=e=>{let{userID:l,team:t,userRole:s,accessToken:a,data:o,setData:i}=e,[c]=ea.Z.useForm(),[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(null),[p,g]=(0,n.useState)(null),[y,f]=(0,n.useState)([]),[Z,_]=(0,n.useState)([]),w=()=>{m(!1),c.resetFields()},b=()=>{m(!1),x(null),c.resetFields()};(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==a){let e=(await N(a,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),f(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,s]);let k=async e=>{try{var t,s,r;let n=null!==(t=null==e?void 0:e.key_alias)&&void 0!==t?t:"",d=null!==(s=null==e?void 0:e.team_id)&&void 0!==s?s:null;if((null!==(r=null==o?void 0:o.filter(e=>e.team_id===d).map(e=>e.key_alias))&&void 0!==r?r:[]).includes(n))throw Error("Key alias ".concat(n," already exists for team with ID ").concat(d,", please provide another key alias"));u.ZP.info("Making API Call"),m(!0);let h=await j(a,l,e);console.log("key create Response:",h),i(e=>e?[...e,h]:[h]),x(h.key),g(h.soft_budget),u.ZP.success("API Key Created"),c.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e),u.ZP.error("Error creating the key: ".concat(e),20)}};return(0,n.useEffect)(()=>{_(t&&t.models.length>0?t.models.includes("all-proxy-models")?y:t.models:y)},[t,y]),(0,r.jsxs)("div",{children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,r.jsx)(er.Z,{title:"Create Key",visible:d,width:800,footer:null,onOk:w,onCancel:b,children:(0,r.jsxs)(ea.Z,{form:c,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:t?t.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,r.jsx)(en.Z,{value:t?t.team_alias:"",disabled:!0})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&c.setFieldsValue({models:["all-team-models"]})},children:[(0,r.jsx)(ec,{value:"all-team-models",children:"All Team Models"},"all-team-models"),Z.map(e=>(0,r.jsx)(ec,{value:e,children:e},e))]})}),(0,r.jsxs)($.Z,{className:"mt-20 mb-8",children:[(0,r.jsx)(Q.Z,{children:(0,r.jsx)("b",{children:"Optional Settings"})}),(0,r.jsxs)(X.Z,{children:[(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(t.max_budget))}}],children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,r.jsxs)(es.default,{defaultValue:null,placeholder:"n/a",children:[(0,r.jsx)(es.default.Option,{value:"24h",children:"daily"}),(0,r.jsx)(es.default.Option,{value:"30d",children:"monthly"})]})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(en.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Create Key"})})]})}),h&&(0,r.jsx)(er.Z,{visible:d,onOk:w,onCancel:b,footer:null,children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(el.Z,{children:"Save your Key"}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,r.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:null!=h?(0,r.jsxs)("div",{children:[(0,r.jsx)(ee.Z,{className:"mt-3",children:"API Key:"}),(0,r.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,r.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:h})}),(0,r.jsx)(et.CopyToClipboard,{text:h,onCopy:()=>{u.ZP.success("API Key copied to clipboard")},children:(0,r.jsx)(J.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,r.jsx)(ee.Z,{children:"Key being created, this might take 30s"})})]})})]})},em=t(9454),eu=t(98941),eh=t(33393),ex=t(5),ep=t(13810),ej=t(61244),eg=t(10827),ey=t(3851),ef=t(2044),eZ=t(64167),e_=t(74480),ew=t(7178),eb=t(95093),ek=t(27166);let{Option:ev}=es.default;var eS=e=>{let{userID:l,userRole:t,accessToken:s,selectedTeam:a,data:o,setData:i,teams:c}=e,[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(!1),[p,j]=(0,n.useState)(null),[g,f]=(0,n.useState)(null),[Z,_]=(0,n.useState)(null),[w,b]=(0,n.useState)(""),[k,v]=(0,n.useState)(!1),[S,A]=(0,n.useState)(!1),[E,I]=(0,n.useState)(null),[C,P]=(0,n.useState)([]),T=new Set,[O,F]=(0,n.useState)(T);(0,n.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==s&&null!==t){let e=(await N(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),P(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[s,l,t]),(0,n.useEffect)(()=>{if(c){let e=new Set;c.forEach((l,t)=>{let s=l.team_id;e.add(s)}),F(e)}},[c]);let R=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),I(e),v(!0)},M=async e=>{if(null==s)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let t=await L(s,e);console.log("handleEditSubmit: newKeyValues",t),o&&i(o.map(e=>e.token===l?t:e)),u.ZP.success("Key updated successfully"),v(!1),I(null)},U=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=o&&(j(e.token),localStorage.removeItem("userData"+l),x(!0))},D=async()=>{if(null!=p&&null!=o){try{await y(s,p);let e=o.filter(e=>e.token!==p);i(e)}catch(e){console.error("Error deleting the key:",e)}x(!1),j(null)}};if(null!=o)return console.log("RERENDER TRIGGERED"),(0,r.jsxs)("div",{children:[(0,r.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,r.jsxs)(eg.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Key Alias"}),(0,r.jsx)(e_.Z,{children:"Secret Key"}),(0,r.jsx)(e_.Z,{children:"Spend (USD)"}),(0,r.jsx)(e_.Z,{children:"Budget (USD)"}),(0,r.jsx)(e_.Z,{children:"Models"}),(0,r.jsx)(e_.Z,{children:"TPM / RPM Limits"})]})}),(0,r.jsx)(ey.Z,{children:o.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(a){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(O.has(e.team_id),", selectedTeam id: ").concat(a.team_id)),(null!=a.team_id||null===e.team_id||O.has(e.team_id))&&e.team_id!=a.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,r.jsx)(ee.Z,{children:e.key_alias}):(0,r.jsx)(ee.Z,{children:"Not Set"})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:e.key_name})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,r.jsx)(ef.Z,{children:null!=e.max_budget?(0,r.jsx)(ee.Z,{children:e.max_budget}):(0,r.jsx)(ee.Z,{children:"Unlimited"})}),(0,r.jsx)(ef.Z,{children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(r.Fragment,{children:a&&a.models&&a.models.length>0?a.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Team Models"})},l):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Team Models"})},l):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(ef.Z,{children:(0,r.jsxs)(ee.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{onClick:()=>{I(e),A(!0)},icon:em.Z,size:"sm"}),(0,r.jsx)(er.Z,{open:S,onCancel:()=>{A(!1),I(null)},footer:null,width:800,children:E&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-8",children:[(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat(E.spend).toFixed(4)}catch(e){return E.spend}})()})})]}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.max_budget?(0,r.jsx)(r.Fragment,{children:E.max_budget}):(0,r.jsx)(r.Fragment,{children:"Unlimited"})})})]},e.name),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,r.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,r.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.expires?(0,r.jsx)(r.Fragment,{children:new Date(E.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,r.jsx)(r.Fragment,{children:"Never"})})})]},e.name)]}),(0,r.jsxs)(ep.Z,{className:"my-4",children:[(0,r.jsx)(el.Z,{children:"Token Name"}),(0,r.jsx)(ee.Z,{className:"my-1",children:E.key_alias?E.key_alias:E.key_name}),(0,r.jsx)(el.Z,{children:"Token ID"}),(0,r.jsx)(ee.Z,{className:"my-1 text-[12px]",children:E.token}),(0,r.jsx)(el.Z,{children:"Metadata"}),(0,r.jsx)(ee.Z,{className:"my-1",children:(0,r.jsxs)("pre",{children:[JSON.stringify(E.metadata)," "]})})]}),(0,r.jsx)(J.Z,{className:"mx-auto flex items-center",onClick:()=>{A(!1),I(null)},children:"Close"})]})}),(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>R(e)}),(0,r.jsx)(ej.Z,{onClick:()=>U(e),icon:eh.Z,size:"sm"})]})]},e.token)})})]}),h&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:""}),(0,r.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(J.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(J.Z,{onClick:()=>{x(!1),j(null)},children:"Cancel"})]})]})]})})]}),E&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,token:s,onSubmit:o}=e,[i]=ea.Z.useForm(),[d,m]=(0,n.useState)(a),[u,h]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1);return(0,r.jsx)(er.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{i.validateFields().then(e=>{i.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(ea.Z,{form:i,onFinish:M,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,r.jsx)(en.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let t=l.filter(e=>!d.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!d.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(t)),t.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(t,"Team models: ").concat(d.models)):Promise.resolve()}}],children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(ev,{value:"all-team-models",children:"All Team Models"},"all-team-models"),d&&d.models?d.models.includes("all-proxy-models")?C.filter(e=>"all-proxy-models"!==e).map(e=>(0,r.jsx)(ev,{value:e,children:e},e)):d.models.map(e=>(0,r.jsx)(ev,{value:e,children:e},e)):C.map(e=>(0,r.jsx)(ev,{value:e,children:e},e))]})}),(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==d?void 0:d.max_budget)!==null&&(null==d?void 0:d.max_budget)!==void 0?null==d?void 0:d.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&d&&null!==d.max_budget&&l>d.max_budget)throw console.log("keyTeam.max_budget: ".concat(d.max_budget)),Error("Budget cannot exceed team max budget: $".concat(d.max_budget))}}],children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{label:"token",name:"token",hidden:!0}),(0,r.jsx)(ea.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,r.jsx)(eb.Z,{value:s.team_alias,children:null==c?void 0:c.map((e,l)=>(0,r.jsx)(ek.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:k,onCancel:()=>{v(!1),I(null)},token:E,onSubmit:M})]})},eN=t(76032),eA=t(35152),eE=e=>{let{userID:l,userRole:t,accessToken:s,userSpend:a,selectedTeam:o}=e;console.log("userSpend: ".concat(a));let[i,c]=(0,n.useState)(null!==a?a:0),[d,m]=(0,n.useState)(0),[u,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=async()=>{if(s&&l&&t&&"Admin"===t&&null==a)try{let e=await w(s);e&&(e.spend?c(e.spend):c(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===t)return;if(null!==s){let e=(await N(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),h(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,s,l]),(0,n.useEffect)(()=>{null!==a&&c(a)},[a]);let x=[];o&&o.models&&(x=o.models),x&&x.includes("all-proxy-models")?(console.log("user models:",u),x=u):x&&x.includes("all-team-models")?x=o.models:x&&0===x.length&&(x=u);let p=void 0!==i?i.toFixed(4):null;return console.log("spend in view user spend: ".concat(i)),(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsxs)("div",{children:[(0,r.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,r.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",p]})]}),(0,r.jsx)("div",{className:"ml-auto",children:(0,r.jsxs)($.Z,{children:[(0,r.jsx)(Q.Z,{children:(0,r.jsx)(ee.Z,{children:"Team Models"})}),(0,r.jsx)(X.Z,{className:"absolute right-0 z-10 bg-white p-2 shadow-lg max-w-xs",children:(0,r.jsx)(eN.Z,{children:x.map(e=>(0,r.jsx)(eA.Z,{children:(0,r.jsx)(ee.Z,{children:e})},e))})})]})})]})},eI=e=>{let{userID:l,userRole:t,selectedTeam:s,accessToken:a}=e,[o,i]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==a){let e=(await N(a,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),i(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[a,l,t]);let c=[];return s&&s.models&&(c=s.models),c&&c.includes("all-proxy-models")&&(console.log("user models:",o),c=o),(0,r.jsx)(r.Fragment,{children:(0,r.jsx)("div",{className:"mb-5",children:(0,r.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==s?void 0:s.team_alias})})})},eC=e=>{let l,{teams:t,setSelectedTeam:s,userRole:a}=e,o={models:[],team_id:null,team_alias:"Default Team"},[i,c]=(0,n.useState)(o);return(l="App User"===a?t:t?[...t,o]:[o],"App User"===a)?null:(0,r.jsxs)("div",{className:"mt-5 mb-5",children:[(0,r.jsx)(el.Z,{children:"Select Team"}),(0,r.jsx)(ee.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,r.jsxs)(ee.Z,{className:"mt-3 mb-3",children:[(0,r.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,r.jsx)(eb.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(ek.Z,{value:String(l),onClick:()=>s(e),children:e.team_alias},l))}):(0,r.jsxs)(ee.Z,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]})},eP=t(37963),eT=t(36083);console.log("isLocal:",!1);var eO=e=>{let{userID:l,userRole:t,teams:s,keys:a,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:m,setKeys:u}=e,[h,x]=(0,n.useState)(null),p=(0,o.useSearchParams)();p.get("viewSpend"),(0,o.useRouter)();let j=p.get("token"),[g,y]=(0,n.useState)(null),[f,_]=(0,n.useState)(null),[b,k]=(0,n.useState)([]),v={models:[],team_alias:"Default Team",team_id:null},[S,A]=(0,n.useState)(s?s[0]:v);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(j){let e=(0,eP.o)(j);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),y(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),i(l)}else console.log("User role not defined");e.user_email?d(e.user_email):console.log("User Email is not set ".concat(e))}}if(l&&g&&t&&!a&&!h){let e=sessionStorage.getItem("userModels"+l);e?k(JSON.parse(e)):(async()=>{try{let e=await Z(g,l,t,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==t){let e=await w(g);x(e),console.log("globalSpend:",e)}else x(e.user_info);u(e.keys),m(e.teams);let s=[...e.teams];s.length>0?(console.log("response['teams']: ".concat(s)),A(s[0])):A(v),sessionStorage.setItem("userData"+l,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(e.user_info));let a=(await N(g,l,t)).data.map(e=>e.id);console.log("available_model_names:",a),k(a),console.log("userModels:",b),sessionStorage.setItem("userModels"+l,JSON.stringify(a))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,j,g,a,t]),(0,n.useEffect)(()=>{if(null!==a&&null!=S){let e=0;for(let l of a)S.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===S.team_id&&(e+=l.spend);_(e)}else if(null!==a){let e=0;for(let l of a)e+=l.spend;_(e)}},[S]),null==l||null==j){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==g)return null;if(null==t&&i("App Owner"),t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=eT.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",S),console.log("teamSpend: ".concat(f)),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsx)(W.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(eI,{userID:l,userRole:t,selectedTeam:S||null,accessToken:g}),(0,r.jsx)(eE,{userID:l,userRole:t,accessToken:g,userSpend:f,selectedTeam:S||null}),(0,r.jsx)(eS,{userID:l,userRole:t,accessToken:g,selectedTeam:S||null,data:a,setData:u,teams:s}),(0,r.jsx)(ed,{userID:l,team:S||null,userRole:t,accessToken:g,data:a,setData:u},S?S.team_id:null),(0,r.jsx)(eC,{teams:s,setSelectedTeam:A,userRole:t})]})})})},eF=t(35087),eR=t(92836),eM=t(26734),eL=t(41608),eU=t(32126),eD=t(23682),eK=t(47047),eB=t(76628),ez=t(57750),eq=t(44041),eV=t(38302),eG=t(28683),eY=t(1460),eW=t(78578),eJ=t(63954),eH=t(90252),e$=t(7905),eX=e=>{let{modelID:l,accessToken:t}=e,[s,a]=(0,n.useState)(!1),o=async()=>{try{u.ZP.info("Making API Call"),a(!0);let e=await p(t,l);console.log("model delete Response:",e),u.ZP.success("Model ".concat(l," deleted successfully")),a(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(ej.Z,{onClick:()=>a(!0),icon:eh.Z,size:"sm"}),(0,r.jsx)(er.Z,{open:s,onOk:o,okType:"danger",onCancel:()=>a(!1),children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 w-full",children:[(0,r.jsx)(el.Z,{children:"Delete Model"}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)("p",{children:["Model ID: ",(0,r.jsx)("b",{children:l})]})})]})})]})},eQ=t(97766),e0=t(46495);let{Title:e1,Link:e2}=eT.default;(s=a||(a={})).OpenAI="OpenAI",s.Azure="Azure",s.Anthropic="Anthropic",s.Google_AI_Studio="Gemini (Google AI Studio)",s.Bedrock="Amazon Bedrock",s.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",s.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)";let e4={OpenAI:"openai",Azure:"azure",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai"},e8={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},e5=async(e,l,t)=>{try{let s=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(s)),console.log("received type of deployments: ".concat(typeof s)),s.forEach(async t=>{console.log("litellm_model: ".concat(t));let s={},a={};s.model=t;let r="";for(let[l,t]of Object.entries(e))if(""!==t){if("model_name"==l)r+=t;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)a[l]=t;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",t);let e={};if(t&&void 0!=t){try{e=JSON.parse(t)}catch(e){throw u.ZP.error("Failed to parse LiteLLM Extra Params: "+e,10),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))s[l]=t}}else s[l]=t}let n={model_name:r,litellm_params:s,model_info:a},o=await x(l,n);console.log("response for model create call: ".concat(o.data))}),t.resetFields()}catch(e){u.ZP.error("Failed to create model: "+e,10)}};var e3=e=>{var l,t,s;let{accessToken:o,token:i,userRole:c,userID:d,modelData:m={data:[]},setModelData:x}=e,[p,j]=(0,n.useState)([]),[g]=ea.Z.useForm(),[y,f]=(0,n.useState)(null),[Z,_]=(0,n.useState)(""),[w,N]=(0,n.useState)([]),A=Object.values(a).filter(e=>isNaN(Number(e))),[E,I]=(0,n.useState)("OpenAI"),[C,P]=(0,n.useState)(""),[T,O]=(0,n.useState)(!1),[F,R]=(0,n.useState)(null),[M,L]=(0,n.useState)([]),[U,K]=(0,n.useState)(null),[B,z]=(0,n.useState)([]),[Y,et]=(0,n.useState)([]),[es,en]=(0,n.useState)([]),[ec,ed]=(0,n.useState)([]),[em,eh]=(0,n.useState)([]),[ev,eS]=(0,n.useState)([]),[eN,eA]=(0,n.useState)([]),[eE,eI]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[eC,eP]=(0,n.useState)(null),[eO,e3]=(0,n.useState)(0),e6=e=>{R(e),O(!0)},e7=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},t=null;for(let[s,a]of Object.entries(e))"model_id"!==s?l[s]=a:t=a;let s={litellm_params:l,model_info:{id:t}};console.log("handleEditSubmit payload:",s);try{await D(o,s),u.ZP.success("Model updated successfully, restart server to see updates"),O(!1),R(null)}catch(e){console.log("Error occurred")}},e9=()=>{_(new Date().toLocaleString())},le=async()=>{if(!o){console.error("Access token is missing");return}console.log("new modelGroupRetryPolicy:",eC);try{await V(o,{router_settings:{model_group_retry_policy:eC}}),u.ZP.success("Retry settings saved successfully")}catch(e){console.error("Failed to save retry settings:",e),u.ZP.error("Failed to save retry settings")}};if((0,n.useEffect)(()=>{if(!o||!i||!c||!d)return;let e=async()=>{try{var e,l,t,s,a,r;let n=await b(o,d,c);console.log("Model data response:",n.data),x(n);let i=new Set;for(let e=0;e0&&(u=m[m.length-1],console.log("_initial_model_group:",u),K(u)),console.log("selectedModelGroup:",U);let h=await k(o,d,c,u,null===(e=eE.from)||void 0===e?void 0:e.toISOString(),null===(l=eE.to)||void 0===l?void 0:l.toISOString());console.log("Model metrics response:",h),et(h.data),en(h.all_api_bases);let p=await S(o,d,c,u,null===(t=eE.from)||void 0===t?void 0:t.toISOString(),null===(s=eE.to)||void 0===s?void 0:s.toISOString());console.log("Model exceptions response:",p),ed(p.data),eh(p.exception_types);let j=await v(o,d,c,u,null===(a=eE.from)||void 0===a?void 0:a.toISOString(),null===(r=eE.to)||void 0===r?void 0:r.toISOString());console.log("slowResponses:",j),eA(j);let g=(await q(o,d,c)).router_settings;console.log("routerSettingsInfo:",g);let y=g.model_group_retry_policy,f=g.num_retries;console.log("model_group_retry_policy:",y),console.log("default_retries:",f),eP(y),e3(f)}catch(e){console.error("There was an error fetching the model data",e)}};o&&i&&c&&d&&e();let l=async()=>{let e=await h();console.log("received model cost map data: ".concat(Object.keys(e))),f(e)};null==y&&l(),e9()},[o,i,c,d,y,Z]),!m||!o||!i||!c||!d)return(0,r.jsx)("div",{children:"Loading..."});let ll=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(y)),null!=y&&"object"==typeof y&&e in y)?y[e].litellm_provider:"openai";if(a){let e=a.split("/"),l=e[0];n=1===e.length?u(a):l}else n="openai";r&&(o=null==r?void 0:r.input_cost_per_token,i=null==r?void 0:r.output_cost_per_token,c=null==r?void 0:r.max_tokens),(null==s?void 0:s.litellm_params)&&(d=Object.fromEntries(Object.entries(null==s?void 0:s.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),m.data[e].provider=n,m.data[e].input_cost=o,m.data[e].output_cost=i,m.data[e].max_tokens=c,m.data[e].api_base=null==s?void 0:null===(t=s.litellm_params)||void 0===t?void 0:t.api_base,m.data[e].cleanedLitellmParams=d,ll.push(s.model_name),console.log(m.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=eT.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let lt=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(a).find(l=>a[l]===e);if(l){let e=e4[l];console.log("mappingResult: ".concat(e));let t=[];"object"==typeof y&&Object.entries(y).forEach(l=>{let[s,a]=l;null!==a&&"object"==typeof a&&"litellm_provider"in a&&(a.litellm_provider===e||a.litellm_provider.includes(e))&&t.push(s)}),N(t),console.log("providerModels: ".concat(w))}},ls=async()=>{try{u.ZP.info("Running health check..."),P("");let e=await G(o);P(e)}catch(e){console.error("Error running health check:",e),P("Error running health check")}},la=async(e,l,t)=>{if(console.log("Updating model metrics for group:",e),o&&d&&c&&l&&t){console.log("inside updateModelMetrics - startTime:",l,"endTime:",t),K(e);try{let s=await k(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model metrics response:",s),et(s.data),en(s.all_api_bases);let a=await S(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model exceptions response:",a),ed(a.data),eh(a.exception_types);let r=await v(o,d,c,e,l.toISOString(),t.toISOString());console.log("slowResponses:",r),eA(r)}catch(e){console.error("Failed to fetch model metrics",e)}}};return console.log("selectedProvider: ".concat(E)),console.log("providerModels.length: ".concat(w.length)),(0,r.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,r.jsxs)(eM.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(eL.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)(eR.Z,{children:"All Models"}),(0,r.jsx)(eR.Z,{children:"Add Model"}),(0,r.jsx)(eR.Z,{children:(0,r.jsx)("pre",{children:"/health Models"})}),(0,r.jsx)(eR.Z,{children:"Model Analytics"}),(0,r.jsx)(eR.Z,{children:"Model Retry Settings"})]}),(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[Z&&(0,r.jsxs)(ee.Z,{children:["Last Refreshed: ",Z]}),(0,r.jsx)(ej.Z,{icon:eJ.Z,variant:"shadow",size:"xs",className:"self-center",onClick:e9})]})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)(W.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(ee.Z,{children:"Filter by Public Model Name"}),(0,r.jsxs)(eb.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:"all",onValueChange:e=>K("all"===e?"all":e),children:[(0,r.jsx)(ek.Z,{value:"all",children:"All Models"}),M.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>K(e),children:e},l))]})]}),(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eg.Z,{className:"mt-5",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Public Model Name "}),(0,r.jsx)(e_.Z,{children:"Provider"}),"Admin"===c&&(0,r.jsx)(e_.Z,{children:"API Base"}),(0,r.jsx)(e_.Z,{children:"Extra litellm Params"}),(0,r.jsx)(e_.Z,{children:"Input Price per token ($)"}),(0,r.jsx)(e_.Z,{children:"Output Price per token ($)"}),(0,r.jsx)(e_.Z,{children:"Max Tokens"}),(0,r.jsx)(e_.Z,{children:"Status"})]})}),(0,r.jsx)(ey.Z,{children:m.data.filter(e=>"all"===U||e.model_name===U||null==U||""===U).map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:e.model_name})}),(0,r.jsx)(ef.Z,{children:e.provider}),"Admin"===c&&(0,r.jsx)(ef.Z,{children:e.api_base}),(0,r.jsx)(ef.Z,{children:(0,r.jsxs)($.Z,{children:[(0,r.jsx)(Q.Z,{children:(0,r.jsx)(ee.Z,{children:"Litellm params"})}),(0,r.jsx)(X.Z,{children:(0,r.jsx)("pre",{children:JSON.stringify(e.cleanedLitellmParams,null,2)})})]})}),(0,r.jsx)(ef.Z,{children:e.input_cost||e.litellm_params.input_cost_per_token||null}),(0,r.jsx)(ef.Z,{children:e.output_cost||e.litellm_params.output_cost_per_token||null}),(0,r.jsx)(ef.Z,{children:e.max_tokens}),(0,r.jsx)(ef.Z,{children:e.model_info.db_model?(0,r.jsx)(ex.Z,{icon:eH.Z,className:"text-white",children:"DB Model"}):(0,r.jsx)(ex.Z,{icon:e$.Z,className:"text-black",children:"Config Model"})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>e6(e)}),(0,r.jsx)(eX,{modelID:e.model_info.id,accessToken:o})]})]},l))})]})})]}),(0,r.jsx)(e=>{let{visible:l,onCancel:t,model:s,onSubmit:a}=e,[n]=ea.Z.useForm(),o={},i="",c="";if(s){o=s.litellm_params,i=s.model_name;let e=s.model_info;e&&(c=e.id,console.log("model_id: ".concat(c)),o.model_id=c)}return(0,r.jsx)(er.Z,{title:"Edit Model "+i,visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a(e),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(ea.Z,{form:n,onFinish:e7,initialValues:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,r.jsx)(H.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"max_retries",name:"max_retries",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,r.jsx)(eo.Z,{min:0,step:1})}),(0,r.jsx)(ea.Z.Item,{label:"input_cost_per_token",name:"input_cost_per_token",tooltip:"float (optional) - Input cost per token",children:(0,r.jsx)(eo.Z,{min:0,step:1e-4})}),(0,r.jsx)(ea.Z.Item,{label:"output_cost_per_token",name:"output_cost_per_token",tooltip:"float (optional) - Output cost per token",children:(0,r.jsx)(eo.Z,{min:0,step:1e-4})}),(0,r.jsx)(ea.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:T,onCancel:()=>{O(!1),R(null)},model:F,onSubmit:e7})]}),(0,r.jsxs)(eU.Z,{className:"h-full",children:[(0,r.jsx)(e1,{level:2,children:"Add new model"}),(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(ea.Z,{form:g,onFinish:()=>{g.validateFields().then(e=>{e5(e,o,g)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eb.Z,{value:E.toString(),children:A.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>{lt(e),I(e)},children:e},l))})}),(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,r.jsx)(H.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(s=E.toString())?"gemini-pro":"Anthropic"==s?"claude-3-opus":"Amazon Bedrock"==s?"claude-3-opus":"Gemini (Google AI Studio)"==s?"gemini-pro":"gpt-3.5-turbo"})}),(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsx)(ee.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===E?(0,r.jsx)(H.Z,{placeholder:"Enter model name"}):w.length>0?(0,r.jsx)(eK.Z,{value:w,children:w.map((e,l)=>(0,r.jsx)(eB.Z,{value:e,children:e},l))}):(0,r.jsx)(H.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsxs)(ee.Z,{className:"mb-3 mt-1",children:["Actual model name used for making ",(0,r.jsx)(e2,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll ",(0,r.jsx)(e2,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," models with the same 'public name'"]})})]}),"Amazon Bedrock"!=E&&"Vertex AI (Anthropic, Gemini, etc.)"!=E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,r.jsx)(H.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==E&&(0,r.jsx)(ea.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,r.jsx)(H.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,r.jsx)(H.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,r.jsx)(H.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,r.jsx)(e0.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;g.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?u.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&u.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,r.jsx)(ei.ZP,{icon:(0,r.jsx)(eQ.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsx)(ee.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==E||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==E)&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,r.jsx)(H.Z,{placeholder:"https://..."})}),"Azure"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,r.jsx)(H.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==E&&(0,r.jsxs)(ea.Z.Item,{label:"Base Model",name:"base_model",children:[(0,r.jsx)(H.Z,{placeholder:"azure/gpt-3.5-turbo"}),(0,r.jsxs)(ee.Z,{children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from ",(0,r.jsx)(e2,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})]}),"Amazon Bedrock"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)(H.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)(H.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,r.jsx)(H.Z,{placeholder:"us-east-1"})}),(0,r.jsx)(ea.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,r.jsx)(eW.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,r.jsxs)(eV.Z,{children:[(0,r.jsx)(eG.Z,{span:10}),(0,r.jsx)(eG.Z,{span:10,children:(0,r.jsxs)(ee.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params ",(0,r.jsx)(e2,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,r.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add Model"})}),(0,r.jsx)(eY.Z,{title:"Get help on our github",children:(0,r.jsx)(eT.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(ee.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,r.jsx)(J.Z,{onClick:ls,children:"Run `/health`"}),C&&(0,r.jsx)("pre",{children:JSON.stringify(C,null,2)})]})}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)(W.Z,{numItems:2,className:"mt-2",children:[(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Time Range"}),(0,r.jsx)(eF.Z,{enableSelect:!0,value:eE,onValueChange:e=>{eI(e),la(U,e.from,e.to)}})]}),(0,r.jsxs)(eG.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Model Group"}),(0,r.jsx)(eb.Z,{className:"mb-4 mt-2",defaultValue:U||M[0],value:U||M[0],children:M.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>la(e,eE.from,eE.to),children:e},l))})]})]}),(0,r.jsxs)(W.Z,{numItems:2,children:[(0,r.jsx)(eG.Z,{children:(0,r.jsxs)(ep.Z,{className:"mr-2 max-h-[400px] min-h-[400px]",children:[(0,r.jsx)(el.Z,{children:"Avg Latency per Token"}),(0,r.jsx)("p",{className:"text-gray-500 italic",children:" (seconds/token)"}),(0,r.jsx)(ee.Z,{className:"text-gray-500 italic mt-1 mb-1",children:"average Latency for successfull requests divided by the total tokens"}),Y&&es&&(0,r.jsx)(ez.Z,{title:"Model Latency",className:"h-72",data:Y,showLegend:!1,index:"date",categories:es,connectNulls:!0,customTooltip:e=>{var l,t;let{payload:s,active:a}=e;if(!a||!s)return null;let n=null===(t=s[0])||void 0===t?void 0:null===(l=t.payload)||void 0===l?void 0:l.date,o=s.sort((e,l)=>l.value-e.value);if(o.length>5){let e=o.length-5;(o=o.slice(0,5)).push({dataKey:"".concat(e," other deployments"),value:s.slice(5).reduce((e,l)=>e+l.value,0),color:"gray"})}return(0,r.jsxs)("div",{className:"w-150 rounded-tremor-default border border-tremor-border bg-tremor-background p-2 text-tremor-default shadow-tremor-dropdown",children:[n&&(0,r.jsxs)("p",{className:"text-tremor-content-emphasis mb-2",children:["Date: ",n]}),o.map((e,l)=>{let t=parseFloat(e.value.toFixed(5)),s=0===t&&e.value>0?"<0.00001":t.toFixed(5);return(0,r.jsxs)("div",{className:"flex justify-between",children:[(0,r.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,r.jsx)("div",{className:"w-2 h-2 mt-1 rounded-full bg-".concat(e.color,"-500")}),(0,r.jsx)("p",{className:"text-tremor-content",children:e.dataKey})]}),(0,r.jsx)("p",{className:"font-medium text-tremor-content-emphasis text-righ ml-2",children:s})]},l)})]})}})]})}),(0,r.jsx)(eG.Z,{children:(0,r.jsx)(ep.Z,{className:"ml-2 max-h-[400px] min-h-[400px] overflow-y-auto",children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Deployment"}),(0,r.jsx)(e_.Z,{children:"Success Responses"}),(0,r.jsxs)(e_.Z,{children:["Slow Responses ",(0,r.jsx)("p",{children:"Success Responses taking 600+s"})]})]})}),(0,r.jsx)(ey.Z,{children:eN.map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.api_base}),(0,r.jsx)(ef.Z,{children:e.total_count}),(0,r.jsx)(ef.Z,{children:e.slow_count})]},l))})]})})})]}),(0,r.jsxs)(ep.Z,{className:"mt-4",children:[(0,r.jsx)(el.Z,{children:"Exceptions per Model"}),(0,r.jsx)(eq.Z,{className:"h-72",data:ec,index:"model",categories:em,stack:!0,colors:["indigo-300","rose-200","#ffcc33"],yAxisWidth:30})]})]}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)(ee.Z,{children:"Filter by Public Model Name"}),(0,r.jsx)(eb.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:U||M[0],value:U||M[0],onValueChange:e=>K(e),children:M.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>K(e),children:e},l))})]}),(0,r.jsxs)(el.Z,{children:["Retry Policy for ",U]}),(0,r.jsx)(ee.Z,{className:"mb-6",children:"How many retries should be attempted based on the Exception"}),e8&&(0,r.jsx)("table",{children:(0,r.jsx)("tbody",{children:Object.entries(e8).map((e,l)=>{var t;let[s,a]=e,n=null==eC?void 0:null===(t=eC[U])||void 0===t?void 0:t[a];return null==n&&(n=eO),(0,r.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,r.jsx)("td",{children:(0,r.jsx)(ee.Z,{children:s})}),(0,r.jsx)("td",{children:(0,r.jsx)(eo.Z,{className:"ml-5",value:n,min:0,step:1,onChange:e=>{eP(l=>{var t;let s=null!==(t=null==l?void 0:l[U])&&void 0!==t?t:{};return{...null!=l?l:{},[U]:{...s,[a]:e}}})}})})]},l)})})}),(0,r.jsx)(J.Z,{className:"mt-6 mr-8",onClick:le,children:"Save"})]})]})]})})};let{Option:e6}=es.default;var e7=e=>{let{userID:l,accessToken:t,teams:s}=e,[a]=ea.Z.useForm(),[o,i]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[m,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await N(t,l,"any"),s=[];for(let l=0;l{i(!1),a.resetFields()},p=()=>{i(!1),d(null),a.resetFields()},j=async e=>{try{u.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let s=await g(t,null,e);console.log("user create Response:",s),d(s.key),u.ZP.success("API user Created"),a.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,r.jsxs)("div",{children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Invite User"}),(0,r.jsxs)(er.Z,{title:"Invite User",visible:o,width:800,footer:null,onOk:x,onCancel:p,children:[(0,r.jsx)(ee.Z,{className:"mb-1",children:"Invite a user to login to the Admin UI and create Keys"}),(0,r.jsx)(ee.Z,{className:"mb-6",children:(0,r.jsx)("b",{children:"Note: SSO Setup Required for this"})}),(0,r.jsxs)(ea.Z,{form:a,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsx)(ea.Z.Item,{label:"User Email",name:"user_email",children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Team ID",name:"team_id",children:(0,r.jsx)(es.default,{placeholder:"Select Team ID",style:{width:"100%"},children:s?s.map(e=>(0,r.jsx)(e6,{value:e.team_id,children:e.team_alias},e.team_id)):(0,r.jsx)(e6,{value:null,children:"Default Team"},"default")})}),(0,r.jsx)(ea.Z.Item,{label:"Metadata",name:"metadata",children:(0,r.jsx)(en.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Create User"})})]})]}),c&&(0,r.jsxs)(er.Z,{title:"User Created Successfully",visible:o,onOk:x,onCancel:p,footer:null,children:[(0,r.jsx)("p",{children:"User has been created to access your proxy. Please Ask them to Log In."}),(0,r.jsx)("br",{}),(0,r.jsx)("p",{children:(0,r.jsx)("b",{children:"Note: This Feature is only supported through SSO on the Admin UI"})})]})]})},e9=e=>{let{accessToken:l,token:t,keys:s,userRole:a,userID:o,teams:i,setKeys:c}=e,[d,m]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(0),[j,g]=n.useState(null),[y,f]=(0,n.useState)(null);return((0,n.useEffect)(()=>{if(!l||!t||!a||!o)return;let e=async()=>{try{let e=await Z(l,null,a,!0,x,25);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};l&&t&&a&&o&&e()},[l,t,a,o,x]),d&&l&&t&&a&&o)?(0,r.jsx)("div",{style:{width:"100%"},children:(0,r.jsxs)(W.Z,{className:"gap-2 p-2 h-[80vh] w-full mt-8",children:[(0,r.jsx)(e7,{userID:o,accessToken:l,teams:i}),(0,r.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[80vh] mb-4",children:[(0,r.jsx)("div",{className:"mb-4 mt-1",children:(0,r.jsx)(ee.Z,{children:"These are Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM"})}),(0,r.jsx)(eM.Z,{children:(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(eg.Z,{className:"mt-5",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"User ID"}),(0,r.jsx)(e_.Z,{children:"User Email"}),(0,r.jsx)(e_.Z,{children:"User Models"}),(0,r.jsx)(e_.Z,{children:"User Spend ($ USD)"}),(0,r.jsx)(e_.Z,{children:"User Max Budget ($ USD)"}),(0,r.jsx)(e_.Z,{children:"User API Key Aliases"})]})}),(0,r.jsx)(ey.Z,{children:d.map(e=>{var l;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.user_id}),(0,r.jsx)(ef.Z,{children:e.user_email}),(0,r.jsx)(ef.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,r.jsx)(ef.Z,{children:e.spend?null===(l=e.spend)||void 0===l?void 0:l.toFixed(2):0}),(0,r.jsx)(ef.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(W.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,r.jsx)(ex.Z,{size:"xs",color:"indigo",children:e.key_aliases.filter(e=>null!==e).join(", ")}):(0,r.jsx)(ex.Z,{size:"xs",color:"gray",children:"No Keys"})})})]},e.user_id)})})]})}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)("div",{className:"flex items-center",children:[(0,r.jsx)("div",{className:"flex-1"}),(0,r.jsx)("div",{className:"flex-1 flex justify-between items-center"})]})})]})})]}),function(){if(!d)return null;let e=Math.ceil(d.length/25);return(0,r.jsxs)("div",{className:"flex justify-between items-center",children:[(0,r.jsxs)("div",{children:["Showing Page ",x+1," of ",e]}),(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===x,onClick:()=>p(x-1),children:"← Prev"}),(0,r.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{p(x+1)},children:"Next →"})]})]})}()]})}):(0,r.jsx)("div",{children:"Loading..."})},le=e=>{let{teams:l,searchParams:t,accessToken:s,setTeams:a,userID:o,userRole:i}=e,[c]=ea.Z.useForm(),[d]=ea.Z.useForm(),{Title:m,Paragraph:h}=eT.default,[x,p]=(0,n.useState)(""),[j,g]=(0,n.useState)(!1),[y,Z]=(0,n.useState)(l?l[0]:null),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1),[S,A]=(0,n.useState)([]),[E,I]=(0,n.useState)(!1),[C,P]=(0,n.useState)(null),[T,O]=(0,n.useState)({}),F=e=>{Z(e),g(!0)},R=async e=>{let t=e.team_id;if(console.log("handleEditSubmit:",e),null==s)return;let r=await U(s,e);l&&a(l.map(e=>e.team_id===t?r.data:e)),u.ZP.success("Team updated successfully"),g(!1),Z(null)},L=async e=>{P(e),I(!0)},D=async()=>{if(null!=C&&null!=l&&null!=s){try{await f(s,C);let e=l.filter(e=>e.team_id!==C);a(e)}catch(e){console.error("Error deleting the team:",e)}I(!1),P(null)}};(0,n.useEffect)(()=>{let e=async()=>{try{if(null===o||null===i||null===s||null===l)return;console.log("fetching team info:");let e={};for(let t=0;t<(null==l?void 0:l.length);t++){let a=l[t].team_id,r=await _(s,a);console.log("teamInfo response:",r),null!==r&&(e={...e,[a]:r})}O(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===o||null===i)return;if(null!==s){let e=(await N(s,o,i)).data.map(e=>e.id);console.log("available_model_names:",e),A(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,o,i,l]);let B=async e=>{try{if(null!=s){var t;let r=null==e?void 0:e.team_alias;if((null!==(t=null==l?void 0:l.map(e=>e.team_alias))&&void 0!==t?t:[]).includes(r))throw Error("Team alias ".concat(r," already exists, please pick another alias"));u.ZP.info("Creating Team");let n=await M(s,e);null!==l?a([...l,n]):a([n]),console.log("response for team create call: ".concat(n)),u.ZP.success("Team created"),b(!1)}}catch(e){console.error("Error creating the team:",e),u.ZP.error("Error creating the team: "+e,20)}},z=async e=>{try{if(null!=s&&null!=l){u.ZP.info("Adding Member");let t={role:"user",user_email:e.user_email,user_id:e.user_id},r=await K(s,y.team_id,t);console.log("response for team create call: ".concat(r.data));let n=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(r.data.team_id)),e.team_id===r.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...l];e[n]=r.data,a(e),Z(r.data)}v(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(JSON.stringify(l))),(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"All Teams"}),(0,r.jsxs)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Team Name"}),(0,r.jsx)(e_.Z,{children:"Spend (USD)"}),(0,r.jsx)(e_.Z,{children:"Budget (USD)"}),(0,r.jsx)(e_.Z,{children:"Models"}),(0,r.jsx)(e_.Z,{children:"TPM / RPM Limits"}),(0,r.jsx)(e_.Z,{children:"Info"})]})}),(0,r.jsx)(ey.Z,{children:l&&l.length>0?l.map(e=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,r.jsx)(ef.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,r.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"red",children:(0,r.jsx)(ee.Z,{children:"All Proxy Models"})},l):(0,r.jsx)(ex.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,r.jsx)(ee.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,r.jsx)(ef.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,r.jsxs)(ee.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,r.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsxs)(ee.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].keys&&T[e.team_id].keys.length," ","Keys"]}),(0,r.jsxs)(ee.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].team_info&&T[e.team_id].team_info.members_with_roles&&T[e.team_id].team_info.members_with_roles.length," ","Members"]})]}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>F(e)}),(0,r.jsx)(ej.Z,{onClick:()=>L(e.team_id),icon:eh.Z,size:"sm"})]})]},e.team_id)):null})]}),E&&(0,r.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,r.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,r.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,r.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,r.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:""}),(0,r.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,r.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,r.jsx)("div",{className:"sm:flex sm:items-start",children:(0,r.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,r.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,r.jsx)("div",{className:"mt-2",children:(0,r.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,r.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,r.jsx)(J.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,r.jsx)(J.Z,{onClick:()=>{I(!1),P(null)},children:"Cancel"})]})]})]})})]})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>b(!0),children:"+ Create New Team"}),(0,r.jsx)(er.Z,{title:"Create Team",visible:w,width:800,footer:null,onOk:()=>{b(!1),c.resetFields()},onCancel:()=>{b(!1),c.resetFields()},children:(0,r.jsxs)(ea.Z,{form:c,onFinish:B,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)(H.Z,{placeholder:""})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(es.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S.map(e=>(0,r.jsx)(es.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(ea.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(m,{level:4,children:"Team Members"}),(0,r.jsx)(h,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,r.jsx)(eb.Z,{defaultValue:"0",children:l.map((e,l)=>(0,r.jsx)(ek.Z,{value:String(l),onClick:()=>{Z(e)},children:e.team_alias},l))}):(0,r.jsxs)(h,{children:["No team created. ",(0,r.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Member Name"}),(0,r.jsx)(e_.Z,{children:"Role"})]})}),(0,r.jsx)(ey.Z,{children:y?y.members_with_roles.map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(ef.Z,{children:e.role})]},l)):null})]})}),y&&(0,r.jsx)(e=>{let{visible:l,onCancel:t,team:s,onSubmit:a}=e,[n]=ea.Z.useForm();return(0,r.jsx)(er.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{a({...e,team_id:s.team_id}),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,r.jsxs)(ea.Z,{form:n,onFinish:R,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,r.jsx)(H.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"Models",name:"models",children:(0,r.jsxs)(es.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,r.jsx)(es.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S&&S.map(e=>(0,r.jsx)(es.default.Option,{value:e,children:e},e))]})}),(0,r.jsx)(ea.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,r.jsx)(eo.Z,{step:.01,precision:2,width:200})}),(0,r.jsx)(ea.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,r.jsx)(eo.Z,{step:1,width:400})}),(0,r.jsx)(ea.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:j,onCancel:()=>{g(!1),Z(null)},team:y,onSubmit:R})]}),(0,r.jsxs)(Y.Z,{numColSpan:1,children:[(0,r.jsx)(J.Z,{className:"mx-auto mb-5",onClick:()=>v(!0),children:"+ Add member"}),(0,r.jsx)(er.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{v(!1),d.resetFields()},onCancel:()=>{v(!1),d.resetFields()},children:(0,r.jsxs)(ea.Z,{form:c,onFinish:z,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(ea.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},ll=t(18190),lt=e=>{let l,{searchParams:t,accessToken:s,showSSOBanner:a}=e,[o]=ea.Z.useForm(),[i]=ea.Z.useForm(),{Title:c,Paragraph:d}=eT.default,[m,h]=(0,n.useState)(""),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)(!1),[y,f]=(0,n.useState)(!1),[Z,_]=(0,n.useState)(!1),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1);try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let S=()=>{v(!1)},N=["proxy_admin","proxy_admin_viewer"];(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],l=await R(s,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let t=await R(s,"proxy_admin");t.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(t)),console.log("combinedList: ".concat(e)),p(e)}})()},[s]);let A=()=>{_(!1),i.resetFields()},E=()=>{_(!1),i.resetFields()},I=e=>(0,r.jsxs)(ea.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,r.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,r.jsx)(ea.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,r.jsx)(en.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add member"})})]}),C=(e,l,t)=>(0,r.jsxs)(ea.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,r.jsx)(eb.Z,{value:l,children:N.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,children:e},l))})}),(0,r.jsx)(ea.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:t,valuePropName:"user_id",className:"mt-8",children:(0,r.jsx)(en.Z,{value:t,disabled:!0})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Update role"})})]}),P=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,null);console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),u.ZP.success("Refresh tab to see updated user role"),_(!1)}}catch(e){console.error("Error creating the key:",e)}},T=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),g(!1)}}catch(e){console.error("Error creating the key:",e)}},O=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call"),e.user_email,e.user_id;let l=await B(s,e,"proxy_admin");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),f(!1)}}catch(e){console.error("Error creating the key:",e)}},F=async e=>{null!=s&&V(s,{environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}})};return console.log("admins: ".concat(null==x?void 0:x.length)),(0,r.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,r.jsx)(c,{level:4,children:"Admin Access "}),(0,r.jsxs)(d,{children:[a&&(0,r.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc. ",(0,r.jsx)("br",{}),(0,r.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsx)(ep.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Member Name"}),(0,r.jsx)(e_.Z,{children:"Role"})]})}),(0,r.jsx)(ey.Z,{children:x?x.map((e,l)=>(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,r.jsx)(ef.Z,{children:e.user_role}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ej.Z,{icon:eu.Z,size:"sm",onClick:()=>_(!0)}),(0,r.jsx)(er.Z,{title:"Update role",visible:Z,width:800,footer:null,onOk:A,onCancel:E,children:C(P,e.user_role,e.user_id)})]})]},l)):null})]})})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)("div",{className:"flex justify-start",children:[(0,r.jsx)(J.Z,{className:"mr-4 mb-5",onClick:()=>f(!0),children:"+ Add admin"}),(0,r.jsx)(er.Z,{title:"Add admin",visible:y,width:800,footer:null,onOk:()=>{f(!1),i.resetFields()},onCancel:()=>{f(!1),i.resetFields()},children:I(O)}),(0,r.jsx)(J.Z,{className:"mb-5",onClick:()=>g(!0),children:"+ Add viewer"}),(0,r.jsx)(er.Z,{title:"Add viewer",visible:j,width:800,footer:null,onOk:()=>{g(!1),i.resetFields()},onCancel:()=>{g(!1),i.resetFields()},children:I(T)})]})})]}),(0,r.jsxs)(W.Z,{children:[(0,r.jsx)(c,{level:4,children:"Add SSO"}),(0,r.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,r.jsx)(J.Z,{onClick:()=>b(!0),children:"Add SSO"}),(0,r.jsx)(er.Z,{title:"Add SSO",visible:w,width:800,footer:null,onOk:()=>{b(!1),o.resetFields()},onCancel:()=>{b(!1),o.resetFields()},children:(0,r.jsxs)(ea.Z,{form:o,onFinish:e=>{O(e),F(e),b(!1),v(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,r.jsx)(en.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,r.jsx)(en.Z,{})}),(0,r.jsx)(ea.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,r.jsx)(en.Z.Password,{})}),(0,r.jsx)(ea.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,r.jsx)(en.Z.Password,{})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,r.jsxs)(er.Z,{title:"SSO Setup Instructions",visible:k,width:800,footer:null,onOk:S,onCancel:()=>{v(!1)},children:[(0,r.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,r.jsx)(ee.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{onClick:S,children:"Done"})})]})]}),(0,r.jsxs)(ll.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access ",(0,r.jsxs)("a",{href:l,target:"_blank",children:[(0,r.jsx)("b",{children:l})," "]})]})]})]})},ls=t(42556);let la=[{name:"slack",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"langfuse",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"openmeter",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}}];var lr=e=>{let{accessToken:l,userRole:t,userID:s}=e,[a,o]=(0,n.useState)(la),[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)(!1),[h]=ea.Z.useForm(),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)([]),[y,f]=(0,n.useState)(""),[Z,_]=(0,n.useState)({}),[w,b]=(0,n.useState)([]),k=e=>{w.includes(e)?b(w.filter(l=>l!==e)):b([...w,e])},v={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)",daily_reports:"Weekly/Monthly Spend Reports"};(0,n.useEffect)(()=>{l&&t&&s&&q(l,s,t).then(e=>{console.log("callbacks",e);let l=la;o(l=l.map(l=>{let t=e.callbacks.find(e=>e.name===l.name);return t?{...l,variables:{...l.variables,...t.variables}}:l}));let t=e.alerts;if(console.log("alerts_data",t),t&&t.length>0){let e=t[0];console.log("_alert_info",e);let l=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",l),b(e.active_alerts),f(l),_(e.alerts_to_webhook)}c(t)})},[l,t,s]);let S=e=>w&&w.includes(e),N=e=>{if(!l)return;let t=Object.fromEntries(Object.entries(e.variables).map(e=>{var l;let[t,s]=e;return[t,(null===(l=document.querySelector('input[name="'.concat(t,'"]')))||void 0===l?void 0:l.value)||s]}));console.log("updatedVariables",t),console.log("updateAlertTypes",j);let s={environment_variables:t,litellm_settings:{success_callback:[e.name]}};try{V(l,s)}catch(e){u.ZP.error("Failed to update callback: "+e,20)}u.ZP.success("Callback updated successfully")},A=()=>{l&&h.validateFields().then(e=>{if(console.log("Form values:",e),"langfuse"===e.callback){V(l,{environment_variables:{LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey,OPENMETER_API_KEY:null}};o(a?[...a,t]:[t])}else if("slack"===e.callback){console.log("values.slackWebhookUrl: ".concat(e.slackWebhookUrl)),V(l,{general_settings:{alerting:["slack"],alerting_threshold:300},environment_variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl}}),console.log("values.callback: ".concat(e.callback));let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null}};o(a?[...a,t]:[t])}else if("openmeter"==e.callback){console.log("values.openMeterApiKey: ".concat(e.openMeterApiKey)),V(l,{environment_variables:{OPENMETER_API_KEY:e.openMeterApiKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:e.openMeterAPIKey}};o(a?[...a,t]:[t])}m(!1),h.resetFields(),p(null)})};return l?(console.log("callbacks: ".concat(a)),(0,r.jsxs)("div",{className:"w-full mx-4",children:[(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,r.jsx)(ll.Z,{title:"[UI] Presidio PII + Guardrails Coming Soon. https://docs.litellm.ai/docs/proxy/pii_masking",color:"sky"}),(0,r.jsxs)(eM.Z,{children:[(0,r.jsxs)(eL.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eR.Z,{value:"1",children:"Logging Callbacks"}),(0,r.jsx)(eR.Z,{value:"2",children:"Alerting"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Callback"}),(0,r.jsx)(e_.Z,{children:"Callback Env Vars"})]})}),(0,r.jsx)(ey.Z,{children:a.filter(e=>"slack"!==e.name).map((e,t)=>{var s;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ex.Z,{color:"emerald",children:e.name})}),(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)("ul",{children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).filter(l=>{let[t,s]=l;return t.toLowerCase().includes(e.name)}).map(e=>{let[l,t]=e;return(0,r.jsxs)("li",{children:[(0,r.jsx)(ee.Z,{className:"mt-2",children:l}),"LANGFUSE_HOST"===l?(0,r.jsx)("p",{children:"default value=https://cloud.langfuse.com"}):(0,r.jsx)("div",{}),(0,r.jsx)(H.Z,{name:l,defaultValue:t,type:"password"})]},l)})}),(0,r.jsx)(J.Z,{className:"mt-2",onClick:()=>N(e),children:"Save Changes"}),(0,r.jsx)(J.Z,{onClick:()=>z(l,e.name),className:"mx-2",children:"Test Callback"})]})]},t)})})]})})}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsxs)(ee.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from ",(0,r.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{}),(0,r.jsx)(e_.Z,{}),(0,r.jsx)(e_.Z,{children:"Slack Webhook URL"})]})}),(0,r.jsx)(ey.Z,{children:Object.entries(v).map((e,l)=>{let[t,s]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ls.Z,{id:"switch",name:"switch",checked:S(t),onChange:()=>k(t)})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ee.Z,{children:s})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(H.Z,{name:t,type:"password",defaultValue:Z&&Z[t]?Z[t]:y})})]},l)})})]}),(0,r.jsx)(J.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(v).forEach(l=>{let[t,s]=l,a=document.querySelector('input[name="'.concat(t,'"]'));console.log("key",t),console.log("webhookInput",a);let r=(null==a?void 0:a.value)||"";console.log("newWebhookValue",r),e[t]=r}),console.log("updatedAlertToWebhooks",e);let t={general_settings:{alert_to_webhook_url:e,alert_types:w}};console.log("payload",t);try{V(l,t)}catch(e){u.ZP.error("Failed to update alerts: "+e,20)}u.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,r.jsx)(J.Z,{onClick:()=>z(l,"slack"),className:"mx-2",children:"Test Alerts"})]})})]})]})]}),(0,r.jsx)(er.Z,{title:"Add Callback",visible:d,onOk:A,width:800,onCancel:()=>{m(!1),h.resetFields(),p(null)},footer:null,children:(0,r.jsxs)(ea.Z,{form:h,layout:"vertical",onFinish:A,children:[(0,r.jsx)(ea.Z.Item,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,r.jsxs)(es.default,{onChange:e=>{p(e)},children:[(0,r.jsx)(es.default.Option,{value:"langfuse",children:"langfuse"}),(0,r.jsx)(es.default.Option,{value:"openmeter",children:"openmeter"})]})}),"langfuse"===x&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"LANGFUSE_PUBLIC_KEY",name:"langfusePublicKey",rules:[{required:!0,message:"Please enter the public key"}],children:(0,r.jsx)(H.Z,{type:"password"})}),(0,r.jsx)(ea.Z.Item,{label:"LANGFUSE_PRIVATE_KEY",name:"langfusePrivateKey",rules:[{required:!0,message:"Please enter the private key"}],children:(0,r.jsx)(H.Z,{type:"password"})})]}),"openmeter"==x&&(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(ea.Z.Item,{label:"OPENMETER_API_KEY",name:"openMeterApiKey",rules:[{required:!0,message:"Please enter the openmeter api key"}],children:(0,r.jsx)(H.Z,{type:"password"})})}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:ln}=es.default;var lo=e=>{let{models:l,accessToken:t,routerSettings:s,setRouterSettings:a}=e,[o]=ea.Z.useForm(),[i,c]=(0,n.useState)(!1),[d,m]=(0,n.useState)("");return(0,r.jsxs)("div",{children:[(0,r.jsx)(J.Z,{className:"mx-auto",onClick:()=>c(!0),children:"+ Add Fallbacks"}),(0,r.jsx)(er.Z,{title:"Add Fallbacks",visible:i,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),o.resetFields()},children:(0,r.jsxs)(ea.Z,{form:o,onFinish:e=>{console.log(e);let{model_name:l,models:r}=e,n=[...s.fallbacks||[],{[l]:r}],i={...s,fallbacks:n};console.log(i);try{V(t,{router_settings:i}),a(i)}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully"),c(!1),o.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(ea.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,r.jsx)(eb.Z,{defaultValue:d,children:l&&l.map((e,l)=>(0,r.jsx)(ek.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,r.jsx)(ea.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,r.jsx)(eK.Z,{value:l,children:l&&l.filter(e=>e!=d).map(e=>(0,r.jsx)(eB.Z,{value:e,children:e},e))})})]}),(0,r.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,r.jsx)(ei.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},li=t(12968);async function lc(e,l){console.log("isLocal:",!1);let t=window.location.origin,s=new li.ZP.OpenAI({apiKey:l,baseURL:t,dangerouslyAllowBrowser:!0});try{let l=await s.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});u.ZP.success((0,r.jsxs)("span",{children:["Test model=",(0,r.jsx)("strong",{children:e}),", received model=",(0,r.jsx)("strong",{children:l.model}),". See ",(0,r.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}let ld={ttl:3600,lowest_latency_buffer:0},lm=e=>{let{selectedStrategy:l,strategyArgs:t,paramExplanation:s}=e;return(0,r.jsxs)($.Z,{children:[(0,r.jsx)(Q.Z,{className:"text-sm font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong",children:"Routing Strategy Specific Args"}),(0,r.jsx)(X.Z,{children:"latency-based-routing"==l?(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Setting"}),(0,r.jsx)(e_.Z,{children:"Value"})]})}),(0,r.jsx)(ey.Z,{children:Object.entries(t).map(e=>{let[l,t]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ee.Z,{children:l}),(0,r.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:s[l]})]}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(H.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]})}):(0,r.jsx)(ee.Z,{children:"No specific settings"})})]})};var lu=e=>{let{accessToken:l,userRole:t,userID:s,modelData:a}=e,[o,i]=(0,n.useState)({}),[c,d]=(0,n.useState)(!1),[m]=ea.Z.useForm(),[h,x]=(0,n.useState)(null),[p,j]=(0,n.useState)(null),[g,y]=(0,n.useState)(null),f={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request",ttl:"(int) Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"(float) Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};(0,n.useEffect)(()=>{l&&t&&s&&q(l,s,t).then(e=>{console.log("callbacks",e),i(e.router_settings)})},[l,t,s]);let Z=async e=>{if(l){console.log("received key: ".concat(e)),console.log("routerSettings['fallbacks']: ".concat(o.fallbacks)),o.fallbacks.map(l=>(e in l&&delete l[e],l));try{await V(l,{router_settings:o}),i({...o}),j(o.routing_strategy),u.ZP.success("Router settings updated successfully")}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}}},_=e=>{if(!l)return;console.log("router_settings",e);let t=Object.fromEntries(Object.entries(e).map(e=>{let[l,t]=e;if("routing_strategy_args"!==l&&"routing_strategy"!==l){var s;return[l,(null===(s=document.querySelector('input[name="'.concat(l,'"]')))||void 0===s?void 0:s.value)||t]}if("routing_strategy"==l)return[l,p];if("routing_strategy_args"==l&&"latency-based-routing"==p){let e={},l=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]');return(null==l?void 0:l.value)&&(e.lowest_latency_buffer=Number(l.value)),(null==t?void 0:t.value)&&(e.ttl=Number(t.value)),console.log("setRoutingStrategyArgs: ".concat(e)),["routing_strategy_args",e]}return null}).filter(e=>null!=e));console.log("updatedVariables",t);try{V(l,{router_settings:t})}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully")};return l?(0,r.jsx)("div",{className:"w-full mx-4",children:(0,r.jsxs)(eM.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,r.jsxs)(eL.Z,{variant:"line",defaultValue:"1",children:[(0,r.jsx)(eR.Z,{value:"1",children:"General Settings"}),(0,r.jsx)(eR.Z,{value:"2",children:"Fallbacks"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,r.jsx)(el.Z,{children:"Router Settings"}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Setting"}),(0,r.jsx)(e_.Z,{children:"Value"})]})}),(0,r.jsx)(ey.Z,{children:Object.entries(o).filter(e=>{let[l,t]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l&&"routing_strategy_args"!=l}).map(e=>{let[l,t]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsxs)(ef.Z,{children:[(0,r.jsx)(ee.Z,{children:l}),(0,r.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:f[l]})]}),(0,r.jsx)(ef.Z,{children:"routing_strategy"==l?(0,r.jsxs)(eb.Z,{defaultValue:t,className:"w-full max-w-md",onValueChange:j,children:[(0,r.jsx)(ek.Z,{value:"usage-based-routing",children:"usage-based-routing"}),(0,r.jsx)(ek.Z,{value:"latency-based-routing",children:"latency-based-routing"}),(0,r.jsx)(ek.Z,{value:"simple-shuffle",children:"simple-shuffle"})]}):(0,r.jsx)(H.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]}),(0,r.jsx)(lm,{selectedStrategy:p,strategyArgs:o&&o.routing_strategy_args&&Object.keys(o.routing_strategy_args).length>0?o.routing_strategy_args:ld,paramExplanation:f})]}),(0,r.jsx)(Y.Z,{children:(0,r.jsx)(J.Z,{className:"mt-2",onClick:()=>_(o),children:"Save Changes"})})]})}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)(eg.Z,{children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"Model Name"}),(0,r.jsx)(e_.Z,{children:"Fallbacks"})]})}),(0,r.jsx)(ey.Z,{children:o.fallbacks&&o.fallbacks.map((e,t)=>Object.entries(e).map(e=>{let[s,a]=e;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:s}),(0,r.jsx)(ef.Z,{children:Array.isArray(a)?a.join(", "):a}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(J.Z,{onClick:()=>lc(s,l),children:"Test Fallback"})}),(0,r.jsx)(ef.Z,{children:(0,r.jsx)(ej.Z,{icon:eh.Z,size:"sm",onClick:()=>Z(s)})})]},t.toString()+s)}))})]}),(0,r.jsx)(lo,{models:(null==a?void 0:a.data)?a.data.map(e=>e.model_name):[],accessToken:l,routerSettings:o,setRouterSettings:i})]})]})]})}):null},lh=t(67951),lx=e=>{let{}=e;return(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(W.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsxs)("div",{className:"mb-5",children:[(0,r.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,r.jsx)(ee.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,r.jsxs)(eM.Z,{children:[(0,r.jsxs)(eL.Z,{children:[(0,r.jsx)(eR.Z,{children:"OpenAI Python SDK"}),(0,r.jsx)(eR.Z,{children:"LlamaIndex"}),(0,r.jsx)(eR.Z,{children:"Langchain Py"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsx)(lh.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n '})}),(0,r.jsx)(eU.Z,{children:(0,r.jsx)(lh.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n '})}),(0,r.jsx)(eU.Z,{children:(0,r.jsx)(lh.Z,{language:"python",children:'\nfrom langchain.chat_models import ChatOpenAI\nfrom langchain.prompts.chat import (\n ChatPromptTemplate,\n HumanMessagePromptTemplate,\n SystemMessagePromptTemplate,\n)\nfrom langchain.schema import HumanMessage, SystemMessage\n\nchat = ChatOpenAI(\n openai_api_base="http://0.0.0.0:4000",\n model = "gpt-3.5-turbo",\n temperature=0.1\n)\n\nmessages = [\n SystemMessage(\n content="You are a helpful assistant that im using to make a test request to."\n ),\n HumanMessage(\n content="test from litellm. tell me why it\'s amazing in 1 sentence"\n ),\n]\nresponse = chat(messages)\n\nprint(response)\n\n '})})]})]})]})})})};async function lp(e,l,t,s){console.log("isLocal:",!1);let a=window.location.origin,r=new li.ZP.OpenAI({apiKey:s,baseURL:a,dangerouslyAllowBrowser:!0});try{for await(let s of(await r.chat.completions.create({model:t,stream:!0,messages:[{role:"user",content:e}]})))console.log(s),s.choices[0].delta.content&&l(s.choices[0].delta.content)}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var lj=e=>{let{accessToken:l,token:t,userRole:s,userID:a}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)(""),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)(void 0),[p,j]=(0,n.useState)([]);(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{let e=await N(l,a,s);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));console.log(l),j(l),x(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,a,s]);let g=(e,l)=>{u(t=>{let s=t[t.length-1];return s&&s.role===e?[...t.slice(0,t.length-1),{role:e,content:s.content+l}]:[...t,{role:e,content:l}]})},y=async()=>{if(""!==c.trim()&&o&&t&&s&&a){u(e=>[...e,{role:"user",content:c}]);try{h&&await lp(c,e=>g("assistant",e),h,o)}catch(e){console.error("Error fetching model response",e),g("assistant","Error fetching model response")}d("")}};if(s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=eT.default;return(0,r.jsxs)("div",{children:[(0,r.jsx)(e,{level:1,children:"Access Denied"}),(0,r.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,r.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,r.jsx)(W.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,r.jsx)(ep.Z,{children:(0,r.jsxs)(eM.Z,{children:[(0,r.jsx)(eL.Z,{children:(0,r.jsx)(eR.Z,{children:"Chat"})}),(0,r.jsx)(eD.Z,{children:(0,r.jsxs)(eU.Z,{children:[(0,r.jsx)("div",{className:"sm:max-w-2xl",children:(0,r.jsxs)(W.Z,{numItems:2,children:[(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(ee.Z,{children:"API Key"}),(0,r.jsx)(H.Z,{placeholder:"Type API Key here",type:"password",onValueChange:i,value:o})]}),(0,r.jsxs)(Y.Z,{className:"mx-2",children:[(0,r.jsx)(ee.Z,{children:"Select Model:"}),(0,r.jsx)(es.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),x(e)},options:p,style:{width:"200px"}})]})]})}),(0,r.jsxs)(eg.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsx)(ew.Z,{children:(0,r.jsx)(ef.Z,{})})}),(0,r.jsx)(ey.Z,{children:m.map((e,l)=>(0,r.jsx)(ew.Z,{children:(0,r.jsx)(ef.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,r.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,r.jsxs)("div",{className:"flex",children:[(0,r.jsx)(H.Z,{type:"text",value:c,onChange:e=>d(e.target.value),placeholder:"Type your message..."}),(0,r.jsx)(J.Z,{onClick:y,className:"ml-2",children:"Send"})]})})]})})]})})})})},lg=t(33509),ly=t(95781);let{Sider:lf}=lg.default;var lZ=e=>{let{setPage:l,userRole:t,defaultSelectedKey:s}=e;return"Admin Viewer"==t?(0,r.jsx)(lg.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,r.jsx)(lf,{width:120,children:(0,r.jsxs)(ly.Z,{mode:"inline",defaultSelectedKeys:s||["4"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(ly.Z.Item,{onClick:()=>l("api-keys"),children:"API Keys"},"4"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("models"),children:"Models"},"2"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("llm-playground"),children:"Chat UI"},"3"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")]})})}):(0,r.jsx)(lg.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,r.jsx)(lf,{width:145,children:(0,r.jsxs)(ly.Z,{mode:"inline",defaultSelectedKeys:s||["1"],style:{height:"100%",borderRight:0},children:[(0,r.jsx)(ly.Z.Item,{onClick:()=>l("api-keys"),children:(0,r.jsx)(ee.Z,{children:"API Keys"})},"1"),(0,r.jsx)(ly.Z.Item,{onClick:()=>l("llm-playground"),children:(0,r.jsx)(ee.Z,{children:"Test Key"})},"3"),"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("models"),children:(0,r.jsx)(ee.Z,{children:"Models"})},"2"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("usage"),children:(0,r.jsx)(ee.Z,{children:"Usage"})},"4"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("teams"),children:(0,r.jsx)(ee.Z,{children:"Teams"})},"6"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("users"),children:(0,r.jsx)(ee.Z,{children:"Users"})},"5"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("settings"),children:(0,r.jsx)(ee.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("general-settings"),children:(0,r.jsx)(ee.Z,{children:"Router Settings"})},"9"):null,"Admin"==t?(0,r.jsx)(ly.Z.Item,{onClick:()=>l("admin-panel"),children:(0,r.jsx)(ee.Z,{children:"Admin"})},"7"):null,(0,r.jsx)(ly.Z.Item,{onClick:()=>l("api_ref"),children:(0,r.jsx)(ee.Z,{children:"API Reference"})},"11")]})})})},l_=t(67989),lw=e=>{let{accessToken:l,token:t,userRole:s,userID:a,keys:o}=e,i=new Date,[c,d]=(0,n.useState)([]),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)([]),[p,j]=(0,n.useState)([]),[g,y]=(0,n.useState)([]),[f,Z]=(0,n.useState)([]),[_,w]=(0,n.useState)([]),[b,k]=(0,n.useState)([]),[v,S]=(0,n.useState)(""),[N,R]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),M=new Date(i.getFullYear(),i.getMonth(),1),L=new Date(i.getFullYear(),i.getMonth()+1,0),U=z(M),D=z(L);console.log("keys in usage",o);let K=async(e,t,s)=>{if(!e||!t||!l)return;console.log("uiSelectedKey",s);let a=await T(l,s,e.toISOString(),t.toISOString());console.log("End user data updated successfully",a),j(a)},B=async(e,t)=>{e&&t&&l&&(Z((await E(l,e.toISOString(),t.toISOString())).spend_per_tag),console.log("Tag spend data updated successfully"))};function z(e){let l=e.getFullYear(),t=e.getMonth()+1,s=e.getDate();return"".concat(l,"-").concat(t<10?"0"+t:t,"-").concat(s<10?"0"+s:s)}return console.log("Start date is ".concat(U)),console.log("End date is ".concat(D)),(0,n.useEffect)(()=>{l&&t&&s&&a&&(async()=>{try{if(console.log("user role: ".concat(s)),"Admin"==s||"Admin Viewer"==s){var e,r;let t=await C(l);d(t);let s=(await P(l)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,10),spend:e.total_spend}));u(s);let a=(await O(l)).map(e=>({key:e.model,spend:e.total_spend}));x(a);let n=await A(l);console.log("teamSpend",n),y(n.daily_spend),w(n.teams);let o=n.total_spend_per_team;o=o.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e)),k(o);let i=await E(l,null===(e=N.from)||void 0===e?void 0:e.toISOString(),null===(r=N.to)||void 0===r?void 0:r.toISOString());Z(i.spend_per_tag);let c=await T(l,null,void 0,void 0);j(c),console.log("spend/user result",c)}else"App Owner"==s&&await I(l,t,s,a,U,D).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),d(l);let t=e.top_api_keys;u(t)}else{let t=(await F(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[t,s]=e;"spend"!==t&&"startTime"!==t&&"models"!==t&&"users"!==t&&l.push({key:t,spend:s})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let t=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(t[0]))),t}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));u(t),d(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[l,t,s,a,U,D]),(0,r.jsxs)("div",{style:{width:"100%"},className:"p-8",children:[(0,r.jsx)(eE,{userID:a,userRole:s,accessToken:l,userSpend:null,selectedTeam:null}),(0,r.jsxs)(eM.Z,{children:[(0,r.jsxs)(eL.Z,{className:"mt-2",children:[(0,r.jsx)(eR.Z,{children:"All Up"}),(0,r.jsx)(eR.Z,{children:"Team Based Usage"}),(0,r.jsx)(eR.Z,{children:"End User Usage"}),(0,r.jsx)(eR.Z,{children:"Tag Based Usage"})]}),(0,r.jsxs)(eD.Z,{children:[(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsx)(Y.Z,{numColSpan:2,children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Monthly Spend"}),(0,r.jsx)(eq.Z,{data:c,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Top API Keys"}),(0,r.jsx)(eq.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,r.jsx)(Y.Z,{numColSpan:1,children:(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Top Models"}),(0,r.jsx)(eq.Z,{className:"mt-4 h-40",data:h,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,r.jsx)(Y.Z,{numColSpan:1})]})}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,r.jsxs)(Y.Z,{numColSpan:2,children:[(0,r.jsxs)(ep.Z,{className:"mb-2",children:[(0,r.jsx)(el.Z,{children:"Total Spend Per Team"}),(0,r.jsx)(l_.Z,{data:b})]}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Daily Spend Per Team"}),(0,r.jsx)(eq.Z,{className:"h-72",data:g,showLegend:!0,index:"date",categories:_,yAxisWidth:80,colors:["blue","green","yellow","red","purple"],stack:!0})]})]}),(0,r.jsx)(Y.Z,{numColSpan:2})]})}),(0,r.jsxs)(eU.Z,{children:[(0,r.jsxs)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:["End-Users of your LLM API calls. Tracked when a `user` param is passed in your LLM calls ",(0,r.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/users",target:"_blank",children:"docs here"})]}),(0,r.jsxs)(W.Z,{numItems:2,children:[(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Time Range"}),(0,r.jsx)(eF.Z,{enableSelect:!0,value:N,onValueChange:e=>{R(e),K(e.from,e.to,null)}})]}),(0,r.jsxs)(Y.Z,{children:[(0,r.jsx)(ee.Z,{children:"Select Key"}),(0,r.jsxs)(eb.Z,{defaultValue:"all-keys",children:[(0,r.jsx)(ek.Z,{value:"all-keys",onClick:()=>{K(N.from,N.to,null)},children:"All Keys"},"all-keys"),null==o?void 0:o.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,r.jsx)(ek.Z,{value:String(l),onClick:()=>{K(N.from,N.to,e.token)},children:e.key_alias},l):null)]})]})]}),(0,r.jsx)(ep.Z,{className:"mt-4",children:(0,r.jsxs)(eg.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,r.jsx)(eZ.Z,{children:(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(e_.Z,{children:"End User"}),(0,r.jsx)(e_.Z,{children:"Spend"}),(0,r.jsx)(e_.Z,{children:"Total Events"})]})}),(0,r.jsx)(ey.Z,{children:null==p?void 0:p.map((e,l)=>{var t;return(0,r.jsxs)(ew.Z,{children:[(0,r.jsx)(ef.Z,{children:e.end_user}),(0,r.jsx)(ef.Z,{children:null===(t=e.total_spend)||void 0===t?void 0:t.toFixed(4)}),(0,r.jsx)(ef.Z,{children:e.total_count})]},l)})})]})})]}),(0,r.jsx)(eU.Z,{children:(0,r.jsxs)(W.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,r.jsxs)(Y.Z,{numColSpan:2,children:[(0,r.jsx)(eF.Z,{className:"mb-4",enableSelect:!0,value:N,onValueChange:e=>{R(e),B(e.from,e.to)}}),(0,r.jsxs)(ep.Z,{children:[(0,r.jsx)(el.Z,{children:"Spend Per Tag"}),(0,r.jsxs)(ee.Z,{children:["Get Started Tracking cost per tag ",(0,r.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags",target:"_blank",children:"here"})]}),(0,r.jsx)(eq.Z,{className:"h-72",data:f,index:"name",categories:["spend"],colors:["blue"]})]})]}),(0,r.jsx)(Y.Z,{numColSpan:2})]})})]})]})]})},lb=()=>{let{Title:e,Paragraph:l}=eT.default,[t,s]=(0,n.useState)(""),[a,i]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,o.useSearchParams)(),[g,y]=(0,n.useState)({data:[]}),f=j.get("userID"),Z=j.get("token"),[_,w]=(0,n.useState)("api-keys"),[b,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,eP.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),s(l),"Admin Viewer"==l&&w("usage")}else console.log("User role not defined");e.user_email?i(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[Z]),(0,r.jsx)(n.Suspense,{fallback:(0,r.jsx)("div",{children:"Loading..."}),children:(0,r.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,r.jsx)(m,{userID:f,userRole:t,userEmail:a,showSSOBanner:x}),(0,r.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,r.jsx)("div",{className:"mt-8",children:(0,r.jsx)(lZ,{setPage:w,userRole:t,defaultSelectedKey:null})}),"api-keys"==_?(0,r.jsx)(eO,{userID:f,userRole:t,teams:c,keys:u,setUserRole:s,userEmail:a,setUserEmail:i,setTeams:d,setKeys:h}):"models"==_?(0,r.jsx)(e3,{userID:f,userRole:t,token:Z,accessToken:b,modelData:g,setModelData:y}):"llm-playground"==_?(0,r.jsx)(lj,{userID:f,userRole:t,token:Z,accessToken:b}):"users"==_?(0,r.jsx)(e9,{userID:f,userRole:t,token:Z,keys:u,teams:c,accessToken:b,setKeys:h}):"teams"==_?(0,r.jsx)(le,{teams:c,setTeams:d,searchParams:j,accessToken:b,userID:f,userRole:t}):"admin-panel"==_?(0,r.jsx)(lt,{setTeams:d,searchParams:j,accessToken:b,showSSOBanner:x}):"api_ref"==_?(0,r.jsx)(lx,{}):"settings"==_?(0,r.jsx)(lr,{userID:f,userRole:t,accessToken:b}):"general-settings"==_?(0,r.jsx)(lu,{userID:f,userRole:t,accessToken:b,modelData:g}):(0,r.jsx)(lw,{userID:f,userRole:t,token:Z,accessToken:b,keys:u})]})]})})}}},function(e){e.O(0,[936,884,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]);
\ No newline at end of file
diff --git a/ui/litellm-dashboard/out/_next/static/chunks/app/page-c35c14c9afd091ec.js b/ui/litellm-dashboard/out/_next/static/chunks/app/page-c35c14c9afd091ec.js
new file mode 100644
index 0000000000..e8b5c33a1c
--- /dev/null
+++ b/ui/litellm-dashboard/out/_next/static/chunks/app/page-c35c14c9afd091ec.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,4858))},4858:function(e,l,t){"use strict";t.r(l),t.d(l,{default:function(){return lS}});var s,r,a=t(3827),n=t(64090),o=t(47907),i=t(8792),c=t(40491),d=t(65270),m=e=>{let{userID:l,userRole:t,userEmail:s,showSSOBanner:r}=e;console.log("User ID:",l),console.log("userEmail:",s),console.log("showSSOBanner:",r);let n=[{key:"1",label:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("p",{children:["Role: ",t]}),(0,a.jsxs)("p",{children:["ID: ",l]})]})}];return(0,a.jsxs)("nav",{className:"left-0 right-0 top-0 flex justify-between items-center h-12 mb-4",children:[(0,a.jsx)("div",{className:"text-left my-2 absolute top-0 left-0",children:(0,a.jsx)("div",{className:"flex flex-col items-center",children:(0,a.jsx)(i.default,{href:"/",children:(0,a.jsx)("button",{className:"text-gray-800 rounded text-center",children:(0,a.jsx)("img",{src:"/get_image",width:160,height:160,alt:"LiteLLM Brand",className:"mr-2"})})})})}),(0,a.jsxs)("div",{className:"text-right mx-4 my-2 absolute top-0 right-0 flex items-center justify-end space-x-2",children:[r?(0,a.jsx)("div",{style:{padding:"6px",borderRadius:"8px"},children:(0,a.jsx)("a",{href:"https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat",target:"_blank",style:{fontSize:"14px",textDecoration:"underline"},children:"Request hosted proxy"})}):null,(0,a.jsx)("div",{style:{border:"1px solid #391085",padding:"6px",borderRadius:"8px"},children:(0,a.jsx)(c.Z,{menu:{items:n},children:(0,a.jsx)(d.Z,{children:s})})})]})]})},u=t(80588);let h=async()=>{try{let e=await fetch("https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json"),l=await e.json();return console.log("received data: ".concat(l)),l}catch(e){throw console.error("Failed to get model cost map:",e),e}},x=async(e,l)=>{try{let t=await fetch("/model/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model created successfully. Wait 60s and refresh on 'All Models' page"),s}catch(e){throw console.error("Failed to create key:",e),e}},p=async(e,l)=>{console.log("model_id in model delete call: ".concat(l));try{let t=await fetch("/model/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({id:l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),u.ZP.success("Model deleted successfully. Restart server to see this."),s}catch(e){throw console.error("Failed to create key:",e),e}},j=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/key/generate",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},g=async(e,l,t)=>{try{if(console.log("Form Values in keyCreateCall:",t),t.description&&(t.metadata||(t.metadata={}),t.metadata.description=t.description,delete t.description,t.metadata=JSON.stringify(t.metadata)),t.metadata){console.log("formValues.metadata:",t.metadata);try{t.metadata=JSON.parse(t.metadata)}catch(e){throw u.ZP.error("Failed to parse metadata: "+e,10),Error("Failed to parse metadata: "+e)}}console.log("Form Values after check:",t);let s=await fetch("/user/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({user_id:l,...t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},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 u.ZP.error("Failed to delete key: "+e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},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 u.ZP.error("Failed to delete team: "+e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to delete key:",e),e}},Z=async function(e,l,t){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3],r=arguments.length>4?arguments[4]:void 0,a=arguments.length>5?arguments[5]:void 0;try{let n="/user/info";"App Owner"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),"App User"==t&&l&&(n="".concat(n,"?user_id=").concat(l)),console.log("in userInfoCall viewAll=",s),s&&a&&null!=r&&void 0!=r&&(n="".concat(n,"?view_all=true&page=").concat(r,"&page_size=").concat(a));let o=await fetch(n,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!o.ok){let e=await o.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let i=await o.json();return console.log("API Response:",i),i}catch(e){throw console.error("Failed to create key:",e),e}},_=async(e,l)=>{try{let t="/team/info";l&&(t="".concat(t,"?team_id=").concat(l)),console.log("in teamInfoCall");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},w=async e=>{try{let l=await fetch("/global/spend",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},b=async(e,l,t)=>{try{let l=await fetch("/v2/model/info",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log("modelInfoCall:",t),t}catch(e){throw console.error("Failed to create key:",e),e}},k=async(e,l,t,s,r,a)=>{try{let l="/model/metrics";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(r,"&endTime=").concat(a));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},v=async(e,l,t,s,r,a)=>{try{let l="/model/metrics/slow_responses";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(r,"&endTime=").concat(a));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},S=async(e,l,t,s,r,a)=>{try{let l="/model/metrics/exceptions";s&&(l="".concat(l,"?_selected_model_group=").concat(s,"&startTime=").concat(r,"&endTime=").concat(a));let t=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to create key:",e),e}},N=async(e,l,t)=>{try{let l=await fetch("/models",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to create key:",e),e}},A=async e=>{try{let l="/global/spend/teams";console.log("in teamSpendLogsCall:",l);let t=await fetch("".concat(l),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},E=async(e,l,t)=>{try{let s="/global/spend/tags";l&&t&&(s="".concat(s,"?start_date=").concat(l,"&end_date=").concat(t)),console.log("in tagsSpendLogsCall:",s);let r=await fetch("".concat(s),{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!r.ok){let e=await r.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let a=await r.json();return console.log(a),a}catch(e){throw console.error("Failed to create key:",e),e}},I=async(e,l,t,s,r,a)=>{try{console.log("user role in spend logs call: ".concat(t));let l="/spend/logs";l="App Owner"==t?"".concat(l,"?user_id=").concat(s,"&start_date=").concat(r,"&end_date=").concat(a):"".concat(l,"?start_date=").concat(r,"&end_date=").concat(a);let n=await fetch(l,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},C=async e=>{try{let l=await fetch("/global/spend/logs",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},P=async e=>{try{let l=await fetch("/global/spend/keys?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},T=async(e,l,t,s)=>{try{let r="";r=l?JSON.stringify({api_key:l,startTime:t,endTime:s}):JSON.stringify({startTime:t,endTime:s});let a={method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}};a.body=r;let n=await fetch("/global/spend/end_users",a);if(!n.ok){let e=await n.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let o=await n.json();return console.log(o),o}catch(e){throw console.error("Failed to create key:",e),e}},O=async e=>{try{let l=await fetch("/global/spend/models?limit=5",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let t=await l.json();return console.log(t),t}catch(e){throw console.error("Failed to create key:",e),e}},F=async(e,l)=>{try{let t=await fetch("/v2/key/info",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({keys:l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let s=await t.json();return console.log(s),s}catch(e){throw console.error("Failed to create key:",e),e}},R=async(e,l)=>{try{let t="/user/get_users?role=".concat(l);console.log("in userGetAllUsersCall:",t);let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to delete key: "+e,10),Error("Network response was not ok")}let r=await s.json();return console.log(r),r}catch(e){throw console.error("Failed to get requested models:",e),e}},M=async(e,l)=>{try{console.log("Form Values in teamCreateCall:",l);let t=await fetch("/team/new",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("API Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},L=async(e,l)=>{try{console.log("Form Values in keyUpdateCall:",l);let t=await fetch("/key/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update key Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},U=async(e,l)=>{try{console.log("Form Values in teamUpateCall:",l);let t=await fetch("/team/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update team: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update Team Response:",s),s}catch(e){throw console.error("Failed to create key:",e),e}},D=async(e,l)=>{try{console.log("Form Values in modelUpateCall:",l);let t=await fetch("/model/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error("Failed to update model: "+e,10),console.error("Error update from the server:",e),Error("Network response was not ok")}let s=await t.json();return console.log("Update model Response:",s),s}catch(e){throw console.error("Failed to update model:",e),e}},K=async(e,l,t)=>{try{console.log("Form Values in teamMemberAddCall:",t);let s=await fetch("/team/member_add",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({team_id:l,member:t})});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let r=await s.json();return console.log("API Response:",r),r}catch(e){throw console.error("Failed to create key:",e),e}},B=async(e,l,t)=>{try{console.log("Form Values in userUpdateUserCall:",l);let s={...l};null!==t&&(s.user_role=t),s=JSON.stringify(s);let r=await fetch("/user/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:s});if(!r.ok){let e=await r.text();throw u.ZP.error("Failed to create key: "+e,10),console.error("Error response from the server:",e),Error("Network response was not ok")}let a=await r.json();return console.log("API Response:",a),a}catch(e){throw console.error("Failed to create key:",e),e}},z=async(e,l)=>{try{let t="/health/services?service=".concat(l);console.log("Checking Slack Budget Alerts service health");let s=await fetch(t,{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!s.ok){let e=await s.text();throw u.ZP.error("Failed ".concat(l," service health check ")+e),Error(e)}let r=await s.json();return u.ZP.success("Test request to ".concat(l," made - check logs/alerts on ").concat(l," to verify")),r}catch(e){throw console.error("Failed to perform health check:",e),e}},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 u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},q=async e=>{try{let l=await fetch("/config/list?config_type=general_settings",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to get callbacks:",e),e}},G=async(e,l,t)=>{try{let s=await fetch("/config/field/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({field_name:l,field_value:t,config_type:"general_settings"})});if(!s.ok){let e=await s.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let r=await s.json();return u.ZP.success("Successfully updated value!"),r}catch(e){throw console.error("Failed to set callbacks:",e),e}},Y=async(e,l)=>{try{let t=await fetch("/config/field/delete",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({field_name:l,config_type:"general_settings"})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}let s=await t.json();return u.ZP.success("Field reset on proxy"),s}catch(e){throw console.error("Failed to get callbacks:",e),e}},W=async(e,l)=>{try{let t=await fetch("/config/update",{method:"POST",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"},body:JSON.stringify({...l})});if(!t.ok){let e=await t.text();throw u.ZP.error(e,10),Error("Network response was not ok")}return await t.json()}catch(e){throw console.error("Failed to set callbacks:",e),e}},J=async e=>{try{let l=await fetch("/health",{method:"GET",headers:{Authorization:"Bearer ".concat(e),"Content-Type":"application/json"}});if(!l.ok){let e=await l.text();throw u.ZP.error(e),Error("Network response was not ok")}return await l.json()}catch(e){throw console.error("Failed to call /health:",e),e}};var H=t(10384),$=t(46453),X=t(16450),Q=t(52273),ee=t(26780),el=t(15595),et=t(6698),es=t(71801),er=t(42440),ea=t(42308),en=t(50670),eo=t(81583),ei=t(99129),ec=t(44839),ed=t(88707),em=t(1861);let{Option:eu}=en.default;var eh=e=>{let{userID:l,team:t,userRole:s,accessToken:r,data:o,setData:i}=e,[c]=eo.Z.useForm(),[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(null),[p,g]=(0,n.useState)(null),[f,y]=(0,n.useState)([]),[Z,_]=(0,n.useState)([]),w=()=>{m(!1),c.resetFields()},b=()=>{m(!1),x(null),c.resetFields()};(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===s)return;if(null!==r){let e=(await N(r,l,s)).data.map(e=>e.id);console.log("available_model_names:",e),y(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[r,l,s]);let k=async e=>{try{var t,s,a;let n=null!==(t=null==e?void 0:e.key_alias)&&void 0!==t?t:"",d=null!==(s=null==e?void 0:e.team_id)&&void 0!==s?s:null;if((null!==(a=null==o?void 0:o.filter(e=>e.team_id===d).map(e=>e.key_alias))&&void 0!==a?a:[]).includes(n))throw Error("Key alias ".concat(n," already exists for team with ID ").concat(d,", please provide another key alias"));u.ZP.info("Making API Call"),m(!0);let h=await j(r,l,e);console.log("key create Response:",h),i(e=>e?[...e,h]:[h]),x(h.key),g(h.soft_budget),u.ZP.success("API Key Created"),c.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the key:",e),u.ZP.error("Error creating the key: ".concat(e),20)}};return(0,n.useEffect)(()=>{_(t&&t.models.length>0?t.models.includes("all-proxy-models")?f:t.models:f)},[t,f]),(0,a.jsxs)("div",{children:[(0,a.jsx)(X.Z,{className:"mx-auto",onClick:()=>m(!0),children:"+ Create New Key"}),(0,a.jsx)(ei.Z,{title:"Create Key",visible:d,width:800,footer:null,onOk:w,onCancel:b,children:(0,a.jsxs)(eo.Z,{form:c,onFinish:k,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(Q.Z,{placeholder:""})}),(0,a.jsx)(eo.Z.Item,{label:"Team ID",name:"team_id",hidden:!0,initialValue:t?t.team_id:null,valuePropName:"team_id",className:"mt-8",children:(0,a.jsx)(ec.Z,{value:t?t.team_alias:"",disabled:!0})}),(0,a.jsx)(eo.Z.Item,{label:"Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsxs)(en.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},onChange:e=>{e.includes("all-team-models")&&c.setFieldsValue({models:["all-team-models"]})},children:[(0,a.jsx)(eu,{value:"all-team-models",children:"All Team Models"},"all-team-models"),Z.map(e=>(0,a.jsx)(eu,{value:e,children:e},e))]})}),(0,a.jsxs)(ee.Z,{className:"mt-20 mb-8",children:[(0,a.jsx)(et.Z,{children:(0,a.jsx)("b",{children:"Optional Settings"})}),(0,a.jsxs)(el.Z,{children:[(0,a.jsx)(eo.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: $".concat((null==t?void 0:t.max_budget)!==null&&(null==t?void 0:t.max_budget)!==void 0?null==t?void 0:t.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.max_budget&&l>t.max_budget)throw Error("Budget cannot exceed team max budget: $".concat(t.max_budget))}}],children:(0,a.jsx)(ed.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(eo.Z.Item,{className:"mt-8",label:"Reset Budget",name:"budget_duration",help:"Team Reset Budget: ".concat((null==t?void 0:t.budget_duration)!==null&&(null==t?void 0:t.budget_duration)!==void 0?null==t?void 0:t.budget_duration:"None"),children:(0,a.jsxs)(en.default,{defaultValue:null,placeholder:"n/a",children:[(0,a.jsx)(en.default.Option,{value:"24h",children:"daily"}),(0,a.jsx)(en.default.Option,{value:"30d",children:"monthly"})]})}),(0,a.jsx)(eo.Z.Item,{className:"mt-8",label:"Tokens per minute Limit (TPM)",name:"tpm_limit",help:"TPM cannot exceed team TPM limit: ".concat((null==t?void 0:t.tpm_limit)!==null&&(null==t?void 0:t.tpm_limit)!==void 0?null==t?void 0:t.tpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.tpm_limit&&l>t.tpm_limit)throw Error("TPM limit cannot exceed team TPM limit: ".concat(t.tpm_limit))}}],children:(0,a.jsx)(ed.Z,{step:1,width:400})}),(0,a.jsx)(eo.Z.Item,{className:"mt-8",label:"Requests per minute Limit (RPM)",name:"rpm_limit",help:"RPM cannot exceed team RPM limit: ".concat((null==t?void 0:t.rpm_limit)!==null&&(null==t?void 0:t.rpm_limit)!==void 0?null==t?void 0:t.rpm_limit:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&t&&null!==t.rpm_limit&&l>t.rpm_limit)throw Error("RPM limit cannot exceed team RPM limit: ".concat(t.rpm_limit))}}],children:(0,a.jsx)(ed.Z,{step:1,width:400})}),(0,a.jsx)(eo.Z.Item,{label:"Expire Key (eg: 30s, 30h, 30d)",name:"duration",className:"mt-8",children:(0,a.jsx)(Q.Z,{placeholder:""})}),(0,a.jsx)(eo.Z.Item,{label:"Metadata",name:"metadata",children:(0,a.jsx)(ec.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})})]})]})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Create Key"})})]})}),h&&(0,a.jsx)(ei.Z,{visible:d,onOk:w,onCancel:b,footer:null,children:(0,a.jsxs)($.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(er.Z,{children:"Save your Key"}),(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Please save this secret key somewhere safe and accessible. For security reasons, ",(0,a.jsx)("b",{children:"you will not be able to view it again"})," ","through your LiteLLM account. If you lose this secret key, you will need to generate a new one."]})}),(0,a.jsx)(H.Z,{numColSpan:1,children:null!=h?(0,a.jsxs)("div",{children:[(0,a.jsx)(es.Z,{className:"mt-3",children:"API Key:"}),(0,a.jsx)("div",{style:{background:"#f8f8f8",padding:"10px",borderRadius:"5px",marginBottom:"10px"},children:(0,a.jsx)("pre",{style:{wordWrap:"break-word",whiteSpace:"normal"},children:h})}),(0,a.jsx)(ea.CopyToClipboard,{text:h,onCopy:()=>{u.ZP.success("API Key copied to clipboard")},children:(0,a.jsx)(X.Z,{className:"mt-3",children:"Copy API Key"})})]}):(0,a.jsx)(es.Z,{children:"Key being created, this might take 30s"})})]})})]})},ex=t(9454),ep=t(98941),ej=t(33393),eg=t(5),ef=t(13810),ey=t(61244),eZ=t(10827),e_=t(3851),ew=t(2044),eb=t(64167),ek=t(74480),ev=t(7178),eS=t(95093),eN=t(27166);let{Option:eA}=en.default;var eE=e=>{let{userID:l,userRole:t,accessToken:s,selectedTeam:r,data:o,setData:i,teams:c}=e,[d,m]=(0,n.useState)(!1),[h,x]=(0,n.useState)(!1),[p,j]=(0,n.useState)(null),[g,y]=(0,n.useState)(null),[Z,_]=(0,n.useState)(null),[w,b]=(0,n.useState)(""),[k,v]=(0,n.useState)(!1),[S,A]=(0,n.useState)(!1),[E,I]=(0,n.useState)(null),[C,P]=(0,n.useState)([]),T=new Set,[O,F]=(0,n.useState)(T);(0,n.useEffect)(()=>{(async()=>{try{if(null===l)return;if(null!==s&&null!==t){let e=(await N(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),P(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[s,l,t]),(0,n.useEffect)(()=>{if(c){let e=new Set;c.forEach((l,t)=>{let s=l.team_id;e.add(s)}),F(e)}},[c]);let R=e=>{console.log("handleEditClick:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),I(e),v(!0)},M=async e=>{if(null==s)return;let l=e.token;e.key=l,console.log("handleEditSubmit:",e);let t=await L(s,e);console.log("handleEditSubmit: newKeyValues",t),o&&i(o.map(e=>e.token===l?t:e)),u.ZP.success("Key updated successfully"),v(!1),I(null)},U=async e=>{console.log("handleDelete:",e),null==e.token&&null!==e.token_id&&(e.token=e.token_id),null!=o&&(j(e.token),localStorage.removeItem("userData"+l),x(!0))},D=async()=>{if(null!=p&&null!=o){try{await 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,a.jsxs)("div",{children:[(0,a.jsxs)(ef.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh] mb-4 mt-2",children:[(0,a.jsxs)(eZ.Z,{className:"mt-5 max-h-[300px] min-h-[300px]",children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Key Alias"}),(0,a.jsx)(ek.Z,{children:"Secret Key"}),(0,a.jsx)(ek.Z,{children:"Spend (USD)"}),(0,a.jsx)(ek.Z,{children:"Budget (USD)"}),(0,a.jsx)(ek.Z,{children:"Models"}),(0,a.jsx)(ek.Z,{children:"TPM / RPM Limits"})]})}),(0,a.jsx)(e_.Z,{children:o.map(e=>{if(console.log(e),"litellm-dashboard"===e.team_id)return null;if(r){if(console.log("item team id: ".concat(e.team_id,", knownTeamIDs.has(item.team_id): ").concat(O.has(e.team_id),", selectedTeam id: ").concat(r.team_id)),(null!=r.team_id||null===e.team_id||O.has(e.team_id))&&e.team_id!=r.team_id)return null;console.log("item team id: ".concat(e.team_id,", is returned"))}return(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{style:{maxWidth:"2px",whiteSpace:"pre-wrap",overflow:"hidden"},children:null!=e.key_alias?(0,a.jsx)(es.Z,{children:e.key_alias}):(0,a.jsx)(es.Z,{children:"Not Set"})}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(es.Z,{children:e.key_name})}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(es.Z,{children:(()=>{try{return parseFloat(e.spend).toFixed(4)}catch(l){return e.spend}})()})}),(0,a.jsx)(ew.Z,{children:null!=e.max_budget?(0,a.jsx)(es.Z,{children:e.max_budget}):(0,a.jsx)(es.Z,{children:"Unlimited"})}),(0,a.jsx)(ew.Z,{children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(a.Fragment,{children:r&&r.models&&r.models.length>0?r.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(es.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(es.Z,{children:"All Team Models"})},l):(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(es.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l)):(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(es.Z,{children:"all-proxy-models"})})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(es.Z,{children:"All Proxy Models"})},l):"all-team-models"===e?(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(es.Z,{children:"All Team Models"})},l):(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(es.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(ew.Z,{children:(0,a.jsxs)(es.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{})," RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ey.Z,{onClick:()=>{I(e),A(!0)},icon:ex.Z,size:"sm"}),(0,a.jsx)(ei.Z,{open:S,onCancel:()=>{A(!1),I(null)},footer:null,width:800,children:E&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 mt-8",children:[(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Spend"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:(()=>{try{return parseFloat(E.spend).toFixed(4)}catch(e){return E.spend}})()})})]}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Budget"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor font-semibold text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.max_budget?(0,a.jsx)(a.Fragment,{children:E.max_budget}):(0,a.jsx)(a.Fragment,{children:"Unlimited"})})})]},e.name),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)("p",{className:"text-tremor-default font-medium text-tremor-content dark:text-dark-tremor-content",children:"Expires"}),(0,a.jsx)("div",{className:"mt-2 flex items-baseline space-x-2.5",children:(0,a.jsx)("p",{className:"text-tremor-default font-small text-tremor-content-strong dark:text-dark-tremor-content-strong",children:null!=E.expires?(0,a.jsx)(a.Fragment,{children:new Date(E.expires).toLocaleString(void 0,{day:"numeric",month:"long",year:"numeric",hour:"numeric",minute:"numeric",second:"numeric"})}):(0,a.jsx)(a.Fragment,{children:"Never"})})})]},e.name)]}),(0,a.jsxs)(ef.Z,{className:"my-4",children:[(0,a.jsx)(er.Z,{children:"Token Name"}),(0,a.jsx)(es.Z,{className:"my-1",children:E.key_alias?E.key_alias:E.key_name}),(0,a.jsx)(er.Z,{children:"Token ID"}),(0,a.jsx)(es.Z,{className:"my-1 text-[12px]",children:E.token}),(0,a.jsx)(er.Z,{children:"Metadata"}),(0,a.jsx)(es.Z,{className:"my-1",children:(0,a.jsxs)("pre",{children:[JSON.stringify(E.metadata)," "]})})]}),(0,a.jsx)(X.Z,{className:"mx-auto flex items-center",onClick:()=>{A(!1),I(null)},children:"Close"})]})}),(0,a.jsx)(ey.Z,{icon:ep.Z,size:"sm",onClick:()=>R(e)}),(0,a.jsx)(ey.Z,{onClick:()=>U(e),icon:ej.Z,size:"sm"})]})]},e.token)})})]}),h&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:""}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Key"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this key ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(X.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(X.Z,{onClick:()=>{x(!1),j(null)},children:"Cancel"})]})]})]})})]}),E&&(0,a.jsx)(e=>{let{visible:l,onCancel:t,token:s,onSubmit:o}=e,[i]=eo.Z.useForm(),[d,m]=(0,n.useState)(r),[u,h]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1);return(0,a.jsx)(ei.Z,{title:"Edit Key",visible:l,width:800,footer:null,onOk:()=>{i.validateFields().then(e=>{i.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,a.jsxs)(eo.Z,{form:i,onFinish:M,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Key Name",name:"key_alias",rules:[{required:!0,message:"Please input a key name"}],help:"required",children:(0,a.jsx)(ec.Z,{})}),(0,a.jsx)(eo.Z.Item,{label:"Models",name:"models",rules:[{validator:(e,l)=>{let t=l.filter(e=>!d.models.includes(e)&&"all-team-models"!==e&&"all-proxy-models"!==e&&!d.models.includes("all-proxy-models"));return(console.log("errorModels: ".concat(t)),t.length>0)?Promise.reject("Some models are not part of the new team's models - ".concat(t,"Team models: ").concat(d.models)):Promise.resolve()}}],children:(0,a.jsxs)(en.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(eA,{value:"all-team-models",children:"All Team Models"},"all-team-models"),d&&d.models?d.models.includes("all-proxy-models")?C.filter(e=>"all-proxy-models"!==e).map(e=>(0,a.jsx)(eA,{value:e,children:e},e)):d.models.map(e=>(0,a.jsx)(eA,{value:e,children:e},e)):C.map(e=>(0,a.jsx)(eA,{value:e,children:e},e))]})}),(0,a.jsx)(eo.Z.Item,{className:"mt-8",label:"Max Budget (USD)",name:"max_budget",help:"Budget cannot exceed team max budget: ".concat((null==d?void 0:d.max_budget)!==null&&(null==d?void 0:d.max_budget)!==void 0?null==d?void 0:d.max_budget:"unlimited"),rules:[{validator:async(e,l)=>{if(l&&d&&null!==d.max_budget&&l>d.max_budget)throw console.log("keyTeam.max_budget: ".concat(d.max_budget)),Error("Budget cannot exceed team max budget: $".concat(d.max_budget))}}],children:(0,a.jsx)(ed.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(eo.Z.Item,{label:"token",name:"token",hidden:!0}),(0,a.jsx)(eo.Z.Item,{label:"Team",name:"team_id",help:"the team this key belongs to",children:(0,a.jsx)(eS.Z,{value:s.team_alias,children:null==c?void 0:c.map((e,l)=>(0,a.jsx)(eN.Z,{value:e.team_id,onClick:()=>m(e),children:e.team_alias},l))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Edit Key"})})]})})},{visible:k,onCancel:()=>{v(!1),I(null)},token:E,onSubmit:M})]})},eI=t(76032),eC=t(35152),eP=e=>{let{userID:l,userRole:t,accessToken:s,userSpend:r,selectedTeam:o}=e;console.log("userSpend: ".concat(r));let[i,c]=(0,n.useState)(null!==r?r:0),[d,m]=(0,n.useState)(0),[u,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{let e=async()=>{if(s&&l&&t&&"Admin"===t&&null==r)try{let e=await w(s);e&&(e.spend?c(e.spend):c(0),e.max_budget?m(e.max_budget):m(0))}catch(e){console.error("Error fetching global spend data:",e)}};(async()=>{try{if(null===l||null===t)return;if(null!==s){let e=(await N(s,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),h(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[t,s,l]),(0,n.useEffect)(()=>{null!==r&&c(r)},[r]);let x=[];o&&o.models&&(x=o.models),x&&x.includes("all-proxy-models")?(console.log("user models:",u),x=u):x&&x.includes("all-team-models")?x=o.models:x&&0===x.length&&(x=u);let p=void 0!==i?i.toFixed(4):null;return console.log("spend in view user spend: ".concat(i)),(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("p",{className:"text-tremor-default text-tremor-content dark:text-dark-tremor-content",children:["Total Spend"," "]}),(0,a.jsxs)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:["$",p]})]}),(0,a.jsx)("div",{className:"ml-auto",children:(0,a.jsxs)(ee.Z,{children:[(0,a.jsx)(et.Z,{children:(0,a.jsx)(es.Z,{children:"Team Models"})}),(0,a.jsx)(el.Z,{className:"absolute right-0 z-10 bg-white p-2 shadow-lg max-w-xs",children:(0,a.jsx)(eI.Z,{children:x.map(e=>(0,a.jsx)(eC.Z,{children:(0,a.jsx)(es.Z,{children:e})},e))})})]})})]})},eT=e=>{let{userID:l,userRole:t,selectedTeam:s,accessToken:r}=e,[o,i]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{if(null===l||null===t)return;if(null!==r){let e=(await N(r,l,t)).data.map(e=>e.id);console.log("available_model_names:",e),i(e)}}catch(e){console.error("Error fetching user models:",e)}})()},[r,l,t]);let c=[];return s&&s.models&&(c=s.models),c&&c.includes("all-proxy-models")&&(console.log("user models:",o),c=o),(0,a.jsx)(a.Fragment,{children:(0,a.jsx)("div",{className:"mb-5",children:(0,a.jsx)("p",{className:"text-3xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:null==s?void 0:s.team_alias})})})},eO=e=>{let l,{teams:t,setSelectedTeam:s,userRole:r}=e,o={models:[],team_id:null,team_alias:"Default Team"},[i,c]=(0,n.useState)(o);return(l="App User"===r?t:t?[...t,o]:[o],"App User"===r)?null:(0,a.jsxs)("div",{className:"mt-5 mb-5",children:[(0,a.jsx)(er.Z,{children:"Select Team"}),(0,a.jsx)(es.Z,{children:"If you belong to multiple teams, this setting controls which team is used by default when creating new API Keys."}),(0,a.jsxs)(es.Z,{className:"mt-3 mb-3",children:[(0,a.jsx)("b",{children:"Default Team:"})," If no team_id is set for a key, it will be grouped under here."]}),l&&l.length>0?(0,a.jsx)(eS.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(eN.Z,{value:String(l),onClick:()=>s(e),children:e.team_alias},l))}):(0,a.jsxs)(es.Z,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]})},eF=t(37963),eR=t(36083);console.log("isLocal:",!1);var eM=e=>{let{userID:l,userRole:t,teams:s,keys:r,setUserRole:i,userEmail:c,setUserEmail:d,setTeams:m,setKeys:u}=e,[h,x]=(0,n.useState)(null),p=(0,o.useSearchParams)();p.get("viewSpend"),(0,o.useRouter)();let j=p.get("token"),[g,f]=(0,n.useState)(null),[y,_]=(0,n.useState)(null),[b,k]=(0,n.useState)([]),v={models:[],team_alias:"Default Team",team_id:null},[S,A]=(0,n.useState)(s?s[0]:v);if(window.addEventListener("beforeunload",function(){sessionStorage.clear()}),(0,n.useEffect)(()=>{if(j){let e=(0,eF.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&&!r&&!h){let e=sessionStorage.getItem("userModels"+l);e?k(JSON.parse(e)):(async()=>{try{let e=await Z(g,l,t,!1,null,null);if(console.log("received teams in user dashboard: ".concat(Object.keys(e),"; team values: ").concat(Object.entries(e.teams))),"Admin"==t){let e=await w(g);x(e),console.log("globalSpend:",e)}else x(e.user_info);u(e.keys),m(e.teams);let s=[...e.teams];s.length>0?(console.log("response['teams']: ".concat(s)),A(s[0])):A(v),sessionStorage.setItem("userData"+l,JSON.stringify(e.keys)),sessionStorage.setItem("userSpendData"+l,JSON.stringify(e.user_info));let r=(await N(g,l,t)).data.map(e=>e.id);console.log("available_model_names:",r),k(r),console.log("userModels:",b),sessionStorage.setItem("userModels"+l,JSON.stringify(r))}catch(e){console.error("There was an error fetching the data",e)}})()}},[l,j,g,r,t]),(0,n.useEffect)(()=>{if(null!==r&&null!=S){let e=0;for(let l of r)S.hasOwnProperty("team_id")&&null!==l.team_id&&l.team_id===S.team_id&&(e+=l.spend);_(e)}else if(null!==r){let e=0;for(let l of r)e+=l.spend;_(e)}},[S]),null==l||null==j){let e="/sso/key/generate";return console.log("Full URL:",e),window.location.href=e,null}if(null==g)return null;if(null==t&&i("App Owner"),t&&"Admin Viewer"==t){let{Title:e,Paragraph:l}=eR.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to create keys"})]})}return console.log("inside user dashboard, selected team",S),console.log("teamSpend: ".concat(y)),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsx)($.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:(0,a.jsxs)(H.Z,{numColSpan:1,children:[(0,a.jsx)(eT,{userID:l,userRole:t,selectedTeam:S||null,accessToken:g}),(0,a.jsx)(eP,{userID:l,userRole:t,accessToken:g,userSpend:y,selectedTeam:S||null}),(0,a.jsx)(eE,{userID:l,userRole:t,accessToken:g,selectedTeam:S||null,data:r,setData:u,teams:s}),(0,a.jsx)(eh,{userID:l,team:S||null,userRole:t,accessToken:g,data:r,setData:u},S?S.team_id:null),(0,a.jsx)(eO,{teams:s,setSelectedTeam:A,userRole:t})]})})})},eL=t(35087),eU=t(92836),eD=t(26734),eK=t(41608),eB=t(32126),ez=t(23682),eV=t(47047),eq=t(76628),eG=t(57750),eY=t(44041),eW=t(38302),eJ=t(28683),eH=t(1460),e$=t(78578),eX=t(63954),eQ=t(90252),e0=t(7905),e1=e=>{let{modelID:l,accessToken:t}=e,[s,r]=(0,n.useState)(!1),o=async()=>{try{u.ZP.info("Making API Call"),r(!0);let e=await p(t,l);console.log("model delete Response:",e),u.ZP.success("Model ".concat(l," deleted successfully")),r(!1)}catch(e){console.error("Error deleting the model:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(ey.Z,{onClick:()=>r(!0),icon:ej.Z,size:"sm"}),(0,a.jsx)(ei.Z,{open:s,onOk:o,okType:"danger",onCancel:()=>r(!1),children:(0,a.jsxs)($.Z,{numItems:1,className:"gap-2 w-full",children:[(0,a.jsx)(er.Z,{children:"Delete Model"}),(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsx)("p",{children:"Are you sure you want to delete this model? This action is irreversible."})}),(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsxs)("p",{children:["Model ID: ",(0,a.jsx)("b",{children:l})]})})]})})]})},e2=t(97766),e4=t(46495);let{Title:e8,Link:e5}=eR.default;(s=r||(r={})).OpenAI="OpenAI",s.Azure="Azure",s.Anthropic="Anthropic",s.Google_AI_Studio="Gemini (Google AI Studio)",s.Bedrock="Amazon Bedrock",s.OpenAI_Compatible="OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)",s.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)";let e3={OpenAI:"openai",Azure:"azure",Anthropic:"anthropic",Google_AI_Studio:"gemini",Bedrock:"bedrock",OpenAI_Compatible:"openai",Vertex_AI:"vertex_ai"},e6={"BadRequestError (400)":"BadRequestErrorRetries","AuthenticationError (401)":"AuthenticationErrorRetries","TimeoutError (408)":"TimeoutErrorRetries","RateLimitError (429)":"RateLimitErrorRetries","ContentPolicyViolationError (400)":"ContentPolicyViolationErrorRetries","InternalServerError (500)":"InternalServerErrorRetries"},e7=async(e,l,t)=>{try{let s=Array.isArray(e.model)?e.model:[e.model];console.log("received deployments: ".concat(s)),console.log("received type of deployments: ".concat(typeof s)),s.forEach(async t=>{console.log("litellm_model: ".concat(t));let s={},r={};s.model=t;let a="";for(let[l,t]of Object.entries(e))if(""!==t){if("model_name"==l)a+=t;else if("custom_llm_provider"==l)continue;else if("model"==l)continue;else if("base_model"===l)r[l]=t;else if("litellm_extra_params"==l){console.log("litellm_extra_params:",t);let e={};if(t&&void 0!=t){try{e=JSON.parse(t)}catch(e){throw u.ZP.error("Failed to parse LiteLLM Extra Params: "+e,10),Error("Failed to parse litellm_extra_params: "+e)}for(let[l,t]of Object.entries(e))s[l]=t}}else s[l]=t}let n={model_name:a,litellm_params:s,model_info:r},o=await x(l,n);console.log("response for model create call: ".concat(o.data))}),t.resetFields()}catch(e){u.ZP.error("Failed to create model: "+e,10)}};var e9=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]=eo.Z.useForm(),[f,y]=(0,n.useState)(null),[Z,_]=(0,n.useState)(""),[w,N]=(0,n.useState)([]),A=Object.values(r).filter(e=>isNaN(Number(e))),[E,I]=(0,n.useState)("OpenAI"),[C,P]=(0,n.useState)(""),[T,O]=(0,n.useState)(!1),[F,R]=(0,n.useState)(null),[M,L]=(0,n.useState)([]),[U,K]=(0,n.useState)(null),[B,z]=(0,n.useState)([]),[q,G]=(0,n.useState)([]),[Y,H]=(0,n.useState)([]),[ea,en]=(0,n.useState)([]),[ec,eu]=(0,n.useState)([]),[eh,ex]=(0,n.useState)([]),[ej,eA]=(0,n.useState)([]),[eE,eI]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),[eC,eP]=(0,n.useState)(null),[eT,eO]=(0,n.useState)(0),eF=e=>{R(e),O(!0)},eM=async e=>{if(console.log("handleEditSubmit:",e),null==o)return;let l={},t=null;for(let[s,r]of Object.entries(e))"model_id"!==s?l[s]=r:t=r;let s={litellm_params:l,model_info:{id:t}};console.log("handleEditSubmit payload:",s);try{await D(o,s),u.ZP.success("Model updated successfully, restart server to see updates"),O(!1),R(null)}catch(e){console.log("Error occurred")}},e9=()=>{_(new Date().toLocaleString())},le=async()=>{if(!o){console.error("Access token is missing");return}console.log("new modelGroupRetryPolicy:",eC);try{await W(o,{router_settings:{model_group_retry_policy:eC}}),u.ZP.success("Retry settings saved successfully")}catch(e){console.error("Failed to save retry settings:",e),u.ZP.error("Failed to save retry settings")}};if((0,n.useEffect)(()=>{if(!o||!i||!c||!d)return;let e=async()=>{try{var e,l,t,s,r,a;let n=await b(o,d,c);console.log("Model data response:",n.data),x(n);let i=new Set;for(let e=0;e0&&(u=m[m.length-1],console.log("_initial_model_group:",u),K(u)),console.log("selectedModelGroup:",U);let h=await k(o,d,c,u,null===(e=eE.from)||void 0===e?void 0:e.toISOString(),null===(l=eE.to)||void 0===l?void 0:l.toISOString());console.log("Model metrics response:",h),G(h.data),H(h.all_api_bases);let p=await S(o,d,c,u,null===(t=eE.from)||void 0===t?void 0:t.toISOString(),null===(s=eE.to)||void 0===s?void 0:s.toISOString());console.log("Model exceptions response:",p),en(p.data),eu(p.exception_types);let j=await v(o,d,c,u,null===(r=eE.from)||void 0===r?void 0:r.toISOString(),null===(a=eE.to)||void 0===a?void 0:a.toISOString());console.log("slowResponses:",j),eA(j);let g=(await V(o,d,c)).router_settings;console.log("routerSettingsInfo:",g);let f=g.model_group_retry_policy,y=g.num_retries;console.log("model_group_retry_policy:",f),console.log("default_retries:",y),eP(f),eO(y)}catch(e){console.error("There was an error fetching the model data",e)}};o&&i&&c&&d&&e();let l=async()=>{let e=await h();console.log("received model cost map data: ".concat(Object.keys(e))),y(e)};null==f&&l(),e9()},[o,i,c,d,f,Z]),!m||!o||!i||!c||!d)return(0,a.jsx)("div",{children:"Loading..."});let ll=[];for(let e=0;e(console.log("GET PROVIDER CALLED! - ".concat(f)),null!=f&&"object"==typeof f&&e in f)?f[e].litellm_provider:"openai";if(r){let e=r.split("/"),l=e[0];n=1===e.length?u(r):l}else n="openai";a&&(o=null==a?void 0:a.input_cost_per_token,i=null==a?void 0:a.output_cost_per_token,c=null==a?void 0:a.max_tokens),(null==s?void 0:s.litellm_params)&&(d=Object.fromEntries(Object.entries(null==s?void 0:s.litellm_params).filter(e=>{let[l]=e;return"model"!==l&&"api_base"!==l}))),m.data[e].provider=n,m.data[e].input_cost=o,m.data[e].output_cost=i,m.data[e].max_tokens=c,m.data[e].api_base=null==s?void 0:null===(t=s.litellm_params)||void 0===t?void 0:t.api_base,m.data[e].cleanedLitellmParams=d,ll.push(s.model_name),console.log(m.data[e])}if(c&&"Admin Viewer"==c){let{Title:e,Paragraph:l}=eR.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to view all models"})]})}let lt=e=>{console.log("received provider string: ".concat(e));let l=Object.keys(r).find(l=>r[l]===e);if(l){let e=e3[l];console.log("mappingResult: ".concat(e));let t=[];"object"==typeof f&&Object.entries(f).forEach(l=>{let[s,r]=l;null!==r&&"object"==typeof r&&"litellm_provider"in r&&(r.litellm_provider===e||r.litellm_provider.includes(e))&&t.push(s)}),N(t),console.log("providerModels: ".concat(w))}},ls=async()=>{try{u.ZP.info("Running health check..."),P("");let e=await J(o);P(e)}catch(e){console.error("Error running health check:",e),P("Error running health check")}},lr=async(e,l,t)=>{if(console.log("Updating model metrics for group:",e),o&&d&&c&&l&&t){console.log("inside updateModelMetrics - startTime:",l,"endTime:",t),K(e);try{let s=await k(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model metrics response:",s),G(s.data),H(s.all_api_bases);let r=await S(o,d,c,e,l.toISOString(),t.toISOString());console.log("Model exceptions response:",r),en(r.data),eu(r.exception_types);let a=await v(o,d,c,e,l.toISOString(),t.toISOString());console.log("slowResponses:",a),eA(a)}catch(e){console.error("Failed to fetch model metrics",e)}}};return console.log("selectedProvider: ".concat(E)),console.log("providerModels.length: ".concat(w.length)),(0,a.jsx)("div",{style:{width:"100%",height:"100%"},children:(0,a.jsxs)(eD.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(eK.Z,{className:"flex justify-between mt-2 w-full items-center",children:[(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(eU.Z,{children:"All Models"}),(0,a.jsx)(eU.Z,{children:"Add Model"}),(0,a.jsx)(eU.Z,{children:(0,a.jsx)("pre",{children:"/health Models"})}),(0,a.jsx)(eU.Z,{children:"Model Analytics"}),(0,a.jsx)(eU.Z,{children:"Model Retry Settings"})]}),(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[Z&&(0,a.jsxs)(es.Z,{children:["Last Refreshed: ",Z]}),(0,a.jsx)(ey.Z,{icon:eX.Z,variant:"shadow",size:"xs",className:"self-center",onClick:e9})]})]}),(0,a.jsxs)(ez.Z,{children:[(0,a.jsxs)(eB.Z,{children:[(0,a.jsxs)($.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(es.Z,{children:"Filter by Public Model Name"}),(0,a.jsxs)(eS.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:"all",onValueChange:e=>K("all"===e?"all":e),children:[(0,a.jsx)(eN.Z,{value:"all",children:"All Models"}),M.map((e,l)=>(0,a.jsx)(eN.Z,{value:e,onClick:()=>K(e),children:e},l))]})]}),(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(eZ.Z,{className:"mt-5",children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Public Model Name "}),(0,a.jsx)(ek.Z,{children:"Provider"}),"Admin"===c&&(0,a.jsx)(ek.Z,{children:"API Base"}),(0,a.jsx)(ek.Z,{children:"Extra litellm Params"}),(0,a.jsx)(ek.Z,{children:"Input Price per token ($)"}),(0,a.jsx)(ek.Z,{children:"Output Price per token ($)"}),(0,a.jsx)(ek.Z,{children:"Max Tokens"}),(0,a.jsx)(ek.Z,{children:"Status"})]})}),(0,a.jsx)(e_.Z,{children:m.data.filter(e=>"all"===U||e.model_name===U||null==U||""===U).map((e,l)=>(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:(0,a.jsx)(es.Z,{children:e.model_name})}),(0,a.jsx)(ew.Z,{children:e.provider}),"Admin"===c&&(0,a.jsx)(ew.Z,{children:e.api_base}),(0,a.jsx)(ew.Z,{children:(0,a.jsxs)(ee.Z,{children:[(0,a.jsx)(et.Z,{children:(0,a.jsx)(es.Z,{children:"Litellm params"})}),(0,a.jsx)(el.Z,{children:(0,a.jsx)("pre",{children:JSON.stringify(e.cleanedLitellmParams,null,2)})})]})}),(0,a.jsx)(ew.Z,{children:e.input_cost||e.litellm_params.input_cost_per_token||null}),(0,a.jsx)(ew.Z,{children:e.output_cost||e.litellm_params.output_cost_per_token||null}),(0,a.jsx)(ew.Z,{children:e.max_tokens}),(0,a.jsx)(ew.Z,{children:e.model_info.db_model?(0,a.jsx)(eg.Z,{icon:eQ.Z,className:"text-white",children:"DB Model"}):(0,a.jsx)(eg.Z,{icon:e0.Z,className:"text-black",children:"Config Model"})}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ey.Z,{icon:ep.Z,size:"sm",onClick:()=>eF(e)}),(0,a.jsx)(e1,{modelID:e.model_info.id,accessToken:o})]})]},l))})]})})]}),(0,a.jsx)(e=>{let{visible:l,onCancel:t,model:s,onSubmit:r}=e,[n]=eo.Z.useForm(),o={},i="",c="";if(s){o=s.litellm_params,i=s.model_name;let e=s.model_info;e&&(c=e.id,console.log("model_id: ".concat(c)),o.model_id=c)}return(0,a.jsx)(ei.Z,{title:"Edit Model "+i,visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{r(e),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,a.jsxs)(eo.Z,{form:n,onFinish:eM,initialValues:o,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{className:"mt-8",label:"api_base",name:"api_base",children:(0,a.jsx)(Q.Z,{})}),(0,a.jsx)(eo.Z.Item,{label:"tpm",name:"tpm",tooltip:"int (optional) - Tokens limit for this deployment: in tokens per minute (tpm). Find this information on your model/providers website",children:(0,a.jsx)(ed.Z,{min:0,step:1})}),(0,a.jsx)(eo.Z.Item,{label:"rpm",name:"rpm",tooltip:"int (optional) - Rate limit for this deployment: in requests per minute (rpm). Find this information on your model/providers website",children:(0,a.jsx)(ed.Z,{min:0,step:1})}),(0,a.jsx)(eo.Z.Item,{label:"max_retries",name:"max_retries",children:(0,a.jsx)(ed.Z,{min:0,step:1})}),(0,a.jsx)(eo.Z.Item,{label:"timeout",name:"timeout",tooltip:"int (optional) - Timeout in seconds for LLM requests (Defaults to 600 seconds)",children:(0,a.jsx)(ed.Z,{min:0,step:1})}),(0,a.jsx)(eo.Z.Item,{label:"stream_timeout",name:"stream_timeout",tooltip:"int (optional) - Timeout for stream requests (seconds)",children:(0,a.jsx)(ed.Z,{min:0,step:1})}),(0,a.jsx)(eo.Z.Item,{label:"input_cost_per_token",name:"input_cost_per_token",tooltip:"float (optional) - Input cost per token",children:(0,a.jsx)(ed.Z,{min:0,step:1e-4})}),(0,a.jsx)(eo.Z.Item,{label:"output_cost_per_token",name:"output_cost_per_token",tooltip:"float (optional) - Output cost per token",children:(0,a.jsx)(ed.Z,{min:0,step:1e-4})}),(0,a.jsx)(eo.Z.Item,{label:"model_id",name:"model_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Save"})})]})})},{visible:T,onCancel:()=>{O(!1),R(null)},model:F,onSubmit:eM})]}),(0,a.jsxs)(eB.Z,{className:"h-full",children:[(0,a.jsx)(e8,{level:2,children:"Add new model"}),(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(eo.Z,{form:g,onFinish:()=>{g.validateFields().then(e=>{e7(e,o,g)}).catch(e=>{console.error("Validation failed:",e)})},labelCol:{span:10},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Provider:",name:"custom_llm_provider",tooltip:"E.g. OpenAI, Azure OpenAI, Anthropic, Bedrock, etc.",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(eS.Z,{value:E.toString(),children:A.map((e,l)=>(0,a.jsx)(eN.Z,{value:e,onClick:()=>{lt(e),I(e)},children:e},l))})}),(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Public Model Name",name:"model_name",tooltip:"Model name your users will pass in. Also used for load-balancing, LiteLLM will load balance between all models with this public name.",className:"mb-0",children:(0,a.jsx)(Q.Z,{placeholder:"Vertex AI (Anthropic, Gemini, etc.)"===(s=E.toString())?"gemini-pro":"Anthropic"==s?"claude-3-opus":"Amazon Bedrock"==s?"claude-3-opus":"Gemini (Google AI Studio)"==s?"gemini-pro":"gpt-3.5-turbo"})}),(0,a.jsxs)(eW.Z,{children:[(0,a.jsx)(eJ.Z,{span:10}),(0,a.jsx)(eJ.Z,{span:10,children:(0,a.jsx)(es.Z,{className:"mb-3 mt-1",children:"Model name your users will pass in."})})]}),(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"LiteLLM Model Name(s)",name:"model",tooltip:"Actual model name used for making litellm.completion() call.",className:"mb-0",children:"Azure"===E?(0,a.jsx)(Q.Z,{placeholder:"Enter model name"}):w.length>0?(0,a.jsx)(eV.Z,{value:w,children:w.map((e,l)=>(0,a.jsx)(eq.Z,{value:e,children:e},l))}):(0,a.jsx)(Q.Z,{placeholder:"gpt-3.5-turbo-0125"})}),(0,a.jsxs)(eW.Z,{children:[(0,a.jsx)(eJ.Z,{span:10}),(0,a.jsx)(eJ.Z,{span:10,children:(0,a.jsxs)(es.Z,{className:"mb-3 mt-1",children:["Actual model name used for making ",(0,a.jsx)(e5,{href:"https://docs.litellm.ai/docs/providers",target:"_blank",children:"litellm.completion() call"}),". We'll ",(0,a.jsx)(e5,{href:"https://docs.litellm.ai/docs/proxy/reliability#step-1---set-deployments-on-config",target:"_blank",children:"loadbalance"})," models with the same 'public name'"]})})]}),"Amazon Bedrock"!=E&&"Vertex AI (Anthropic, Gemini, etc.)"!=E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Key",name:"api_key",children:(0,a.jsx)(Q.Z,{placeholder:"sk-",type:"password"})}),"OpenAI"==E&&(0,a.jsx)(eo.Z.Item,{label:"Organization ID",name:"organization_id",children:(0,a.jsx)(Q.Z,{placeholder:"[OPTIONAL] my-unique-org"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Project",name:"vertex_project",children:(0,a.jsx)(Q.Z,{placeholder:"adroit-cadet-1234.."})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Location",name:"vertex_location",children:(0,a.jsx)(Q.Z,{placeholder:"us-east-1"})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"Vertex Credentials",name:"vertex_credentials",className:"mb-0",children:(0,a.jsx)(e4.Z,{name:"file",accept:".json",beforeUpload:e=>{if("application/json"===e.type){let l=new FileReader;l.onload=e=>{if(e.target){let l=e.target.result;g.setFieldsValue({vertex_credentials:l})}},l.readAsText(e)}return!1},onChange(e){"uploading"!==e.file.status&&console.log(e.file,e.fileList),"done"===e.file.status?u.ZP.success("".concat(e.file.name," file uploaded successfully")):"error"===e.file.status&&u.ZP.error("".concat(e.file.name," file upload failed."))},children:(0,a.jsx)(em.ZP,{icon:(0,a.jsx)(e2.Z,{}),children:"Click to Upload"})})}),"Vertex AI (Anthropic, Gemini, etc.)"==E&&(0,a.jsxs)(eW.Z,{children:[(0,a.jsx)(eJ.Z,{span:10}),(0,a.jsx)(eJ.Z,{span:10,children:(0,a.jsx)(es.Z,{className:"mb-3 mt-1",children:"Give litellm a gcp service account(.json file), so it can make the relevant calls"})})]}),("Azure"==E||"OpenAI-Compatible Endpoints (Groq, Together AI, Mistral AI, etc.)"==E)&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Base",name:"api_base",children:(0,a.jsx)(Q.Z,{placeholder:"https://..."})}),"Azure"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"API Version",name:"api_version",children:(0,a.jsx)(Q.Z,{placeholder:"2023-07-01-preview"})}),"Azure"==E&&(0,a.jsxs)(eo.Z.Item,{label:"Base Model",name:"base_model",children:[(0,a.jsx)(Q.Z,{placeholder:"azure/gpt-3.5-turbo"}),(0,a.jsxs)(es.Z,{children:["The actual model your azure deployment uses. Used for accurate cost tracking. Select name from ",(0,a.jsx)(e5,{href:"https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json",target:"_blank",children:"here"})]})]}),"Amazon Bedrock"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Access Key ID",name:"aws_access_key_id",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(Q.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Secret Access Key",name:"aws_secret_access_key",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(Q.Z,{placeholder:""})}),"Amazon Bedrock"==E&&(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"AWS Region Name",name:"aws_region_name",tooltip:"You can provide the raw key or the environment variable (e.g. `os.environ/MY_SECRET_KEY`).",children:(0,a.jsx)(Q.Z,{placeholder:"us-east-1"})}),(0,a.jsx)(eo.Z.Item,{label:"LiteLLM Params",name:"litellm_extra_params",tooltip:"Optional litellm params used for making a litellm.completion() call.",className:"mb-0",children:(0,a.jsx)(e$.Z,{rows:4,placeholder:'{ "rpm": 100, "timeout": 0, "stream_timeout": 0 }'})}),(0,a.jsxs)(eW.Z,{children:[(0,a.jsx)(eJ.Z,{span:10}),(0,a.jsx)(eJ.Z,{span:10,children:(0,a.jsxs)(es.Z,{className:"mb-3 mt-1",children:["Pass JSON of litellm supported params ",(0,a.jsx)(e5,{href:"https://docs.litellm.ai/docs/completion/input",target:"_blank",children:"litellm.completion() call"})]})})]})]}),(0,a.jsx)("div",{style:{textAlign:"center",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Add Model"})}),(0,a.jsx)(eH.Z,{title:"Get help on our github",children:(0,a.jsx)(eR.default.Link,{href:"https://github.com/BerriAI/litellm/issues",children:"Need Help?"})})]})})]}),(0,a.jsx)(eB.Z,{children:(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(es.Z,{children:"`/health` will run a very small request through your models configured on litellm"}),(0,a.jsx)(X.Z,{onClick:ls,children:"Run `/health`"}),C&&(0,a.jsx)("pre",{children:JSON.stringify(C,null,2)})]})}),(0,a.jsxs)(eB.Z,{children:[(0,a.jsxs)($.Z,{numItems:2,className:"mt-2",children:[(0,a.jsxs)(eJ.Z,{children:[(0,a.jsx)(es.Z,{children:"Select Time Range"}),(0,a.jsx)(eL.Z,{enableSelect:!0,value:eE,onValueChange:e=>{eI(e),lr(U,e.from,e.to)}})]}),(0,a.jsxs)(eJ.Z,{children:[(0,a.jsx)(es.Z,{children:"Select Model Group"}),(0,a.jsx)(eS.Z,{className:"mb-4 mt-2",defaultValue:U||M[0],value:U||M[0],children:M.map((e,l)=>(0,a.jsx)(eN.Z,{value:e,onClick:()=>lr(e,eE.from,eE.to),children:e},l))})]})]}),(0,a.jsxs)($.Z,{numItems:2,children:[(0,a.jsx)(eJ.Z,{children:(0,a.jsxs)(ef.Z,{className:"mr-2 max-h-[400px] min-h-[400px]",children:[(0,a.jsx)(er.Z,{children:"Avg Latency per Token"}),(0,a.jsx)("p",{className:"text-gray-500 italic",children:" (seconds/token)"}),(0,a.jsx)(es.Z,{className:"text-gray-500 italic mt-1 mb-1",children:"average Latency for successfull requests divided by the total tokens"}),q&&Y&&(0,a.jsx)(eG.Z,{title:"Model Latency",className:"h-72",data:q,showLegend:!1,index:"date",categories:Y,connectNulls:!0,customTooltip:e=>{var l,t;let{payload:s,active:r}=e;if(!r||!s)return null;let n=null===(t=s[0])||void 0===t?void 0:null===(l=t.payload)||void 0===l?void 0:l.date,o=s.sort((e,l)=>l.value-e.value);if(o.length>5){let e=o.length-5;(o=o.slice(0,5)).push({dataKey:"".concat(e," other deployments"),value:s.slice(5).reduce((e,l)=>e+l.value,0),color:"gray"})}return(0,a.jsxs)("div",{className:"w-150 rounded-tremor-default border border-tremor-border bg-tremor-background p-2 text-tremor-default shadow-tremor-dropdown",children:[n&&(0,a.jsxs)("p",{className:"text-tremor-content-emphasis mb-2",children:["Date: ",n]}),o.map((e,l)=>{let t=parseFloat(e.value.toFixed(5)),s=0===t&&e.value>0?"<0.00001":t.toFixed(5);return(0,a.jsxs)("div",{className:"flex justify-between",children:[(0,a.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,a.jsx)("div",{className:"w-2 h-2 mt-1 rounded-full bg-".concat(e.color,"-500")}),(0,a.jsx)("p",{className:"text-tremor-content",children:e.dataKey})]}),(0,a.jsx)("p",{className:"font-medium text-tremor-content-emphasis text-righ ml-2",children:s})]},l)})]})}})]})}),(0,a.jsx)(eJ.Z,{children:(0,a.jsx)(ef.Z,{className:"ml-2 max-h-[400px] min-h-[400px] overflow-y-auto",children:(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Deployment"}),(0,a.jsx)(ek.Z,{children:"Success Responses"}),(0,a.jsxs)(ek.Z,{children:["Slow Responses ",(0,a.jsx)("p",{children:"Success Responses taking 600+s"})]})]})}),(0,a.jsx)(e_.Z,{children:ej.map((e,l)=>(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:e.api_base}),(0,a.jsx)(ew.Z,{children:e.total_count}),(0,a.jsx)(ew.Z,{children:e.slow_count})]},l))})]})})})]}),(0,a.jsxs)(ef.Z,{className:"mt-4",children:[(0,a.jsx)(er.Z,{children:"Exceptions per Model"}),(0,a.jsx)(eY.Z,{className:"h-72",data:ea,index:"model",categories:ec,stack:!0,colors:["indigo-300","rose-200","#ffcc33"],yAxisWidth:30})]})]}),(0,a.jsxs)(eB.Z,{children:[(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)(es.Z,{children:"Filter by Public Model Name"}),(0,a.jsx)(eS.Z,{className:"mb-4 mt-2 ml-2 w-50",defaultValue:U||M[0],value:U||M[0],onValueChange:e=>K(e),children:M.map((e,l)=>(0,a.jsx)(eN.Z,{value:e,onClick:()=>K(e),children:e},l))})]}),(0,a.jsxs)(er.Z,{children:["Retry Policy for ",U]}),(0,a.jsx)(es.Z,{className:"mb-6",children:"How many retries should be attempted based on the Exception"}),e6&&(0,a.jsx)("table",{children:(0,a.jsx)("tbody",{children:Object.entries(e6).map((e,l)=>{var t;let[s,r]=e,n=null==eC?void 0:null===(t=eC[U])||void 0===t?void 0:t[r];return null==n&&(n=eT),(0,a.jsxs)("tr",{className:"flex justify-between items-center mt-2",children:[(0,a.jsx)("td",{children:(0,a.jsx)(es.Z,{children:s})}),(0,a.jsx)("td",{children:(0,a.jsx)(ed.Z,{className:"ml-5",value:n,min:0,step:1,onChange:e=>{eP(l=>{var t;let s=null!==(t=null==l?void 0:l[U])&&void 0!==t?t:{};return{...null!=l?l:{},[U]:{...s,[r]:e}}})}})})]},l)})})}),(0,a.jsx)(X.Z,{className:"mt-6 mr-8",onClick:le,children:"Save"})]})]})]})})};let{Option:le}=en.default;var ll=e=>{let{userID:l,accessToken:t,teams:s}=e,[r]=eo.Z.useForm(),[o,i]=(0,n.useState)(!1),[c,d]=(0,n.useState)(null),[m,h]=(0,n.useState)([]);(0,n.useEffect)(()=>{(async()=>{try{let e=await N(t,l,"any"),s=[];for(let l=0;l{i(!1),r.resetFields()},p=()=>{i(!1),d(null),r.resetFields()},j=async e=>{try{u.ZP.info("Making API Call"),i(!0),console.log("formValues in create user:",e);let s=await g(t,null,e);console.log("user create Response:",s),d(s.key),u.ZP.success("API user Created"),r.resetFields(),localStorage.removeItem("userData"+l)}catch(e){console.error("Error creating the user:",e)}};return(0,a.jsxs)("div",{children:[(0,a.jsx)(X.Z,{className:"mx-auto",onClick:()=>i(!0),children:"+ Invite User"}),(0,a.jsxs)(ei.Z,{title:"Invite User",visible:o,width:800,footer:null,onOk:x,onCancel:p,children:[(0,a.jsx)(es.Z,{className:"mb-1",children:"Invite a user to login to the Admin UI and create Keys"}),(0,a.jsx)(es.Z,{className:"mb-6",children:(0,a.jsx)("b",{children:"Note: SSO Setup Required for this"})}),(0,a.jsxs)(eo.Z,{form:r,onFinish:j,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsx)(eo.Z.Item,{label:"User Email",name:"user_email",children:(0,a.jsx)(Q.Z,{placeholder:""})}),(0,a.jsx)(eo.Z.Item,{label:"Team ID",name:"team_id",children:(0,a.jsx)(en.default,{placeholder:"Select Team ID",style:{width:"100%"},children:s?s.map(e=>(0,a.jsx)(le,{value:e.team_id,children:e.team_alias},e.team_id)):(0,a.jsx)(le,{value:null,children:"Default Team"},"default")})}),(0,a.jsx)(eo.Z.Item,{label:"Metadata",name:"metadata",children:(0,a.jsx)(ec.Z.TextArea,{rows:4,placeholder:"Enter metadata as JSON"})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Create User"})})]})]}),c&&(0,a.jsxs)(ei.Z,{title:"User Created Successfully",visible:o,onOk:x,onCancel:p,footer:null,children:[(0,a.jsx)("p",{children:"User has been created to access your proxy. Please Ask them to Log In."}),(0,a.jsx)("br",{}),(0,a.jsx)("p",{children:(0,a.jsx)("b",{children:"Note: This Feature is only supported through SSO on the Admin UI"})})]})]})},lt=e=>{let{accessToken:l,token:t,keys:s,userRole:r,userID:o,teams:i,setKeys:c}=e,[d,m]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(0),[j,g]=n.useState(null),[f,y]=(0,n.useState)(null);return((0,n.useEffect)(()=>{if(!l||!t||!r||!o)return;let e=async()=>{try{let e=await Z(l,null,r,!0,x,25);console.log("user data response:",e),m(e)}catch(e){console.error("There was an error fetching the model data",e)}};l&&t&&r&&o&&e()},[l,t,r,o,x]),d&&l&&t&&r&&o)?(0,a.jsx)("div",{style:{width:"100%"},children:(0,a.jsxs)($.Z,{className:"gap-2 p-2 h-[80vh] w-full mt-8",children:[(0,a.jsx)(ll,{userID:o,accessToken:l,teams:i}),(0,a.jsxs)(ef.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[80vh] mb-4",children:[(0,a.jsx)("div",{className:"mb-4 mt-1",children:(0,a.jsx)(es.Z,{children:"These are Users on LiteLLM that created API Keys. Automatically tracked by LiteLLM"})}),(0,a.jsx)(eD.Z,{children:(0,a.jsxs)(ez.Z,{children:[(0,a.jsx)(eB.Z,{children:(0,a.jsxs)(eZ.Z,{className:"mt-5",children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"User ID"}),(0,a.jsx)(ek.Z,{children:"User Email"}),(0,a.jsx)(ek.Z,{children:"User Models"}),(0,a.jsx)(ek.Z,{children:"User Spend ($ USD)"}),(0,a.jsx)(ek.Z,{children:"User Max Budget ($ USD)"}),(0,a.jsx)(ek.Z,{children:"User API Key Aliases"})]})}),(0,a.jsx)(e_.Z,{children:d.map(e=>{var l;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:e.user_id}),(0,a.jsx)(ew.Z,{children:e.user_email}),(0,a.jsx)(ew.Z,{children:e.models&&e.models.length>0?e.models:"All Models"}),(0,a.jsx)(ew.Z,{children:e.spend?null===(l=e.spend)||void 0===l?void 0:l.toFixed(2):0}),(0,a.jsx)(ew.Z,{children:e.max_budget?e.max_budget:"Unlimited"}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)($.Z,{numItems:2,children:e&&e.key_aliases&&e.key_aliases.filter(e=>null!==e).length>0?(0,a.jsx)(eg.Z,{size:"xs",color:"indigo",children:e.key_aliases.filter(e=>null!==e).join(", ")}):(0,a.jsx)(eg.Z,{size:"xs",color:"gray",children:"No Keys"})})})]},e.user_id)})})]})}),(0,a.jsx)(eB.Z,{children:(0,a.jsxs)("div",{className:"flex items-center",children:[(0,a.jsx)("div",{className:"flex-1"}),(0,a.jsx)("div",{className:"flex-1 flex justify-between items-center"})]})})]})})]}),function(){if(!d)return null;let e=Math.ceil(d.length/25);return(0,a.jsxs)("div",{className:"flex justify-between items-center",children:[(0,a.jsxs)("div",{children:["Showing Page ",x+1," of ",e]}),(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-l focus:outline-none",disabled:0===x,onClick:()=>p(x-1),children:"← Prev"}),(0,a.jsx)("button",{className:"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-r focus:outline-none",onClick:()=>{p(x+1)},children:"Next →"})]})]})}()]})}):(0,a.jsx)("div",{children:"Loading..."})},ls=e=>{let{teams:l,searchParams:t,accessToken:s,setTeams:r,userID:o,userRole:i}=e,[c]=eo.Z.useForm(),[d]=eo.Z.useForm(),{Title:m,Paragraph:h}=eR.default,[x,p]=(0,n.useState)(""),[j,g]=(0,n.useState)(!1),[f,Z]=(0,n.useState)(l?l[0]:null),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1),[S,A]=(0,n.useState)([]),[E,I]=(0,n.useState)(!1),[C,P]=(0,n.useState)(null),[T,O]=(0,n.useState)({}),F=e=>{Z(e),g(!0)},R=async e=>{let t=e.team_id;if(console.log("handleEditSubmit:",e),null==s)return;let a=await U(s,e);l&&r(l.map(e=>e.team_id===t?a.data:e)),u.ZP.success("Team updated successfully"),g(!1),Z(null)},L=async e=>{P(e),I(!0)},D=async()=>{if(null!=C&&null!=l&&null!=s){try{await y(s,C);let e=l.filter(e=>e.team_id!==C);r(e)}catch(e){console.error("Error deleting the team:",e)}I(!1),P(null)}};(0,n.useEffect)(()=>{let e=async()=>{try{if(null===o||null===i||null===s||null===l)return;console.log("fetching team info:");let e={};for(let t=0;t<(null==l?void 0:l.length);t++){let r=l[t].team_id,a=await _(s,r);console.log("teamInfo response:",a),null!==a&&(e={...e,[r]:a})}O(e)}catch(e){console.error("Error fetching team info:",e)}};(async()=>{try{if(null===o||null===i)return;if(null!==s){let e=(await N(s,o,i)).data.map(e=>e.id);console.log("available_model_names:",e),A(e)}}catch(e){console.error("Error fetching user models:",e)}})(),e()},[s,o,i,l]);let B=async e=>{try{if(null!=s){var t;let a=null==e?void 0:e.team_alias;if((null!==(t=null==l?void 0:l.map(e=>e.team_alias))&&void 0!==t?t:[]).includes(a))throw Error("Team alias ".concat(a," already exists, please pick another alias"));u.ZP.info("Creating Team");let n=await M(s,e);null!==l?r([...l,n]):r([n]),console.log("response for team create call: ".concat(n)),u.ZP.success("Team created"),b(!1)}}catch(e){console.error("Error creating the team:",e),u.ZP.error("Error creating the team: "+e,20)}},z=async e=>{try{if(null!=s&&null!=l){u.ZP.info("Adding Member");let t={role:"user",user_email:e.user_email,user_id:e.user_id},a=await K(s,f.team_id,t);console.log("response for team create call: ".concat(a.data));let n=l.findIndex(e=>(console.log("team.team_id=".concat(e.team_id,"; response.data.team_id=").concat(a.data.team_id)),e.team_id===a.data.team_id));if(console.log("foundIndex: ".concat(n)),-1!==n){let e=[...l];e[n]=a.data,r(e),Z(a.data)}v(!1)}}catch(e){console.error("Error creating the team:",e)}};return console.log("received teams ".concat(JSON.stringify(l))),(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)($.Z,{numItems:1,className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(H.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"All Teams"}),(0,a.jsxs)(ef.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:[(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Team Name"}),(0,a.jsx)(ek.Z,{children:"Spend (USD)"}),(0,a.jsx)(ek.Z,{children:"Budget (USD)"}),(0,a.jsx)(ek.Z,{children:"Models"}),(0,a.jsx)(ek.Z,{children:"TPM / RPM Limits"}),(0,a.jsx)(ek.Z,{children:"Info"})]})}),(0,a.jsx)(e_.Z,{children:l&&l.length>0?l.map(e=>(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.team_alias}),(0,a.jsx)(ew.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.spend}),(0,a.jsx)(ew.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:e.max_budget?e.max_budget:"No limit"}),(0,a.jsx)(ew.Z,{style:{maxWidth:"8-x",whiteSpace:"pre-wrap",overflow:"hidden"},children:Array.isArray(e.models)?(0,a.jsx)("div",{style:{display:"flex",flexDirection:"column"},children:0===e.models.length?(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(es.Z,{children:"All Proxy Models"})}):e.models.map((e,l)=>"all-proxy-models"===e?(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"red",children:(0,a.jsx)(es.Z,{children:"All Proxy Models"})},l):(0,a.jsx)(eg.Z,{size:"xs",className:"mb-1",color:"blue",children:(0,a.jsx)(es.Z,{children:e.length>30?"".concat(e.slice(0,30),"..."):e})},l))}):null}),(0,a.jsx)(ew.Z,{style:{maxWidth:"4px",whiteSpace:"pre-wrap",overflow:"hidden"},children:(0,a.jsxs)(es.Z,{children:["TPM: ",e.tpm_limit?e.tpm_limit:"Unlimited"," ",(0,a.jsx)("br",{}),"RPM:"," ",e.rpm_limit?e.rpm_limit:"Unlimited"]})}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsxs)(es.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].keys&&T[e.team_id].keys.length," ","Keys"]}),(0,a.jsxs)(es.Z,{children:[T&&e.team_id&&T[e.team_id]&&T[e.team_id].team_info&&T[e.team_id].team_info.members_with_roles&&T[e.team_id].team_info.members_with_roles.length," ","Members"]})]}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ey.Z,{icon:ep.Z,size:"sm",onClick:()=>F(e)}),(0,a.jsx)(ey.Z,{onClick:()=>L(e.team_id),icon:ej.Z,size:"sm"})]})]},e.team_id)):null})]}),E&&(0,a.jsx)("div",{className:"fixed z-10 inset-0 overflow-y-auto",children:(0,a.jsxs)("div",{className:"flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0",children:[(0,a.jsx)("div",{className:"fixed inset-0 transition-opacity","aria-hidden":"true",children:(0,a.jsx)("div",{className:"absolute inset-0 bg-gray-500 opacity-75"})}),(0,a.jsx)("span",{className:"hidden sm:inline-block sm:align-middle sm:h-screen","aria-hidden":"true",children:""}),(0,a.jsxs)("div",{className:"inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full",children:[(0,a.jsx)("div",{className:"bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4",children:(0,a.jsx)("div",{className:"sm:flex sm:items-start",children:(0,a.jsxs)("div",{className:"mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left",children:[(0,a.jsx)("h3",{className:"text-lg leading-6 font-medium text-gray-900",children:"Delete Team"}),(0,a.jsx)("div",{className:"mt-2",children:(0,a.jsx)("p",{className:"text-sm text-gray-500",children:"Are you sure you want to delete this team ?"})})]})})}),(0,a.jsxs)("div",{className:"bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse",children:[(0,a.jsx)(X.Z,{onClick:D,color:"red",className:"ml-2",children:"Delete"}),(0,a.jsx)(X.Z,{onClick:()=>{I(!1),P(null)},children:"Cancel"})]})]})]})})]})]}),(0,a.jsxs)(H.Z,{numColSpan:1,children:[(0,a.jsx)(X.Z,{className:"mx-auto",onClick:()=>b(!0),children:"+ Create New Team"}),(0,a.jsx)(ei.Z,{title:"Create Team",visible:w,width:800,footer:null,onOk:()=>{b(!1),c.resetFields()},onCancel:()=>{b(!1),c.resetFields()},children:(0,a.jsxs)(eo.Z,{form:c,onFinish:B,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(Q.Z,{placeholder:""})}),(0,a.jsx)(eo.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(en.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(en.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S.map(e=>(0,a.jsx)(en.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(eo.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(ed.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(eo.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(ed.Z,{step:1,width:400})}),(0,a.jsx)(eo.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(ed.Z,{step:1,width:400})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Create Team"})})]})})]}),(0,a.jsxs)(H.Z,{numColSpan:1,children:[(0,a.jsx)(m,{level:4,children:"Team Members"}),(0,a.jsx)(h,{children:"If you belong to multiple teams, this setting controls which teams members you see."}),l&&l.length>0?(0,a.jsx)(eS.Z,{defaultValue:"0",children:l.map((e,l)=>(0,a.jsx)(eN.Z,{value:String(l),onClick:()=>{Z(e)},children:e.team_alias},l))}):(0,a.jsxs)(h,{children:["No team created. ",(0,a.jsx)("b",{children:"Defaulting to personal account."})]})]}),(0,a.jsxs)(H.Z,{numColSpan:1,children:[(0,a.jsx)(ef.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Member Name"}),(0,a.jsx)(ek.Z,{children:"Role"})]})}),(0,a.jsx)(e_.Z,{children:f?f.members_with_roles.map((e,l)=>(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsx)(ew.Z,{children:e.role})]},l)):null})]})}),f&&(0,a.jsx)(e=>{let{visible:l,onCancel:t,team:s,onSubmit:r}=e,[n]=eo.Z.useForm();return(0,a.jsx)(ei.Z,{title:"Edit Team",visible:l,width:800,footer:null,onOk:()=>{n.validateFields().then(e=>{r({...e,team_id:s.team_id}),n.resetFields()}).catch(e=>{console.error("Validation failed:",e)})},onCancel:t,children:(0,a.jsxs)(eo.Z,{form:n,onFinish:R,initialValues:s,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Team Name",name:"team_alias",rules:[{required:!0,message:"Please input a team name"}],children:(0,a.jsx)(Q.Z,{})}),(0,a.jsx)(eo.Z.Item,{label:"Models",name:"models",children:(0,a.jsxs)(en.default,{mode:"multiple",placeholder:"Select models",style:{width:"100%"},children:[(0,a.jsx)(en.default.Option,{value:"all-proxy-models",children:"All Proxy Models"},"all-proxy-models"),S&&S.map(e=>(0,a.jsx)(en.default.Option,{value:e,children:e},e))]})}),(0,a.jsx)(eo.Z.Item,{label:"Max Budget (USD)",name:"max_budget",children:(0,a.jsx)(ed.Z,{step:.01,precision:2,width:200})}),(0,a.jsx)(eo.Z.Item,{label:"Tokens per minute Limit (TPM)",name:"tpm_limit",children:(0,a.jsx)(ed.Z,{step:1,width:400})}),(0,a.jsx)(eo.Z.Item,{label:"Requests per minute Limit (RPM)",name:"rpm_limit",children:(0,a.jsx)(ed.Z,{step:1,width:400})}),(0,a.jsx)(eo.Z.Item,{label:"Requests per minute Limit (RPM)",name:"team_id",hidden:!0})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Edit Team"})})]})})},{visible:j,onCancel:()=>{g(!1),Z(null)},team:f,onSubmit:R})]}),(0,a.jsxs)(H.Z,{numColSpan:1,children:[(0,a.jsx)(X.Z,{className:"mx-auto mb-5",onClick:()=>v(!0),children:"+ Add member"}),(0,a.jsx)(ei.Z,{title:"Add member",visible:k,width:800,footer:null,onOk:()=>{v(!1),d.resetFields()},onCancel:()=>{v(!1),d.resetFields()},children:(0,a.jsxs)(eo.Z,{form:c,onFinish:z,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,a.jsx)(ec.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,a.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,a.jsx)(eo.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,a.jsx)(ec.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Add member"})})]})})]})]})})},lr=t(18190),la=e=>{let l,{searchParams:t,accessToken:s,showSSOBanner:r}=e,[o]=eo.Z.useForm(),[i]=eo.Z.useForm(),{Title:c,Paragraph:d}=eR.default,[m,h]=(0,n.useState)(""),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)(!1),[f,y]=(0,n.useState)(!1),[Z,_]=(0,n.useState)(!1),[w,b]=(0,n.useState)(!1),[k,v]=(0,n.useState)(!1);try{l=window.location.origin}catch(e){l=""}l+="/fallback/login";let S=()=>{v(!1)},N=["proxy_admin","proxy_admin_viewer"];(0,n.useEffect)(()=>{(async()=>{if(null!=s){let e=[],l=await R(s,"proxy_admin_viewer");l.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy viewers: ".concat(l));let t=await R(s,"proxy_admin");t.forEach(l=>{e.push({user_role:l.user_role,user_id:l.user_id,user_email:l.user_email})}),console.log("proxy admins: ".concat(t)),console.log("combinedList: ".concat(e)),p(e)}})()},[s]);let A=()=>{_(!1),i.resetFields()},E=()=>{_(!1),i.resetFields()},I=e=>(0,a.jsxs)(eo.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Email",name:"user_email",className:"mb-4",children:(0,a.jsx)(ec.Z,{name:"user_email",className:"px-3 py-2 border rounded-md w-full"})}),(0,a.jsx)("div",{className:"text-center mb-4",children:"OR"}),(0,a.jsx)(eo.Z.Item,{label:"User ID",name:"user_id",className:"mb-4",children:(0,a.jsx)(ec.Z,{name:"user_id",className:"px-3 py-2 border rounded-md w-full"})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Add member"})})]}),C=(e,l,t)=>(0,a.jsxs)(eo.Z,{form:o,onFinish:e,labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{rules:[{required:!0,message:"Required"}],label:"User Role",name:"user_role",labelCol:{span:10},labelAlign:"left",children:(0,a.jsx)(eS.Z,{value:l,children:N.map((e,l)=>(0,a.jsx)(eN.Z,{value:e,children:e},l))})}),(0,a.jsx)(eo.Z.Item,{label:"Team ID",name:"user_id",hidden:!0,initialValue:t,valuePropName:"user_id",className:"mt-8",children:(0,a.jsx)(ec.Z,{value:t,disabled:!0})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Update role"})})]}),P=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,null);console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),u.ZP.success("Refresh tab to see updated user role"),_(!1)}}catch(e){console.error("Error creating the key:",e)}},T=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call");let l=await B(s,e,"proxy_admin_viewer");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),g(!1)}}catch(e){console.error("Error creating the key:",e)}},O=async e=>{try{if(null!=s&&null!=x){u.ZP.info("Making API Call"),e.user_email,e.user_id;let l=await B(s,e,"proxy_admin");console.log("response for team create call: ".concat(l));let t=x.findIndex(e=>(console.log("user.user_id=".concat(e.user_id,"; response.user_id=").concat(l.user_id)),e.user_id===l.user_id));console.log("foundIndex: ".concat(t)),-1==t&&(console.log("updates admin with new user"),x.push(l),p(x)),y(!1)}}catch(e){console.error("Error creating the key:",e)}},F=async e=>{null!=s&&W(s,{environment_variables:{PROXY_BASE_URL:e.proxy_base_url,GOOGLE_CLIENT_ID:e.google_client_id,GOOGLE_CLIENT_SECRET:e.google_client_secret}})};return console.log("admins: ".concat(null==x?void 0:x.length)),(0,a.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,a.jsx)(c,{level:4,children:"Admin Access "}),(0,a.jsxs)(d,{children:[r&&(0,a.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/ui#restrict-ui-access",children:"Requires SSO Setup"}),(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin: "})," Can create keys, teams, users, add models, etc. ",(0,a.jsx)("br",{}),(0,a.jsx)("b",{children:"Proxy Admin Viewer: "}),"Can just view spend. They cannot create keys, teams or grant users access to new models."," "]}),(0,a.jsxs)($.Z,{numItems:1,className:"gap-2 p-2 w-full",children:[(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsx)(ef.Z,{className:"w-full mx-auto flex-auto overflow-y-auto max-h-[50vh]",children:(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Member Name"}),(0,a.jsx)(ek.Z,{children:"Role"})]})}),(0,a.jsx)(e_.Z,{children:x?x.map((e,l)=>(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:e.user_email?e.user_email:e.user_id?e.user_id:null}),(0,a.jsx)(ew.Z,{children:e.user_role}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(ey.Z,{icon:ep.Z,size:"sm",onClick:()=>_(!0)}),(0,a.jsx)(ei.Z,{title:"Update role",visible:Z,width:800,footer:null,onOk:A,onCancel:E,children:C(P,e.user_role,e.user_id)})]})]},l)):null})]})})}),(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsxs)("div",{className:"flex justify-start",children:[(0,a.jsx)(X.Z,{className:"mr-4 mb-5",onClick:()=>y(!0),children:"+ Add admin"}),(0,a.jsx)(ei.Z,{title:"Add admin",visible:f,width:800,footer:null,onOk:()=>{y(!1),i.resetFields()},onCancel:()=>{y(!1),i.resetFields()},children:I(O)}),(0,a.jsx)(X.Z,{className:"mb-5",onClick:()=>g(!0),children:"+ Add viewer"}),(0,a.jsx)(ei.Z,{title:"Add viewer",visible:j,width:800,footer:null,onOk:()=>{g(!1),i.resetFields()},onCancel:()=>{g(!1),i.resetFields()},children:I(T)})]})})]}),(0,a.jsxs)($.Z,{children:[(0,a.jsx)(c,{level:4,children:"Add SSO"}),(0,a.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,a.jsx)(X.Z,{onClick:()=>b(!0),children:"Add SSO"}),(0,a.jsx)(ei.Z,{title:"Add SSO",visible:w,width:800,footer:null,onOk:()=>{b(!1),o.resetFields()},onCancel:()=>{b(!1),o.resetFields()},children:(0,a.jsxs)(eo.Z,{form:o,onFinish:e=>{O(e),F(e),b(!1),v(!0)},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Admin Email",name:"user_email",rules:[{required:!0,message:"Please enter the email of the proxy admin"}],children:(0,a.jsx)(ec.Z,{})}),(0,a.jsx)(eo.Z.Item,{label:"PROXY BASE URL",name:"proxy_base_url",rules:[{required:!0,message:"Please enter the proxy base url"}],children:(0,a.jsx)(ec.Z,{})}),(0,a.jsx)(eo.Z.Item,{label:"GOOGLE CLIENT ID",name:"google_client_id",rules:[{required:!0,message:"Please enter the google client id"}],children:(0,a.jsx)(ec.Z.Password,{})}),(0,a.jsx)(eo.Z.Item,{label:"GOOGLE CLIENT SECRET",name:"google_client_secret",rules:[{required:!0,message:"Please enter the google client secret"}],children:(0,a.jsx)(ec.Z.Password,{})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Save"})})]})}),(0,a.jsxs)(ei.Z,{title:"SSO Setup Instructions",visible:k,width:800,footer:null,onOk:S,onCancel:()=>{v(!1)},children:[(0,a.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,a.jsx)(es.Z,{className:"mt-2",children:"1. DO NOT Exit this TAB"}),(0,a.jsx)(es.Z,{className:"mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,a.jsx)(es.Z,{className:"mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,a.jsx)(es.Z,{className:"mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{onClick:S,children:"Done"})})]})]}),(0,a.jsxs)(lr.Z,{title:"Login without SSO",color:"teal",children:["If you need to login without sso, you can access ",(0,a.jsxs)("a",{href:l,target:"_blank",children:[(0,a.jsx)("b",{children:l})," "]})]})]})]})},ln=t(42556);let lo=[{name:"slack",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"langfuse",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}},{name:"openmeter",variables:{LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null,SLACK_WEBHOOK_URL:null}}];var li=e=>{let{accessToken:l,userRole:t,userID:s}=e,[r,o]=(0,n.useState)(lo),[i,c]=(0,n.useState)([]),[d,m]=(0,n.useState)(!1),[h]=eo.Z.useForm(),[x,p]=(0,n.useState)(null),[j,g]=(0,n.useState)([]),[f,y]=(0,n.useState)(""),[Z,_]=(0,n.useState)({}),[w,b]=(0,n.useState)([]),k=e=>{w.includes(e)?b(w.filter(l=>l!==e)):b([...w,e])},v={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)",daily_reports:"Weekly/Monthly Spend Reports"};(0,n.useEffect)(()=>{l&&t&&s&&V(l,s,t).then(e=>{console.log("callbacks",e);let l=lo;o(l=l.map(l=>{let t=e.callbacks.find(e=>e.name===l.name);return t?{...l,variables:{...l.variables,...t.variables}}:l}));let t=e.alerts;if(console.log("alerts_data",t),t&&t.length>0){let e=t[0];console.log("_alert_info",e);let l=e.variables.SLACK_WEBHOOK_URL;console.log("catch_all_webhook",l),b(e.active_alerts),y(l),_(e.alerts_to_webhook)}c(t)})},[l,t,s]);let S=e=>w&&w.includes(e),N=e=>{if(!l)return;let t=Object.fromEntries(Object.entries(e.variables).map(e=>{var l;let[t,s]=e;return[t,(null===(l=document.querySelector('input[name="'.concat(t,'"]')))||void 0===l?void 0:l.value)||s]}));console.log("updatedVariables",t),console.log("updateAlertTypes",j);let s={environment_variables:t,litellm_settings:{success_callback:[e.name]}};try{W(l,s)}catch(e){u.ZP.error("Failed to update callback: "+e,20)}u.ZP.success("Callback updated successfully")},A=()=>{l&&h.validateFields().then(e=>{if(console.log("Form values:",e),"langfuse"===e.callback){W(l,{environment_variables:{LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:e.langfusePublicKey,LANGFUSE_SECRET_KEY:e.langfusePrivateKey,OPENMETER_API_KEY:null}};o(r?[...r,t]:[t])}else if("slack"===e.callback){console.log("values.slackWebhookUrl: ".concat(e.slackWebhookUrl)),W(l,{general_settings:{alerting:["slack"],alerting_threshold:300},environment_variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl}}),console.log("values.callback: ".concat(e.callback));let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:e.slackWebhookUrl,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:null}};o(r?[...r,t]:[t])}else if("openmeter"==e.callback){console.log("values.openMeterApiKey: ".concat(e.openMeterApiKey)),W(l,{environment_variables:{OPENMETER_API_KEY:e.openMeterApiKey},litellm_settings:{success_callback:[e.callback]}});let t={name:e.callback,variables:{SLACK_WEBHOOK_URL:null,LANGFUSE_HOST:null,LANGFUSE_PUBLIC_KEY:null,LANGFUSE_SECRET_KEY:null,OPENMETER_API_KEY:e.openMeterAPIKey}};o(r?[...r,t]:[t])}m(!1),h.resetFields(),p(null)})};return l?(console.log("callbacks: ".concat(r)),(0,a.jsxs)("div",{className:"w-full mx-4",children:[(0,a.jsxs)($.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,a.jsx)(lr.Z,{title:"[UI] Presidio PII + Guardrails Coming Soon. https://docs.litellm.ai/docs/proxy/pii_masking",color:"sky"}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsxs)(eK.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(eU.Z,{value:"1",children:"Logging Callbacks"}),(0,a.jsx)(eU.Z,{value:"2",children:"Alerting"})]}),(0,a.jsxs)(ez.Z,{children:[(0,a.jsx)(eB.Z,{children:(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Callback"}),(0,a.jsx)(ek.Z,{children:"Callback Env Vars"})]})}),(0,a.jsx)(e_.Z,{children:r.filter(e=>"slack"!==e.name).map((e,t)=>{var s;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:(0,a.jsx)(eg.Z,{color:"emerald",children:e.name})}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)("ul",{children:Object.entries(null!==(s=e.variables)&&void 0!==s?s:{}).filter(l=>{let[t,s]=l;return t.toLowerCase().includes(e.name)}).map(e=>{let[l,t]=e;return(0,a.jsxs)("li",{children:[(0,a.jsx)(es.Z,{className:"mt-2",children:l}),"LANGFUSE_HOST"===l?(0,a.jsx)("p",{children:"default value=https://cloud.langfuse.com"}):(0,a.jsx)("div",{}),(0,a.jsx)(Q.Z,{name:l,defaultValue:t,type:"password"})]},l)})}),(0,a.jsx)(X.Z,{className:"mt-2",onClick:()=>N(e),children:"Save Changes"}),(0,a.jsx)(X.Z,{onClick:()=>z(l,e.name),className:"mx-2",children:"Test Callback"})]})]},t)})})]})})}),(0,a.jsx)(eB.Z,{children:(0,a.jsxs)(ef.Z,{children:[(0,a.jsxs)(es.Z,{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from ",(0,a.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{}),(0,a.jsx)(ek.Z,{}),(0,a.jsx)(ek.Z,{children:"Slack Webhook URL"})]})}),(0,a.jsx)(e_.Z,{children:Object.entries(v).map((e,l)=>{let[t,s]=e;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:(0,a.jsx)(ln.Z,{id:"switch",name:"switch",checked:S(t),onChange:()=>k(t)})}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(es.Z,{children:s})}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(Q.Z,{name:t,type:"password",defaultValue:Z&&Z[t]?Z[t]:f})})]},l)})})]}),(0,a.jsx)(X.Z,{size:"xs",className:"mt-2",onClick:()=>{if(!l)return;let e={};Object.entries(v).forEach(l=>{let[t,s]=l,r=document.querySelector('input[name="'.concat(t,'"]'));console.log("key",t),console.log("webhookInput",r);let a=(null==r?void 0:r.value)||"";console.log("newWebhookValue",a),e[t]=a}),console.log("updatedAlertToWebhooks",e);let t={general_settings:{alert_to_webhook_url:e,alert_types:w}};console.log("payload",t);try{W(l,t)}catch(e){u.ZP.error("Failed to update alerts: "+e,20)}u.ZP.success("Alerts updated successfully")},children:"Save Changes"}),(0,a.jsx)(X.Z,{onClick:()=>z(l,"slack"),className:"mx-2",children:"Test Alerts"})]})})]})]})]}),(0,a.jsx)(ei.Z,{title:"Add Callback",visible:d,onOk:A,width:800,onCancel:()=>{m(!1),h.resetFields(),p(null)},footer:null,children:(0,a.jsxs)(eo.Z,{form:h,layout:"vertical",onFinish:A,children:[(0,a.jsx)(eo.Z.Item,{label:"Callback",name:"callback",rules:[{required:!0,message:"Please select a callback"}],children:(0,a.jsxs)(en.default,{onChange:e=>{p(e)},children:[(0,a.jsx)(en.default.Option,{value:"langfuse",children:"langfuse"}),(0,a.jsx)(en.default.Option,{value:"openmeter",children:"openmeter"})]})}),"langfuse"===x&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"LANGFUSE_PUBLIC_KEY",name:"langfusePublicKey",rules:[{required:!0,message:"Please enter the public key"}],children:(0,a.jsx)(Q.Z,{type:"password"})}),(0,a.jsx)(eo.Z.Item,{label:"LANGFUSE_PRIVATE_KEY",name:"langfusePrivateKey",rules:[{required:!0,message:"Please enter the private key"}],children:(0,a.jsx)(Q.Z,{type:"password"})})]}),"openmeter"==x&&(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(eo.Z.Item,{label:"OPENMETER_API_KEY",name:"openMeterApiKey",rules:[{required:!0,message:"Please enter the openmeter api key"}],children:(0,a.jsx)(Q.Z,{type:"password"})})}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Save"})})]})})]})):null};let{Option:lc}=en.default;var ld=e=>{let{models:l,accessToken:t,routerSettings:s,setRouterSettings:r}=e,[o]=eo.Z.useForm(),[i,c]=(0,n.useState)(!1),[d,m]=(0,n.useState)("");return(0,a.jsxs)("div",{children:[(0,a.jsx)(X.Z,{className:"mx-auto",onClick:()=>c(!0),children:"+ Add Fallbacks"}),(0,a.jsx)(ei.Z,{title:"Add Fallbacks",visible:i,width:800,footer:null,onOk:()=>{c(!1),o.resetFields()},onCancel:()=>{c(!1),o.resetFields()},children:(0,a.jsxs)(eo.Z,{form:o,onFinish:e=>{console.log(e);let{model_name:l,models:a}=e,n=[...s.fallbacks||[],{[l]:a}],i={...s,fallbacks:n};console.log(i);try{W(t,{router_settings:i}),r(i)}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully"),c(!1),o.resetFields()},labelCol:{span:8},wrapperCol:{span:16},labelAlign:"left",children:[(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(eo.Z.Item,{label:"Public Model Name",name:"model_name",rules:[{required:!0,message:"Set the model to fallback for"}],help:"required",children:(0,a.jsx)(eS.Z,{defaultValue:d,children:l&&l.map((e,l)=>(0,a.jsx)(eN.Z,{value:e,onClick:()=>m(e),children:e},l))})}),(0,a.jsx)(eo.Z.Item,{label:"Fallback Models",name:"models",rules:[{required:!0,message:"Please select a model"}],help:"required",children:(0,a.jsx)(eV.Z,{value:l,children:l&&l.filter(e=>e!=d).map(e=>(0,a.jsx)(eq.Z,{value:e,children:e},e))})})]}),(0,a.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,a.jsx)(em.ZP,{htmlType:"submit",children:"Add Fallbacks"})})]})})]})},lm=t(12968);async function lu(e,l){console.log("isLocal:",!1);let t=window.location.origin,s=new lm.ZP.OpenAI({apiKey:l,baseURL:t,dangerouslyAllowBrowser:!0});try{let l=await s.chat.completions.create({model:e,messages:[{role:"user",content:"Hi, this is a test message"}],mock_testing_fallbacks:!0});u.ZP.success((0,a.jsxs)("span",{children:["Test model=",(0,a.jsx)("strong",{children:e}),", received model=",(0,a.jsx)("strong",{children:l.model}),". See"," ",(0,a.jsx)("a",{href:"#",onClick:()=>window.open("https://docs.litellm.ai/docs/proxy/reliability","_blank"),style:{textDecoration:"underline",color:"blue"},children:"curl"})]}))}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}let lh={ttl:3600,lowest_latency_buffer:0},lx=e=>{let{selectedStrategy:l,strategyArgs:t,paramExplanation:s}=e;return(0,a.jsxs)(ee.Z,{children:[(0,a.jsx)(et.Z,{className:"text-sm font-medium text-tremor-content-strong dark:text-dark-tremor-content-strong",children:"Routing Strategy Specific Args"}),(0,a.jsx)(el.Z,{children:"latency-based-routing"==l?(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Setting"}),(0,a.jsx)(ek.Z,{children:"Value"})]})}),(0,a.jsx)(e_.Z,{children:Object.entries(t).map(e=>{let[l,t]=e;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(es.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:s[l]})]}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(Q.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]})}):(0,a.jsx)(es.Z,{children:"No specific settings"})})]})};var lp=e=>{let{accessToken:l,userRole:t,userID:s,modelData:r}=e,[o,i]=(0,n.useState)({}),[c,d]=(0,n.useState)({}),[m,h]=(0,n.useState)([]),[x,p]=(0,n.useState)(!1),[j]=eo.Z.useForm(),[g,f]=(0,n.useState)(null),[y,Z]=(0,n.useState)(null),[_,w]=(0,n.useState)(null),b={routing_strategy_args:"(dict) Arguments to pass to the routing strategy",routing_strategy:"(string) Routing strategy to use",allowed_fails:"(int) Number of times a deployment can fail before being added to cooldown",cooldown_time:"(int) time in seconds to cooldown a deployment after failure",num_retries:"(int) Number of retries for failed requests. Defaults to 0.",timeout:"(float) Timeout for requests. Defaults to None.",retry_after:"(int) Minimum time to wait before retrying a failed request",ttl:"(int) Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"(float) Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};(0,n.useEffect)(()=>{l&&t&&s&&(V(l,s,t).then(e=>{console.log("callbacks",e),i(e.router_settings)}),q(l).then(e=>{h(e)}))},[l,t,s]);let k=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 W(l,{router_settings:o}),i({...o}),Z(o.routing_strategy),u.ZP.success("Router settings updated successfully")}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}}},v=(e,l)=>{h(m.map(t=>t.field_name===e?{...t,field_value:l}:t))},S=(e,t)=>{if(!l)return;let s=m[t].field_value;if(null!=s&&void 0!=s)try{G(l,e,s);let t=m.map(l=>l.field_name===e?{...l,stored_in_db:!0}:l);h(t)}catch(e){}},N=(e,t)=>{if(l)try{Y(l,e);let t=m.map(l=>l.field_name===e?{...l,stored_in_db:null,field_value:null}:l);h(t)}catch(e){}},A=e=>{if(!l)return;console.log("router_settings",e);let t=Object.fromEntries(Object.entries(e).map(e=>{let[l,t]=e;if("routing_strategy_args"!==l&&"routing_strategy"!==l){var s;return[l,(null===(s=document.querySelector('input[name="'.concat(l,'"]')))||void 0===s?void 0:s.value)||t]}if("routing_strategy"==l)return[l,y];if("routing_strategy_args"==l&&"latency-based-routing"==y){let e={},l=document.querySelector('input[name="lowest_latency_buffer"]'),t=document.querySelector('input[name="ttl"]');return(null==l?void 0:l.value)&&(e.lowest_latency_buffer=Number(l.value)),(null==t?void 0:t.value)&&(e.ttl=Number(t.value)),console.log("setRoutingStrategyArgs: ".concat(e)),["routing_strategy_args",e]}return null}).filter(e=>null!=e));console.log("updatedVariables",t);try{W(l,{router_settings:t})}catch(e){u.ZP.error("Failed to update router settings: "+e,20)}u.ZP.success("router settings updated successfully")};return l?(0,a.jsx)("div",{className:"w-full mx-4",children:(0,a.jsxs)(eD.Z,{className:"gap-2 p-8 h-[75vh] w-full mt-2",children:[(0,a.jsxs)(eK.Z,{variant:"line",defaultValue:"1",children:[(0,a.jsx)(eU.Z,{value:"1",children:"Loadbalancing"}),(0,a.jsx)(eU.Z,{value:"2",children:"Fallbacks"}),(0,a.jsx)(eU.Z,{value:"3",children:"General"})]}),(0,a.jsxs)(ez.Z,{children:[(0,a.jsx)(eB.Z,{children:(0,a.jsxs)($.Z,{numItems:1,className:"gap-2 p-8 w-full mt-2",children:[(0,a.jsx)(er.Z,{children:"Router Settings"}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Setting"}),(0,a.jsx)(ek.Z,{children:"Value"})]})}),(0,a.jsx)(e_.Z,{children:Object.entries(o).filter(e=>{let[l,t]=e;return"fallbacks"!=l&&"context_window_fallbacks"!=l&&"routing_strategy_args"!=l}).map(e=>{let[l,t]=e;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(es.Z,{children:l}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:b[l]})]}),(0,a.jsx)(ew.Z,{children:"routing_strategy"==l?(0,a.jsxs)(eS.Z,{defaultValue:t,className:"w-full max-w-md",onValueChange:Z,children:[(0,a.jsx)(eN.Z,{value:"usage-based-routing",children:"usage-based-routing"}),(0,a.jsx)(eN.Z,{value:"latency-based-routing",children:"latency-based-routing"}),(0,a.jsx)(eN.Z,{value:"simple-shuffle",children:"simple-shuffle"})]}):(0,a.jsx)(Q.Z,{name:l,defaultValue:"object"==typeof t?JSON.stringify(t,null,2):t.toString()})})]},l)})})]}),(0,a.jsx)(lx,{selectedStrategy:y,strategyArgs:o&&o.routing_strategy_args&&Object.keys(o.routing_strategy_args).length>0?o.routing_strategy_args:lh,paramExplanation:b})]}),(0,a.jsx)(H.Z,{children:(0,a.jsx)(X.Z,{className:"mt-2",onClick:()=>A(o),children:"Save Changes"})})]})}),(0,a.jsxs)(eB.Z,{children:[(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Model Name"}),(0,a.jsx)(ek.Z,{children:"Fallbacks"})]})}),(0,a.jsx)(e_.Z,{children:o.fallbacks&&o.fallbacks.map((e,t)=>Object.entries(e).map(e=>{let[s,r]=e;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:s}),(0,a.jsx)(ew.Z,{children:Array.isArray(r)?r.join(", "):r}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(X.Z,{onClick:()=>lu(s,l),children:"Test Fallback"})}),(0,a.jsx)(ew.Z,{children:(0,a.jsx)(ey.Z,{icon:ej.Z,size:"sm",onClick:()=>k(s)})})]},t.toString()+s)}))})]}),(0,a.jsx)(ld,{models:(null==r?void 0:r.data)?r.data.map(e=>e.model_name):[],accessToken:l,routerSettings:o,setRouterSettings:i})]}),(0,a.jsx)(eB.Z,{children:(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(eZ.Z,{children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"Setting"}),(0,a.jsx)(ek.Z,{children:"Value"}),(0,a.jsx)(ek.Z,{children:"Status"}),(0,a.jsx)(ek.Z,{children:"Action"})]})}),(0,a.jsx)(e_.Z,{children:m.map((e,l)=>(0,a.jsxs)(ev.Z,{children:[(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(es.Z,{children:e.field_name}),(0,a.jsx)("p",{style:{fontSize:"0.65rem",color:"#808080",fontStyle:"italic"},className:"mt-1",children:e.field_description})]}),(0,a.jsx)(ew.Z,{children:"Integer"==e.field_type?(0,a.jsx)(ed.Z,{step:1,value:e.field_value,onChange:l=>v(e.field_name,l)}):null}),(0,a.jsx)(ew.Z,{children:!0==e.stored_in_db?(0,a.jsx)(eg.Z,{icon:eQ.Z,className:"text-white",children:"In DB"}):!1==e.stored_in_db?(0,a.jsx)(eg.Z,{className:"text-gray bg-white outline",children:"In Config"}):(0,a.jsx)(eg.Z,{className:"text-gray bg-white outline",children:"Not Set"})}),(0,a.jsxs)(ew.Z,{children:[(0,a.jsx)(X.Z,{onClick:()=>S(e.field_name,l),children:"Update"}),(0,a.jsx)(ey.Z,{icon:ej.Z,color:"red",onClick:()=>N(e.field_name,l),children:"Reset"})]})]},l))})]})})})]})]})}):null},lj=t(67951),lg=e=>{let{}=e;return(0,a.jsx)(a.Fragment,{children:(0,a.jsx)($.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsxs)("div",{className:"mb-5",children:[(0,a.jsx)("p",{className:"text-2xl text-tremor-content-strong dark:text-dark-tremor-content-strong font-semibold",children:"OpenAI Compatible Proxy: API Reference"}),(0,a.jsx)(es.Z,{className:"mt-2 mb-2",children:"LiteLLM is OpenAI Compatible. This means your API Key works with the OpenAI SDK. Just replace the base_url to point to your litellm proxy. Example Below "}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsxs)(eK.Z,{children:[(0,a.jsx)(eU.Z,{children:"OpenAI Python SDK"}),(0,a.jsx)(eU.Z,{children:"LlamaIndex"}),(0,a.jsx)(eU.Z,{children:"Langchain Py"})]}),(0,a.jsxs)(ez.Z,{children:[(0,a.jsx)(eB.Z,{children:(0,a.jsx)(lj.Z,{language:"python",children:'\nimport openai\nclient = openai.OpenAI(\n api_key="your_api_key",\n base_url="http://0.0.0.0:4000" # LiteLLM Proxy is OpenAI compatible, Read More: https://docs.litellm.ai/docs/proxy/user_keys\n)\n\nresponse = client.chat.completions.create(\n model="gpt-3.5-turbo", # model to send to the proxy\n messages = [\n {\n "role": "user",\n "content": "this is a test request, write a short poem"\n }\n ]\n)\n\nprint(response)\n '})}),(0,a.jsx)(eB.Z,{children:(0,a.jsx)(lj.Z,{language:"python",children:'\nimport os, dotenv\n\nfrom llama_index.llms import AzureOpenAI\nfrom llama_index.embeddings import AzureOpenAIEmbedding\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader, ServiceContext\n\nllm = AzureOpenAI(\n engine="azure-gpt-3.5", # model_name on litellm proxy\n temperature=0.0,\n azure_endpoint="http://0.0.0.0:4000", # litellm proxy endpoint\n api_key="sk-1234", # litellm proxy API Key\n api_version="2023-07-01-preview",\n)\n\nembed_model = AzureOpenAIEmbedding(\n deployment_name="azure-embedding-model",\n azure_endpoint="http://0.0.0.0:4000",\n api_key="sk-1234",\n api_version="2023-07-01-preview",\n)\n\n\ndocuments = SimpleDirectoryReader("llama_index_data").load_data()\nservice_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model)\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nquery_engine = index.as_query_engine()\nresponse = query_engine.query("What did the author do growing up?")\nprint(response)\n\n '})}),(0,a.jsx)(eB.Z,{children:(0,a.jsx)(lj.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 lf(e,l,t,s){console.log("isLocal:",!1);let r=window.location.origin,a=new lm.ZP.OpenAI({apiKey:s,baseURL:r,dangerouslyAllowBrowser:!0});try{for await(let s of(await a.chat.completions.create({model:t,stream:!0,messages:[{role:"user",content:e}]})))console.log(s),s.choices[0].delta.content&&l(s.choices[0].delta.content)}catch(e){u.ZP.error("Error occurred while generating model response. Please try again. Error: ".concat(e),20)}}var ly=e=>{let{accessToken:l,token:t,userRole:s,userID:r}=e,[o,i]=(0,n.useState)(""),[c,d]=(0,n.useState)(""),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)(void 0),[p,j]=(0,n.useState)([]);(0,n.useEffect)(()=>{l&&t&&s&&r&&(async()=>{try{let e=await N(l,r,s);if(console.log("model_info:",e),(null==e?void 0:e.data.length)>0){let l=e.data.map(e=>({value:e.id,label:e.id}));console.log(l),j(l),x(e.data[0].id)}}catch(e){console.error("Error fetching model info:",e)}})()},[l,r,s]);let g=(e,l)=>{u(t=>{let s=t[t.length-1];return s&&s.role===e?[...t.slice(0,t.length-1),{role:e,content:s.content+l}]:[...t,{role:e,content:l}]})},f=async()=>{if(""!==c.trim()&&o&&t&&s&&r){u(e=>[...e,{role:"user",content:c}]);try{h&&await lf(c,e=>g("assistant",e),h,o)}catch(e){console.error("Error fetching model response",e),g("assistant","Error fetching model response")}d("")}};if(s&&"Admin Viewer"==s){let{Title:e,Paragraph:l}=eR.default;return(0,a.jsxs)("div",{children:[(0,a.jsx)(e,{level:1,children:"Access Denied"}),(0,a.jsx)(l,{children:"Ask your proxy admin for access to test models"})]})}return(0,a.jsx)("div",{style:{width:"100%",position:"relative"},children:(0,a.jsx)($.Z,{className:"gap-2 p-8 h-[80vh] w-full mt-2",children:(0,a.jsx)(ef.Z,{children:(0,a.jsxs)(eD.Z,{children:[(0,a.jsx)(eK.Z,{children:(0,a.jsx)(eU.Z,{children:"Chat"})}),(0,a.jsx)(ez.Z,{children:(0,a.jsxs)(eB.Z,{children:[(0,a.jsx)("div",{className:"sm:max-w-2xl",children:(0,a.jsxs)($.Z,{numItems:2,children:[(0,a.jsxs)(H.Z,{children:[(0,a.jsx)(es.Z,{children:"API Key"}),(0,a.jsx)(Q.Z,{placeholder:"Type API Key here",type:"password",onValueChange:i,value:o})]}),(0,a.jsxs)(H.Z,{className:"mx-2",children:[(0,a.jsx)(es.Z,{children:"Select Model:"}),(0,a.jsx)(en.default,{placeholder:"Select a Model",onChange:e=>{console.log("selected ".concat(e)),x(e)},options:p,style:{width:"200px"}})]})]})}),(0,a.jsxs)(eZ.Z,{className:"mt-5",style:{display:"block",maxHeight:"60vh",overflowY:"auto"},children:[(0,a.jsx)(eb.Z,{children:(0,a.jsx)(ev.Z,{children:(0,a.jsx)(ew.Z,{})})}),(0,a.jsx)(e_.Z,{children:m.map((e,l)=>(0,a.jsx)(ev.Z,{children:(0,a.jsx)(ew.Z,{children:"".concat(e.role,": ").concat(e.content)})},l))})]}),(0,a.jsx)("div",{className:"mt-3",style:{position:"absolute",bottom:5,width:"95%"},children:(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)(Q.Z,{type:"text",value:c,onChange:e=>d(e.target.value),placeholder:"Type your message..."}),(0,a.jsx)(X.Z,{onClick:f,className:"ml-2",children:"Send"})]})})]})})]})})})})},lZ=t(33509),l_=t(95781);let{Sider:lw}=lZ.default;var lb=e=>{let{setPage:l,userRole:t,defaultSelectedKey:s}=e;return"Admin Viewer"==t?(0,a.jsx)(lZ.default,{style:{minHeight:"100vh",maxWidth:"120px"},children:(0,a.jsx)(lw,{width:120,children:(0,a.jsxs)(l_.Z,{mode:"inline",defaultSelectedKeys:s||["4"],style:{height:"100%",borderRight:0},children:[(0,a.jsx)(l_.Z.Item,{onClick:()=>l("api-keys"),children:"API Keys"},"4"),(0,a.jsx)(l_.Z.Item,{onClick:()=>l("models"),children:"Models"},"2"),(0,a.jsx)(l_.Z.Item,{onClick:()=>l("llm-playground"),children:"Chat UI"},"3"),(0,a.jsx)(l_.Z.Item,{onClick:()=>l("usage"),children:"Usage"},"1")]})})}):(0,a.jsx)(lZ.default,{style:{minHeight:"100vh",maxWidth:"145px"},children:(0,a.jsx)(lw,{width:145,children:(0,a.jsxs)(l_.Z,{mode:"inline",defaultSelectedKeys:s||["1"],style:{height:"100%",borderRight:0},children:[(0,a.jsx)(l_.Z.Item,{onClick:()=>l("api-keys"),children:(0,a.jsx)(es.Z,{children:"API Keys"})},"1"),(0,a.jsx)(l_.Z.Item,{onClick:()=>l("llm-playground"),children:(0,a.jsx)(es.Z,{children:"Test Key"})},"3"),"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("models"),children:(0,a.jsx)(es.Z,{children:"Models"})},"2"):null,"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("usage"),children:(0,a.jsx)(es.Z,{children:"Usage"})},"4"):null,"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("teams"),children:(0,a.jsx)(es.Z,{children:"Teams"})},"6"):null,"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("users"),children:(0,a.jsx)(es.Z,{children:"Users"})},"5"):null,"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("settings"),children:(0,a.jsx)(es.Z,{children:"Logging & Alerts"})},"8"):null,"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("general-settings"),children:(0,a.jsx)(es.Z,{children:"Router Settings"})},"9"):null,"Admin"==t?(0,a.jsx)(l_.Z.Item,{onClick:()=>l("admin-panel"),children:(0,a.jsx)(es.Z,{children:"Admin"})},"7"):null,(0,a.jsx)(l_.Z.Item,{onClick:()=>l("api_ref"),children:(0,a.jsx)(es.Z,{children:"API Reference"})},"11")]})})})},lk=t(67989),lv=e=>{let{accessToken:l,token:t,userRole:s,userID:r,keys:o}=e,i=new Date,[c,d]=(0,n.useState)([]),[m,u]=(0,n.useState)([]),[h,x]=(0,n.useState)([]),[p,j]=(0,n.useState)([]),[g,f]=(0,n.useState)([]),[y,Z]=(0,n.useState)([]),[_,w]=(0,n.useState)([]),[b,k]=(0,n.useState)([]),[v,S]=(0,n.useState)(""),[N,R]=(0,n.useState)({from:new Date(Date.now()-6048e5),to:new Date}),M=new Date(i.getFullYear(),i.getMonth(),1),L=new Date(i.getFullYear(),i.getMonth()+1,0),U=z(M),D=z(L);console.log("keys in usage",o);let K=async(e,t,s)=>{if(!e||!t||!l)return;console.log("uiSelectedKey",s);let r=await T(l,s,e.toISOString(),t.toISOString());console.log("End user data updated successfully",r),j(r)},B=async(e,t)=>{e&&t&&l&&(Z((await E(l,e.toISOString(),t.toISOString())).spend_per_tag),console.log("Tag spend data updated successfully"))};function z(e){let l=e.getFullYear(),t=e.getMonth()+1,s=e.getDate();return"".concat(l,"-").concat(t<10?"0"+t:t,"-").concat(s<10?"0"+s:s)}return console.log("Start date is ".concat(U)),console.log("End date is ".concat(D)),(0,n.useEffect)(()=>{l&&t&&s&&r&&(async()=>{try{if(console.log("user role: ".concat(s)),"Admin"==s||"Admin Viewer"==s){var e,a;let t=await C(l);d(t);let s=(await P(l)).map(e=>({key:(e.key_name||e.key_alias||e.api_key).substring(0,10),spend:e.total_spend}));u(s);let r=(await O(l)).map(e=>({key:e.model,spend:e.total_spend}));x(r);let n=await A(l);console.log("teamSpend",n),f(n.daily_spend),w(n.teams);let o=n.total_spend_per_team;o=o.map(e=>(e.name=e.team_id||"",e.value=e.total_spend||0,e)),k(o);let i=await E(l,null===(e=N.from)||void 0===e?void 0:e.toISOString(),null===(a=N.to)||void 0===a?void 0:a.toISOString());Z(i.spend_per_tag);let c=await T(l,null,void 0,void 0);j(c),console.log("spend/user result",c)}else"App Owner"==s&&await I(l,t,s,r,U,D).then(async e=>{if(console.log("result from spend logs call",e),"daily_spend"in e){let l=e.daily_spend;console.log("daily spend",l),d(l);let t=e.top_api_keys;u(t)}else{let t=(await F(l,function(e){let l=[];e.forEach(e=>{Object.entries(e).forEach(e=>{let[t,s]=e;"spend"!==t&&"startTime"!==t&&"models"!==t&&"users"!==t&&l.push({key:t,spend:s})})}),l.sort((e,l)=>Number(l.spend)-Number(e.spend));let t=l.slice(0,5).map(e=>e.key);return console.log("topKeys: ".concat(Object.keys(t[0]))),t}(e))).info.map(e=>({key:(e.key_name||e.key_alias).substring(0,10),spend:e.spend}));u(t),d(e)}})}catch(e){console.error("There was an error fetching the data",e)}})()},[l,t,s,r,U,D]),(0,a.jsxs)("div",{style:{width:"100%"},className:"p-8",children:[(0,a.jsx)(eP,{userID:r,userRole:s,accessToken:l,userSpend:null,selectedTeam:null}),(0,a.jsxs)(eD.Z,{children:[(0,a.jsxs)(eK.Z,{className:"mt-2",children:[(0,a.jsx)(eU.Z,{children:"All Up"}),(0,a.jsx)(eU.Z,{children:"Team Based Usage"}),(0,a.jsx)(eU.Z,{children:"End User Usage"}),(0,a.jsx)(eU.Z,{children:"Tag Based Usage"})]}),(0,a.jsxs)(ez.Z,{children:[(0,a.jsx)(eB.Z,{children:(0,a.jsxs)($.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsx)(H.Z,{numColSpan:2,children:(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(er.Z,{children:"Monthly Spend"}),(0,a.jsx)(eY.Z,{data:c,index:"date",categories:["spend"],colors:["blue"],valueFormatter:e=>"$ ".concat(new Intl.NumberFormat("us").format(e).toString()),yAxisWidth:100,tickGap:5})]})}),(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(er.Z,{children:"Top API Keys"}),(0,a.jsx)(eY.Z,{className:"mt-4 h-40",data:m,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:80,tickGap:5,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(H.Z,{numColSpan:1,children:(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(er.Z,{children:"Top Models"}),(0,a.jsx)(eY.Z,{className:"mt-4 h-40",data:h,index:"key",categories:["spend"],colors:["blue"],yAxisWidth:200,layout:"vertical",showXAxis:!1,showLegend:!1})]})}),(0,a.jsx)(H.Z,{numColSpan:1})]})}),(0,a.jsx)(eB.Z,{children:(0,a.jsxs)($.Z,{numItems:2,className:"gap-2 h-[75vh] w-full",children:[(0,a.jsxs)(H.Z,{numColSpan:2,children:[(0,a.jsxs)(ef.Z,{className:"mb-2",children:[(0,a.jsx)(er.Z,{children:"Total Spend Per Team"}),(0,a.jsx)(lk.Z,{data:b})]}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(er.Z,{children:"Daily Spend Per Team"}),(0,a.jsx)(eY.Z,{className:"h-72",data:g,showLegend:!0,index:"date",categories:_,yAxisWidth:80,colors:["blue","green","yellow","red","purple"],stack:!0})]})]}),(0,a.jsx)(H.Z,{numColSpan:2})]})}),(0,a.jsxs)(eB.Z,{children:[(0,a.jsxs)("p",{className:"mb-2 text-gray-500 italic text-[12px]",children:["End-Users of your LLM API calls. Tracked when a `user` param is passed in your LLM calls ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/users",target:"_blank",children:"docs here"})]}),(0,a.jsxs)($.Z,{numItems:2,children:[(0,a.jsxs)(H.Z,{children:[(0,a.jsx)(es.Z,{children:"Select Time Range"}),(0,a.jsx)(eL.Z,{enableSelect:!0,value:N,onValueChange:e=>{R(e),K(e.from,e.to,null)}})]}),(0,a.jsxs)(H.Z,{children:[(0,a.jsx)(es.Z,{children:"Select Key"}),(0,a.jsxs)(eS.Z,{defaultValue:"all-keys",children:[(0,a.jsx)(eN.Z,{value:"all-keys",onClick:()=>{K(N.from,N.to,null)},children:"All Keys"},"all-keys"),null==o?void 0:o.map((e,l)=>e&&null!==e.key_alias&&e.key_alias.length>0?(0,a.jsx)(eN.Z,{value:String(l),onClick:()=>{K(N.from,N.to,e.token)},children:e.key_alias},l):null)]})]})]}),(0,a.jsx)(ef.Z,{className:"mt-4",children:(0,a.jsxs)(eZ.Z,{className:"max-h-[70vh] min-h-[500px]",children:[(0,a.jsx)(eb.Z,{children:(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ek.Z,{children:"End User"}),(0,a.jsx)(ek.Z,{children:"Spend"}),(0,a.jsx)(ek.Z,{children:"Total Events"})]})}),(0,a.jsx)(e_.Z,{children:null==p?void 0:p.map((e,l)=>{var t;return(0,a.jsxs)(ev.Z,{children:[(0,a.jsx)(ew.Z,{children:e.end_user}),(0,a.jsx)(ew.Z,{children:null===(t=e.total_spend)||void 0===t?void 0:t.toFixed(4)}),(0,a.jsx)(ew.Z,{children:e.total_count})]},l)})})]})})]}),(0,a.jsx)(eB.Z,{children:(0,a.jsxs)($.Z,{numItems:2,className:"gap-2 h-[75vh] w-full mb-4",children:[(0,a.jsxs)(H.Z,{numColSpan:2,children:[(0,a.jsx)(eL.Z,{className:"mb-4",enableSelect:!0,value:N,onValueChange:e=>{R(e),B(e.from,e.to)}}),(0,a.jsxs)(ef.Z,{children:[(0,a.jsx)(er.Z,{children:"Spend Per Tag"}),(0,a.jsxs)(es.Z,{children:["Get Started Tracking cost per tag ",(0,a.jsx)("a",{className:"text-blue-500",href:"https://docs.litellm.ai/docs/proxy/enterprise#tracking-spend-for-custom-tags",target:"_blank",children:"here"})]}),(0,a.jsx)(eY.Z,{className:"h-72",data:y,index:"name",categories:["spend"],colors:["blue"]})]})]}),(0,a.jsx)(H.Z,{numColSpan:2})]})})]})]})]})},lS=()=>{let{Title:e,Paragraph:l}=eR.default,[t,s]=(0,n.useState)(""),[r,i]=(0,n.useState)(null),[c,d]=(0,n.useState)(null),[u,h]=(0,n.useState)(null),[x,p]=(0,n.useState)(!0),j=(0,o.useSearchParams)(),[g,f]=(0,n.useState)({data:[]}),y=j.get("userID"),Z=j.get("token"),[_,w]=(0,n.useState)("api-keys"),[b,k]=(0,n.useState)(null);return(0,n.useEffect)(()=>{if(Z){let e=(0,eF.o)(Z);if(e){if(console.log("Decoded token:",e),console.log("Decoded key:",e.key),k(e.key),e.user_role){let l=function(e){if(!e)return"Undefined Role";switch(console.log("Received user role: ".concat(e.toLowerCase())),console.log("Received user role length: ".concat(e.toLowerCase().length)),e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"app_admin":case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"app_user":return"App User";default:return"Unknown Role"}}(e.user_role);console.log("Decoded user_role:",l),s(l),"Admin Viewer"==l&&w("usage")}else console.log("User role not defined");e.user_email?i(e.user_email):console.log("User Email is not set ".concat(e)),e.login_method?p("username_password"==e.login_method):console.log("User Email is not set ".concat(e))}}},[Z]),(0,a.jsx)(n.Suspense,{fallback:(0,a.jsx)("div",{children:"Loading..."}),children:(0,a.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,a.jsx)(m,{userID:y,userRole:t,userEmail:r,showSSOBanner:x}),(0,a.jsxs)("div",{className:"flex flex-1 overflow-auto",children:[(0,a.jsx)("div",{className:"mt-8",children:(0,a.jsx)(lb,{setPage:w,userRole:t,defaultSelectedKey:null})}),"api-keys"==_?(0,a.jsx)(eM,{userID:y,userRole:t,teams:c,keys:u,setUserRole:s,userEmail:r,setUserEmail:i,setTeams:d,setKeys:h}):"models"==_?(0,a.jsx)(e9,{userID:y,userRole:t,token:Z,accessToken:b,modelData:g,setModelData:f}):"llm-playground"==_?(0,a.jsx)(ly,{userID:y,userRole:t,token:Z,accessToken:b}):"users"==_?(0,a.jsx)(lt,{userID:y,userRole:t,token:Z,keys:u,teams:c,accessToken:b,setKeys:h}):"teams"==_?(0,a.jsx)(ls,{teams:c,setTeams:d,searchParams:j,accessToken:b,userID:y,userRole:t}):"admin-panel"==_?(0,a.jsx)(la,{setTeams:d,searchParams:j,accessToken:b,showSSOBanner:x}):"api_ref"==_?(0,a.jsx)(lg,{}):"settings"==_?(0,a.jsx)(li,{userID:y,userRole:t,accessToken:b}):"general-settings"==_?(0,a.jsx)(lp,{userID:y,userRole:t,accessToken:b,modelData:g}):(0,a.jsx)(lv,{userID:y,userRole:t,token:Z,accessToken:b,keys:u})]})]})})}}},function(e){e.O(0,[936,884,971,69,744],function(){return e(e.s=20661)}),_N_E=e.O()}]);
\ No newline at end of file
diff --git a/ui/litellm-dashboard/out/index.html b/ui/litellm-dashboard/out/index.html
index 930018e005..011bb7fc76 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 d67a480b37..ce4099b2cd 100644
--- a/ui/litellm-dashboard/out/index.txt
+++ b/ui/litellm-dashboard/out/index.txt
@@ -1,7 +1,7 @@
2:I[77831,[],""]
-3:I[7926,["936","static/chunks/2f6dbc85-052c4579f80d66ae.js","884","static/chunks/884-7576ee407a2ecbe6.js","931","static/chunks/app/page-6a39771cacf75ea6.js"],""]
+3:I[4858,["936","static/chunks/2f6dbc85-052c4579f80d66ae.js","884","static/chunks/884-7576ee407a2ecbe6.js","931","static/chunks/app/page-c35c14c9afd091ec.js"],""]
4:I[5613,[],""]
5:I[31778,[],""]
-0:["obp5wqVSVDMiDTC414cR8",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_c23dc8","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/f04e46b02318b660.css","precedence":"next","crossOrigin":""}]],"$L6"]]]]
+0:["2ASoJGxS-D4w-vat00xMy",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},["$L1",["$","$L2",null,{"propsForComponent":{"params":{}},"Component":"$3","isStaticGeneration":true}],null]]},[null,["$","html",null,{"lang":"en","children":["$","body",null,{"className":"__className_c23dc8","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","loadingScripts":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"styles":null}]}]}],null]],[[["$","link","0",{"rel":"stylesheet","href":"/ui/_next/static/css/f04e46b02318b660.css","precedence":"next","crossOrigin":""}]],"$L6"]]]]
6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"LiteLLM Dashboard"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]]
1:null
diff --git a/ui/litellm-dashboard/src/components/general_settings.tsx b/ui/litellm-dashboard/src/components/general_settings.tsx
index c2013b1578..d16b434b89 100644
--- a/ui/litellm-dashboard/src/components/general_settings.tsx
+++ b/ui/litellm-dashboard/src/components/general_settings.tsx
@@ -23,12 +23,44 @@ import {
AccordionHeader,
AccordionList,
} from "@tremor/react";
-import { TabPanel, TabPanels, TabGroup, TabList, Tab, Icon } from "@tremor/react";
-import { getCallbacksCall, setCallbacksCall, serviceHealthCheck } from "./networking";
-import { Modal, Form, Input, Select, Button as Button2, message } from "antd";
-import { InformationCircleIcon, PencilAltIcon, PencilIcon, StatusOnlineIcon, TrashIcon, RefreshIcon } from "@heroicons/react/outline";
+import {
+ TabPanel,
+ TabPanels,
+ TabGroup,
+ TabList,
+ Tab,
+ Icon,
+} from "@tremor/react";
+import {
+ getCallbacksCall,
+ setCallbacksCall,
+ getGeneralSettingsCall,
+ serviceHealthCheck,
+ updateConfigFieldSetting,
+ deleteConfigFieldSetting,
+} from "./networking";
+import {
+ Modal,
+ Form,
+ Input,
+ Select,
+ Button as Button2,
+ message,
+ InputNumber,
+} from "antd";
+import {
+ InformationCircleIcon,
+ PencilAltIcon,
+ PencilIcon,
+ StatusOnlineIcon,
+ TrashIcon,
+ RefreshIcon,
+ CheckCircleIcon,
+ XCircleIcon,
+ QuestionMarkCircleIcon,
+} from "@heroicons/react/outline";
import StaticGenerationSearchParamsBailoutProvider from "next/dist/client/components/static-generation-searchparams-bailout-provider";
-import AddFallbacks from "./add_fallbacks"
+import AddFallbacks from "./add_fallbacks";
import openai from "openai";
import Paragraph from "antd/es/skeleton/Paragraph";
@@ -36,7 +68,7 @@ interface GeneralSettingsPageProps {
accessToken: string | null;
userRole: string | null;
userID: string | null;
- modelData: any
+ modelData: any;
}
async function testFallbackModelResponse(
@@ -65,43 +97,71 @@ async function testFallbackModelResponse(
},
],
// @ts-ignore
- mock_testing_fallbacks: true
+ mock_testing_fallbacks: true,
});
message.success(
- Test model={selectedModel}, received model={response.model}.
- See window.open('https://docs.litellm.ai/docs/proxy/reliability', '_blank')} style={{ textDecoration: 'underline', color: 'blue' }}>curl
+ Test model={selectedModel}, received model=
+ {response.model}. See{" "}
+
+ window.open(
+ "https://docs.litellm.ai/docs/proxy/reliability",
+ "_blank"
+ )
+ }
+ style={{ textDecoration: "underline", color: "blue" }}
+ >
+ curl
+
);
} catch (error) {
- message.error(`Error occurred while generating model response. Please try again. Error: ${error}`, 20);
+ message.error(
+ `Error occurred while generating model response. Please try again. Error: ${error}`,
+ 20
+ );
}
}
interface AccordionHeroProps {
selectedStrategy: string | null;
strategyArgs: routingStrategyArgs;
- paramExplanation: { [key: string]: string }
+ paramExplanation: { [key: string]: string };
}
interface routingStrategyArgs {
- ttl?: number;
- lowest_latency_buffer?: number;
+ ttl?: number;
+ lowest_latency_buffer?: number;
+}
+
+interface generalSettingsItem {
+ field_name: string;
+ field_type: string;
+ field_value: any;
+ field_description: string;
+ stored_in_db: boolean | null;
}
const defaultLowestLatencyArgs: routingStrategyArgs = {
- "ttl": 3600,
- "lowest_latency_buffer": 0
-}
+ ttl: 3600,
+ lowest_latency_buffer: 0,
+};
-export const AccordionHero: React.FC = ({ selectedStrategy, strategyArgs, paramExplanation }) => (
+export const AccordionHero: React.FC = ({
+ selectedStrategy,
+ strategyArgs,
+ paramExplanation,
+}) => (
- Routing Strategy Specific Args
-
- {
- selectedStrategy == "latency-based-routing" ?
-
+
+ Routing Strategy Specific Args
+
+
+ {selectedStrategy == "latency-based-routing" ? (
+