mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-26 11:14:04 +00:00
fix: stability fixes for ui
This commit is contained in:
parent
034ca95a94
commit
524cdb74a4
16 changed files with 248 additions and 120 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
<!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/ui/_next/static/chunks/webpack-12184ee6a95c1363.js" crossorigin=""/><script src="/ui/_next/static/chunks/fd9d1056-a85b2c176012d8e5.js" async="" crossorigin=""></script><script src="/ui/_next/static/chunks/69-e1b183dda365ec86.js" async="" crossorigin=""></script><script src="/ui/_next/static/chunks/main-app-096338c8e1915716.js" async="" crossorigin=""></script><title>🚅 LiteLLM</title><meta name="description" content="LiteLLM Proxy Admin UI"/><link rel="icon" href="/ui/favicon.ico" type="image/x-icon" sizes="16x16"/><meta name="next-size-adjust"/><script src="/ui/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js" crossorigin="" noModule=""></script></head><body><script src="/ui/_next/static/chunks/webpack-12184ee6a95c1363.js" crossorigin="" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/ui/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/ui/_next/static/css/a40ad0909dd7838e.css\",\"style\",{\"crossOrigin\":\"\"}]\n0:\"$L3\"\n"])</script><script>self.__next_f.push([1,"4:I[47690,[],\"\"]\n6:I[77831,[],\"\"]\n7:I[30280,[\"303\",\"static/chunks/303-d80f23087a9e6aec.js\",\"931\",\"static/chunks/app/page-f5480eede36fdcd5.js\"],\"\"]\n8:I[5613,[],\"\"]\n9:I[31778,[],\"\"]\nb:I[48955,[],\"\"]\nc:[]\n"])</script><script>self.__next_f.push([1,"3:[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/ui/_next/static/css/a40ad0909dd7838e.css\",\"precedence\":\"next\",\"crossOrigin\":\"\"}]],[\"$\",\"$L4\",null,{\"buildId\":\"HOfpn9FdKIMCOfG_am2z2\",\"assetPrefix\":\"/ui\",\"initialCanonicalUrl\":\"/\",\"initialTree\":[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"__PAGE__\",{},[\"$L5\",[\"$\",\"$L6\",null,{\"propsForComponent\":{\"params\":{}},\"Component\":\"$7\",\"isStaticGeneration\":true}],null]]},[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"className\":\"__className_c23dc8\",\"children\":[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"loading\":\"$undefined\",\"loadingStyles\":\"$undefined\",\"loadingScripts\":\"$undefined\",\"hasLoading\":false,\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L9\",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]],\"initialHead\":[false,\"$La\"],\"globalErrorComponent\":\"$b\",\"missingSlots\":\"$Wc\"}]]\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"🚅 LiteLLM\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"LiteLLM Proxy Admin UI\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/ui/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"16x16\"}],[\"$\",\"meta\",\"5\",{\"name\":\"next-size-adjust\"}]]\n5:null\n"])</script><script>self.__next_f.push([1,""])</script></body></html>
|
||||
<!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/ui/_next/static/chunks/webpack-12184ee6a95c1363.js" crossorigin=""/><script src="/ui/_next/static/chunks/fd9d1056-a85b2c176012d8e5.js" async="" crossorigin=""></script><script src="/ui/_next/static/chunks/69-e1b183dda365ec86.js" async="" crossorigin=""></script><script src="/ui/_next/static/chunks/main-app-096338c8e1915716.js" async="" crossorigin=""></script><title>🚅 LiteLLM</title><meta name="description" content="LiteLLM Proxy Admin UI"/><link rel="icon" href="/ui/favicon.ico" type="image/x-icon" sizes="16x16"/><meta name="next-size-adjust"/><script src="/ui/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js" crossorigin="" noModule=""></script></head><body><script src="/ui/_next/static/chunks/webpack-12184ee6a95c1363.js" crossorigin="" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/ui/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/ui/_next/static/css/a40ad0909dd7838e.css\",\"style\",{\"crossOrigin\":\"\"}]\n0:\"$L3\"\n"])</script><script>self.__next_f.push([1,"4:I[47690,[],\"\"]\n6:I[77831,[],\"\"]\n7:I[30280,[\"303\",\"static/chunks/303-d80f23087a9e6aec.js\",\"931\",\"static/chunks/app/page-f9c7d1158cda8c5f.js\"],\"\"]\n8:I[5613,[],\"\"]\n9:I[31778,[],\"\"]\nb:I[48955,[],\"\"]\nc:[]\n"])</script><script>self.__next_f.push([1,"3:[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/ui/_next/static/css/a40ad0909dd7838e.css\",\"precedence\":\"next\",\"crossOrigin\":\"\"}]],[\"$\",\"$L4\",null,{\"buildId\":\"Au9NvM222ys66B_S9303T\",\"assetPrefix\":\"/ui\",\"initialCanonicalUrl\":\"/\",\"initialTree\":[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"__PAGE__\",{},[\"$L5\",[\"$\",\"$L6\",null,{\"propsForComponent\":{\"params\":{}},\"Component\":\"$7\",\"isStaticGeneration\":true}],null]]},[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"className\":\"__className_c23dc8\",\"children\":[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"loading\":\"$undefined\",\"loadingStyles\":\"$undefined\",\"loadingScripts\":\"$undefined\",\"hasLoading\":false,\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L9\",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]],\"initialHead\":[false,\"$La\"],\"globalErrorComponent\":\"$b\",\"missingSlots\":\"$Wc\"}]]\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"🚅 LiteLLM\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"LiteLLM Proxy Admin UI\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/ui/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"16x16\"}],[\"$\",\"meta\",\"5\",{\"name\":\"next-size-adjust\"}]]\n5:null\n"])</script><script>self.__next_f.push([1,""])</script></body></html>
|
|
@ -1,7 +1,7 @@
|
|||
2:I[77831,[],""]
|
||||
3:I[30280,["303","static/chunks/303-d80f23087a9e6aec.js","931","static/chunks/app/page-f5480eede36fdcd5.js"],""]
|
||||
3:I[30280,["303","static/chunks/303-d80f23087a9e6aec.js","931","static/chunks/app/page-f9c7d1158cda8c5f.js"],""]
|
||||
4:I[5613,[],""]
|
||||
5:I[31778,[],""]
|
||||
0:["HOfpn9FdKIMCOfG_am2z2",[[["",{"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/a40ad0909dd7838e.css","precedence":"next","crossOrigin":""}]],"$L6"]]]]
|
||||
0:["Au9NvM222ys66B_S9303T",[[["",{"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/a40ad0909dd7838e.css","precedence":"next","crossOrigin":""}]],"$L6"]]]]
|
||||
6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"🚅 LiteLLM"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]]
|
||||
1:null
|
||||
|
|
|
@ -785,6 +785,7 @@ async def user_api_key_auth(
|
|||
"/v1/models",
|
||||
"/global/spend/logs",
|
||||
"/global/spend/keys",
|
||||
"/global/spend/models",
|
||||
]
|
||||
# check if the current route startswith any of the allowed routes
|
||||
if (
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
<!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/ui/_next/static/chunks/webpack-12184ee6a95c1363.js" crossorigin=""/><script src="/ui/_next/static/chunks/fd9d1056-a85b2c176012d8e5.js" async="" crossorigin=""></script><script src="/ui/_next/static/chunks/69-e1b183dda365ec86.js" async="" crossorigin=""></script><script src="/ui/_next/static/chunks/main-app-096338c8e1915716.js" async="" crossorigin=""></script><title>🚅 LiteLLM</title><meta name="description" content="LiteLLM Proxy Admin UI"/><link rel="icon" href="/ui/favicon.ico" type="image/x-icon" sizes="16x16"/><meta name="next-size-adjust"/><script src="/ui/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js" crossorigin="" noModule=""></script></head><body><script src="/ui/_next/static/chunks/webpack-12184ee6a95c1363.js" crossorigin="" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/ui/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/ui/_next/static/css/a40ad0909dd7838e.css\",\"style\",{\"crossOrigin\":\"\"}]\n0:\"$L3\"\n"])</script><script>self.__next_f.push([1,"4:I[47690,[],\"\"]\n6:I[77831,[],\"\"]\n7:I[30280,[\"303\",\"static/chunks/303-d80f23087a9e6aec.js\",\"931\",\"static/chunks/app/page-f5480eede36fdcd5.js\"],\"\"]\n8:I[5613,[],\"\"]\n9:I[31778,[],\"\"]\nb:I[48955,[],\"\"]\nc:[]\n"])</script><script>self.__next_f.push([1,"3:[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/ui/_next/static/css/a40ad0909dd7838e.css\",\"precedence\":\"next\",\"crossOrigin\":\"\"}]],[\"$\",\"$L4\",null,{\"buildId\":\"HOfpn9FdKIMCOfG_am2z2\",\"assetPrefix\":\"/ui\",\"initialCanonicalUrl\":\"/\",\"initialTree\":[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"__PAGE__\",{},[\"$L5\",[\"$\",\"$L6\",null,{\"propsForComponent\":{\"params\":{}},\"Component\":\"$7\",\"isStaticGeneration\":true}],null]]},[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"className\":\"__className_c23dc8\",\"children\":[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"loading\":\"$undefined\",\"loadingStyles\":\"$undefined\",\"loadingScripts\":\"$undefined\",\"hasLoading\":false,\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L9\",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]],\"initialHead\":[false,\"$La\"],\"globalErrorComponent\":\"$b\",\"missingSlots\":\"$Wc\"}]]\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"🚅 LiteLLM\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"LiteLLM Proxy Admin UI\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/ui/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"16x16\"}],[\"$\",\"meta\",\"5\",{\"name\":\"next-size-adjust\"}]]\n5:null\n"])</script><script>self.__next_f.push([1,""])</script></body></html>
|
||||
<!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/ui/_next/static/chunks/webpack-12184ee6a95c1363.js" crossorigin=""/><script src="/ui/_next/static/chunks/fd9d1056-a85b2c176012d8e5.js" async="" crossorigin=""></script><script src="/ui/_next/static/chunks/69-e1b183dda365ec86.js" async="" crossorigin=""></script><script src="/ui/_next/static/chunks/main-app-096338c8e1915716.js" async="" crossorigin=""></script><title>🚅 LiteLLM</title><meta name="description" content="LiteLLM Proxy Admin UI"/><link rel="icon" href="/ui/favicon.ico" type="image/x-icon" sizes="16x16"/><meta name="next-size-adjust"/><script src="/ui/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js" crossorigin="" noModule=""></script></head><body><script src="/ui/_next/static/chunks/webpack-12184ee6a95c1363.js" crossorigin="" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/ui/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/ui/_next/static/css/a40ad0909dd7838e.css\",\"style\",{\"crossOrigin\":\"\"}]\n0:\"$L3\"\n"])</script><script>self.__next_f.push([1,"4:I[47690,[],\"\"]\n6:I[77831,[],\"\"]\n7:I[30280,[\"303\",\"static/chunks/303-d80f23087a9e6aec.js\",\"931\",\"static/chunks/app/page-f9c7d1158cda8c5f.js\"],\"\"]\n8:I[5613,[],\"\"]\n9:I[31778,[],\"\"]\nb:I[48955,[],\"\"]\nc:[]\n"])</script><script>self.__next_f.push([1,"3:[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/ui/_next/static/css/a40ad0909dd7838e.css\",\"precedence\":\"next\",\"crossOrigin\":\"\"}]],[\"$\",\"$L4\",null,{\"buildId\":\"Au9NvM222ys66B_S9303T\",\"assetPrefix\":\"/ui\",\"initialCanonicalUrl\":\"/\",\"initialTree\":[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"__PAGE__\",{},[\"$L5\",[\"$\",\"$L6\",null,{\"propsForComponent\":{\"params\":{}},\"Component\":\"$7\",\"isStaticGeneration\":true}],null]]},[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"className\":\"__className_c23dc8\",\"children\":[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"loading\":\"$undefined\",\"loadingStyles\":\"$undefined\",\"loadingScripts\":\"$undefined\",\"hasLoading\":false,\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L9\",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]],\"initialHead\":[false,\"$La\"],\"globalErrorComponent\":\"$b\",\"missingSlots\":\"$Wc\"}]]\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"🚅 LiteLLM\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"LiteLLM Proxy Admin UI\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/ui/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"16x16\"}],[\"$\",\"meta\",\"5\",{\"name\":\"next-size-adjust\"}]]\n5:null\n"])</script><script>self.__next_f.push([1,""])</script></body></html>
|
|
@ -1,7 +1,7 @@
|
|||
2:I[77831,[],""]
|
||||
3:I[30280,["303","static/chunks/303-d80f23087a9e6aec.js","931","static/chunks/app/page-f5480eede36fdcd5.js"],""]
|
||||
3:I[30280,["303","static/chunks/303-d80f23087a9e6aec.js","931","static/chunks/app/page-f9c7d1158cda8c5f.js"],""]
|
||||
4:I[5613,[],""]
|
||||
5:I[31778,[],""]
|
||||
0:["HOfpn9FdKIMCOfG_am2z2",[[["",{"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/a40ad0909dd7838e.css","precedence":"next","crossOrigin":""}]],"$L6"]]]]
|
||||
0:["Au9NvM222ys66B_S9303T",[[["",{"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/a40ad0909dd7838e.css","precedence":"next","crossOrigin":""}]],"$L6"]]]]
|
||||
6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"🚅 LiteLLM"}],["$","meta","3",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","4",{"rel":"icon","href":"/ui/favicon.ico","type":"image/x-icon","sizes":"16x16"}],["$","meta","5",{"name":"next-size-adjust"}]]
|
||||
1:null
|
||||
|
|
|
@ -11,8 +11,10 @@ import ChatUI from "@/components/chat_ui";
|
|||
import Sidebar from "../components/leftnav";
|
||||
import Usage from "../components/usage";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
import { Typography } from "antd";
|
||||
|
||||
const CreateKeyPage = () => {
|
||||
const { Title, Paragraph } = Typography;
|
||||
const [userRole, setUserRole] = useState("");
|
||||
const [userEmail, setUserEmail] = useState<null | string>(null);
|
||||
const [teams, setTeams] = useState<null | any[]>(null);
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
import { modelAvailableCall } from "./networking";
|
||||
import openai from "openai";
|
||||
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||
import { Typography } from "antd";
|
||||
|
||||
interface ChatUIProps {
|
||||
accessToken: string | null;
|
||||
|
@ -145,6 +146,16 @@ const ChatUI: React.FC<ChatUIProps> = ({
|
|||
setInputMessage("");
|
||||
};
|
||||
|
||||
if (userRole && userRole == "Admin Viewer") {
|
||||
const { Title, Paragraph } = Typography;
|
||||
return (
|
||||
<div>
|
||||
<Title level={1}>Access Denied</Title>
|
||||
<Paragraph>Ask your proxy admin for access to test models</Paragraph>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ width: "100%", position: "relative" }}>
|
||||
<Grid className="gap-2 p-10 h-[75vh] w-full">
|
||||
|
|
|
@ -23,10 +23,19 @@ const Sidebar: React.FC<SidebarProps> = ({
|
|||
<Menu
|
||||
mode="inline"
|
||||
defaultSelectedKeys={
|
||||
defaultSelectedKey ? defaultSelectedKey : ["1"]
|
||||
defaultSelectedKey ? defaultSelectedKey : ["4"]
|
||||
}
|
||||
style={{ height: "100%", borderRight: 0 }}
|
||||
>
|
||||
<Menu.Item key="4" onClick={() => setPage("api-keys")}>
|
||||
API Keys
|
||||
</Menu.Item>
|
||||
<Menu.Item key="2" onClick={() => setPage("models")}>
|
||||
Models
|
||||
</Menu.Item>
|
||||
<Menu.Item key="3" onClick={() => setPage("llm-playground")}>
|
||||
Chat UI
|
||||
</Menu.Item>
|
||||
<Menu.Item key="1" onClick={() => setPage("usage")}>
|
||||
Usage
|
||||
</Menu.Item>
|
||||
|
|
|
@ -1,8 +1,20 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { Card, Title, Subtitle, Table, TableHead, TableRow, TableCell, TableBody, Metric, Grid } from "@tremor/react";
|
||||
import {
|
||||
Card,
|
||||
Title,
|
||||
Subtitle,
|
||||
Table,
|
||||
TableHead,
|
||||
TableRow,
|
||||
TableCell,
|
||||
TableBody,
|
||||
Metric,
|
||||
Grid,
|
||||
} from "@tremor/react";
|
||||
import { modelInfoCall, userGetRequesedtModelsCall } from "./networking";
|
||||
import { Badge, BadgeDelta, Button } from '@tremor/react';
|
||||
import { Badge, BadgeDelta, Button } from "@tremor/react";
|
||||
import RequestAccess from "./request_model_access";
|
||||
import { Typography } from "antd";
|
||||
|
||||
interface ModelDashboardProps {
|
||||
accessToken: string | null;
|
||||
|
@ -20,7 +32,6 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
|
|||
const [modelData, setModelData] = useState<any>({ data: [] });
|
||||
const [pendingRequests, setPendingRequests] = useState<any[]>([]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (!accessToken || !token || !userRole || !userID) {
|
||||
return;
|
||||
|
@ -28,17 +39,20 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
|
|||
const fetchData = async () => {
|
||||
try {
|
||||
// Replace with your actual API call for model data
|
||||
const modelDataResponse = await modelInfoCall(accessToken, userID, userRole);
|
||||
const modelDataResponse = await modelInfoCall(
|
||||
accessToken,
|
||||
userID,
|
||||
userRole
|
||||
);
|
||||
console.log("Model data response:", modelDataResponse.data);
|
||||
setModelData(modelDataResponse);
|
||||
|
||||
// if userRole is Admin, show the pending requests
|
||||
// if userRole is Admin, show the pending requests
|
||||
if (userRole === "Admin" && accessToken) {
|
||||
const user_requests = await userGetRequesedtModelsCall(accessToken);
|
||||
console.log("Pending Requests:", pendingRequests);
|
||||
setPendingRequests(user_requests.requests || []);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("There was an error fetching the model data", error);
|
||||
}
|
||||
|
@ -58,7 +72,7 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
|
|||
}
|
||||
let all_models_on_proxy: any[] = [];
|
||||
|
||||
// loop through model data and edit each row
|
||||
// loop through model data and edit each row
|
||||
for (let i = 0; i < modelData.data.length; i++) {
|
||||
let curr_model = modelData.data[i];
|
||||
let litellm_model_name = curr_model?.litellm_params?.model;
|
||||
|
@ -67,110 +81,155 @@ const ModelDashboard: React.FC<ModelDashboardProps> = ({
|
|||
|
||||
let defaultProvider = "openai";
|
||||
let provider = "";
|
||||
let input_cost = "Undefined"
|
||||
let output_cost = "Undefined"
|
||||
let max_tokens = "Undefined"
|
||||
let input_cost = "Undefined";
|
||||
let output_cost = "Undefined";
|
||||
let max_tokens = "Undefined";
|
||||
|
||||
// Check if litellm_model_name is null or undefined
|
||||
if (litellm_model_name) {
|
||||
// Split litellm_model_name based on "/"
|
||||
let splitModel = litellm_model_name.split("/");
|
||||
// Split litellm_model_name based on "/"
|
||||
let splitModel = litellm_model_name.split("/");
|
||||
|
||||
// Get the first element in the split
|
||||
let firstElement = splitModel[0];
|
||||
// Get the first element in the split
|
||||
let firstElement = splitModel[0];
|
||||
|
||||
// If there is only one element, default provider to openai
|
||||
provider = splitModel.length === 1 ? defaultProvider : firstElement;
|
||||
|
||||
// If there is only one element, default provider to openai
|
||||
provider = splitModel.length === 1 ? defaultProvider : firstElement;
|
||||
} else {
|
||||
// litellm_model_name is null or undefined, default provider to openai
|
||||
provider = defaultProvider;
|
||||
// litellm_model_name is null or undefined, default provider to openai
|
||||
provider = defaultProvider;
|
||||
}
|
||||
|
||||
if (model_info) {
|
||||
input_cost = model_info?.input_cost_per_token;
|
||||
output_cost = model_info?.output_cost_per_token;
|
||||
max_tokens = model_info?.max_tokens;
|
||||
|
||||
input_cost = model_info?.input_cost_per_token;
|
||||
output_cost = model_info?.output_cost_per_token;
|
||||
max_tokens = model_info?.max_tokens;
|
||||
}
|
||||
modelData.data[i].provider = provider
|
||||
modelData.data[i].input_cost = input_cost
|
||||
modelData.data[i].output_cost = output_cost
|
||||
modelData.data[i].max_tokens = max_tokens
|
||||
modelData.data[i].provider = provider;
|
||||
modelData.data[i].input_cost = input_cost;
|
||||
modelData.data[i].output_cost = output_cost;
|
||||
modelData.data[i].max_tokens = max_tokens;
|
||||
|
||||
all_models_on_proxy.push(curr_model.model_name);
|
||||
|
||||
console.log(modelData.data[i]);
|
||||
|
||||
}
|
||||
// when users click request access show pop up to allow them to request access
|
||||
|
||||
if (userRole && userRole == "Admin Viewer") {
|
||||
const { Title, Paragraph } = Typography;
|
||||
return (
|
||||
<div>
|
||||
<Title level={1}>Access Denied</Title>
|
||||
<Paragraph>
|
||||
Ask your proxy admin for access to view all models
|
||||
</Paragraph>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ width: "100%" }}>
|
||||
<Grid className="gap-2 p-10 h-[75vh] w-full">
|
||||
<Card>
|
||||
<Table className="mt-5">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell><Title>Model Name </Title></TableCell>
|
||||
<TableCell><Title>Provider</Title></TableCell>
|
||||
<TableCell><Title>Access</Title></TableCell>
|
||||
<TableCell><Title>Input Price per token ($)</Title></TableCell>
|
||||
<TableCell><Title>Output Price per token ($)</Title></TableCell>
|
||||
<TableCell><Title>Max Tokens</Title></TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{modelData.data.map((model: any) => (
|
||||
<TableRow key={model.model_name}>
|
||||
|
||||
<TableCell><Title>{model.model_name}</Title></TableCell>
|
||||
<TableCell>{model.provider}</TableCell>
|
||||
|
||||
<Grid className="gap-2 p-10 h-[75vh] w-full">
|
||||
<Card>
|
||||
<Table className="mt-5">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
{model.user_access ? <Badge color={"green"}>Yes</Badge> : <RequestAccess userModels={all_models_on_proxy} accessToken={accessToken} userID={userID}></RequestAccess>}
|
||||
<Title>Model Name </Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>Provider</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>Access</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>Input Price per token ($)</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>Output Price per token ($)</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>Max Tokens</Title>
|
||||
</TableCell>
|
||||
|
||||
<TableCell>{model.input_cost}</TableCell>
|
||||
<TableCell>{model.output_cost}</TableCell>
|
||||
<TableCell>{model.max_tokens}</TableCell>
|
||||
|
||||
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Card>
|
||||
{
|
||||
userRole === "Admin" && pendingRequests && pendingRequests.length > 0 ? (
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{modelData.data.map((model: any) => (
|
||||
<TableRow key={model.model_name}>
|
||||
<TableCell>
|
||||
<Title>{model.model_name}</Title>
|
||||
</TableCell>
|
||||
<TableCell>{model.provider}</TableCell>
|
||||
|
||||
<TableCell>
|
||||
{model.user_access ? (
|
||||
<Badge color={"green"}>Yes</Badge>
|
||||
) : (
|
||||
<RequestAccess
|
||||
userModels={all_models_on_proxy}
|
||||
accessToken={accessToken}
|
||||
userID={userID}
|
||||
></RequestAccess>
|
||||
)}
|
||||
</TableCell>
|
||||
|
||||
<TableCell>{model.input_cost}</TableCell>
|
||||
<TableCell>{model.output_cost}</TableCell>
|
||||
<TableCell>{model.max_tokens}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Card>
|
||||
{userRole === "Admin" &&
|
||||
pendingRequests &&
|
||||
pendingRequests.length > 0 ? (
|
||||
<Card>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<Title>Pending Requests</Title>
|
||||
<TableRow>
|
||||
<TableCell><Title>User ID</Title></TableCell>
|
||||
<TableCell><Title>Requested Models</Title></TableCell>
|
||||
<TableCell><Title>Justification</Title></TableCell>
|
||||
<TableCell><Title>Justification</Title></TableCell>
|
||||
<TableCell>
|
||||
<Title>User ID</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>Requested Models</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>Justification</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>Justification</Title>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{pendingRequests.map((request: any) => (
|
||||
<TableRow key={request.request_id}>
|
||||
<TableCell><p>{request.user_id}</p></TableCell>
|
||||
<TableCell><p>{request.models[0]}</p></TableCell>
|
||||
<TableCell><p>{request.justification}</p></TableCell>
|
||||
<TableCell><p>{request.user_id}</p></TableCell>
|
||||
<TableCell>
|
||||
<p>{request.user_id}</p>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<p>{request.models[0]}</p>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<p>{request.justification}</p>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<p>{request.user_id}</p>
|
||||
</TableCell>
|
||||
<Button>Approve</Button>
|
||||
<Button variant="secondary" className="ml-2">Deny</Button>
|
||||
<Button variant="secondary" className="ml-2">
|
||||
Deny
|
||||
</Button>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Card>
|
||||
) : null
|
||||
}
|
||||
</Card>
|
||||
) : null}
|
||||
</Grid>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -8,7 +8,7 @@ import ViewUserSpend from "./view_user_spend";
|
|||
import DashboardTeam from "./dashboard_default_team";
|
||||
import { useSearchParams, useRouter } from "next/navigation";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
|
||||
import { Typography } from "antd";
|
||||
const isLocal = process.env.NODE_ENV === "development";
|
||||
console.log("isLocal:", isLocal);
|
||||
const proxyBaseUrl = isLocal ? "http://localhost:4000" : null;
|
||||
|
@ -184,6 +184,16 @@ const UserDashboard: React.FC<UserDashboardProps> = ({
|
|||
setUserRole("App Owner");
|
||||
}
|
||||
|
||||
if (userRole && userRole == "Admin Viewer") {
|
||||
const { Title, Paragraph } = Typography;
|
||||
return (
|
||||
<div>
|
||||
<Title level={1}>Access Denied</Title>
|
||||
<Paragraph>Ask your proxy admin for access to create keys</Paragraph>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Grid numItems={1} className="gap-0 p-10 h-[75vh] w-full">
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { Card, Title, Subtitle, Table, TableHead, TableRow, TableCell, TableBody, Metric, Grid } from "@tremor/react";
|
||||
import {
|
||||
Card,
|
||||
Title,
|
||||
Subtitle,
|
||||
Table,
|
||||
TableHead,
|
||||
TableRow,
|
||||
TableCell,
|
||||
TableBody,
|
||||
Metric,
|
||||
Grid,
|
||||
} from "@tremor/react";
|
||||
import { userInfoCall } from "./networking";
|
||||
import { Badge, BadgeDelta, Button } from '@tremor/react';
|
||||
import { Badge, BadgeDelta, Button } from "@tremor/react";
|
||||
import RequestAccess from "./request_model_access";
|
||||
import CreateUser from "./create_user_button";
|
||||
|
||||
|
@ -21,7 +32,6 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({
|
|||
const [userData, setuserData] = useState<null | any[]>(null);
|
||||
const [pendingRequests, setPendingRequests] = useState<any[]>([]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (!accessToken || !token || !userRole || !userID) {
|
||||
return;
|
||||
|
@ -29,10 +39,14 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({
|
|||
const fetchData = async () => {
|
||||
try {
|
||||
// Replace with your actual API call for model data
|
||||
const userDataResponse = await userInfoCall(accessToken, null, userRole, true);
|
||||
const userDataResponse = await userInfoCall(
|
||||
accessToken,
|
||||
null,
|
||||
userRole,
|
||||
true
|
||||
);
|
||||
console.log("user data response:", userDataResponse);
|
||||
setuserData(userDataResponse);
|
||||
|
||||
} catch (error) {
|
||||
console.error("There was an error fetching the model data", error);
|
||||
}
|
||||
|
@ -51,40 +65,62 @@ const ViewUserDashboard: React.FC<ViewUserDashboardProps> = ({
|
|||
return <div>Loading...</div>;
|
||||
}
|
||||
|
||||
// when users click request access show pop up to allow them to request access
|
||||
|
||||
return (
|
||||
<div style={{ width: "100%" }}>
|
||||
<Grid className="gap-2 p-10 h-[75vh] w-full">
|
||||
<CreateUser
|
||||
userID={userID}
|
||||
accessToken={accessToken}
|
||||
/>
|
||||
<Card>
|
||||
<Table className="mt-5">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell><Title>User ID </Title></TableCell>
|
||||
<TableCell><Title>User Role</Title></TableCell>
|
||||
<TableCell><Title>User Models</Title></TableCell>
|
||||
<TableCell><Title>User Spend ($ USD)</Title></TableCell>
|
||||
<TableCell><Title>User Max Budget ($ USD)</Title></TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{userData.map((user: any) => (
|
||||
<TableRow key={user.user_id}>
|
||||
<TableCell><Title>{user.user_id}</Title></TableCell>
|
||||
<TableCell><Title>{user.user_role ? user.user_role : "app_user"}</Title></TableCell>
|
||||
<TableCell><Title>{user.models && user.models.length > 0 ? user.models : "All Models"}</Title></TableCell>
|
||||
<TableCell><Title>{user.spend ? user.spend : 0}</Title></TableCell>
|
||||
<TableCell><Title>{user.max_budget ? user.max_budget : "Unlimited"}</Title></TableCell>
|
||||
|
||||
<Grid className="gap-2 p-10 h-[75vh] w-full">
|
||||
<CreateUser userID={userID} accessToken={accessToken} />
|
||||
<Card>
|
||||
<Table className="mt-5">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<Title>User ID </Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>User Role</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>User Models</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>User Spend ($ USD)</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>User Max Budget ($ USD)</Title>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Card>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{userData.map((user: any) => (
|
||||
<TableRow key={user.user_id}>
|
||||
<TableCell>
|
||||
<Title>{user.user_id}</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>
|
||||
{user.user_role ? user.user_role : "app_user"}
|
||||
</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>
|
||||
{user.models && user.models.length > 0
|
||||
? user.models
|
||||
: "All Models"}
|
||||
</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>{user.spend ? user.spend : 0}</Title>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Title>
|
||||
{user.max_budget ? user.max_budget : "Unlimited"}
|
||||
</Title>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Card>
|
||||
</Grid>
|
||||
</div>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue