khoj 1.17.1.dev229__py3-none-any.whl → 1.20.3__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 (213) hide show
  1. khoj/app/settings.py +7 -2
  2. khoj/configure.py +21 -0
  3. khoj/database/adapters/__init__.py +9 -5
  4. khoj/database/admin.py +2 -0
  5. khoj/database/migrations/0055_alter_agent_style_icon.py +37 -0
  6. khoj/database/models/__init__.py +2 -0
  7. khoj/interface/compiled/404/index.html +1 -0
  8. khoj/interface/compiled/_next/static/chunks/1603-fb2d80ae73990df3.js +1 -0
  9. khoj/interface/compiled/_next/static/chunks/2614-7cf01576d4457a75.js +3 -0
  10. khoj/interface/compiled/_next/static/chunks/3062-a42d847c919a9ea4.js +29 -0
  11. khoj/interface/compiled/_next/static/chunks/3678-8c0e55c3b5d83a22.js +25 -0
  12. khoj/interface/compiled/_next/static/chunks/4504-1629487c8bc82203.js +1 -0
  13. khoj/interface/compiled/_next/static/chunks/6297-d1c842ed3f714ab0.js +1 -0
  14. khoj/interface/compiled/_next/static/chunks/6648-ff677e51f1b2bcf1.js +1 -0
  15. khoj/interface/compiled/_next/static/chunks/7023-52c1be60135eb057.js +2 -0
  16. khoj/interface/compiled/_next/static/chunks/7071-b4711cecca6619a8.js +1 -0
  17. khoj/interface/compiled/_next/static/chunks/743-1a64254447cda71f.js +1 -0
  18. khoj/interface/compiled/_next/static/chunks/8423-132ea64eac83fd43.js +1 -0
  19. khoj/interface/compiled/_next/static/chunks/9001-acbca3e19b1a5ddf.js +21 -0
  20. khoj/interface/compiled/_next/static/chunks/9162-4a6d0d0dc5e27618.js +11 -0
  21. khoj/interface/compiled/_next/static/chunks/9178-859894e0d9d67aa5.js +1 -0
  22. khoj/interface/compiled/_next/static/chunks/9417-2e54c6fd056982d8.js +1 -0
  23. khoj/interface/compiled/_next/static/chunks/9693-91b03052c5cabded.js +1 -0
  24. khoj/interface/compiled/_next/static/chunks/app/_not-found/page-07ff4ab42b07845e.js +1 -0
  25. khoj/interface/compiled/_next/static/chunks/app/agents/layout-e71c8e913cccf792.js +1 -0
  26. khoj/interface/compiled/_next/static/chunks/app/agents/page-922694b75f1fb67b.js +1 -0
  27. khoj/interface/compiled/_next/static/chunks/app/automations/layout-27c28e923c9b1ff0.js +1 -0
  28. khoj/interface/compiled/_next/static/chunks/app/automations/page-46913728bcb8f4c6.js +1 -0
  29. khoj/interface/compiled/_next/static/chunks/app/chat/layout-8102549127db3067.js +1 -0
  30. khoj/interface/compiled/_next/static/chunks/app/chat/page-51ab7c4b766ff344.js +1 -0
  31. khoj/interface/compiled/_next/static/chunks/app/factchecker/layout-7b30c541c05fb904.js +1 -0
  32. khoj/interface/compiled/_next/static/chunks/app/factchecker/page-60be5e3295e2c0bc.js +1 -0
  33. khoj/interface/compiled/_next/static/chunks/app/layout-f3e40d346da53112.js +1 -0
  34. khoj/interface/compiled/_next/static/chunks/app/page-635b30b582201b05.js +1 -0
  35. khoj/interface/compiled/_next/static/chunks/app/search/layout-3720f1362310bebb.js +1 -0
  36. khoj/interface/compiled/_next/static/chunks/app/search/page-dcd385f03255ef36.js +1 -0
  37. khoj/interface/compiled/_next/static/chunks/app/settings/layout-6f9314b0d7a26046.js +1 -0
  38. khoj/interface/compiled/_next/static/chunks/app/settings/page-e83f6fa32691ca64.js +1 -0
  39. khoj/interface/compiled/_next/static/chunks/app/share/chat/layout-39f03f9e32399f0f.js +1 -0
  40. khoj/interface/compiled/_next/static/chunks/app/share/chat/page-699b364dc6fbf139.js +1 -0
  41. khoj/interface/compiled/_next/static/chunks/d3ac728e-a9e3522eef9b6b28.js +1 -0
  42. khoj/interface/compiled/_next/static/chunks/fd9d1056-2b978342deb60015.js +1 -0
  43. khoj/interface/compiled/_next/static/chunks/framework-8e0e0f4a6b83a956.js +33 -0
  44. khoj/interface/compiled/_next/static/chunks/main-175c164f5e0f026c.js +1 -0
  45. khoj/interface/compiled/_next/static/chunks/main-app-6d6ee3495efe03d4.js +1 -0
  46. khoj/interface/compiled/_next/static/chunks/pages/_app-f870474a17b7f2fd.js +1 -0
  47. khoj/interface/compiled/_next/static/chunks/pages/_error-c66a4e8afc46f17b.js +1 -0
  48. khoj/interface/compiled/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js +1 -0
  49. khoj/interface/compiled/_next/static/chunks/webpack-97d9516936918753.js +1 -0
  50. khoj/interface/compiled/_next/static/css/1538cedb321e3a97.css +1 -0
  51. khoj/interface/compiled/_next/static/css/1de368beed21dfba.css +25 -0
  52. khoj/interface/compiled/_next/static/css/2272c73fc7a3b571.css +1 -0
  53. khoj/interface/compiled/_next/static/css/4cae6c0e5c72fb2d.css +1 -0
  54. khoj/interface/compiled/_next/static/css/553f9cdcc7a2bcd6.css +1 -0
  55. khoj/interface/compiled/_next/static/css/a22d83f18a32957e.css +1 -0
  56. khoj/interface/compiled/_next/static/css/a3530ec58b0b660f.css +1 -0
  57. khoj/interface/compiled/_next/static/css/b81e909d403fb2df.css +1 -0
  58. khoj/interface/compiled/_next/static/css/df6f4c34ec280d53.css +1 -0
  59. khoj/interface/compiled/_next/static/iCI2Ycgat9pFGG9HeJvvH/_buildManifest.js +1 -0
  60. khoj/interface/compiled/_next/static/iCI2Ycgat9pFGG9HeJvvH/_ssgManifest.js +1 -0
  61. khoj/interface/compiled/_next/static/media/0e790e04fd40ad16-s.p.woff2 +0 -0
  62. khoj/interface/compiled/_next/static/media/4221e1667cd19c7d-s.woff2 +0 -0
  63. khoj/interface/compiled/_next/static/media/6c276159aa0eb14b-s.woff2 +0 -0
  64. khoj/interface/compiled/_next/static/media/6cc0b9500e4f9168-s.woff2 +0 -0
  65. khoj/interface/compiled/_next/static/media/9d9319a7a2ac39c6-s.woff2 +0 -0
  66. khoj/interface/compiled/_next/static/media/KaTeX_AMS-Regular.1608a09b.woff +0 -0
  67. khoj/interface/compiled/_next/static/media/KaTeX_AMS-Regular.4aafdb68.ttf +0 -0
  68. khoj/interface/compiled/_next/static/media/KaTeX_AMS-Regular.a79f1c31.woff2 +0 -0
  69. khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Bold.b6770918.woff +0 -0
  70. khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Bold.cce5b8ec.ttf +0 -0
  71. khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Bold.ec17d132.woff2 +0 -0
  72. khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Regular.07ef19e7.ttf +0 -0
  73. khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Regular.55fac258.woff2 +0 -0
  74. khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Regular.dad44a7f.woff +0 -0
  75. khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Bold.9f256b85.woff +0 -0
  76. khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Bold.b18f59e1.ttf +0 -0
  77. khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Bold.d42a5579.woff2 +0 -0
  78. khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Regular.7c187121.woff +0 -0
  79. khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Regular.d3c882a6.woff2 +0 -0
  80. khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Regular.ed38e79f.ttf +0 -0
  81. khoj/interface/compiled/_next/static/media/KaTeX_Main-Bold.b74a1a8b.ttf +0 -0
  82. khoj/interface/compiled/_next/static/media/KaTeX_Main-Bold.c3fb5ac2.woff2 +0 -0
  83. khoj/interface/compiled/_next/static/media/KaTeX_Main-Bold.d181c465.woff +0 -0
  84. khoj/interface/compiled/_next/static/media/KaTeX_Main-BoldItalic.6f2bb1df.woff2 +0 -0
  85. khoj/interface/compiled/_next/static/media/KaTeX_Main-BoldItalic.70d8b0a5.ttf +0 -0
  86. khoj/interface/compiled/_next/static/media/KaTeX_Main-BoldItalic.e3f82f9d.woff +0 -0
  87. khoj/interface/compiled/_next/static/media/KaTeX_Main-Italic.47373d1e.ttf +0 -0
  88. khoj/interface/compiled/_next/static/media/KaTeX_Main-Italic.8916142b.woff2 +0 -0
  89. khoj/interface/compiled/_next/static/media/KaTeX_Main-Italic.9024d815.woff +0 -0
  90. khoj/interface/compiled/_next/static/media/KaTeX_Main-Regular.0462f03b.woff2 +0 -0
  91. khoj/interface/compiled/_next/static/media/KaTeX_Main-Regular.7f51fe03.woff +0 -0
  92. khoj/interface/compiled/_next/static/media/KaTeX_Main-Regular.b7f8fe9b.ttf +0 -0
  93. khoj/interface/compiled/_next/static/media/KaTeX_Math-BoldItalic.572d331f.woff2 +0 -0
  94. khoj/interface/compiled/_next/static/media/KaTeX_Math-BoldItalic.a879cf83.ttf +0 -0
  95. khoj/interface/compiled/_next/static/media/KaTeX_Math-BoldItalic.f1035d8d.woff +0 -0
  96. khoj/interface/compiled/_next/static/media/KaTeX_Math-Italic.5295ba48.woff +0 -0
  97. khoj/interface/compiled/_next/static/media/KaTeX_Math-Italic.939bc644.ttf +0 -0
  98. khoj/interface/compiled/_next/static/media/KaTeX_Math-Italic.f28c23ac.woff2 +0 -0
  99. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Bold.8c5b5494.woff2 +0 -0
  100. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Bold.94e1e8dc.ttf +0 -0
  101. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Bold.bf59d231.woff +0 -0
  102. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Italic.3b1e59b3.woff2 +0 -0
  103. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Italic.7c9bc82b.woff +0 -0
  104. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Italic.b4c20c84.ttf +0 -0
  105. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Regular.74048478.woff +0 -0
  106. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Regular.ba21ed5f.woff2 +0 -0
  107. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Regular.d4d7ba48.ttf +0 -0
  108. khoj/interface/compiled/_next/static/media/KaTeX_Script-Regular.03e9641d.woff2 +0 -0
  109. khoj/interface/compiled/_next/static/media/KaTeX_Script-Regular.07505710.woff +0 -0
  110. khoj/interface/compiled/_next/static/media/KaTeX_Script-Regular.fe9cbbe1.ttf +0 -0
  111. khoj/interface/compiled/_next/static/media/KaTeX_Size1-Regular.e1e279cb.woff +0 -0
  112. khoj/interface/compiled/_next/static/media/KaTeX_Size1-Regular.eae34984.woff2 +0 -0
  113. khoj/interface/compiled/_next/static/media/KaTeX_Size1-Regular.fabc004a.ttf +0 -0
  114. khoj/interface/compiled/_next/static/media/KaTeX_Size2-Regular.57727022.woff +0 -0
  115. khoj/interface/compiled/_next/static/media/KaTeX_Size2-Regular.5916a24f.woff2 +0 -0
  116. khoj/interface/compiled/_next/static/media/KaTeX_Size2-Regular.d6b476ec.ttf +0 -0
  117. khoj/interface/compiled/_next/static/media/KaTeX_Size3-Regular.9acaf01c.woff +0 -0
  118. khoj/interface/compiled/_next/static/media/KaTeX_Size3-Regular.a144ef58.ttf +0 -0
  119. khoj/interface/compiled/_next/static/media/KaTeX_Size3-Regular.b4230e7e.woff2 +0 -0
  120. khoj/interface/compiled/_next/static/media/KaTeX_Size4-Regular.10d95fd3.woff2 +0 -0
  121. khoj/interface/compiled/_next/static/media/KaTeX_Size4-Regular.7a996c9d.woff +0 -0
  122. khoj/interface/compiled/_next/static/media/KaTeX_Size4-Regular.fbccdabe.ttf +0 -0
  123. khoj/interface/compiled/_next/static/media/KaTeX_Typewriter-Regular.6258592b.woff +0 -0
  124. khoj/interface/compiled/_next/static/media/KaTeX_Typewriter-Regular.a8709e36.woff2 +0 -0
  125. khoj/interface/compiled/_next/static/media/KaTeX_Typewriter-Regular.d97aaf4a.ttf +0 -0
  126. khoj/interface/compiled/_next/static/media/a75c8ea86756d52d-s.woff2 +0 -0
  127. khoj/interface/compiled/_next/static/media/abce7c400ca31a51-s.woff2 +0 -0
  128. khoj/interface/compiled/_next/static/media/f759c939737fb668-s.woff2 +0 -0
  129. khoj/interface/compiled/_next/static/media/flags.3afdda2f.webp +0 -0
  130. khoj/interface/compiled/_next/static/media/flags@2x.5fbe9fc1.webp +0 -0
  131. khoj/interface/compiled/_next/static/media/globe.98e105ca.webp +0 -0
  132. khoj/interface/compiled/_next/static/media/globe@2x.974df6f8.webp +0 -0
  133. khoj/interface/compiled/agents/index.html +1 -0
  134. khoj/interface/compiled/agents/index.txt +7 -0
  135. khoj/interface/compiled/agents.svg +6 -0
  136. khoj/interface/compiled/automation.svg +37 -0
  137. khoj/interface/compiled/automations/index.html +1 -0
  138. khoj/interface/compiled/automations/index.txt +8 -0
  139. khoj/interface/compiled/chat/index.html +1 -0
  140. khoj/interface/compiled/chat/index.txt +7 -0
  141. khoj/interface/compiled/close.svg +5 -0
  142. khoj/interface/compiled/factchecker/index.html +1 -0
  143. khoj/interface/compiled/factchecker/index.txt +7 -0
  144. khoj/interface/compiled/favicon.ico +0 -0
  145. khoj/interface/compiled/index.html +1 -0
  146. khoj/interface/compiled/index.txt +7 -0
  147. khoj/interface/compiled/logo.svg +24 -0
  148. khoj/interface/compiled/search/index.html +1 -0
  149. khoj/interface/compiled/search/index.txt +7 -0
  150. khoj/interface/compiled/settings/index.html +1 -0
  151. khoj/interface/compiled/settings/index.txt +8 -0
  152. khoj/interface/compiled/share/chat/index.html +1 -0
  153. khoj/interface/compiled/share/chat/index.txt +7 -0
  154. khoj/interface/web/assets/icons/agents.svg +17 -5
  155. khoj/interface/web/assets/icons/automation.svg +40 -35
  156. khoj/interface/web/assets/icons/search.svg +40 -8
  157. khoj/interface/web/login.html +1 -1
  158. khoj/routers/api_chat.py +5 -16
  159. khoj/routers/helpers.py +74 -0
  160. khoj/routers/web_client.py +30 -131
  161. khoj/utils/constants.py +1 -0
  162. {khoj-1.17.1.dev229.dist-info → khoj-1.20.3.dist-info}/METADATA +1 -1
  163. khoj-1.20.3.dist-info/RECORD +353 -0
  164. khoj/interface/web/404.html +0 -56
  165. khoj/interface/web/agent.html +0 -312
  166. khoj/interface/web/agents.html +0 -276
  167. khoj/interface/web/assets/icons/cancel.svg +0 -3
  168. khoj/interface/web/assets/icons/collapse.svg +0 -17
  169. khoj/interface/web/assets/icons/computer.png +0 -0
  170. khoj/interface/web/assets/icons/confirm-icon.svg +0 -1
  171. khoj/interface/web/assets/icons/credit-card.png +0 -0
  172. khoj/interface/web/assets/icons/delete.svg +0 -26
  173. khoj/interface/web/assets/icons/docx.svg +0 -7
  174. khoj/interface/web/assets/icons/edit.svg +0 -4
  175. khoj/interface/web/assets/icons/key.svg +0 -4
  176. khoj/interface/web/assets/icons/markdown.svg +0 -1
  177. khoj/interface/web/assets/icons/new.svg +0 -23
  178. khoj/interface/web/assets/icons/notion.svg +0 -4
  179. khoj/interface/web/assets/icons/openai-logomark.svg +0 -1
  180. khoj/interface/web/assets/icons/org.svg +0 -1
  181. khoj/interface/web/assets/icons/pdf.svg +0 -23
  182. khoj/interface/web/assets/icons/pencil-edit.svg +0 -5
  183. khoj/interface/web/assets/icons/plaintext.svg +0 -1
  184. khoj/interface/web/assets/icons/question-mark-icon.svg +0 -1
  185. khoj/interface/web/assets/icons/speaker.svg +0 -4
  186. khoj/interface/web/assets/icons/stop-solid.svg +0 -37
  187. khoj/interface/web/assets/icons/user-silhouette.svg +0 -4
  188. khoj/interface/web/assets/icons/voice.svg +0 -8
  189. khoj/interface/web/assets/icons/web.svg +0 -2
  190. khoj/interface/web/assets/icons/whatsapp.svg +0 -17
  191. khoj/interface/web/assets/markdown-it.min.js +0 -8476
  192. khoj/interface/web/assets/natural-cron.min.js +0 -1
  193. khoj/interface/web/assets/org.min.js +0 -1823
  194. khoj/interface/web/assets/pico.min.css +0 -5
  195. khoj/interface/web/assets/purify.min.js +0 -3
  196. khoj/interface/web/chat.html +0 -3436
  197. khoj/interface/web/config_automation.html +0 -1103
  198. khoj/interface/web/content_source_computer_input.html +0 -139
  199. khoj/interface/web/content_source_notion_input.html +0 -94
  200. khoj/interface/web/public_conversation.html +0 -2006
  201. khoj/interface/web/search.html +0 -470
  202. khoj/interface/web/settings.html +0 -1011
  203. khoj-1.17.1.dev229.dist-info/RECORD +0 -244
  204. /khoj/interface/{web/assets/icons → compiled}/chat.svg +0 -0
  205. /khoj/interface/{web/assets/icons → compiled}/copy-button-success.svg +0 -0
  206. /khoj/interface/{web/assets/icons → compiled}/copy-button.svg +0 -0
  207. /khoj/interface/{web/assets/icons → compiled}/send.svg +0 -0
  208. /khoj/interface/{web/assets/icons → compiled}/share.svg +0 -0
  209. /khoj/interface/{web/assets/icons/thumbs-down-svgrepo-com.svg → compiled/thumbs-down.svg} +0 -0
  210. /khoj/interface/{web/assets/icons/thumbs-up-svgrepo-com.svg → compiled/thumbs-up.svg} +0 -0
  211. {khoj-1.17.1.dev229.dist-info → khoj-1.20.3.dist-info}/WHEEL +0 -0
  212. {khoj-1.17.1.dev229.dist-info → khoj-1.20.3.dist-info}/entry_points.txt +0 -0
  213. {khoj-1.17.1.dev229.dist-info → khoj-1.20.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,37 +1,42 @@
1
1
  <svg
2
- width="800px"
3
- height="800px"
4
- viewBox="0 0 24 24"
5
- fill="none"
6
- version="1.1"
7
- xmlns="http://www.w3.org/2000/svg"
8
- xmlns:svg="http://www.w3.org/2000/svg">
9
- <path
10
- d="m 19.402765,19.007843 c 1.380497,-1.679442 2.307667,-4.013099 2.307667,-6.330999 C 21.710432,7.2551476 17.193958,2.86 11.622674,2.86 6.0513555,2.86 1.5349153,7.2551476 1.5349153,12.676844 c 0,5.421663 4.5164402,9.816844 10.0877587,9.816844 2.381867,0 4.570922,-0.803307 6.296712,-2.14673 z m -7.780091,1.925408 c -4.3394583,0 -8.6708434,-4.033489 -8.6708434,-8.256407 0,-4.2229187 4.3313851,-8.2564401 8.6708434,-8.2564401 4.339458,0 8.670809,4.2369112 8.670809,8.4598301 0,4.222918 -4.331351,8.053017 -8.670809,8.053017 z"
11
- fill="#1c274c"
12
- fill-rule="evenodd"
13
- clip-rule="evenodd"
14
- fill-opacity="1"
15
- stroke-width="1.10519"
16
- stroke-dasharray="none" />
17
- <path
18
- d="m 14.177351,11.200265 0.05184,2.153289"
19
- stroke="#1c274c"
20
- stroke-width="1.95702"
21
- stroke-linecap="round" />
22
- <path
23
- d="m 9.271347,11.140946 0.051844,2.153289"
24
- stroke="#1c274c"
25
- stroke-width="1.95701"
26
- stroke-linecap="round" />
27
- <path
28
- d="m 13.557051,1.4687179 c -1.779392,0.00605 -3.082184,0.01209 -3.6968064,0.018135"
29
- stroke="#1c274c"
30
- stroke-width="1.77333"
31
- stroke-linecap="round" />
32
- <path
33
- d="M 20.342466,5.7144363 19.140447,6.8696139"
34
- stroke="#1c274c"
35
- stroke-width="1.95701"
36
- stroke-linecap="round" />
2
+ xmlns="http://www.w3.org/2000/svg"
3
+ version="1.1"
4
+ viewBox="0 0 24 24"
5
+ width="800"
6
+ height="800"
7
+ fill="none"
8
+ >
9
+ <path
10
+ d="m 20.503667,19.512812 c 1.498791,-1.721309 2.505409,-4.113142 2.505409,-6.488822 0,-5.556853 -4.903485,-10.0615654 -10.952165,-10.0615654 -6.0487172,0 -10.9521652,4.5047124 -10.9521652,10.0615654 0,5.556818 4.903448,10.061562 10.9521652,10.061562 2.585967,0 4.962599,-0.823331 6.836268,-2.200243 z m -8.446756,1.973405 c -4.7113005,0 -9.4138363,-4.134038 -9.4138363,-8.462227 0,-4.3281914 4.7025358,-8.4622628 9.4138363,-8.4622628 4.711301,0 9.4138,4.3425313 9.4138,8.6707228 0,4.328187 -4.702499,8.253767 -9.4138,8.253767 z"
11
+ fill="currentColor"
12
+ fill-rule="evenodd"
13
+ clip-rule="evenodd"
14
+ fill-opacity="1"
15
+ stroke-width="1.16584"
16
+ stroke-dasharray="none"
17
+ />
18
+ <path
19
+ d="m 14.703831,11.557853 0.0553,2.175599"
20
+ stroke="currentColor"
21
+ stroke-width="2.03174"
22
+ stroke-linecap="round"
23
+ />
24
+ <path
25
+ d="m 9.470316,11.497919 0.055305,2.175598"
26
+ stroke="currentColor"
27
+ stroke-width="2.03172"
28
+ stroke-linecap="round"
29
+ />
30
+ <path
31
+ d="m 13.921987,2.0293778 c -1.700446,0.00578 -2.945437,0.011553 -3.53279,0.01733"
32
+ stroke="currentColor"
33
+ stroke-width="1.69465"
34
+ stroke-linecap="round"
35
+ />
36
+ <path
37
+ d="m 21.395697,5.8423397 -1.28226,1.167146"
38
+ stroke="currentColor"
39
+ stroke-width="2.03172"
40
+ stroke-linecap="round"
41
+ />
37
42
  </svg>
@@ -1,25 +1,57 @@
1
- <svg xmlns="http://www.w3.org/2000/svg"
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg
2
3
  width="800px"
3
4
  height="800px"
4
5
  viewBox="0 0 24 24"
5
6
  fill="none"
6
- version="1.1">
7
+ version="1.1"
8
+ id="svg3"
9
+ sodipodi:docname="search.svg"
10
+ inkscape:version="1.3 (0e150ed, 2023-07-21)"
11
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
13
+ xmlns="http://www.w3.org/2000/svg"
14
+ xmlns:svg="http://www.w3.org/2000/svg">
15
+ <defs
16
+ id="defs3" />
17
+ <sodipodi:namedview
18
+ id="namedview3"
19
+ pagecolor="#ffffff"
20
+ bordercolor="#000000"
21
+ borderopacity="0.25"
22
+ inkscape:showpageshadow="2"
23
+ inkscape:pageopacity="0.0"
24
+ inkscape:pagecheckerboard="0"
25
+ inkscape:deskcolor="#d1d1d1"
26
+ inkscape:zoom="0.295"
27
+ inkscape:cx="398.30508"
28
+ inkscape:cy="400"
29
+ inkscape:window-width="1312"
30
+ inkscape:window-height="449"
31
+ inkscape:window-x="0"
32
+ inkscape:window-y="0"
33
+ inkscape:window-maximized="0"
34
+ inkscape:current-layer="svg3" />
7
35
  <path
8
- d="m 18.562765,17.147843 c 1.380497,-1.679442 2.307667,-4.013099 2.307667,-6.330999 C 20.870432,5.3951476 16.353958,1 10.782674,1 5.2113555,1 0.69491525,5.3951476 0.69491525,10.816844 c 0,5.421663 4.51644025,9.816844 10.08775875,9.816844 2.381867,0 4.570922,-0.803307 6.296712,-2.14673 0.508475,-0.508475 4.514633,4.192839 4.514633,4.192839 1.036377,1.008544 2.113087,-0.02559 1.07671,-1.034139 z m -7.780091,1.925408 c -4.3394583,0 -8.6708434,-4.033489 -8.6708434,-8.256407 0,-4.2229187 4.3313851,-8.2564401 8.6708434,-8.2564401 4.339458,0 8.670809,4.2369112 8.670809,8.4598301 0,4.222918 -4.331351,8.053017 -8.670809,8.053017 z"
36
+ d="m 18.682765,16.907843 c 1.380497,-1.679442 2.307667,-4.013099 2.307667,-6.330999 C 20.990432,5.1551476 16.473958,0.76 10.902674,0.76 5.3313555,0.76 0.81491525,5.1551476 0.81491525,10.576844 c 0,5.421663 4.51644025,9.816844 10.08775875,9.816844 2.381867,0 4.570922,-0.803307 6.296712,-2.14673 0.508475,-0.508475 4.616328,4.599619 4.616328,4.599619 1.036377,1.008544 2.113087,-0.02559 1.07671,-1.034139 z m -7.780091,1.925408 c -4.3394583,0 -8.6708434,-4.033489 -8.6708434,-8.256407 0,-4.2229187 4.3313851,-8.2564401 8.6708434,-8.2564401 4.339458,0 8.670809,4.2369112 8.670809,8.4598301 0,4.222918 -4.331351,8.053017 -8.670809,8.053017 z"
9
37
  fill="#1c274c"
10
38
  fill-rule="evenodd"
11
39
  clip-rule="evenodd"
12
40
  fill-opacity="1"
13
41
  stroke-width="1.10519"
14
- stroke-dasharray="none" />
42
+ stroke-dasharray="none"
43
+ id="path1"
44
+ sodipodi:nodetypes="cssssccccsssss" />
15
45
  <path
16
- d="m 13.337351,9.3402647 0.05184,2.1532893"
46
+ d="m 13.457351,9.1002647 0.05184,2.1532893"
17
47
  stroke="#1c274c"
18
48
  stroke-width="1.95702"
19
- stroke-linecap="round" />
49
+ stroke-linecap="round"
50
+ id="path2" />
20
51
  <path
21
- d="M 8.431347,9.2809457 8.483191,11.434235"
52
+ d="M 8.551347,9.0409457 8.603191,11.194235"
22
53
  stroke="#1c274c"
23
54
  stroke-width="1.95701"
24
- stroke-linecap="round" />
55
+ stroke-linecap="round"
56
+ id="path3" />
25
57
  </svg>
@@ -18,7 +18,7 @@
18
18
  <div class="login-modal-title">Login to Khoj</div>
19
19
  <!-- Sign in with Magic Link -->
20
20
  <div class="khoj-magic-link">
21
- <input type="email" id="email" placeholder="Email" required>
21
+ <input type="email" id="email" placeholder="Email" autofocus required>
22
22
  <button id="magic-link-button">Send Magic Link</button>
23
23
  </div>
24
24
  <!-- Divider -->
khoj/routers/api_chat.py CHANGED
@@ -41,6 +41,7 @@ from khoj.routers.helpers import (
41
41
  get_conversation_command,
42
42
  is_query_empty,
43
43
  is_ready_to_chat,
44
+ read_chat_stream,
44
45
  text_to_image,
45
46
  update_telemetry_state,
46
47
  validate_conversation_config,
@@ -570,8 +571,7 @@ async def chat(
570
571
  logger.error(f"Failed to stream chat API response to {user} on {common.client}: {e}", exc_info=True)
571
572
  return
572
573
  finally:
573
- if stream:
574
- yield event_delimiter
574
+ yield event_delimiter
575
575
 
576
576
  async def send_llm_response(response: str):
577
577
  async for result in send_event(ChatEvent.START_LLM_RESPONSE, ""):
@@ -937,17 +937,6 @@ async def chat(
937
937
  return StreamingResponse(event_generator(q), media_type="text/plain")
938
938
  ## Non-Streaming Text Response
939
939
  else:
940
- # Get the full response from the generator if the stream is not requested.
941
- response_obj = {}
942
- actual_response = ""
943
- iterator = event_generator(q)
944
- async for item in iterator:
945
- try:
946
- item_json = json.loads(item)
947
- if "type" in item_json and item_json["type"] == ChatEvent.REFERENCES.value:
948
- response_obj = item_json["data"]
949
- except:
950
- actual_response += item
951
- response_obj["response"] = actual_response
952
-
953
- return Response(content=json.dumps(response_obj), media_type="application/json", status_code=200)
940
+ response_iterator = event_generator(q)
941
+ response_data = await read_chat_stream(response_iterator)
942
+ return Response(content=json.dumps(response_data), media_type="application/json", status_code=200)
khoj/routers/helpers.py CHANGED
@@ -15,6 +15,7 @@ from random import random
15
15
  from typing import (
16
16
  Annotated,
17
17
  Any,
18
+ AsyncGenerator,
18
19
  Callable,
19
20
  Dict,
20
21
  Iterator,
@@ -1225,6 +1226,79 @@ class ChatEvent(Enum):
1225
1226
  STATUS = "status"
1226
1227
 
1227
1228
 
1229
+ class MessageProcessor:
1230
+ def __init__(self):
1231
+ self.references = {}
1232
+ self.raw_response = ""
1233
+
1234
+ def convert_message_chunk_to_json(self, raw_chunk: str) -> Dict[str, Any]:
1235
+ if raw_chunk.startswith("{") and raw_chunk.endswith("}"):
1236
+ try:
1237
+ json_chunk = json.loads(raw_chunk)
1238
+ if "type" not in json_chunk:
1239
+ json_chunk = {"type": "message", "data": json_chunk}
1240
+ return json_chunk
1241
+ except json.JSONDecodeError:
1242
+ return {"type": "message", "data": raw_chunk}
1243
+ elif raw_chunk:
1244
+ return {"type": "message", "data": raw_chunk}
1245
+ return {"type": "", "data": ""}
1246
+
1247
+ def process_message_chunk(self, raw_chunk: str) -> None:
1248
+ chunk = self.convert_message_chunk_to_json(raw_chunk)
1249
+ if not chunk or not chunk["type"]:
1250
+ return
1251
+
1252
+ chunk_type = ChatEvent(chunk["type"])
1253
+ if chunk_type == ChatEvent.REFERENCES:
1254
+ self.references = chunk["data"]
1255
+ elif chunk_type == ChatEvent.MESSAGE:
1256
+ chunk_data = chunk["data"]
1257
+ if isinstance(chunk_data, dict):
1258
+ self.raw_response = self.handle_json_response(chunk_data)
1259
+ elif (
1260
+ isinstance(chunk_data, str) and chunk_data.strip().startswith("{") and chunk_data.strip().endswith("}")
1261
+ ):
1262
+ try:
1263
+ json_data = json.loads(chunk_data.strip())
1264
+ self.raw_response = self.handle_json_response(json_data)
1265
+ except json.JSONDecodeError:
1266
+ self.raw_response += chunk_data
1267
+ else:
1268
+ self.raw_response += chunk_data
1269
+
1270
+ def handle_json_response(self, json_data: Dict[str, str]) -> str | Dict[str, str]:
1271
+ if "image" in json_data or "details" in json_data:
1272
+ return json_data
1273
+ if "response" in json_data:
1274
+ return json_data["response"]
1275
+ return json_data
1276
+
1277
+
1278
+ async def read_chat_stream(response_iterator: AsyncGenerator[str, None]) -> Dict[str, Any]:
1279
+ processor = MessageProcessor()
1280
+ event_delimiter = "␃🔚␗"
1281
+ buffer = ""
1282
+
1283
+ async for chunk in response_iterator:
1284
+ # Start buffering chunks until complete event is received
1285
+ buffer += chunk
1286
+
1287
+ # Once the buffer contains a complete event
1288
+ while event_delimiter in buffer:
1289
+ # Extract the event from the buffer
1290
+ event, buffer = buffer.split(event_delimiter, 1)
1291
+ # Process the event
1292
+ if event:
1293
+ processor.process_message_chunk(event)
1294
+
1295
+ # Process any remaining data in the buffer
1296
+ if buffer:
1297
+ processor.process_message_chunk(buffer)
1298
+
1299
+ return {"response": processor.raw_response, "references": processor.references}
1300
+
1301
+
1228
1302
  def get_user_config(user: KhojUser, request: Request, is_detailed: bool = False):
1229
1303
  user_picture = request.session.get("user", {}).get("picture")
1230
1304
  is_active = has_required_scope(request, ["premium"])
@@ -1,68 +1,54 @@
1
1
  # System Packages
2
2
  import json
3
3
  import os
4
- from typing import Optional
5
4
 
6
5
  from fastapi import APIRouter, Request
7
6
  from fastapi.responses import FileResponse, HTMLResponse, RedirectResponse
8
7
  from fastapi.templating import Jinja2Templates
9
8
  from starlette.authentication import requires
10
9
 
11
- from khoj.database.adapters import (
12
- AgentAdapters,
13
- PublicConversationAdapters,
14
- get_user_github_config,
15
- get_user_notion_config,
16
- )
17
- from khoj.database.models import KhojUser
10
+ from khoj.database.adapters import get_user_github_config
18
11
  from khoj.routers.helpers import get_next_url, get_user_config
19
- from khoj.utils import constants, state
20
- from khoj.utils.rawconfig import (
21
- GithubContentConfig,
22
- GithubRepoConfig,
23
- NotionContentConfig,
24
- )
12
+ from khoj.utils import constants
13
+ from khoj.utils.rawconfig import GithubContentConfig, GithubRepoConfig
25
14
 
26
15
  # Initialize Router
27
16
  web_client = APIRouter()
28
- templates = Jinja2Templates([constants.web_directory, constants.next_js_directory])
17
+ templates = Jinja2Templates([constants.web_directory, constants.next_js_directory, constants.pypi_static_directory])
29
18
 
30
19
 
31
20
  # Create Routes
32
21
  @web_client.get("/", response_class=FileResponse)
33
- @requires(["authenticated"], redirect="login_page")
34
22
  def index(request: Request):
35
- user = request.user.object
36
- user_config = get_user_config(user, request)
37
-
38
- return templates.TemplateResponse("chat.html", context=user_config)
23
+ return templates.TemplateResponse("index.html", context={"request": request})
39
24
 
40
25
 
41
26
  @web_client.post("/", response_class=FileResponse)
42
27
  @requires(["authenticated"], redirect="login_page")
43
28
  def index_post(request: Request):
44
- user = request.user.object
45
- user_config = get_user_config(user, request)
46
-
47
- return templates.TemplateResponse("chat.html", context=user_config)
29
+ return templates.TemplateResponse("index.html", context={"request": request})
48
30
 
49
31
 
50
32
  @web_client.get("/search", response_class=FileResponse)
51
33
  @requires(["authenticated"], redirect="login_page")
52
34
  def search_page(request: Request):
53
- user = request.user.object
54
- user_config = get_user_config(user, request)
55
-
56
- return templates.TemplateResponse("search.html", context=user_config)
35
+ return templates.TemplateResponse(
36
+ "search/index.html",
37
+ context={
38
+ "request": request,
39
+ },
40
+ )
57
41
 
58
42
 
59
43
  @web_client.get("/chat", response_class=FileResponse)
60
44
  @requires(["authenticated"], redirect="login_page")
61
45
  def chat_page(request: Request):
62
- user = request.user.object
63
- user_config = get_user_config(user, request)
64
-
65
- return templates.TemplateResponse("chat.html", context=user_config)
46
+ return templates.TemplateResponse(
47
+ "chat/index.html",
48
+ context={
49
+ "request": request,
50
+ },
51
+ )
66
52
 
67
53
 
68
54
  @web_client.get("/experimental", response_class=FileResponse)
@@ -113,38 +99,10 @@ def agents_page(request: Request):
113
99
  )
114
100
 
115
101
 
116
- @web_client.get("/agent/{agent_slug}", response_class=HTMLResponse)
117
- def agent_page(request: Request, agent_slug: str):
118
- user: KhojUser = request.user.object if request.user.is_authenticated else None
119
- user_config = get_user_config(user, request)
120
- agent = AgentAdapters.get_agent_by_slug(agent_slug)
121
-
122
- if agent == None:
123
- user_config["has_documents"] = False
124
- return templates.TemplateResponse("404.html", context=user_config)
125
-
126
- user_config["agent"] = {
127
- "slug": agent.slug,
128
- "avatar": agent.avatar,
129
- "name": agent.name,
130
- "personality": agent.personality,
131
- "public": agent.public,
132
- "creator": agent.creator.username if agent.creator else None,
133
- "managed_by_admin": agent.managed_by_admin,
134
- "chat_model": agent.chat_model.chat_model,
135
- "creator_not_self": agent.creator != user,
136
- }
137
-
138
- return templates.TemplateResponse("agent.html", context=user_config)
139
-
140
-
141
102
  @web_client.get("/settings", response_class=HTMLResponse)
142
103
  @requires(["authenticated"], redirect="login_page")
143
104
  def config_page(request: Request):
144
- user: KhojUser = request.user.object
145
- user_config = get_user_config(user, request, is_detailed=True)
146
-
147
- return templates.TemplateResponse("settings.html", context=user_config)
105
+ return templates.TemplateResponse("settings/index.html", context={"request": request})
148
106
 
149
107
 
150
108
  @web_client.get("/settings/content/github", response_class=HTMLResponse)
@@ -177,82 +135,23 @@ def github_config_page(request: Request):
177
135
  return templates.TemplateResponse("content_source_github_input.html", context=user_config)
178
136
 
179
137
 
180
- @web_client.get("/settings/content/notion", response_class=HTMLResponse)
181
- @requires(["authenticated"], redirect="login_page")
182
- def notion_config_page(request: Request):
183
- user = request.user.object
184
- user_config = get_user_config(user, request)
185
-
186
- current_notion_config = get_user_notion_config(user)
187
- token = current_notion_config.token if current_notion_config else ""
188
- current_config = NotionContentConfig(token=token)
189
- current_config = json.loads(current_config.model_dump_json())
190
-
191
- user_config["current_config"] = current_config
192
- return templates.TemplateResponse("content_source_notion_input.html", context=user_config)
193
-
194
-
195
- @web_client.get("/settings/content/computer", response_class=HTMLResponse)
196
- @requires(["authenticated"], redirect="login_page")
197
- def computer_config_page(request: Request):
198
- user = request.user.object if request.user.is_authenticated else None
199
- user_config = get_user_config(user, request)
200
-
201
- return templates.TemplateResponse("content_source_computer_input.html", context=user_config)
202
-
203
-
204
138
  @web_client.get("/share/chat/{public_conversation_slug}", response_class=HTMLResponse)
205
139
  def view_public_conversation(request: Request):
206
- public_conversation_slug = request.path_params.get("public_conversation_slug")
207
- public_conversation = PublicConversationAdapters.get_public_conversation_by_slug(public_conversation_slug)
208
- if not public_conversation:
209
- return templates.TemplateResponse(
210
- "404.html",
211
- context={
212
- "request": request,
213
- "khoj_version": state.khoj_version,
214
- },
215
- )
216
- user = request.user.object if request.user.is_authenticated else None
217
- user_config = get_user_config(user, request)
218
- user_config["public_conversation_slug"] = public_conversation_slug
219
- user_config["google_client_id"] = os.environ.get("GOOGLE_CLIENT_ID")
220
-
221
- all_agents = AgentAdapters.get_all_accessible_agents(request.user.object if request.user.is_authenticated else None)
222
-
223
- # Filter out the current agent
224
- all_agents = [agent for agent in all_agents if agent != public_conversation.agent]
225
- agents_packet = []
226
- for agent in all_agents:
227
- agents_packet.append(
228
- {
229
- "slug": agent.slug,
230
- "avatar": agent.avatar,
231
- "name": agent.name,
232
- }
233
- )
234
- user_config["agents"] = agents_packet
235
-
236
- redirect_uri = str(request.app.url_path_for("auth"))
237
- next_url = str(
238
- request.app.url_path_for("view_public_conversation", public_conversation_slug=public_conversation_slug)
140
+ return templates.TemplateResponse(
141
+ "share/chat/index.html",
142
+ context={
143
+ "request": request,
144
+ },
239
145
  )
240
- user_config["redirect_uri"] = f"{redirect_uri}?next={next_url}"
241
-
242
- return templates.TemplateResponse("public_conversation.html", context=user_config)
243
146
 
244
147
 
245
148
  @web_client.get("/automations", response_class=HTMLResponse)
246
149
  def automations_config_page(
247
150
  request: Request,
248
- subject: Optional[str] = None,
249
- crontime: Optional[str] = None,
250
- queryToRun: Optional[str] = None,
251
151
  ):
252
- user = request.user.object if request.user.is_authenticated else None
253
- user_config = get_user_config(user, request)
254
- user_config["subject"] = subject if subject else ""
255
- user_config["crontime"] = crontime if crontime else ""
256
- user_config["queryToRun"] = queryToRun if queryToRun else ""
257
-
258
- return templates.TemplateResponse("config_automation.html", context=user_config)
152
+ return templates.TemplateResponse(
153
+ "automations/index.html",
154
+ context={
155
+ "request": request,
156
+ },
157
+ )
khoj/utils/constants.py CHANGED
@@ -3,6 +3,7 @@ from pathlib import Path
3
3
  app_root_directory = Path(__file__).parent.parent.parent
4
4
  web_directory = app_root_directory / "khoj/interface/web/"
5
5
  next_js_directory = app_root_directory / "khoj/interface/built/"
6
+ pypi_static_directory = app_root_directory / "khoj/interface/compiled/"
6
7
  empty_escape_sequences = "\n|\r|\t| "
7
8
  app_env_filepath = "~/.khoj/env"
8
9
  telemetry_server = "https://khoj.beta.haletic.com/v1/telemetry"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: khoj
3
- Version: 1.17.1.dev229
3
+ Version: 1.20.3
4
4
  Summary: Your Second Brain
5
5
  Project-URL: Homepage, https://khoj.dev
6
6
  Project-URL: Documentation, https://docs.khoj.dev