khoj 1.30.2.dev11__py3-none-any.whl → 1.30.2.dev15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. khoj/interface/compiled/404/index.html +1 -1
  2. khoj/interface/compiled/_next/static/chunks/1603-1407afe510f0145a.js +1 -0
  3. khoj/interface/compiled/_next/static/chunks/app/agents/{page-5f6e0dacc34e33ad.js → page-b086c9b0aa5a3833.js} +1 -1
  4. khoj/interface/compiled/_next/static/chunks/app/automations/{page-60bc7454bc3ea881.js → page-697a2d415e11a872.js} +1 -1
  5. khoj/interface/compiled/_next/static/chunks/app/chat/{page-ac366c9111374312.js → page-461e26fcb7578d39.js} +1 -1
  6. khoj/interface/compiled/_next/static/chunks/app/{page-358154a4436ef316.js → page-4a3c49c5e996cc40.js} +1 -1
  7. khoj/interface/compiled/_next/static/chunks/app/search/{page-64ea1717528979af.js → page-9013658bebfc3d17.js} +1 -1
  8. khoj/interface/compiled/_next/static/chunks/app/settings/{page-17a538580c65e7fe.js → page-41eb536497bb544a.js} +1 -1
  9. khoj/interface/compiled/_next/static/chunks/app/share/chat/{page-47641b3691fb0856.js → page-6a68ac7e227b34e7.js} +1 -1
  10. khoj/interface/compiled/_next/static/chunks/{webpack-1c0a37d7df44bed9.js → webpack-224b38bd040ae7a0.js} +1 -1
  11. khoj/interface/compiled/_next/static/css/23f801d22927d568.css +1 -0
  12. khoj/interface/compiled/_next/static/css/592ca99f5122e75a.css +1 -0
  13. khoj/interface/compiled/agents/index.html +1 -1
  14. khoj/interface/compiled/agents/index.txt +2 -2
  15. khoj/interface/compiled/automations/index.html +1 -1
  16. khoj/interface/compiled/automations/index.txt +2 -2
  17. khoj/interface/compiled/chat/index.html +1 -1
  18. khoj/interface/compiled/chat/index.txt +2 -2
  19. khoj/interface/compiled/index.html +1 -1
  20. khoj/interface/compiled/index.txt +2 -2
  21. khoj/interface/compiled/search/index.html +1 -1
  22. khoj/interface/compiled/search/index.txt +2 -2
  23. khoj/interface/compiled/settings/index.html +1 -1
  24. khoj/interface/compiled/settings/index.txt +2 -2
  25. khoj/interface/compiled/share/chat/index.html +1 -1
  26. khoj/interface/compiled/share/chat/index.txt +2 -2
  27. khoj/processor/conversation/anthropic/utils.py +15 -1
  28. khoj/processor/conversation/google/utils.py +12 -1
  29. khoj/processor/conversation/openai/utils.py +33 -17
  30. khoj/processor/conversation/utils.py +3 -2
  31. khoj/routers/api_chat.py +29 -14
  32. khoj/routers/helpers.py +4 -1
  33. khoj/utils/constants.py +17 -0
  34. khoj/utils/helpers.py +24 -0
  35. {khoj-1.30.2.dev11.dist-info → khoj-1.30.2.dev15.dist-info}/METADATA +1 -1
  36. {khoj-1.30.2.dev11.dist-info → khoj-1.30.2.dev15.dist-info}/RECORD +41 -41
  37. khoj/interface/compiled/_next/static/chunks/1603-859ddcf58f3ca639.js +0 -1
  38. khoj/interface/compiled/_next/static/css/2ff098d0815fdbc1.css +0 -1
  39. khoj/interface/compiled/_next/static/css/4cae6c0e5c72fb2d.css +0 -1
  40. /khoj/interface/compiled/_next/static/{ZwZ17DepweYHu7DUF8zml → j4py4V8sxXHwFlBE4LvN_}/_buildManifest.js +0 -0
  41. /khoj/interface/compiled/_next/static/{ZwZ17DepweYHu7DUF8zml → j4py4V8sxXHwFlBE4LvN_}/_ssgManifest.js +0 -0
  42. {khoj-1.30.2.dev11.dist-info → khoj-1.30.2.dev15.dist-info}/WHEEL +0 -0
  43. {khoj-1.30.2.dev11.dist-info → khoj-1.30.2.dev15.dist-info}/entry_points.txt +0 -0
  44. {khoj-1.30.2.dev11.dist-info → khoj-1.30.2.dev15.dist-info}/licenses/LICENSE +0 -0
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/5455839c73f146e7-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/0e9d53dcd7f11342.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/1a4038cc4acc8ee4.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/3cf13271869a4aeb.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/2ff098d0815fdbc1.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/1f293605f2871853.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-1c0a37d7df44bed9.js"/><script src="/_next/static/chunks/fd9d1056-2e6c8140e79afc3b.js" async=""></script><script src="/_next/static/chunks/7023-e8de2bded4df6539.js" async=""></script><script src="/_next/static/chunks/main-app-6d6ee3495efe03d4.js" async=""></script><script src="/_next/static/chunks/d3ac728e-a9e3522eef9b6b28.js" async=""></script><script src="/_next/static/chunks/3072-be830e4f8412b9d2.js" async=""></script><script src="/_next/static/chunks/216-b2e4344315b88832.js" async=""></script><script src="/_next/static/chunks/3124-e8410bbd01f6f188.js" async=""></script><script src="/_next/static/chunks/7592-a09c39a38e60634b.js" async=""></script><script src="/_next/static/chunks/3690-51312931ba1eae30.js" async=""></script><script src="/_next/static/chunks/796-36ee2d6829448c6d.js" async=""></script><script src="/_next/static/chunks/1603-859ddcf58f3ca639.js" async=""></script><script src="/_next/static/chunks/9417-06236cd650f1abcd.js" async=""></script><script src="/_next/static/chunks/8423-1dda16bc56236523.js" async=""></script><script src="/_next/static/chunks/5538-e5f3c9f4d67a64b9.js" async=""></script><script src="/_next/static/chunks/app/share/chat/page-47641b3691fb0856.js" async=""></script><meta http-equiv="Content-Security-Policy" content="default-src &#x27;self&#x27; https://assets.khoj.dev; media-src * blob:; script-src &#x27;self&#x27; https://assets.khoj.dev &#x27;unsafe-inline&#x27; &#x27;unsafe-eval&#x27;; connect-src &#x27;self&#x27; blob: https://ipapi.co/json ws://localhost:42110; style-src &#x27;self&#x27; https://assets.khoj.dev &#x27;unsafe-inline&#x27; https://fonts.googleapis.com; img-src &#x27;self&#x27; data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src &#x27;self&#x27; https://assets.khoj.dev https://fonts.gstatic.com; child-src &#x27;none&#x27;; object-src &#x27;none&#x27;;"/><meta http-equiv="Content-Security-Policy" content="default-src &#x27;self&#x27; https://assets.khoj.dev; script-src &#x27;self&#x27; https://assets.khoj.dev &#x27;unsafe-inline&#x27; &#x27;unsafe-eval&#x27;; connect-src &#x27;self&#x27; blob: https://ipapi.co/json ws://localhost:42110; style-src &#x27;self&#x27; https://assets.khoj.dev &#x27;unsafe-inline&#x27; https://fonts.googleapis.com; img-src &#x27;self&#x27; data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src &#x27;self&#x27; https://assets.khoj.dev https://fonts.gstatic.com; child-src &#x27;none&#x27;; object-src &#x27;none&#x27;;"/><title>Khoj AI - Chat</title><meta name="description" content="Use this page to view a chat with Khoj AI."/><link rel="manifest" href="/static/khoj.webmanifest" crossorigin="use-credentials"/><meta property="og:title" content="Khoj AI"/><meta property="og:description" content="Your Second Brain."/><meta property="og:url" content="https://app.khoj.dev/"/><meta property="og:site_name" content="Khoj AI"/><meta property="og:image" content="https://assets.khoj.dev/khoj_lantern_256x256.png"/><meta property="og:image:width" content="256"/><meta property="og:image:height" content="256"/><meta property="og:image" content="https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:type" content="website"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:title" content="Khoj AI"/><meta name="twitter:description" content="Your Second Brain."/><meta name="twitter:image" content="https://assets.khoj.dev/khoj_lantern_256x256.png"/><meta name="twitter:image:width" content="256"/><meta name="twitter:image:height" content="256"/><meta name="twitter:image" content="https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png"/><meta name="twitter:image:width" content="1200"/><meta name="twitter:image:height" content="630"/><link rel="icon" href="/static/assets/icons/khoj_lantern.ico"/><link rel="apple-touch-icon" href="/static/assets/icons/khoj_lantern_256x256.png"/><meta name="next-size-adjust"/><script src="/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js" noModule=""></script></head><body class="__className_af6c42"><html lang="en"><body class="__className_af6c42"><div class="bg-background opacity-50 flex items-center justify-center h-screen"><div>Loading<!-- --> <span><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 256 256" class="inline animate-spin h-5 w-5"><path d="M232,128a104,104,0,0,1-208,0c0-41,23.81-78.36,60.66-95.27a8,8,0,0,1,6.68,14.54C60.15,61.59,40,93.27,40,128a88,88,0,0,0,176,0c0-34.73-20.15-66.41-51.34-80.73a8,8,0,0,1,6.68-14.54C208.19,49.64,232,87,232,128Z"></path></svg></span></div></div><script>window.EXCALIDRAW_ASSET_PATH = 'https://assets.khoj.dev/@excalidraw/excalidraw/dist/';</script><script src="/_next/static/chunks/webpack-1c0a37d7df44bed9.js" async=""></script></body></html><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/media/5455839c73f146e7-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/_next/static/css/0e9d53dcd7f11342.css\",\"style\"]\n3:HL[\"/_next/static/css/1a4038cc4acc8ee4.css\",\"style\"]\n4:HL[\"/_next/static/css/3cf13271869a4aeb.css\",\"style\"]\n5:HL[\"/_next/static/css/2ff098d0815fdbc1.css\",\"style\"]\n6:HL[\"/_next/static/css/1f293605f2871853.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"7:I[95751,[],\"\"]\n9:I[66513,[],\"ClientPageRoot\"]\na:I[5506,[\"3954\",\"static/chunks/d3ac728e-a9e3522eef9b6b28.js\",\"3072\",\"static/chunks/3072-be830e4f8412b9d2.js\",\"216\",\"static/chunks/216-b2e4344315b88832.js\",\"3124\",\"static/chunks/3124-e8410bbd01f6f188.js\",\"7592\",\"static/chunks/7592-a09c39a38e60634b.js\",\"3690\",\"static/chunks/3690-51312931ba1eae30.js\",\"796\",\"static/chunks/796-36ee2d6829448c6d.js\",\"1603\",\"static/chunks/1603-859ddcf58f3ca639.js\",\"9417\",\"static/chunks/9417-06236cd650f1abcd.js\",\"8423\",\"static/chunks/8423-1dda16bc56236523.js\",\"5538\",\"static/chunks/5538-e5f3c9f4d67a64b9.js\",\"3111\",\"static/chunks/app/share/chat/page-47641b3691fb0856.js\"],\"default\",1]\nb:I[39275,[],\"\"]\nc:I[61343,[],\"\"]\ne:I[76130,[],\"\"]\nf:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L7\",null,{\"buildId\":\"ZwZ17DepweYHu7DUF8zml\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"share\",\"chat\",\"\"],\"initialTree\":[\"\",{\"children\":[\"share\",{\"children\":[\"chat\",{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"share\",{\"children\":[\"chat\",{\"children\":[\"__PAGE__\",{},[[\"$L8\",[\"$\",\"$L9\",null,{\"props\":{\"params\":{},\"searchParams\":{}},\"Component\":\"$a\"}],[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/3cf13271869a4aeb.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/2ff098d0815fdbc1.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"2\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/1f293605f2871853.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]]],null],null]},[[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[[\"$\",\"meta\",null,{\"httpEquiv\":\"Content-Security-Policy\",\"content\":\"default-src 'self' https://assets.khoj.dev; script-src 'self' https://assets.khoj.dev 'unsafe-inline' 'unsafe-eval'; connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110; style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com; child-src 'none'; object-src 'none';\"}],[\"$\",\"body\",null,{\"className\":\"__className_af6c42\",\"children\":[[\"$\",\"$Lb\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"share\",\"children\",\"chat\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$Lc\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}],[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"window.EXCALIDRAW_ASSET_PATH = 'https://assets.khoj.dev/@excalidraw/excalidraw/dist/';\"}}]]}]]}]],null],null]},[null,[\"$\",\"$Lb\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"share\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$Lc\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/0e9d53dcd7f11342.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/1a4038cc4acc8ee4.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[[\"$\",\"meta\",null,{\"httpEquiv\":\"Content-Security-Policy\",\"content\":\"default-src 'self' https://assets.khoj.dev; media-src * blob:; script-src 'self' https://assets.khoj.dev 'unsafe-inline' 'unsafe-eval'; connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110; style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com; child-src 'none'; object-src 'none';\"}],[\"$\",\"body\",null,{\"className\":\"__className_af6c42\",\"children\":[\"$\",\"$Lb\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$Lc\",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\":[]}]}]]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[null,\"$Ld\"],\"globalErrorComponent\":\"$e\",\"missingSlots\":\"$Wf\"}]\n"])</script><script>self.__next_f.push([1,"d:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"Khoj AI - Chat\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Use this page to view a chat with Khoj AI.\"}],[\"$\",\"link\",\"4\",{\"rel\":\"manifest\",\"href\":\"/static/khoj.webmanifest\",\"crossOrigin\":\"use-credentials\"}],[\"$\",\"meta\",\"5\",{\"property\":\"og:title\",\"content\":\"Khoj AI\"}],[\"$\",\"meta\",\"6\",{\"property\":\"og:description\",\"content\":\"Your Second Brain.\"}],[\"$\",\"meta\",\"7\",{\"property\":\"og:url\",\"content\":\"https://app.khoj.dev/\"}],[\"$\",\"meta\",\"8\",{\"property\":\"og:site_name\",\"content\":\"Khoj AI\"}],[\"$\",\"meta\",\"9\",{\"property\":\"og:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_256x256.png\"}],[\"$\",\"meta\",\"10\",{\"property\":\"og:image:width\",\"content\":\"256\"}],[\"$\",\"meta\",\"11\",{\"property\":\"og:image:height\",\"content\":\"256\"}],[\"$\",\"meta\",\"12\",{\"property\":\"og:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png\"}],[\"$\",\"meta\",\"13\",{\"property\":\"og:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"14\",{\"property\":\"og:image:height\",\"content\":\"630\"}],[\"$\",\"meta\",\"15\",{\"property\":\"og:type\",\"content\":\"website\"}],[\"$\",\"meta\",\"16\",{\"name\":\"twitter:card\",\"content\":\"summary_large_image\"}],[\"$\",\"meta\",\"17\",{\"name\":\"twitter:title\",\"content\":\"Khoj AI\"}],[\"$\",\"meta\",\"18\",{\"name\":\"twitter:description\",\"content\":\"Your Second Brain.\"}],[\"$\",\"meta\",\"19\",{\"name\":\"twitter:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_256x256.png\"}],[\"$\",\"meta\",\"20\",{\"name\":\"twitter:image:width\",\"content\":\"256\"}],[\"$\",\"meta\",\"21\",{\"name\":\"twitter:image:height\",\"content\":\"256\"}],[\"$\",\"meta\",\"22\",{\"name\":\"twitter:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png\"}],[\"$\",\"meta\",\"23\",{\"name\":\"twitter:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"24\",{\"name\":\"twitter:image:height\",\"content\":\"630\"}],[\"$\",\"link\",\"25\",{\"rel\":\"icon\",\"href\":\"/static/assets/icons/khoj_lantern.ico\"}],[\"$\",\"link\",\"26\",{\"rel\":\"apple-touch-icon\",\"href\":\"/static/assets/icons/khoj_lantern_256x256.png\"}],[\"$\",\"meta\",\"27\",{\"name\":\"next-size-adjust\"}]]\n"])</script><script>self.__next_f.push([1,"8:null\n"])</script></body></html>
1
+ <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/5455839c73f146e7-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/0e9d53dcd7f11342.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/1a4038cc4acc8ee4.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/3cf13271869a4aeb.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/23f801d22927d568.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/1f293605f2871853.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-224b38bd040ae7a0.js"/><script src="/_next/static/chunks/fd9d1056-2e6c8140e79afc3b.js" async=""></script><script src="/_next/static/chunks/7023-e8de2bded4df6539.js" async=""></script><script src="/_next/static/chunks/main-app-6d6ee3495efe03d4.js" async=""></script><script src="/_next/static/chunks/d3ac728e-a9e3522eef9b6b28.js" async=""></script><script src="/_next/static/chunks/3072-be830e4f8412b9d2.js" async=""></script><script src="/_next/static/chunks/216-b2e4344315b88832.js" async=""></script><script src="/_next/static/chunks/3124-e8410bbd01f6f188.js" async=""></script><script src="/_next/static/chunks/7592-a09c39a38e60634b.js" async=""></script><script src="/_next/static/chunks/3690-51312931ba1eae30.js" async=""></script><script src="/_next/static/chunks/796-36ee2d6829448c6d.js" async=""></script><script src="/_next/static/chunks/1603-1407afe510f0145a.js" async=""></script><script src="/_next/static/chunks/9417-06236cd650f1abcd.js" async=""></script><script src="/_next/static/chunks/8423-1dda16bc56236523.js" async=""></script><script src="/_next/static/chunks/5538-e5f3c9f4d67a64b9.js" async=""></script><script src="/_next/static/chunks/app/share/chat/page-6a68ac7e227b34e7.js" async=""></script><meta http-equiv="Content-Security-Policy" content="default-src &#x27;self&#x27; https://assets.khoj.dev; media-src * blob:; script-src &#x27;self&#x27; https://assets.khoj.dev &#x27;unsafe-inline&#x27; &#x27;unsafe-eval&#x27;; connect-src &#x27;self&#x27; blob: https://ipapi.co/json ws://localhost:42110; style-src &#x27;self&#x27; https://assets.khoj.dev &#x27;unsafe-inline&#x27; https://fonts.googleapis.com; img-src &#x27;self&#x27; data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src &#x27;self&#x27; https://assets.khoj.dev https://fonts.gstatic.com; child-src &#x27;none&#x27;; object-src &#x27;none&#x27;;"/><meta http-equiv="Content-Security-Policy" content="default-src &#x27;self&#x27; https://assets.khoj.dev; script-src &#x27;self&#x27; https://assets.khoj.dev &#x27;unsafe-inline&#x27; &#x27;unsafe-eval&#x27;; connect-src &#x27;self&#x27; blob: https://ipapi.co/json ws://localhost:42110; style-src &#x27;self&#x27; https://assets.khoj.dev &#x27;unsafe-inline&#x27; https://fonts.googleapis.com; img-src &#x27;self&#x27; data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src &#x27;self&#x27; https://assets.khoj.dev https://fonts.gstatic.com; child-src &#x27;none&#x27;; object-src &#x27;none&#x27;;"/><title>Khoj AI - Chat</title><meta name="description" content="Use this page to view a chat with Khoj AI."/><link rel="manifest" href="/static/khoj.webmanifest" crossorigin="use-credentials"/><meta property="og:title" content="Khoj AI"/><meta property="og:description" content="Your Second Brain."/><meta property="og:url" content="https://app.khoj.dev/"/><meta property="og:site_name" content="Khoj AI"/><meta property="og:image" content="https://assets.khoj.dev/khoj_lantern_256x256.png"/><meta property="og:image:width" content="256"/><meta property="og:image:height" content="256"/><meta property="og:image" content="https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:type" content="website"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:title" content="Khoj AI"/><meta name="twitter:description" content="Your Second Brain."/><meta name="twitter:image" content="https://assets.khoj.dev/khoj_lantern_256x256.png"/><meta name="twitter:image:width" content="256"/><meta name="twitter:image:height" content="256"/><meta name="twitter:image" content="https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png"/><meta name="twitter:image:width" content="1200"/><meta name="twitter:image:height" content="630"/><link rel="icon" href="/static/assets/icons/khoj_lantern.ico"/><link rel="apple-touch-icon" href="/static/assets/icons/khoj_lantern_256x256.png"/><meta name="next-size-adjust"/><script src="/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js" noModule=""></script></head><body class="__className_af6c42"><html lang="en"><body class="__className_af6c42"><div class="bg-background opacity-50 flex items-center justify-center h-screen"><div>Loading<!-- --> <span><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 256 256" class="inline animate-spin h-5 w-5"><path d="M232,128a104,104,0,0,1-208,0c0-41,23.81-78.36,60.66-95.27a8,8,0,0,1,6.68,14.54C60.15,61.59,40,93.27,40,128a88,88,0,0,0,176,0c0-34.73-20.15-66.41-51.34-80.73a8,8,0,0,1,6.68-14.54C208.19,49.64,232,87,232,128Z"></path></svg></span></div></div><script>window.EXCALIDRAW_ASSET_PATH = 'https://assets.khoj.dev/@excalidraw/excalidraw/dist/';</script><script src="/_next/static/chunks/webpack-224b38bd040ae7a0.js" async=""></script></body></html><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/media/5455839c73f146e7-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/_next/static/css/0e9d53dcd7f11342.css\",\"style\"]\n3:HL[\"/_next/static/css/1a4038cc4acc8ee4.css\",\"style\"]\n4:HL[\"/_next/static/css/3cf13271869a4aeb.css\",\"style\"]\n5:HL[\"/_next/static/css/23f801d22927d568.css\",\"style\"]\n6:HL[\"/_next/static/css/1f293605f2871853.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"7:I[95751,[],\"\"]\n9:I[66513,[],\"ClientPageRoot\"]\na:I[5506,[\"3954\",\"static/chunks/d3ac728e-a9e3522eef9b6b28.js\",\"3072\",\"static/chunks/3072-be830e4f8412b9d2.js\",\"216\",\"static/chunks/216-b2e4344315b88832.js\",\"3124\",\"static/chunks/3124-e8410bbd01f6f188.js\",\"7592\",\"static/chunks/7592-a09c39a38e60634b.js\",\"3690\",\"static/chunks/3690-51312931ba1eae30.js\",\"796\",\"static/chunks/796-36ee2d6829448c6d.js\",\"1603\",\"static/chunks/1603-1407afe510f0145a.js\",\"9417\",\"static/chunks/9417-06236cd650f1abcd.js\",\"8423\",\"static/chunks/8423-1dda16bc56236523.js\",\"5538\",\"static/chunks/5538-e5f3c9f4d67a64b9.js\",\"3111\",\"static/chunks/app/share/chat/page-6a68ac7e227b34e7.js\"],\"default\",1]\nb:I[39275,[],\"\"]\nc:I[61343,[],\"\"]\ne:I[76130,[],\"\"]\nf:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L7\",null,{\"buildId\":\"j4py4V8sxXHwFlBE4LvN_\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"share\",\"chat\",\"\"],\"initialTree\":[\"\",{\"children\":[\"share\",{\"children\":[\"chat\",{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"share\",{\"children\":[\"chat\",{\"children\":[\"__PAGE__\",{},[[\"$L8\",[\"$\",\"$L9\",null,{\"props\":{\"params\":{},\"searchParams\":{}},\"Component\":\"$a\"}],[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/3cf13271869a4aeb.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/23f801d22927d568.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"2\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/1f293605f2871853.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]]],null],null]},[[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[[\"$\",\"meta\",null,{\"httpEquiv\":\"Content-Security-Policy\",\"content\":\"default-src 'self' https://assets.khoj.dev; script-src 'self' https://assets.khoj.dev 'unsafe-inline' 'unsafe-eval'; connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110; style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com; child-src 'none'; object-src 'none';\"}],[\"$\",\"body\",null,{\"className\":\"__className_af6c42\",\"children\":[[\"$\",\"$Lb\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"share\",\"children\",\"chat\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$Lc\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}],[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"window.EXCALIDRAW_ASSET_PATH = 'https://assets.khoj.dev/@excalidraw/excalidraw/dist/';\"}}]]}]]}]],null],null]},[null,[\"$\",\"$Lb\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"share\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$Lc\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/0e9d53dcd7f11342.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/1a4038cc4acc8ee4.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[[\"$\",\"meta\",null,{\"httpEquiv\":\"Content-Security-Policy\",\"content\":\"default-src 'self' https://assets.khoj.dev; media-src * blob:; script-src 'self' https://assets.khoj.dev 'unsafe-inline' 'unsafe-eval'; connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110; style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com; child-src 'none'; object-src 'none';\"}],[\"$\",\"body\",null,{\"className\":\"__className_af6c42\",\"children\":[\"$\",\"$Lb\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$Lc\",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\":[]}]}]]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[null,\"$Ld\"],\"globalErrorComponent\":\"$e\",\"missingSlots\":\"$Wf\"}]\n"])</script><script>self.__next_f.push([1,"d:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"Khoj AI - Chat\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Use this page to view a chat with Khoj AI.\"}],[\"$\",\"link\",\"4\",{\"rel\":\"manifest\",\"href\":\"/static/khoj.webmanifest\",\"crossOrigin\":\"use-credentials\"}],[\"$\",\"meta\",\"5\",{\"property\":\"og:title\",\"content\":\"Khoj AI\"}],[\"$\",\"meta\",\"6\",{\"property\":\"og:description\",\"content\":\"Your Second Brain.\"}],[\"$\",\"meta\",\"7\",{\"property\":\"og:url\",\"content\":\"https://app.khoj.dev/\"}],[\"$\",\"meta\",\"8\",{\"property\":\"og:site_name\",\"content\":\"Khoj AI\"}],[\"$\",\"meta\",\"9\",{\"property\":\"og:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_256x256.png\"}],[\"$\",\"meta\",\"10\",{\"property\":\"og:image:width\",\"content\":\"256\"}],[\"$\",\"meta\",\"11\",{\"property\":\"og:image:height\",\"content\":\"256\"}],[\"$\",\"meta\",\"12\",{\"property\":\"og:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png\"}],[\"$\",\"meta\",\"13\",{\"property\":\"og:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"14\",{\"property\":\"og:image:height\",\"content\":\"630\"}],[\"$\",\"meta\",\"15\",{\"property\":\"og:type\",\"content\":\"website\"}],[\"$\",\"meta\",\"16\",{\"name\":\"twitter:card\",\"content\":\"summary_large_image\"}],[\"$\",\"meta\",\"17\",{\"name\":\"twitter:title\",\"content\":\"Khoj AI\"}],[\"$\",\"meta\",\"18\",{\"name\":\"twitter:description\",\"content\":\"Your Second Brain.\"}],[\"$\",\"meta\",\"19\",{\"name\":\"twitter:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_256x256.png\"}],[\"$\",\"meta\",\"20\",{\"name\":\"twitter:image:width\",\"content\":\"256\"}],[\"$\",\"meta\",\"21\",{\"name\":\"twitter:image:height\",\"content\":\"256\"}],[\"$\",\"meta\",\"22\",{\"name\":\"twitter:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png\"}],[\"$\",\"meta\",\"23\",{\"name\":\"twitter:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"24\",{\"name\":\"twitter:image:height\",\"content\":\"630\"}],[\"$\",\"link\",\"25\",{\"rel\":\"icon\",\"href\":\"/static/assets/icons/khoj_lantern.ico\"}],[\"$\",\"link\",\"26\",{\"rel\":\"apple-touch-icon\",\"href\":\"/static/assets/icons/khoj_lantern_256x256.png\"}],[\"$\",\"meta\",\"27\",{\"name\":\"next-size-adjust\"}]]\n"])</script><script>self.__next_f.push([1,"8:null\n"])</script></body></html>
@@ -1,7 +1,7 @@
1
1
  2:I[66513,[],"ClientPageRoot"]
2
- 3:I[5506,["3954","static/chunks/d3ac728e-a9e3522eef9b6b28.js","3072","static/chunks/3072-be830e4f8412b9d2.js","216","static/chunks/216-b2e4344315b88832.js","3124","static/chunks/3124-e8410bbd01f6f188.js","7592","static/chunks/7592-a09c39a38e60634b.js","3690","static/chunks/3690-51312931ba1eae30.js","796","static/chunks/796-36ee2d6829448c6d.js","1603","static/chunks/1603-859ddcf58f3ca639.js","9417","static/chunks/9417-06236cd650f1abcd.js","8423","static/chunks/8423-1dda16bc56236523.js","5538","static/chunks/5538-e5f3c9f4d67a64b9.js","3111","static/chunks/app/share/chat/page-47641b3691fb0856.js"],"default",1]
2
+ 3:I[5506,["3954","static/chunks/d3ac728e-a9e3522eef9b6b28.js","3072","static/chunks/3072-be830e4f8412b9d2.js","216","static/chunks/216-b2e4344315b88832.js","3124","static/chunks/3124-e8410bbd01f6f188.js","7592","static/chunks/7592-a09c39a38e60634b.js","3690","static/chunks/3690-51312931ba1eae30.js","796","static/chunks/796-36ee2d6829448c6d.js","1603","static/chunks/1603-1407afe510f0145a.js","9417","static/chunks/9417-06236cd650f1abcd.js","8423","static/chunks/8423-1dda16bc56236523.js","5538","static/chunks/5538-e5f3c9f4d67a64b9.js","3111","static/chunks/app/share/chat/page-6a68ac7e227b34e7.js"],"default",1]
3
3
  4:I[39275,[],""]
4
4
  5:I[61343,[],""]
5
- 0:["ZwZ17DepweYHu7DUF8zml",[[["",{"children":["share",{"children":["chat",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["share",{"children":["chat",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/3cf13271869a4aeb.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/2ff098d0815fdbc1.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","2",{"rel":"stylesheet","href":"/_next/static/css/1f293605f2871853.css","precedence":"next","crossOrigin":"$undefined"}]]],null],null]},[[null,["$","html",null,{"lang":"en","children":[["$","meta",null,{"httpEquiv":"Content-Security-Policy","content":"default-src 'self' https://assets.khoj.dev; script-src 'self' https://assets.khoj.dev 'unsafe-inline' 'unsafe-eval'; connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110; style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com; child-src 'none'; object-src 'none';"}],["$","body",null,{"className":"__className_af6c42","children":[["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","share","children","chat","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}],["$","script",null,{"dangerouslySetInnerHTML":{"__html":"window.EXCALIDRAW_ASSET_PATH = 'https://assets.khoj.dev/@excalidraw/excalidraw/dist/';"}}]]}]]}]],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","share","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/0e9d53dcd7f11342.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/1a4038cc4acc8ee4.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":[["$","meta",null,{"httpEquiv":"Content-Security-Policy","content":"default-src 'self' https://assets.khoj.dev; media-src * blob:; script-src 'self' https://assets.khoj.dev 'unsafe-inline' 'unsafe-eval'; connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110; style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com; child-src 'none'; object-src 'none';"}],["$","body",null,{"className":"__className_af6c42","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"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":[]}]}]]}]],null],null],["$L6",null]]]]
5
+ 0:["j4py4V8sxXHwFlBE4LvN_",[[["",{"children":["share",{"children":["chat",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["share",{"children":["chat",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/3cf13271869a4aeb.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/23f801d22927d568.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","2",{"rel":"stylesheet","href":"/_next/static/css/1f293605f2871853.css","precedence":"next","crossOrigin":"$undefined"}]]],null],null]},[[null,["$","html",null,{"lang":"en","children":[["$","meta",null,{"httpEquiv":"Content-Security-Policy","content":"default-src 'self' https://assets.khoj.dev; script-src 'self' https://assets.khoj.dev 'unsafe-inline' 'unsafe-eval'; connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110; style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com; child-src 'none'; object-src 'none';"}],["$","body",null,{"className":"__className_af6c42","children":[["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","share","children","chat","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}],["$","script",null,{"dangerouslySetInnerHTML":{"__html":"window.EXCALIDRAW_ASSET_PATH = 'https://assets.khoj.dev/@excalidraw/excalidraw/dist/';"}}]]}]]}]],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","share","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/0e9d53dcd7f11342.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/1a4038cc4acc8ee4.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":[["$","meta",null,{"httpEquiv":"Content-Security-Policy","content":"default-src 'self' https://assets.khoj.dev; media-src * blob:; script-src 'self' https://assets.khoj.dev 'unsafe-inline' 'unsafe-eval'; connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110; style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com; child-src 'none'; object-src 'none';"}],["$","body",null,{"className":"__className_af6c42","children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"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":[]}]}]]}]],null],null],["$L6",null]]]]
6
6
  6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Khoj AI - Chat"}],["$","meta","3",{"name":"description","content":"Use this page to view a chat with Khoj AI."}],["$","link","4",{"rel":"manifest","href":"/static/khoj.webmanifest","crossOrigin":"use-credentials"}],["$","meta","5",{"property":"og:title","content":"Khoj AI"}],["$","meta","6",{"property":"og:description","content":"Your Second Brain."}],["$","meta","7",{"property":"og:url","content":"https://app.khoj.dev/"}],["$","meta","8",{"property":"og:site_name","content":"Khoj AI"}],["$","meta","9",{"property":"og:image","content":"https://assets.khoj.dev/khoj_lantern_256x256.png"}],["$","meta","10",{"property":"og:image:width","content":"256"}],["$","meta","11",{"property":"og:image:height","content":"256"}],["$","meta","12",{"property":"og:image","content":"https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png"}],["$","meta","13",{"property":"og:image:width","content":"1200"}],["$","meta","14",{"property":"og:image:height","content":"630"}],["$","meta","15",{"property":"og:type","content":"website"}],["$","meta","16",{"name":"twitter:card","content":"summary_large_image"}],["$","meta","17",{"name":"twitter:title","content":"Khoj AI"}],["$","meta","18",{"name":"twitter:description","content":"Your Second Brain."}],["$","meta","19",{"name":"twitter:image","content":"https://assets.khoj.dev/khoj_lantern_256x256.png"}],["$","meta","20",{"name":"twitter:image:width","content":"256"}],["$","meta","21",{"name":"twitter:image:height","content":"256"}],["$","meta","22",{"name":"twitter:image","content":"https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png"}],["$","meta","23",{"name":"twitter:image:width","content":"1200"}],["$","meta","24",{"name":"twitter:image:height","content":"630"}],["$","link","25",{"rel":"icon","href":"/static/assets/icons/khoj_lantern.ico"}],["$","link","26",{"rel":"apple-touch-icon","href":"/static/assets/icons/khoj_lantern_256x256.png"}],["$","meta","27",{"name":"next-size-adjust"}]]
7
7
  1:null
@@ -18,7 +18,7 @@ from khoj.processor.conversation.utils import (
18
18
  get_image_from_url,
19
19
  )
20
20
  from khoj.utils import state
21
- from khoj.utils.helpers import in_debug_mode, is_none_or_empty
21
+ from khoj.utils.helpers import get_chat_usage_metrics, in_debug_mode, is_none_or_empty
22
22
 
23
23
  logger = logging.getLogger(__name__)
24
24
 
@@ -59,6 +59,7 @@ def anthropic_completion_with_backoff(
59
59
  aggregated_response = "{" if response_type == "json_object" else ""
60
60
  max_tokens = max_tokens or DEFAULT_MAX_TOKENS_ANTHROPIC
61
61
 
62
+ final_message = None
62
63
  model_kwargs = model_kwargs or dict()
63
64
  if system_prompt:
64
65
  model_kwargs["system"] = system_prompt
@@ -73,6 +74,12 @@ def anthropic_completion_with_backoff(
73
74
  ) as stream:
74
75
  for text in stream.text_stream:
75
76
  aggregated_response += text
77
+ final_message = stream.get_final_message()
78
+
79
+ # Calculate cost of chat
80
+ input_tokens = final_message.usage.input_tokens
81
+ output_tokens = final_message.usage.output_tokens
82
+ tracer["usage"] = get_chat_usage_metrics(model_name, input_tokens, output_tokens, tracer.get("usage"))
76
83
 
77
84
  # Save conversation trace
78
85
  tracer["chat_model"] = model_name
@@ -126,6 +133,7 @@ def anthropic_llm_thread(
126
133
  ]
127
134
 
128
135
  aggregated_response = ""
136
+ final_message = None
129
137
  with client.messages.stream(
130
138
  messages=formatted_messages,
131
139
  model=model_name, # type: ignore
@@ -138,6 +146,12 @@ def anthropic_llm_thread(
138
146
  for text in stream.text_stream:
139
147
  aggregated_response += text
140
148
  g.send(text)
149
+ final_message = stream.get_final_message()
150
+
151
+ # Calculate cost of chat
152
+ input_tokens = final_message.usage.input_tokens
153
+ output_tokens = final_message.usage.output_tokens
154
+ tracer["usage"] = get_chat_usage_metrics(model_name, input_tokens, output_tokens, tracer.get("usage"))
141
155
 
142
156
  # Save conversation trace
143
157
  tracer["chat_model"] = model_name
@@ -25,7 +25,7 @@ from khoj.processor.conversation.utils import (
25
25
  get_image_from_url,
26
26
  )
27
27
  from khoj.utils import state
28
- from khoj.utils.helpers import in_debug_mode, is_none_or_empty
28
+ from khoj.utils.helpers import get_chat_usage_metrics, in_debug_mode, is_none_or_empty
29
29
 
30
30
  logger = logging.getLogger(__name__)
31
31
 
@@ -68,6 +68,7 @@ def gemini_completion_with_backoff(
68
68
  response = chat_session.send_message(formatted_messages[-1]["parts"])
69
69
  response_text = response.text
70
70
  except StopCandidateException as e:
71
+ response = None
71
72
  response_text, _ = handle_gemini_response(e.args)
72
73
  # Respond with reason for stopping
73
74
  logger.warning(
@@ -75,6 +76,11 @@ def gemini_completion_with_backoff(
75
76
  + f"Last Message by {messages[-1].role}: {messages[-1].content}"
76
77
  )
77
78
 
79
+ # Aggregate cost of chat
80
+ input_tokens = response.usage_metadata.prompt_token_count if response else 0
81
+ output_tokens = response.usage_metadata.candidates_token_count if response else 0
82
+ tracer["usage"] = get_chat_usage_metrics(model_name, input_tokens, output_tokens, tracer.get("usage"))
83
+
78
84
  # Save conversation trace
79
85
  tracer["chat_model"] = model_name
80
86
  tracer["temperature"] = temperature
@@ -146,6 +152,11 @@ def gemini_llm_thread(
146
152
  if stopped:
147
153
  raise StopCandidateException(message)
148
154
 
155
+ # Calculate cost of chat
156
+ input_tokens = chunk.usage_metadata.prompt_token_count
157
+ output_tokens = chunk.usage_metadata.candidates_token_count
158
+ tracer["usage"] = get_chat_usage_metrics(model_name, input_tokens, output_tokens, tracer.get("usage"))
159
+
149
160
  # Save conversation trace
150
161
  tracer["chat_model"] = model_name
151
162
  tracer["temperature"] = temperature
@@ -4,6 +4,8 @@ from threading import Thread
4
4
  from typing import Dict
5
5
 
6
6
  import openai
7
+ from openai.types.chat.chat_completion import ChatCompletion
8
+ from openai.types.chat.chat_completion_chunk import ChatCompletionChunk
7
9
  from tenacity import (
8
10
  before_sleep_log,
9
11
  retry,
@@ -18,7 +20,7 @@ from khoj.processor.conversation.utils import (
18
20
  commit_conversation_trace,
19
21
  )
20
22
  from khoj.utils import state
21
- from khoj.utils.helpers import in_debug_mode
23
+ from khoj.utils.helpers import get_chat_usage_metrics, in_debug_mode
22
24
 
23
25
  logger = logging.getLogger(__name__)
24
26
 
@@ -63,27 +65,34 @@ def completion_with_backoff(
63
65
  if os.getenv("KHOJ_LLM_SEED"):
64
66
  model_kwargs["seed"] = int(os.getenv("KHOJ_LLM_SEED"))
65
67
 
66
- chat = client.chat.completions.create(
67
- stream=stream,
68
+ chat: ChatCompletion | openai.Stream[ChatCompletionChunk] = client.chat.completions.create(
68
69
  messages=formatted_messages, # type: ignore
69
70
  model=model, # type: ignore
71
+ stream=stream,
72
+ stream_options={"include_usage": True} if stream else {},
70
73
  temperature=temperature,
71
74
  timeout=20,
72
75
  **(model_kwargs or dict()),
73
76
  )
74
77
 
75
- if not stream:
76
- return chat.choices[0].message.content
77
-
78
78
  aggregated_response = ""
79
- for chunk in chat:
80
- if len(chunk.choices) == 0:
81
- continue
82
- delta_chunk = chunk.choices[0].delta # type: ignore
83
- if isinstance(delta_chunk, str):
84
- aggregated_response += delta_chunk
85
- elif delta_chunk.content:
86
- aggregated_response += delta_chunk.content
79
+ if not stream:
80
+ chunk = chat
81
+ aggregated_response = chunk.choices[0].message.content
82
+ else:
83
+ for chunk in chat:
84
+ if len(chunk.choices) == 0:
85
+ continue
86
+ delta_chunk = chunk.choices[0].delta # type: ignore
87
+ if isinstance(delta_chunk, str):
88
+ aggregated_response += delta_chunk
89
+ elif delta_chunk.content:
90
+ aggregated_response += delta_chunk.content
91
+
92
+ # Calculate cost of chat
93
+ input_tokens = chunk.usage.prompt_tokens if hasattr(chunk, "usage") and chunk.usage else 0
94
+ output_tokens = chunk.usage.completion_tokens if hasattr(chunk, "usage") and chunk.usage else 0
95
+ tracer["usage"] = get_chat_usage_metrics(model, input_tokens, output_tokens, tracer.get("usage"))
87
96
 
88
97
  # Save conversation trace
89
98
  tracer["chat_model"] = model
@@ -162,10 +171,11 @@ def llm_thread(
162
171
  if os.getenv("KHOJ_LLM_SEED"):
163
172
  model_kwargs["seed"] = int(os.getenv("KHOJ_LLM_SEED"))
164
173
 
165
- chat = client.chat.completions.create(
166
- stream=stream,
174
+ chat: ChatCompletion | openai.Stream[ChatCompletionChunk] = client.chat.completions.create(
167
175
  messages=formatted_messages,
168
176
  model=model_name, # type: ignore
177
+ stream=stream,
178
+ stream_options={"include_usage": True} if stream else {},
169
179
  temperature=temperature,
170
180
  timeout=20,
171
181
  **(model_kwargs or dict()),
@@ -173,7 +183,8 @@ def llm_thread(
173
183
 
174
184
  aggregated_response = ""
175
185
  if not stream:
176
- aggregated_response = chat.choices[0].message.content
186
+ chunk = chat
187
+ aggregated_response = chunk.choices[0].message.content
177
188
  g.send(aggregated_response)
178
189
  else:
179
190
  for chunk in chat:
@@ -189,6 +200,11 @@ def llm_thread(
189
200
  aggregated_response += text_chunk
190
201
  g.send(text_chunk)
191
202
 
203
+ # Calculate cost of chat
204
+ input_tokens = chunk.usage.prompt_tokens if hasattr(chunk, "usage") and chunk.usage else 0
205
+ output_tokens = chunk.usage.completion_tokens if hasattr(chunk, "usage") and chunk.usage else 0
206
+ tracer["usage"] = get_chat_usage_metrics(model_name, input_tokens, output_tokens, tracer.get("usage"))
207
+
192
208
  # Save conversation trace
193
209
  tracer["chat_model"] = model_name
194
210
  tracer["temperature"] = temperature
@@ -5,7 +5,6 @@ import math
5
5
  import mimetypes
6
6
  import os
7
7
  import queue
8
- import re
9
8
  import uuid
10
9
  from dataclasses import dataclass
11
10
  from datetime import datetime
@@ -57,7 +56,7 @@ model_to_prompt_size = {
57
56
  "gemini-1.5-flash": 20000,
58
57
  "gemini-1.5-pro": 20000,
59
58
  # Anthropic Models
60
- "claude-3-5-sonnet-20240620": 20000,
59
+ "claude-3-5-sonnet-20241022": 20000,
61
60
  "claude-3-5-haiku-20241022": 20000,
62
61
  # Offline Models
63
62
  "bartowski/Meta-Llama-3.1-8B-Instruct-GGUF": 20000,
@@ -213,6 +212,8 @@ class ChatEvent(Enum):
213
212
  REFERENCES = "references"
214
213
  STATUS = "status"
215
214
  METADATA = "metadata"
215
+ USAGE = "usage"
216
+ END_RESPONSE = "end_response"
216
217
 
217
218
 
218
219
  def message_to_log(
khoj/routers/api_chat.py CHANGED
@@ -667,27 +667,37 @@ async def chat(
667
667
  finally:
668
668
  yield event_delimiter
669
669
 
670
- async def send_llm_response(response: str):
670
+ async def send_llm_response(response: str, usage: dict = None):
671
+ # Send Chat Response
671
672
  async for result in send_event(ChatEvent.START_LLM_RESPONSE, ""):
672
673
  yield result
673
674
  async for result in send_event(ChatEvent.MESSAGE, response):
674
675
  yield result
675
676
  async for result in send_event(ChatEvent.END_LLM_RESPONSE, ""):
676
677
  yield result
678
+ # Send Usage Metadata once llm interactions are complete
679
+ if usage:
680
+ async for event in send_event(ChatEvent.USAGE, usage):
681
+ yield event
682
+ async for result in send_event(ChatEvent.END_RESPONSE, ""):
683
+ yield result
677
684
 
678
685
  def collect_telemetry():
679
686
  # Gather chat response telemetry
680
687
  nonlocal chat_metadata
681
688
  latency = time.perf_counter() - start_time
682
689
  cmd_set = set([cmd.value for cmd in conversation_commands])
690
+ cost = (tracer.get("usage", {}) or {}).get("cost", 0)
683
691
  chat_metadata = chat_metadata or {}
684
692
  chat_metadata["conversation_command"] = cmd_set
685
693
  chat_metadata["agent"] = conversation.agent.slug if conversation and conversation.agent else None
686
694
  chat_metadata["latency"] = f"{latency:.3f}"
687
695
  chat_metadata["ttft_latency"] = f"{ttft:.3f}"
696
+ chat_metadata["usage"] = tracer.get("usage")
688
697
 
689
698
  logger.info(f"Chat response time to first token: {ttft:.3f} seconds")
690
699
  logger.info(f"Chat response total time: {latency:.3f} seconds")
700
+ logger.info(f"Chat response cost: ${cost:.5f}")
691
701
  update_telemetry_state(
692
702
  request=request,
693
703
  telemetry_type="api",
@@ -699,7 +709,7 @@ async def chat(
699
709
  )
700
710
 
701
711
  if is_query_empty(q):
702
- async for result in send_llm_response("Please ask your query to get started."):
712
+ async for result in send_llm_response("Please ask your query to get started.", tracer.get("usage")):
703
713
  yield result
704
714
  return
705
715
 
@@ -713,7 +723,7 @@ async def chat(
713
723
  create_new=body.create_new,
714
724
  )
715
725
  if not conversation:
716
- async for result in send_llm_response(f"Conversation {conversation_id} not found"):
726
+ async for result in send_llm_response(f"Conversation {conversation_id} not found", tracer.get("usage")):
717
727
  yield result
718
728
  return
719
729
  conversation_id = conversation.id
@@ -777,7 +787,7 @@ async def chat(
777
787
  await conversation_command_rate_limiter.update_and_check_if_valid(request, cmd)
778
788
  q = q.replace(f"/{cmd.value}", "").strip()
779
789
  except HTTPException as e:
780
- async for result in send_llm_response(str(e.detail)):
790
+ async for result in send_llm_response(str(e.detail), tracer.get("usage")):
781
791
  yield result
782
792
  return
783
793
 
@@ -834,7 +844,7 @@ async def chat(
834
844
  agent_has_entries = await EntryAdapters.aagent_has_entries(agent)
835
845
  if len(file_filters) == 0 and not agent_has_entries:
836
846
  response_log = "No files selected for summarization. Please add files using the section on the left."
837
- async for result in send_llm_response(response_log):
847
+ async for result in send_llm_response(response_log, tracer.get("usage")):
838
848
  yield result
839
849
  else:
840
850
  async for response in generate_summary_from_files(
@@ -853,7 +863,7 @@ async def chat(
853
863
  else:
854
864
  if isinstance(response, str):
855
865
  response_log = response
856
- async for result in send_llm_response(response):
866
+ async for result in send_llm_response(response, tracer.get("usage")):
857
867
  yield result
858
868
 
859
869
  await sync_to_async(save_to_conversation_log)(
@@ -880,7 +890,7 @@ async def chat(
880
890
  conversation_config = await ConversationAdapters.aget_default_conversation_config(user)
881
891
  model_type = conversation_config.model_type
882
892
  formatted_help = help_message.format(model=model_type, version=state.khoj_version, device=get_device())
883
- async for result in send_llm_response(formatted_help):
893
+ async for result in send_llm_response(formatted_help, tracer.get("usage")):
884
894
  yield result
885
895
  return
886
896
  # Adding specification to search online specifically on khoj.dev pages.
@@ -895,7 +905,7 @@ async def chat(
895
905
  except Exception as e:
896
906
  logger.error(f"Error scheduling task {q} for {user.email}: {e}")
897
907
  error_message = f"Unable to create automation. Ensure the automation doesn't already exist."
898
- async for result in send_llm_response(error_message):
908
+ async for result in send_llm_response(error_message, tracer.get("usage")):
899
909
  yield result
900
910
  return
901
911
 
@@ -916,7 +926,7 @@ async def chat(
916
926
  raw_query_files=raw_query_files,
917
927
  tracer=tracer,
918
928
  )
919
- async for result in send_llm_response(llm_response):
929
+ async for result in send_llm_response(llm_response, tracer.get("usage")):
920
930
  yield result
921
931
  return
922
932
 
@@ -963,7 +973,7 @@ async def chat(
963
973
  yield result
964
974
 
965
975
  if conversation_commands == [ConversationCommand.Notes] and not await EntryAdapters.auser_has_entries(user):
966
- async for result in send_llm_response(f"{no_entries_found.format()}"):
976
+ async for result in send_llm_response(f"{no_entries_found.format()}", tracer.get("usage")):
967
977
  yield result
968
978
  return
969
979
 
@@ -1105,7 +1115,7 @@ async def chat(
1105
1115
  "detail": improved_image_prompt,
1106
1116
  "image": None,
1107
1117
  }
1108
- async for result in send_llm_response(json.dumps(content_obj)):
1118
+ async for result in send_llm_response(json.dumps(content_obj), tracer.get("usage")):
1109
1119
  yield result
1110
1120
  return
1111
1121
 
@@ -1132,7 +1142,7 @@ async def chat(
1132
1142
  "inferredQueries": [improved_image_prompt],
1133
1143
  "image": generated_image,
1134
1144
  }
1135
- async for result in send_llm_response(json.dumps(content_obj)):
1145
+ async for result in send_llm_response(json.dumps(content_obj), tracer.get("usage")):
1136
1146
  yield result
1137
1147
  return
1138
1148
 
@@ -1166,7 +1176,7 @@ async def chat(
1166
1176
  diagram_description = excalidraw_diagram_description
1167
1177
  else:
1168
1178
  error_message = "Failed to generate diagram. Please try again later."
1169
- async for result in send_llm_response(error_message):
1179
+ async for result in send_llm_response(error_message, tracer.get("usage")):
1170
1180
  yield result
1171
1181
 
1172
1182
  await sync_to_async(save_to_conversation_log)(
@@ -1213,7 +1223,7 @@ async def chat(
1213
1223
  tracer=tracer,
1214
1224
  )
1215
1225
 
1216
- async for result in send_llm_response(json.dumps(content_obj)):
1226
+ async for result in send_llm_response(json.dumps(content_obj), tracer.get("usage")):
1217
1227
  yield result
1218
1228
  return
1219
1229
 
@@ -1252,6 +1262,11 @@ async def chat(
1252
1262
  if item is None:
1253
1263
  async for result in send_event(ChatEvent.END_LLM_RESPONSE, ""):
1254
1264
  yield result
1265
+ # Send Usage Metadata once llm interactions are complete
1266
+ async for event in send_event(ChatEvent.USAGE, tracer.get("usage")):
1267
+ yield event
1268
+ async for result in send_event(ChatEvent.END_RESPONSE, ""):
1269
+ yield result
1255
1270
  logger.debug("Finished streaming response")
1256
1271
  return
1257
1272
  if not connection_alive or not continue_stream:
khoj/routers/helpers.py CHANGED
@@ -1770,6 +1770,7 @@ Manage your automations [here](/automations).
1770
1770
  class MessageProcessor:
1771
1771
  def __init__(self):
1772
1772
  self.references = {}
1773
+ self.usage = {}
1773
1774
  self.raw_response = ""
1774
1775
 
1775
1776
  def convert_message_chunk_to_json(self, raw_chunk: str) -> Dict[str, Any]:
@@ -1793,6 +1794,8 @@ class MessageProcessor:
1793
1794
  chunk_type = ChatEvent(chunk["type"])
1794
1795
  if chunk_type == ChatEvent.REFERENCES:
1795
1796
  self.references = chunk["data"]
1797
+ elif chunk_type == ChatEvent.USAGE:
1798
+ self.usage = chunk["data"]
1796
1799
  elif chunk_type == ChatEvent.MESSAGE:
1797
1800
  chunk_data = chunk["data"]
1798
1801
  if isinstance(chunk_data, dict):
@@ -1837,7 +1840,7 @@ async def read_chat_stream(response_iterator: AsyncGenerator[str, None]) -> Dict
1837
1840
  if buffer:
1838
1841
  processor.process_message_chunk(buffer)
1839
1842
 
1840
- return {"response": processor.raw_response, "references": processor.references}
1843
+ return {"response": processor.raw_response, "references": processor.references, "usage": processor.usage}
1841
1844
 
1842
1845
 
1843
1846
  def get_user_config(user: KhojUser, request: Request, is_detailed: bool = False):
khoj/utils/constants.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from pathlib import Path
2
+ from typing import Dict
2
3
 
3
4
  app_root_directory = Path(__file__).parent.parent.parent
4
5
  web_directory = app_root_directory / "khoj/interface/web/"
@@ -31,3 +32,19 @@ default_config = {
31
32
  "image": {"encoder": "sentence-transformers/clip-ViT-B-32", "model_directory": "~/.khoj/search/image/"},
32
33
  },
33
34
  }
35
+
36
+ model_to_cost: Dict[str, Dict[str, float]] = {
37
+ # OpenAI Pricing: https://openai.com/api/pricing/
38
+ "gpt-4o": {"input": 2.50, "output": 10.00},
39
+ "gpt-4o-mini": {"input": 0.15, "output": 0.60},
40
+ "o1-preview": {"input": 15.0, "output": 60.00},
41
+ "o1-mini": {"input": 3.0, "output": 12.0},
42
+ # Gemini Pricing: https://ai.google.dev/pricing
43
+ "gemini-1.5-flash": {"input": 0.075, "output": 0.30},
44
+ "gemini-1.5-flash-002": {"input": 0.075, "output": 0.30},
45
+ "gemini-1.5-pro": {"input": 1.25, "output": 5.00},
46
+ "gemini-1.5-pro-002": {"input": 1.25, "output": 5.00},
47
+ # Anthropic Pricing: https://www.anthropic.com/pricing#anthropic-api_
48
+ "claude-3-5-sonnet-20241022": {"input": 3.0, "output": 15.0},
49
+ "claude-3-5-haiku-20241022": {"input": 1.0, "output": 5.0},
50
+ }
khoj/utils/helpers.py CHANGED
@@ -540,3 +540,27 @@ def get_country_code_from_timezone(tz: str) -> str:
540
540
  def get_country_name_from_timezone(tz: str) -> str:
541
541
  """Get country name from timezone"""
542
542
  return country_names.get(get_country_code_from_timezone(tz), "United States")
543
+
544
+
545
+ def get_cost_of_chat_message(model_name: str, input_tokens: int = 0, output_tokens: int = 0, prev_cost: float = 0.0):
546
+ """
547
+ Calculate cost of chat message based on input and output tokens
548
+ """
549
+
550
+ # Calculate cost of input and output tokens. Costs are per million tokens
551
+ input_cost = constants.model_to_cost.get(model_name, {}).get("input", 0) * (input_tokens / 1e6)
552
+ output_cost = constants.model_to_cost.get(model_name, {}).get("output", 0) * (output_tokens / 1e6)
553
+
554
+ return input_cost + output_cost + prev_cost
555
+
556
+
557
+ def get_chat_usage_metrics(model_name: str, input_tokens: int = 0, output_tokens: int = 0, usage: dict = {}):
558
+ """
559
+ Get usage metrics for chat message based on input and output tokens
560
+ """
561
+ prev_usage = usage or {"input_tokens": 0, "output_tokens": 0, "cost": 0.0}
562
+ return {
563
+ "input_tokens": prev_usage["input_tokens"] + input_tokens,
564
+ "output_tokens": prev_usage["output_tokens"] + output_tokens,
565
+ "cost": get_cost_of_chat_message(model_name, input_tokens, output_tokens, prev_cost=prev_usage["cost"]),
566
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: khoj
3
- Version: 1.30.2.dev11
3
+ Version: 1.30.2.dev15
4
4
  Summary: Your Second Brain
5
5
  Project-URL: Homepage, https://khoj.dev
6
6
  Project-URL: Documentation, https://docs.khoj.dev