khoj 1.33.3.dev32__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 (393) hide show
  1. khoj/__init__.py +0 -0
  2. khoj/app/README.md +94 -0
  3. khoj/app/__init__.py +0 -0
  4. khoj/app/asgi.py +16 -0
  5. khoj/app/settings.py +218 -0
  6. khoj/app/urls.py +25 -0
  7. khoj/configure.py +452 -0
  8. khoj/database/__init__.py +0 -0
  9. khoj/database/adapters/__init__.py +1821 -0
  10. khoj/database/admin.py +417 -0
  11. khoj/database/apps.py +6 -0
  12. khoj/database/management/__init__.py +0 -0
  13. khoj/database/management/commands/__init__.py +0 -0
  14. khoj/database/management/commands/change_default_model.py +116 -0
  15. khoj/database/management/commands/change_generated_images_url.py +61 -0
  16. khoj/database/management/commands/convert_images_png_to_webp.py +99 -0
  17. khoj/database/migrations/0001_khojuser.py +98 -0
  18. khoj/database/migrations/0002_googleuser.py +32 -0
  19. khoj/database/migrations/0003_vector_extension.py +10 -0
  20. khoj/database/migrations/0004_content_types_and_more.py +181 -0
  21. khoj/database/migrations/0005_embeddings_corpus_id.py +19 -0
  22. khoj/database/migrations/0006_embeddingsdates.py +33 -0
  23. khoj/database/migrations/0007_add_conversation.py +27 -0
  24. khoj/database/migrations/0008_alter_conversation_conversation_log.py +17 -0
  25. khoj/database/migrations/0009_khojapiuser.py +24 -0
  26. khoj/database/migrations/0010_chatmodeloptions_and_more.py +83 -0
  27. khoj/database/migrations/0010_rename_embeddings_entry_and_more.py +30 -0
  28. khoj/database/migrations/0011_merge_20231102_0138.py +14 -0
  29. khoj/database/migrations/0012_entry_file_source.py +21 -0
  30. khoj/database/migrations/0013_subscription.py +37 -0
  31. khoj/database/migrations/0014_alter_googleuser_picture.py +17 -0
  32. khoj/database/migrations/0015_alter_subscription_user.py +21 -0
  33. khoj/database/migrations/0016_alter_subscription_renewal_date.py +17 -0
  34. khoj/database/migrations/0017_searchmodel.py +32 -0
  35. khoj/database/migrations/0018_searchmodelconfig_delete_searchmodel.py +30 -0
  36. khoj/database/migrations/0019_alter_googleuser_family_name_and_more.py +27 -0
  37. khoj/database/migrations/0020_reflectivequestion.py +36 -0
  38. khoj/database/migrations/0021_speechtotextmodeloptions_and_more.py +42 -0
  39. khoj/database/migrations/0022_texttoimagemodelconfig.py +25 -0
  40. khoj/database/migrations/0023_usersearchmodelconfig.py +33 -0
  41. khoj/database/migrations/0024_alter_entry_embeddings.py +18 -0
  42. khoj/database/migrations/0025_clientapplication_khojuser_phone_number_and_more.py +46 -0
  43. khoj/database/migrations/0025_searchmodelconfig_embeddings_inference_endpoint_and_more.py +22 -0
  44. khoj/database/migrations/0026_searchmodelconfig_cross_encoder_inference_endpoint_and_more.py +22 -0
  45. khoj/database/migrations/0027_merge_20240118_1324.py +13 -0
  46. khoj/database/migrations/0028_khojuser_verified_phone_number.py +17 -0
  47. khoj/database/migrations/0029_userrequests.py +27 -0
  48. khoj/database/migrations/0030_conversation_slug_and_title.py +38 -0
  49. khoj/database/migrations/0031_agent_conversation_agent.py +53 -0
  50. khoj/database/migrations/0031_alter_googleuser_locale.py +30 -0
  51. khoj/database/migrations/0032_merge_20240322_0427.py +14 -0
  52. khoj/database/migrations/0033_rename_tuning_agent_personality.py +17 -0
  53. khoj/database/migrations/0034_alter_chatmodeloptions_chat_model.py +32 -0
  54. khoj/database/migrations/0035_processlock.py +26 -0
  55. khoj/database/migrations/0036_alter_processlock_name.py +19 -0
  56. khoj/database/migrations/0036_delete_offlinechatprocessorconversationconfig.py +15 -0
  57. khoj/database/migrations/0036_publicconversation.py +42 -0
  58. khoj/database/migrations/0037_chatmodeloptions_openai_config_and_more.py +51 -0
  59. khoj/database/migrations/0037_searchmodelconfig_bi_encoder_docs_encode_config_and_more.py +32 -0
  60. khoj/database/migrations/0038_merge_20240425_0857.py +14 -0
  61. khoj/database/migrations/0038_merge_20240426_1640.py +12 -0
  62. khoj/database/migrations/0039_merge_20240501_0301.py +12 -0
  63. khoj/database/migrations/0040_alter_processlock_name.py +26 -0
  64. khoj/database/migrations/0040_merge_20240504_1010.py +14 -0
  65. khoj/database/migrations/0041_merge_20240505_1234.py +14 -0
  66. khoj/database/migrations/0042_serverchatsettings.py +46 -0
  67. khoj/database/migrations/0043_alter_chatmodeloptions_model_type.py +21 -0
  68. khoj/database/migrations/0044_conversation_file_filters.py +17 -0
  69. khoj/database/migrations/0045_fileobject.py +37 -0
  70. khoj/database/migrations/0046_khojuser_email_verification_code_and_more.py +22 -0
  71. khoj/database/migrations/0047_alter_entry_file_type.py +31 -0
  72. khoj/database/migrations/0048_voicemodeloption_uservoicemodelconfig.py +52 -0
  73. khoj/database/migrations/0049_datastore.py +38 -0
  74. khoj/database/migrations/0049_texttoimagemodelconfig_api_key_and_more.py +58 -0
  75. khoj/database/migrations/0050_alter_processlock_name.py +25 -0
  76. khoj/database/migrations/0051_merge_20240702_1220.py +14 -0
  77. khoj/database/migrations/0052_alter_searchmodelconfig_bi_encoder_docs_encode_config_and_more.py +27 -0
  78. khoj/database/migrations/0053_agent_style_color_agent_style_icon.py +61 -0
  79. khoj/database/migrations/0054_alter_agent_style_color.py +38 -0
  80. khoj/database/migrations/0055_alter_agent_style_icon.py +37 -0
  81. khoj/database/migrations/0056_chatmodeloptions_vision_enabled.py +17 -0
  82. khoj/database/migrations/0056_searchmodelconfig_cross_encoder_model_config.py +17 -0
  83. khoj/database/migrations/0057_merge_20240816_1409.py +13 -0
  84. khoj/database/migrations/0057_remove_serverchatsettings_default_model_and_more.py +51 -0
  85. khoj/database/migrations/0058_alter_chatmodeloptions_chat_model.py +17 -0
  86. khoj/database/migrations/0059_searchmodelconfig_bi_encoder_confidence_threshold.py +17 -0
  87. khoj/database/migrations/0060_merge_20240905_1828.py +14 -0
  88. khoj/database/migrations/0061_alter_chatmodeloptions_model_type.py +26 -0
  89. khoj/database/migrations/0061_alter_texttoimagemodelconfig_model_type.py +21 -0
  90. khoj/database/migrations/0062_merge_20240913_0222.py +14 -0
  91. khoj/database/migrations/0063_conversation_temp_id.py +36 -0
  92. khoj/database/migrations/0064_remove_conversation_temp_id_alter_conversation_id.py +86 -0
  93. khoj/database/migrations/0065_remove_agent_avatar_remove_agent_public_and_more.py +49 -0
  94. khoj/database/migrations/0066_remove_agent_tools_agent_input_tools_and_more.py +69 -0
  95. khoj/database/migrations/0067_alter_agent_style_icon.py +50 -0
  96. khoj/database/migrations/0068_alter_agent_output_modes.py +24 -0
  97. khoj/database/migrations/0069_webscraper_serverchatsettings_web_scraper.py +89 -0
  98. khoj/database/migrations/0070_alter_agent_input_tools_alter_agent_output_modes.py +46 -0
  99. khoj/database/migrations/0071_subscription_enabled_trial_at_and_more.py +32 -0
  100. khoj/database/migrations/0072_entry_search_model.py +24 -0
  101. khoj/database/migrations/0073_delete_usersearchmodelconfig.py +15 -0
  102. khoj/database/migrations/0074_alter_conversation_title.py +17 -0
  103. khoj/database/migrations/0075_migrate_generated_assets_and_validate.py +85 -0
  104. khoj/database/migrations/0076_rename_openaiprocessorconversationconfig_aimodelapi_and_more.py +26 -0
  105. khoj/database/migrations/0077_chatmodel_alter_agent_chat_model_and_more.py +62 -0
  106. khoj/database/migrations/0078_khojuser_email_verification_code_expiry.py +17 -0
  107. khoj/database/migrations/__init__.py +0 -0
  108. khoj/database/models/__init__.py +725 -0
  109. khoj/database/tests.py +3 -0
  110. khoj/interface/compiled/404/index.html +1 -0
  111. khoj/interface/compiled/_next/static/Tg-vU1p1B-YKT5Qv8KSHt/_buildManifest.js +1 -0
  112. khoj/interface/compiled/_next/static/Tg-vU1p1B-YKT5Qv8KSHt/_ssgManifest.js +1 -0
  113. khoj/interface/compiled/_next/static/chunks/1010-8f39bb4648b5ba10.js +1 -0
  114. khoj/interface/compiled/_next/static/chunks/182-f1c48a203dc91e0e.js +20 -0
  115. khoj/interface/compiled/_next/static/chunks/1915-d3c36ad6ce697ce7.js +1 -0
  116. khoj/interface/compiled/_next/static/chunks/2117-165ef4747a5b836b.js +2 -0
  117. khoj/interface/compiled/_next/static/chunks/2581-455000f8aeb08fc3.js +1 -0
  118. khoj/interface/compiled/_next/static/chunks/3727.dcea8f2193111552.js +1 -0
  119. khoj/interface/compiled/_next/static/chunks/3789-a09e37a819171a9d.js +1 -0
  120. khoj/interface/compiled/_next/static/chunks/4124-6c28322ce218d2d5.js +1 -0
  121. khoj/interface/compiled/_next/static/chunks/5427-b52d95253e692bfa.js +1 -0
  122. khoj/interface/compiled/_next/static/chunks/5473-b1cf56dedac6577a.js +1 -0
  123. khoj/interface/compiled/_next/static/chunks/5477-0bbddb79c25a54a7.js +1 -0
  124. khoj/interface/compiled/_next/static/chunks/6065-64db9ad305ba0bcd.js +1 -0
  125. khoj/interface/compiled/_next/static/chunks/6293-469dd16402ea8a6f.js +3 -0
  126. khoj/interface/compiled/_next/static/chunks/688-b5b4391bbc0376f1.js +1 -0
  127. khoj/interface/compiled/_next/static/chunks/8667-b6bf63c72b2d76eb.js +1 -0
  128. khoj/interface/compiled/_next/static/chunks/9259-1172dbaca0515237.js +1 -0
  129. khoj/interface/compiled/_next/static/chunks/94ca1967.1d9b42d929a1ee8c.js +1 -0
  130. khoj/interface/compiled/_next/static/chunks/9597.83583248dfbf6e73.js +1 -0
  131. khoj/interface/compiled/_next/static/chunks/964ecbae.51d6faf8801d15e6.js +1 -0
  132. khoj/interface/compiled/_next/static/chunks/9665-391df1e5c51c960a.js +1 -0
  133. khoj/interface/compiled/_next/static/chunks/app/_not-found/page-a834eddae3e235df.js +1 -0
  134. khoj/interface/compiled/_next/static/chunks/app/agents/layout-e00fb81dca656a10.js +1 -0
  135. khoj/interface/compiled/_next/static/chunks/app/agents/page-28ce086a1129bca2.js +1 -0
  136. khoj/interface/compiled/_next/static/chunks/app/automations/layout-1fe1537449f43496.js +1 -0
  137. khoj/interface/compiled/_next/static/chunks/app/automations/page-bf365a60829d347f.js +1 -0
  138. khoj/interface/compiled/_next/static/chunks/app/chat/layout-33934fc2d6ae6838.js +1 -0
  139. khoj/interface/compiled/_next/static/chunks/app/chat/page-0e476e57eb2015e3.js +1 -0
  140. khoj/interface/compiled/_next/static/chunks/app/layout-30e7fda7262713ce.js +1 -0
  141. khoj/interface/compiled/_next/static/chunks/app/page-a5515ea71aec5ef0.js +1 -0
  142. khoj/interface/compiled/_next/static/chunks/app/search/layout-c02531d586972d7d.js +1 -0
  143. khoj/interface/compiled/_next/static/chunks/app/search/page-9140541e67ea307d.js +1 -0
  144. khoj/interface/compiled/_next/static/chunks/app/settings/layout-d09d6510a45cd4bd.js +1 -0
  145. khoj/interface/compiled/_next/static/chunks/app/settings/page-951ba40b5b94b23a.js +1 -0
  146. khoj/interface/compiled/_next/static/chunks/app/share/chat/layout-e8e5db7830bf3f47.js +1 -0
  147. khoj/interface/compiled/_next/static/chunks/app/share/chat/page-1beb80d8d741c932.js +1 -0
  148. khoj/interface/compiled/_next/static/chunks/d3ac728e-44ebd2a0c99b12a0.js +1 -0
  149. khoj/interface/compiled/_next/static/chunks/fd9d1056-4482b99a36fd1673.js +1 -0
  150. khoj/interface/compiled/_next/static/chunks/framework-8e0e0f4a6b83a956.js +1 -0
  151. khoj/interface/compiled/_next/static/chunks/main-app-de1f09df97a3cfc7.js +1 -0
  152. khoj/interface/compiled/_next/static/chunks/main-db4bfac6b0a8d00b.js +1 -0
  153. khoj/interface/compiled/_next/static/chunks/pages/_app-3c9ca398d360b709.js +1 -0
  154. khoj/interface/compiled/_next/static/chunks/pages/_error-cf5ca766ac8f493f.js +1 -0
  155. khoj/interface/compiled/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  156. khoj/interface/compiled/_next/static/chunks/webpack-a03962458328b163.js +1 -0
  157. khoj/interface/compiled/_next/static/css/089de1d8526b96e9.css +1 -0
  158. khoj/interface/compiled/_next/static/css/37a73b87f02df402.css +1 -0
  159. khoj/interface/compiled/_next/static/css/4e4e6a4a1c920d06.css +1 -0
  160. khoj/interface/compiled/_next/static/css/8d02837c730f8d13.css +25 -0
  161. khoj/interface/compiled/_next/static/css/8e6a3ca11a60b189.css +1 -0
  162. khoj/interface/compiled/_next/static/css/9c164d9727dd8092.css +1 -0
  163. khoj/interface/compiled/_next/static/css/dac88c17aaee5fcf.css +1 -0
  164. khoj/interface/compiled/_next/static/css/df4b47a2d0d85eae.css +1 -0
  165. khoj/interface/compiled/_next/static/css/e4eb883b5265d372.css +1 -0
  166. khoj/interface/compiled/_next/static/media/1d8a05b60287ae6c-s.p.woff2 +0 -0
  167. khoj/interface/compiled/_next/static/media/6f22fce21a7c433c-s.woff2 +0 -0
  168. khoj/interface/compiled/_next/static/media/77c207b095007c34-s.p.woff2 +0 -0
  169. khoj/interface/compiled/_next/static/media/82ef96de0e8f4d8c-s.p.woff2 +0 -0
  170. khoj/interface/compiled/_next/static/media/KaTeX_AMS-Regular.1608a09b.woff +0 -0
  171. khoj/interface/compiled/_next/static/media/KaTeX_AMS-Regular.4aafdb68.ttf +0 -0
  172. khoj/interface/compiled/_next/static/media/KaTeX_AMS-Regular.a79f1c31.woff2 +0 -0
  173. khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Bold.b6770918.woff +0 -0
  174. khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Bold.cce5b8ec.ttf +0 -0
  175. khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Bold.ec17d132.woff2 +0 -0
  176. khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Regular.07ef19e7.ttf +0 -0
  177. khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Regular.55fac258.woff2 +0 -0
  178. khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Regular.dad44a7f.woff +0 -0
  179. khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Bold.9f256b85.woff +0 -0
  180. khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Bold.b18f59e1.ttf +0 -0
  181. khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Bold.d42a5579.woff2 +0 -0
  182. khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Regular.7c187121.woff +0 -0
  183. khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Regular.d3c882a6.woff2 +0 -0
  184. khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Regular.ed38e79f.ttf +0 -0
  185. khoj/interface/compiled/_next/static/media/KaTeX_Main-Bold.b74a1a8b.ttf +0 -0
  186. khoj/interface/compiled/_next/static/media/KaTeX_Main-Bold.c3fb5ac2.woff2 +0 -0
  187. khoj/interface/compiled/_next/static/media/KaTeX_Main-Bold.d181c465.woff +0 -0
  188. khoj/interface/compiled/_next/static/media/KaTeX_Main-BoldItalic.6f2bb1df.woff2 +0 -0
  189. khoj/interface/compiled/_next/static/media/KaTeX_Main-BoldItalic.70d8b0a5.ttf +0 -0
  190. khoj/interface/compiled/_next/static/media/KaTeX_Main-BoldItalic.e3f82f9d.woff +0 -0
  191. khoj/interface/compiled/_next/static/media/KaTeX_Main-Italic.47373d1e.ttf +0 -0
  192. khoj/interface/compiled/_next/static/media/KaTeX_Main-Italic.8916142b.woff2 +0 -0
  193. khoj/interface/compiled/_next/static/media/KaTeX_Main-Italic.9024d815.woff +0 -0
  194. khoj/interface/compiled/_next/static/media/KaTeX_Main-Regular.0462f03b.woff2 +0 -0
  195. khoj/interface/compiled/_next/static/media/KaTeX_Main-Regular.7f51fe03.woff +0 -0
  196. khoj/interface/compiled/_next/static/media/KaTeX_Main-Regular.b7f8fe9b.ttf +0 -0
  197. khoj/interface/compiled/_next/static/media/KaTeX_Math-BoldItalic.572d331f.woff2 +0 -0
  198. khoj/interface/compiled/_next/static/media/KaTeX_Math-BoldItalic.a879cf83.ttf +0 -0
  199. khoj/interface/compiled/_next/static/media/KaTeX_Math-BoldItalic.f1035d8d.woff +0 -0
  200. khoj/interface/compiled/_next/static/media/KaTeX_Math-Italic.5295ba48.woff +0 -0
  201. khoj/interface/compiled/_next/static/media/KaTeX_Math-Italic.939bc644.ttf +0 -0
  202. khoj/interface/compiled/_next/static/media/KaTeX_Math-Italic.f28c23ac.woff2 +0 -0
  203. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Bold.8c5b5494.woff2 +0 -0
  204. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Bold.94e1e8dc.ttf +0 -0
  205. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Bold.bf59d231.woff +0 -0
  206. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Italic.3b1e59b3.woff2 +0 -0
  207. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Italic.7c9bc82b.woff +0 -0
  208. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Italic.b4c20c84.ttf +0 -0
  209. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Regular.74048478.woff +0 -0
  210. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Regular.ba21ed5f.woff2 +0 -0
  211. khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Regular.d4d7ba48.ttf +0 -0
  212. khoj/interface/compiled/_next/static/media/KaTeX_Script-Regular.03e9641d.woff2 +0 -0
  213. khoj/interface/compiled/_next/static/media/KaTeX_Script-Regular.07505710.woff +0 -0
  214. khoj/interface/compiled/_next/static/media/KaTeX_Script-Regular.fe9cbbe1.ttf +0 -0
  215. khoj/interface/compiled/_next/static/media/KaTeX_Size1-Regular.e1e279cb.woff +0 -0
  216. khoj/interface/compiled/_next/static/media/KaTeX_Size1-Regular.eae34984.woff2 +0 -0
  217. khoj/interface/compiled/_next/static/media/KaTeX_Size1-Regular.fabc004a.ttf +0 -0
  218. khoj/interface/compiled/_next/static/media/KaTeX_Size2-Regular.57727022.woff +0 -0
  219. khoj/interface/compiled/_next/static/media/KaTeX_Size2-Regular.5916a24f.woff2 +0 -0
  220. khoj/interface/compiled/_next/static/media/KaTeX_Size2-Regular.d6b476ec.ttf +0 -0
  221. khoj/interface/compiled/_next/static/media/KaTeX_Size3-Regular.9acaf01c.woff +0 -0
  222. khoj/interface/compiled/_next/static/media/KaTeX_Size3-Regular.a144ef58.ttf +0 -0
  223. khoj/interface/compiled/_next/static/media/KaTeX_Size3-Regular.b4230e7e.woff2 +0 -0
  224. khoj/interface/compiled/_next/static/media/KaTeX_Size4-Regular.10d95fd3.woff2 +0 -0
  225. khoj/interface/compiled/_next/static/media/KaTeX_Size4-Regular.7a996c9d.woff +0 -0
  226. khoj/interface/compiled/_next/static/media/KaTeX_Size4-Regular.fbccdabe.ttf +0 -0
  227. khoj/interface/compiled/_next/static/media/KaTeX_Typewriter-Regular.6258592b.woff +0 -0
  228. khoj/interface/compiled/_next/static/media/KaTeX_Typewriter-Regular.a8709e36.woff2 +0 -0
  229. khoj/interface/compiled/_next/static/media/KaTeX_Typewriter-Regular.d97aaf4a.ttf +0 -0
  230. khoj/interface/compiled/_next/static/media/a6ecd16fa044d500-s.p.woff2 +0 -0
  231. khoj/interface/compiled/_next/static/media/bd82c78e5b7b3fe9-s.p.woff2 +0 -0
  232. khoj/interface/compiled/_next/static/media/c32c8052c071fc42-s.woff2 +0 -0
  233. khoj/interface/compiled/_next/static/media/c4250770ab8708b6-s.p.woff2 +0 -0
  234. khoj/interface/compiled/_next/static/media/e098aaaecc9cfbb2-s.p.woff2 +0 -0
  235. khoj/interface/compiled/_next/static/media/flags.3afdda2f.webp +0 -0
  236. khoj/interface/compiled/_next/static/media/flags@2x.5fbe9fc1.webp +0 -0
  237. khoj/interface/compiled/_next/static/media/globe.98e105ca.webp +0 -0
  238. khoj/interface/compiled/_next/static/media/globe@2x.974df6f8.webp +0 -0
  239. khoj/interface/compiled/agents/index.html +1 -0
  240. khoj/interface/compiled/agents/index.txt +7 -0
  241. khoj/interface/compiled/agents.svg +6 -0
  242. khoj/interface/compiled/assets/icons/khoj_lantern.ico +0 -0
  243. khoj/interface/compiled/assets/icons/khoj_lantern.svg +100 -0
  244. khoj/interface/compiled/assets/icons/khoj_lantern_1200x1200.png +0 -0
  245. khoj/interface/compiled/assets/icons/khoj_lantern_128x128.png +0 -0
  246. khoj/interface/compiled/assets/icons/khoj_lantern_128x128_dark.png +0 -0
  247. khoj/interface/compiled/assets/icons/khoj_lantern_256x256.png +0 -0
  248. khoj/interface/compiled/assets/icons/khoj_lantern_512x512.png +0 -0
  249. khoj/interface/compiled/assets/icons/khoj_lantern_logomarktype_1200x630.png +0 -0
  250. khoj/interface/compiled/assets/samples/desktop-browse-draw-sample.png +0 -0
  251. khoj/interface/compiled/assets/samples/desktop-plain-chat-sample.png +0 -0
  252. khoj/interface/compiled/assets/samples/desktop-remember-plan-sample.png +0 -0
  253. khoj/interface/compiled/assets/samples/phone-browse-draw-sample.png +0 -0
  254. khoj/interface/compiled/assets/samples/phone-plain-chat-sample.png +0 -0
  255. khoj/interface/compiled/assets/samples/phone-remember-plan-sample.png +0 -0
  256. khoj/interface/compiled/automation.svg +37 -0
  257. khoj/interface/compiled/automations/index.html +1 -0
  258. khoj/interface/compiled/automations/index.txt +8 -0
  259. khoj/interface/compiled/chat/index.html +1 -0
  260. khoj/interface/compiled/chat/index.txt +7 -0
  261. khoj/interface/compiled/chat.svg +24 -0
  262. khoj/interface/compiled/close.svg +5 -0
  263. khoj/interface/compiled/copy-button-success.svg +6 -0
  264. khoj/interface/compiled/copy-button.svg +5 -0
  265. khoj/interface/compiled/index.html +1 -0
  266. khoj/interface/compiled/index.txt +7 -0
  267. khoj/interface/compiled/khoj.webmanifest +76 -0
  268. khoj/interface/compiled/logo.svg +24 -0
  269. khoj/interface/compiled/search/index.html +1 -0
  270. khoj/interface/compiled/search/index.txt +7 -0
  271. khoj/interface/compiled/send.svg +1 -0
  272. khoj/interface/compiled/settings/index.html +1 -0
  273. khoj/interface/compiled/settings/index.txt +9 -0
  274. khoj/interface/compiled/share/chat/index.html +1 -0
  275. khoj/interface/compiled/share/chat/index.txt +7 -0
  276. khoj/interface/compiled/share.svg +8 -0
  277. khoj/interface/compiled/thumbs-down.svg +6 -0
  278. khoj/interface/compiled/thumbs-up.svg +6 -0
  279. khoj/interface/email/feedback.html +34 -0
  280. khoj/interface/email/magic_link.html +40 -0
  281. khoj/interface/email/task.html +37 -0
  282. khoj/interface/email/welcome.html +90 -0
  283. khoj/interface/web/.well-known/assetlinks.json +11 -0
  284. khoj/interface/web/assets/icons/agents.svg +19 -0
  285. khoj/interface/web/assets/icons/automation.svg +43 -0
  286. khoj/interface/web/assets/icons/chat.svg +24 -0
  287. khoj/interface/web/assets/icons/github.svg +1 -0
  288. khoj/interface/web/assets/icons/khoj-logo-sideways-200.png +0 -0
  289. khoj/interface/web/assets/icons/khoj-logo-sideways-500.png +0 -0
  290. khoj/interface/web/assets/icons/khoj-logo-sideways.svg +32 -0
  291. khoj/interface/web/assets/icons/khoj.svg +26 -0
  292. khoj/interface/web/assets/icons/logotype.svg +1 -0
  293. khoj/interface/web/assets/icons/search.svg +57 -0
  294. khoj/interface/web/assets/icons/sync.svg +4 -0
  295. khoj/interface/web/assets/khoj.css +237 -0
  296. khoj/interface/web/assets/utils.js +33 -0
  297. khoj/interface/web/base_config.html +445 -0
  298. khoj/interface/web/content_source_github_input.html +208 -0
  299. khoj/interface/web/login.html +310 -0
  300. khoj/interface/web/utils.html +48 -0
  301. khoj/main.py +249 -0
  302. khoj/manage.py +22 -0
  303. khoj/migrations/__init__.py +0 -0
  304. khoj/migrations/migrate_offline_chat_default_model.py +69 -0
  305. khoj/migrations/migrate_offline_chat_default_model_2.py +71 -0
  306. khoj/migrations/migrate_offline_chat_schema.py +83 -0
  307. khoj/migrations/migrate_offline_model.py +29 -0
  308. khoj/migrations/migrate_processor_config_openai.py +67 -0
  309. khoj/migrations/migrate_server_pg.py +132 -0
  310. khoj/migrations/migrate_version.py +17 -0
  311. khoj/processor/__init__.py +0 -0
  312. khoj/processor/content/__init__.py +0 -0
  313. khoj/processor/content/docx/__init__.py +0 -0
  314. khoj/processor/content/docx/docx_to_entries.py +111 -0
  315. khoj/processor/content/github/__init__.py +0 -0
  316. khoj/processor/content/github/github_to_entries.py +226 -0
  317. khoj/processor/content/images/__init__.py +0 -0
  318. khoj/processor/content/images/image_to_entries.py +117 -0
  319. khoj/processor/content/markdown/__init__.py +0 -0
  320. khoj/processor/content/markdown/markdown_to_entries.py +160 -0
  321. khoj/processor/content/notion/notion_to_entries.py +259 -0
  322. khoj/processor/content/org_mode/__init__.py +0 -0
  323. khoj/processor/content/org_mode/org_to_entries.py +226 -0
  324. khoj/processor/content/org_mode/orgnode.py +532 -0
  325. khoj/processor/content/pdf/__init__.py +0 -0
  326. khoj/processor/content/pdf/pdf_to_entries.py +119 -0
  327. khoj/processor/content/plaintext/__init__.py +0 -0
  328. khoj/processor/content/plaintext/plaintext_to_entries.py +117 -0
  329. khoj/processor/content/text_to_entries.py +296 -0
  330. khoj/processor/conversation/__init__.py +0 -0
  331. khoj/processor/conversation/anthropic/__init__.py +0 -0
  332. khoj/processor/conversation/anthropic/anthropic_chat.py +243 -0
  333. khoj/processor/conversation/anthropic/utils.py +217 -0
  334. khoj/processor/conversation/google/__init__.py +0 -0
  335. khoj/processor/conversation/google/gemini_chat.py +253 -0
  336. khoj/processor/conversation/google/utils.py +260 -0
  337. khoj/processor/conversation/offline/__init__.py +0 -0
  338. khoj/processor/conversation/offline/chat_model.py +308 -0
  339. khoj/processor/conversation/offline/utils.py +80 -0
  340. khoj/processor/conversation/offline/whisper.py +15 -0
  341. khoj/processor/conversation/openai/__init__.py +0 -0
  342. khoj/processor/conversation/openai/gpt.py +243 -0
  343. khoj/processor/conversation/openai/utils.py +232 -0
  344. khoj/processor/conversation/openai/whisper.py +13 -0
  345. khoj/processor/conversation/prompts.py +1188 -0
  346. khoj/processor/conversation/utils.py +867 -0
  347. khoj/processor/embeddings.py +122 -0
  348. khoj/processor/image/generate.py +215 -0
  349. khoj/processor/speech/__init__.py +0 -0
  350. khoj/processor/speech/text_to_speech.py +51 -0
  351. khoj/processor/tools/__init__.py +0 -0
  352. khoj/processor/tools/online_search.py +472 -0
  353. khoj/processor/tools/run_code.py +179 -0
  354. khoj/routers/__init__.py +0 -0
  355. khoj/routers/api.py +760 -0
  356. khoj/routers/api_agents.py +295 -0
  357. khoj/routers/api_chat.py +1273 -0
  358. khoj/routers/api_content.py +634 -0
  359. khoj/routers/api_model.py +123 -0
  360. khoj/routers/api_phone.py +86 -0
  361. khoj/routers/api_subscription.py +144 -0
  362. khoj/routers/auth.py +307 -0
  363. khoj/routers/email.py +135 -0
  364. khoj/routers/helpers.py +2333 -0
  365. khoj/routers/notion.py +85 -0
  366. khoj/routers/research.py +364 -0
  367. khoj/routers/storage.py +63 -0
  368. khoj/routers/twilio.py +36 -0
  369. khoj/routers/web_client.py +141 -0
  370. khoj/search_filter/__init__.py +0 -0
  371. khoj/search_filter/base_filter.py +15 -0
  372. khoj/search_filter/date_filter.py +215 -0
  373. khoj/search_filter/file_filter.py +32 -0
  374. khoj/search_filter/word_filter.py +29 -0
  375. khoj/search_type/__init__.py +0 -0
  376. khoj/search_type/text_search.py +255 -0
  377. khoj/utils/__init__.py +0 -0
  378. khoj/utils/cli.py +101 -0
  379. khoj/utils/config.py +81 -0
  380. khoj/utils/constants.py +51 -0
  381. khoj/utils/fs_syncer.py +252 -0
  382. khoj/utils/helpers.py +627 -0
  383. khoj/utils/initialization.py +301 -0
  384. khoj/utils/jsonl.py +43 -0
  385. khoj/utils/models.py +47 -0
  386. khoj/utils/rawconfig.py +208 -0
  387. khoj/utils/state.py +48 -0
  388. khoj/utils/yaml.py +47 -0
  389. khoj-1.33.3.dev32.dist-info/METADATA +190 -0
  390. khoj-1.33.3.dev32.dist-info/RECORD +393 -0
  391. khoj-1.33.3.dev32.dist-info/WHEEL +4 -0
  392. khoj-1.33.3.dev32.dist-info/entry_points.txt +2 -0
  393. khoj-1.33.3.dev32.dist-info/licenses/LICENSE +661 -0
khoj/database/admin.py ADDED
@@ -0,0 +1,417 @@
1
+ import csv
2
+ import json
3
+ from datetime import datetime, timedelta
4
+
5
+ from apscheduler.job import Job
6
+ from django.contrib import admin, messages
7
+ from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin
8
+ from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
9
+ from django.contrib.auth.models import Group
10
+ from django.http import HttpResponse
11
+ from django_apscheduler.admin import DjangoJobAdmin, DjangoJobExecutionAdmin
12
+ from django_apscheduler.jobstores import DjangoJobStore
13
+ from django_apscheduler.models import DjangoJob, DjangoJobExecution
14
+ from unfold import admin as unfold_admin
15
+
16
+ from khoj.database.models import (
17
+ Agent,
18
+ AiModelApi,
19
+ ChatModel,
20
+ ClientApplication,
21
+ Conversation,
22
+ Entry,
23
+ GithubConfig,
24
+ KhojUser,
25
+ NotionConfig,
26
+ ProcessLock,
27
+ ReflectiveQuestion,
28
+ SearchModelConfig,
29
+ ServerChatSettings,
30
+ SpeechToTextModelOptions,
31
+ Subscription,
32
+ TextToImageModelConfig,
33
+ UserConversationConfig,
34
+ UserRequests,
35
+ UserVoiceModelConfig,
36
+ VoiceModelOption,
37
+ WebScraper,
38
+ )
39
+ from khoj.utils.helpers import ImageIntentType
40
+
41
+
42
+ class KhojDjangoJobAdmin(DjangoJobAdmin, unfold_admin.ModelAdmin):
43
+ list_display = (
44
+ "id",
45
+ "next_run_time",
46
+ "job_info",
47
+ )
48
+ search_fields = ("id", "next_run_time")
49
+ ordering = ("-next_run_time",)
50
+ job_store = DjangoJobStore()
51
+
52
+ def job_info(self, obj):
53
+ job: Job = self.job_store.lookup_job(obj.id)
54
+ return f"{job.func_ref} {job.args} {job.kwargs}" if job else "None"
55
+
56
+ job_info.short_description = "Job Info" # type: ignore
57
+
58
+ def get_search_results(self, request, queryset, search_term):
59
+ queryset, use_distinct = super().get_search_results(request, queryset, search_term)
60
+ if search_term:
61
+ jobs = [job.id for job in self.job_store.get_all_jobs() if search_term in str(job)]
62
+ queryset |= self.model.objects.filter(id__in=jobs)
63
+ return queryset, use_distinct
64
+
65
+
66
+ class KhojDjangoJobExecutionAdmin(DjangoJobExecutionAdmin, unfold_admin.ModelAdmin):
67
+ pass
68
+
69
+
70
+ admin.site.unregister(DjangoJob)
71
+ admin.site.register(DjangoJob, KhojDjangoJobAdmin)
72
+ admin.site.unregister(DjangoJobExecution)
73
+ admin.site.register(DjangoJobExecution, KhojDjangoJobExecutionAdmin)
74
+
75
+
76
+ class GroupAdmin(BaseGroupAdmin, unfold_admin.ModelAdmin):
77
+ pass
78
+
79
+
80
+ class UserAdmin(BaseUserAdmin, unfold_admin.ModelAdmin):
81
+ pass
82
+
83
+
84
+ class KhojUserAdmin(UserAdmin, unfold_admin.ModelAdmin):
85
+ class DateJoinedAfterFilter(admin.SimpleListFilter):
86
+ title = "Joined after"
87
+ parameter_name = "joined_after"
88
+
89
+ def lookups(self, request, model_admin):
90
+ return (
91
+ ("1d", "Last 24 hours"),
92
+ ("7d", "Last 7 days"),
93
+ ("30d", "Last 30 days"),
94
+ ("90d", "Last 90 days"),
95
+ )
96
+
97
+ def queryset(self, request, queryset):
98
+ if self.value():
99
+ days = int(self.value().rstrip("d"))
100
+ date_threshold = datetime.now() - timedelta(days=days)
101
+ return queryset.filter(date_joined__gte=date_threshold)
102
+ return queryset
103
+
104
+ class HasGoogleAuthFilter(admin.SimpleListFilter):
105
+ title = "Has Google Auth"
106
+ parameter_name = "has_google_auth"
107
+
108
+ def lookups(self, request, model_admin):
109
+ return (("True", "True"), ("False", "False"))
110
+
111
+ def queryset(self, request, queryset):
112
+ if self.value() == "True":
113
+ return queryset.filter(googleuser__isnull=False)
114
+ if self.value() == "False":
115
+ return queryset.filter(googleuser__isnull=True)
116
+
117
+ list_display = (
118
+ "id",
119
+ "email",
120
+ "username",
121
+ "phone_number",
122
+ "is_active",
123
+ "uuid",
124
+ "is_staff",
125
+ "is_superuser",
126
+ )
127
+ search_fields = ("email", "username", "phone_number", "uuid")
128
+ filter_horizontal = ("groups", "user_permissions")
129
+
130
+ list_filter = (
131
+ HasGoogleAuthFilter,
132
+ DateJoinedAfterFilter,
133
+ "verified_email",
134
+ ) + UserAdmin.list_filter
135
+
136
+ fieldsets = (
137
+ (
138
+ "Personal info",
139
+ {
140
+ "fields": (
141
+ "phone_number",
142
+ "email_verification_code",
143
+ "verified_phone_number",
144
+ "verified_email",
145
+ "email_verification_code_expiry",
146
+ )
147
+ },
148
+ ),
149
+ ) + UserAdmin.fieldsets
150
+
151
+ actions = ["get_email_login_url"]
152
+
153
+ def get_email_login_url(self, request, queryset):
154
+ for user in queryset:
155
+ if user.email:
156
+ host = request.get_host()
157
+ unique_id = user.email_verification_code
158
+ login_url = f"{host}/auth/magic?code={unique_id}&email={user.email}"
159
+ messages.info(request, f"Email login URL for {user.email}: {login_url}")
160
+
161
+ get_email_login_url.short_description = "Get email login URL" # type: ignore
162
+
163
+
164
+ admin.site.unregister(Group)
165
+ admin.site.register(KhojUser, KhojUserAdmin)
166
+
167
+ admin.site.register(ProcessLock, unfold_admin.ModelAdmin)
168
+ admin.site.register(SpeechToTextModelOptions, unfold_admin.ModelAdmin)
169
+ admin.site.register(ReflectiveQuestion, unfold_admin.ModelAdmin)
170
+ admin.site.register(ClientApplication, unfold_admin.ModelAdmin)
171
+ admin.site.register(GithubConfig, unfold_admin.ModelAdmin)
172
+ admin.site.register(NotionConfig, unfold_admin.ModelAdmin)
173
+ admin.site.register(UserVoiceModelConfig, unfold_admin.ModelAdmin)
174
+ admin.site.register(VoiceModelOption, unfold_admin.ModelAdmin)
175
+ admin.site.register(UserRequests, unfold_admin.ModelAdmin)
176
+
177
+
178
+ @admin.register(Agent)
179
+ class AgentAdmin(unfold_admin.ModelAdmin):
180
+ list_display = (
181
+ "id",
182
+ "name",
183
+ )
184
+ search_fields = ("id", "name")
185
+ list_filter = ("privacy_level",)
186
+ ordering = ("-created_at",)
187
+
188
+
189
+ @admin.register(Entry)
190
+ class EntryAdmin(unfold_admin.ModelAdmin):
191
+ list_display = (
192
+ "id",
193
+ "created_at",
194
+ "updated_at",
195
+ "user",
196
+ "agent",
197
+ "file_source",
198
+ "file_type",
199
+ "file_name",
200
+ "file_path",
201
+ )
202
+ search_fields = ("id", "user__email", "user__username", "file_path")
203
+ list_filter = (
204
+ "file_type",
205
+ "user__email",
206
+ "search_model__name",
207
+ )
208
+ ordering = ("-created_at",)
209
+
210
+
211
+ @admin.register(Subscription)
212
+ class KhojUserSubscription(unfold_admin.ModelAdmin):
213
+ list_display = (
214
+ "id",
215
+ "user",
216
+ "type",
217
+ )
218
+
219
+ search_fields = ("id", "user__email", "user__username", "type")
220
+ list_filter = ("type",)
221
+
222
+
223
+ @admin.register(ChatModel)
224
+ class ChatModelAdmin(unfold_admin.ModelAdmin):
225
+ list_display = (
226
+ "id",
227
+ "name",
228
+ "ai_model_api",
229
+ "max_prompt_size",
230
+ )
231
+ search_fields = ("id", "name", "ai_model_api__name")
232
+
233
+
234
+ @admin.register(TextToImageModelConfig)
235
+ class TextToImageModelOptionsAdmin(unfold_admin.ModelAdmin):
236
+ list_display = (
237
+ "id",
238
+ "model_name",
239
+ "model_type",
240
+ )
241
+ search_fields = ("id", "model_name", "model_type")
242
+
243
+
244
+ @admin.register(AiModelApi)
245
+ class AiModelApiAdmin(unfold_admin.ModelAdmin):
246
+ list_display = (
247
+ "id",
248
+ "name",
249
+ "api_key",
250
+ "api_base_url",
251
+ )
252
+ search_fields = ("id", "name", "api_key", "api_base_url")
253
+
254
+
255
+ @admin.register(SearchModelConfig)
256
+ class SearchModelConfigAdmin(unfold_admin.ModelAdmin):
257
+ list_display = (
258
+ "id",
259
+ "name",
260
+ "bi_encoder",
261
+ "cross_encoder",
262
+ )
263
+ search_fields = ("id", "name", "bi_encoder", "cross_encoder")
264
+
265
+
266
+ @admin.register(ServerChatSettings)
267
+ class ServerChatSettingsAdmin(unfold_admin.ModelAdmin):
268
+ list_display = (
269
+ "chat_default",
270
+ "chat_advanced",
271
+ "web_scraper",
272
+ )
273
+
274
+
275
+ @admin.register(WebScraper)
276
+ class WebScraperAdmin(unfold_admin.ModelAdmin):
277
+ list_display = (
278
+ "priority",
279
+ "name",
280
+ "type",
281
+ "api_key",
282
+ "api_url",
283
+ "created_at",
284
+ )
285
+ search_fields = ("name", "api_key", "api_url", "type")
286
+ ordering = ("priority",)
287
+
288
+
289
+ @admin.register(Conversation)
290
+ class ConversationAdmin(unfold_admin.ModelAdmin):
291
+ list_display = (
292
+ "id",
293
+ "user",
294
+ "created_at",
295
+ "updated_at",
296
+ "client",
297
+ )
298
+ search_fields = ("id", "user__email", "user__username", "client__name")
299
+ list_filter = ("agent", "client", "user")
300
+ ordering = ("-created_at",)
301
+
302
+ actions = ["export_selected_objects", "export_selected_minimal_objects"]
303
+
304
+ def export_selected_objects(self, request, queryset):
305
+ response = HttpResponse(content_type="text/csv")
306
+ response["Content-Disposition"] = 'attachment; filename="conversations.csv"'
307
+
308
+ writer = csv.writer(response)
309
+ writer.writerow(["id", "user", "created_at", "updated_at", "conversation_log"])
310
+
311
+ for conversation in queryset:
312
+ modified_log = conversation.conversation_log
313
+ chat_log = modified_log.get("chat", [])
314
+ for idx, log in enumerate(chat_log):
315
+ if log["by"] == "khoj" and log["images"]:
316
+ log["images"] = ["inline image redacted for space"]
317
+ chat_log[idx] = log
318
+
319
+ modified_log["chat"] = chat_log
320
+
321
+ writer.writerow(
322
+ [
323
+ conversation.id,
324
+ conversation.user,
325
+ conversation.created_at,
326
+ conversation.updated_at,
327
+ json.dumps(modified_log),
328
+ ]
329
+ )
330
+
331
+ return response
332
+
333
+ export_selected_objects.short_description = "Export selected conversations" # type: ignore
334
+
335
+ def export_selected_minimal_objects(self, request, queryset):
336
+ response = HttpResponse(content_type="text/csv")
337
+ response["Content-Disposition"] = 'attachment; filename="conversations.csv"'
338
+
339
+ writer = csv.writer(response)
340
+ writer.writerow(["id", "user", "created_at", "updated_at", "conversation_log"])
341
+
342
+ fields_to_keep = set(["message", "by", "created"])
343
+
344
+ for conversation in queryset:
345
+ return_log = dict()
346
+ chat_log = conversation.conversation_log.get("chat", [])
347
+ for idx, log in enumerate(chat_log):
348
+ updated_log = {}
349
+ for key in fields_to_keep:
350
+ updated_log[key] = log[key]
351
+ if (
352
+ log["by"] == "khoj"
353
+ and log["intent"]
354
+ and log["intent"]["type"]
355
+ and (
356
+ log["intent"]["type"] == ImageIntentType.TEXT_TO_IMAGE.value
357
+ or log["intent"]["type"] == ImageIntentType.TEXT_TO_IMAGE_V3.value
358
+ )
359
+ ):
360
+ updated_log["message"] = "inline image redacted for space"
361
+ chat_log[idx] = updated_log
362
+ return_log["chat"] = chat_log
363
+
364
+ writer.writerow(
365
+ [
366
+ conversation.id,
367
+ conversation.user,
368
+ conversation.created_at,
369
+ conversation.updated_at,
370
+ json.dumps(return_log),
371
+ ]
372
+ )
373
+
374
+ return response
375
+
376
+ export_selected_minimal_objects.short_description = "Export selected conversations (minimal)" # type: ignore
377
+
378
+ def get_actions(self, request):
379
+ actions = super().get_actions(request)
380
+ if not request.user.is_superuser:
381
+ if "export_selected_objects" in actions:
382
+ del actions["export_selected_objects"]
383
+ if "export_selected_minimal_objects" in actions:
384
+ del actions["export_selected_minimal_objects"]
385
+ return actions
386
+
387
+
388
+ @admin.register(UserConversationConfig)
389
+ class UserConversationConfigAdmin(unfold_admin.ModelAdmin):
390
+ list_display = (
391
+ "id",
392
+ "get_user_email",
393
+ "get_chat_model",
394
+ "get_subscription_type",
395
+ )
396
+ search_fields = ("id", "user__email", "setting__name", "user__subscription__type")
397
+ ordering = ("-updated_at",)
398
+
399
+ def get_user_email(self, obj):
400
+ return obj.user.email
401
+
402
+ get_user_email.short_description = "User Email" # type: ignore
403
+ get_user_email.admin_order_field = "user__email" # type: ignore
404
+
405
+ def get_chat_model(self, obj):
406
+ return obj.setting.name if obj.setting else None
407
+
408
+ get_chat_model.short_description = "Chat Model" # type: ignore
409
+ get_chat_model.admin_order_field = "setting__name" # type: ignore
410
+
411
+ def get_subscription_type(self, obj):
412
+ if hasattr(obj.user, "subscription"):
413
+ return obj.user.subscription.type
414
+ return None
415
+
416
+ get_subscription_type.short_description = "Subscription Type" # type: ignore
417
+ get_subscription_type.admin_order_field = "user__subscription__type" # type: ignore
khoj/database/apps.py ADDED
@@ -0,0 +1,6 @@
1
+ from django.apps import AppConfig
2
+
3
+
4
+ class DatabaseConfig(AppConfig):
5
+ default_auto_field = "django.db.models.BigAutoField"
6
+ name = "khoj.database"
File without changes
File without changes
@@ -0,0 +1,116 @@
1
+ import logging
2
+ from typing import List
3
+
4
+ from django.core.management.base import BaseCommand
5
+ from django.db import transaction
6
+ from django.db.models import Count, Q
7
+ from tqdm import tqdm
8
+
9
+ from khoj.database.adapters import get_default_search_model
10
+ from khoj.database.models import Agent, Entry, KhojUser, SearchModelConfig
11
+ from khoj.processor.embeddings import EmbeddingsModel
12
+
13
+ logging.basicConfig(level=logging.INFO)
14
+ logger = logging.getLogger(__name__)
15
+
16
+ BATCH_SIZE = 1000 # Define an appropriate batch size
17
+
18
+
19
+ class Command(BaseCommand):
20
+ help = "Convert all existing Entry objects to use a new default Search model."
21
+
22
+ def add_arguments(self, parser):
23
+ # Pass default SearchModelConfig ID
24
+ parser.add_argument(
25
+ "--search_model_id",
26
+ action="store",
27
+ help="ID of the SearchModelConfig object to set as the default search model for all existing Entry objects.",
28
+ required=True,
29
+ )
30
+
31
+ # Set the apply flag to apply the new default Search model to all existing Entry objects.
32
+ parser.add_argument(
33
+ "--apply",
34
+ action="store_true",
35
+ help="Apply the new default Search model to all existing Entry objects. Otherwise, only display the number of Entry objects that will be affected.",
36
+ )
37
+
38
+ def handle(self, *args, **options):
39
+ @transaction.atomic
40
+ def regenerate_entries(entry_filter: Q, embeddings_model: EmbeddingsModel, search_model: SearchModelConfig):
41
+ total_entries = Entry.objects.filter(entry_filter).count()
42
+ for start in tqdm(range(0, total_entries, BATCH_SIZE)):
43
+ end = start + BATCH_SIZE
44
+ entries = Entry.objects.filter(entry_filter)[start:end]
45
+ compiled_entries = [entry.compiled for entry in entries]
46
+ updated_entries: List[Entry] = []
47
+
48
+ try:
49
+ embeddings = embeddings_model.embed_documents(compiled_entries)
50
+ except Exception as e:
51
+ logger.error(f"Error embedding documents: {e}")
52
+ return
53
+
54
+ for i, entry in enumerate(entries):
55
+ entry.embeddings = embeddings[i]
56
+ entry.search_model_id = search_model.id
57
+ updated_entries.append(entry)
58
+
59
+ Entry.objects.bulk_update(updated_entries, ["embeddings", "search_model_id", "file_path"])
60
+
61
+ search_model_config_id = options.get("search_model_id")
62
+ apply = options.get("apply")
63
+
64
+ logger.info(f"SearchModelConfig ID: {search_model_config_id}")
65
+ logger.info(f"Apply: {apply}")
66
+
67
+ embeddings_model = dict()
68
+
69
+ search_models = SearchModelConfig.objects.all()
70
+ for model in search_models:
71
+ embeddings_model.update(
72
+ {
73
+ model.name: EmbeddingsModel(
74
+ model.bi_encoder,
75
+ model.embeddings_inference_endpoint,
76
+ model.embeddings_inference_endpoint_api_key,
77
+ query_encode_kwargs=model.bi_encoder_query_encode_config,
78
+ docs_encode_kwargs=model.bi_encoder_docs_encode_config,
79
+ model_kwargs=model.bi_encoder_model_config,
80
+ )
81
+ }
82
+ )
83
+
84
+ new_default_search_model_config = SearchModelConfig.objects.get(id=search_model_config_id)
85
+ logger.info(f"New default Search model: {new_default_search_model_config}")
86
+
87
+ logger.info("----")
88
+
89
+ current_default = get_default_search_model()
90
+
91
+ # Create an entry filter with no conditions
92
+ entry_filter = Q()
93
+ relevant_entries = Entry.objects.filter(entry_filter).all()
94
+ logger.info(f"Number of Entry objects to update: {relevant_entries.count()}")
95
+
96
+ if apply:
97
+ try:
98
+ regenerate_entries(
99
+ entry_filter=entry_filter,
100
+ embeddings_model=embeddings_model[new_default_search_model_config.name],
101
+ search_model=new_default_search_model_config,
102
+ )
103
+ except Exception as e:
104
+ logger.error(f"Error updating Entry objects: {e}")
105
+ return
106
+
107
+ if apply and current_default.id != new_default_search_model_config.id:
108
+ # Get the existing default SearchModelConfig object and update its name
109
+ current_default.name = f"prev_default_{current_default.id}"
110
+ current_default.save()
111
+
112
+ # Update the new default SearchModelConfig object's name
113
+ new_default_search_model_config.name = "default"
114
+ new_default_search_model_config.save()
115
+ if not apply:
116
+ logger.info("Run the command with the --apply flag to apply the new default Search model.")
@@ -0,0 +1,61 @@
1
+ from django.core.management.base import BaseCommand
2
+ from tqdm import tqdm
3
+
4
+ from khoj.database.models import Conversation
5
+ from khoj.utils.helpers import ImageIntentType, is_none_or_empty
6
+
7
+
8
+ class Command(BaseCommand):
9
+ help = "Serve Khoj generated images from a different URL."
10
+
11
+ def add_arguments(self, parser):
12
+ # Pass Source URL
13
+ parser.add_argument(
14
+ "--source",
15
+ action="store",
16
+ help="URL from which generated images are currently served.",
17
+ )
18
+ # Pass Destination URL
19
+ parser.add_argument("--destination", action="store", help="URL to serve generated image from going forward.")
20
+
21
+ # Add a new argument 'reverse' to the command
22
+ parser.add_argument(
23
+ "--reverse",
24
+ action="store_true",
25
+ help="Revert to serve generated images from source instead of destination URL.",
26
+ )
27
+
28
+ def handle(self, *args, **options):
29
+ updated_count = 0
30
+ if not options.get("source") or not options.get("destination"):
31
+ self.stdout.write(
32
+ self.style.ERROR(
33
+ "Set --source, --destination args to migrate serving images from source to destination URL."
34
+ )
35
+ )
36
+ return
37
+
38
+ destination = options["source"] if options["reverse"] else options["destination"]
39
+ source = options["destination"] if options["reverse"] else options["source"]
40
+ for conversation in Conversation.objects.all():
41
+ conversation_updated = False
42
+ for chat in tqdm(conversation.conversation_log.get("chat", []), desc="Processing Conversations"):
43
+ if (
44
+ chat.get("by", "") == "khoj"
45
+ and not is_none_or_empty(chat.get("message"))
46
+ and chat.get("message", "").startswith(source)
47
+ and chat.get("intent", {}).get("type", "") == ImageIntentType.TEXT_TO_IMAGE2.value
48
+ and chat.get("message", "").endswith(".webp")
49
+ ):
50
+ # Convert source url to destination url
51
+ chat["message"] = chat["message"].replace(source, destination)
52
+ conversation_updated = True
53
+ updated_count += 1
54
+
55
+ if conversation_updated:
56
+ print(f"Save the updated conversation {conversation.id} to the database.")
57
+ conversation.save()
58
+
59
+ if updated_count > 0:
60
+ success = f"Successfully converted {updated_count} image URLs from {source} to {destination}.".strip()
61
+ self.stdout.write(self.style.SUCCESS(success))