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.
- khoj/__init__.py +0 -0
- khoj/app/README.md +94 -0
- khoj/app/__init__.py +0 -0
- khoj/app/asgi.py +16 -0
- khoj/app/settings.py +218 -0
- khoj/app/urls.py +25 -0
- khoj/configure.py +452 -0
- khoj/database/__init__.py +0 -0
- khoj/database/adapters/__init__.py +1821 -0
- khoj/database/admin.py +417 -0
- khoj/database/apps.py +6 -0
- khoj/database/management/__init__.py +0 -0
- khoj/database/management/commands/__init__.py +0 -0
- khoj/database/management/commands/change_default_model.py +116 -0
- khoj/database/management/commands/change_generated_images_url.py +61 -0
- khoj/database/management/commands/convert_images_png_to_webp.py +99 -0
- khoj/database/migrations/0001_khojuser.py +98 -0
- khoj/database/migrations/0002_googleuser.py +32 -0
- khoj/database/migrations/0003_vector_extension.py +10 -0
- khoj/database/migrations/0004_content_types_and_more.py +181 -0
- khoj/database/migrations/0005_embeddings_corpus_id.py +19 -0
- khoj/database/migrations/0006_embeddingsdates.py +33 -0
- khoj/database/migrations/0007_add_conversation.py +27 -0
- khoj/database/migrations/0008_alter_conversation_conversation_log.py +17 -0
- khoj/database/migrations/0009_khojapiuser.py +24 -0
- khoj/database/migrations/0010_chatmodeloptions_and_more.py +83 -0
- khoj/database/migrations/0010_rename_embeddings_entry_and_more.py +30 -0
- khoj/database/migrations/0011_merge_20231102_0138.py +14 -0
- khoj/database/migrations/0012_entry_file_source.py +21 -0
- khoj/database/migrations/0013_subscription.py +37 -0
- khoj/database/migrations/0014_alter_googleuser_picture.py +17 -0
- khoj/database/migrations/0015_alter_subscription_user.py +21 -0
- khoj/database/migrations/0016_alter_subscription_renewal_date.py +17 -0
- khoj/database/migrations/0017_searchmodel.py +32 -0
- khoj/database/migrations/0018_searchmodelconfig_delete_searchmodel.py +30 -0
- khoj/database/migrations/0019_alter_googleuser_family_name_and_more.py +27 -0
- khoj/database/migrations/0020_reflectivequestion.py +36 -0
- khoj/database/migrations/0021_speechtotextmodeloptions_and_more.py +42 -0
- khoj/database/migrations/0022_texttoimagemodelconfig.py +25 -0
- khoj/database/migrations/0023_usersearchmodelconfig.py +33 -0
- khoj/database/migrations/0024_alter_entry_embeddings.py +18 -0
- khoj/database/migrations/0025_clientapplication_khojuser_phone_number_and_more.py +46 -0
- khoj/database/migrations/0025_searchmodelconfig_embeddings_inference_endpoint_and_more.py +22 -0
- khoj/database/migrations/0026_searchmodelconfig_cross_encoder_inference_endpoint_and_more.py +22 -0
- khoj/database/migrations/0027_merge_20240118_1324.py +13 -0
- khoj/database/migrations/0028_khojuser_verified_phone_number.py +17 -0
- khoj/database/migrations/0029_userrequests.py +27 -0
- khoj/database/migrations/0030_conversation_slug_and_title.py +38 -0
- khoj/database/migrations/0031_agent_conversation_agent.py +53 -0
- khoj/database/migrations/0031_alter_googleuser_locale.py +30 -0
- khoj/database/migrations/0032_merge_20240322_0427.py +14 -0
- khoj/database/migrations/0033_rename_tuning_agent_personality.py +17 -0
- khoj/database/migrations/0034_alter_chatmodeloptions_chat_model.py +32 -0
- khoj/database/migrations/0035_processlock.py +26 -0
- khoj/database/migrations/0036_alter_processlock_name.py +19 -0
- khoj/database/migrations/0036_delete_offlinechatprocessorconversationconfig.py +15 -0
- khoj/database/migrations/0036_publicconversation.py +42 -0
- khoj/database/migrations/0037_chatmodeloptions_openai_config_and_more.py +51 -0
- khoj/database/migrations/0037_searchmodelconfig_bi_encoder_docs_encode_config_and_more.py +32 -0
- khoj/database/migrations/0038_merge_20240425_0857.py +14 -0
- khoj/database/migrations/0038_merge_20240426_1640.py +12 -0
- khoj/database/migrations/0039_merge_20240501_0301.py +12 -0
- khoj/database/migrations/0040_alter_processlock_name.py +26 -0
- khoj/database/migrations/0040_merge_20240504_1010.py +14 -0
- khoj/database/migrations/0041_merge_20240505_1234.py +14 -0
- khoj/database/migrations/0042_serverchatsettings.py +46 -0
- khoj/database/migrations/0043_alter_chatmodeloptions_model_type.py +21 -0
- khoj/database/migrations/0044_conversation_file_filters.py +17 -0
- khoj/database/migrations/0045_fileobject.py +37 -0
- khoj/database/migrations/0046_khojuser_email_verification_code_and_more.py +22 -0
- khoj/database/migrations/0047_alter_entry_file_type.py +31 -0
- khoj/database/migrations/0048_voicemodeloption_uservoicemodelconfig.py +52 -0
- khoj/database/migrations/0049_datastore.py +38 -0
- khoj/database/migrations/0049_texttoimagemodelconfig_api_key_and_more.py +58 -0
- khoj/database/migrations/0050_alter_processlock_name.py +25 -0
- khoj/database/migrations/0051_merge_20240702_1220.py +14 -0
- khoj/database/migrations/0052_alter_searchmodelconfig_bi_encoder_docs_encode_config_and_more.py +27 -0
- khoj/database/migrations/0053_agent_style_color_agent_style_icon.py +61 -0
- khoj/database/migrations/0054_alter_agent_style_color.py +38 -0
- khoj/database/migrations/0055_alter_agent_style_icon.py +37 -0
- khoj/database/migrations/0056_chatmodeloptions_vision_enabled.py +17 -0
- khoj/database/migrations/0056_searchmodelconfig_cross_encoder_model_config.py +17 -0
- khoj/database/migrations/0057_merge_20240816_1409.py +13 -0
- khoj/database/migrations/0057_remove_serverchatsettings_default_model_and_more.py +51 -0
- khoj/database/migrations/0058_alter_chatmodeloptions_chat_model.py +17 -0
- khoj/database/migrations/0059_searchmodelconfig_bi_encoder_confidence_threshold.py +17 -0
- khoj/database/migrations/0060_merge_20240905_1828.py +14 -0
- khoj/database/migrations/0061_alter_chatmodeloptions_model_type.py +26 -0
- khoj/database/migrations/0061_alter_texttoimagemodelconfig_model_type.py +21 -0
- khoj/database/migrations/0062_merge_20240913_0222.py +14 -0
- khoj/database/migrations/0063_conversation_temp_id.py +36 -0
- khoj/database/migrations/0064_remove_conversation_temp_id_alter_conversation_id.py +86 -0
- khoj/database/migrations/0065_remove_agent_avatar_remove_agent_public_and_more.py +49 -0
- khoj/database/migrations/0066_remove_agent_tools_agent_input_tools_and_more.py +69 -0
- khoj/database/migrations/0067_alter_agent_style_icon.py +50 -0
- khoj/database/migrations/0068_alter_agent_output_modes.py +24 -0
- khoj/database/migrations/0069_webscraper_serverchatsettings_web_scraper.py +89 -0
- khoj/database/migrations/0070_alter_agent_input_tools_alter_agent_output_modes.py +46 -0
- khoj/database/migrations/0071_subscription_enabled_trial_at_and_more.py +32 -0
- khoj/database/migrations/0072_entry_search_model.py +24 -0
- khoj/database/migrations/0073_delete_usersearchmodelconfig.py +15 -0
- khoj/database/migrations/0074_alter_conversation_title.py +17 -0
- khoj/database/migrations/0075_migrate_generated_assets_and_validate.py +85 -0
- khoj/database/migrations/0076_rename_openaiprocessorconversationconfig_aimodelapi_and_more.py +26 -0
- khoj/database/migrations/0077_chatmodel_alter_agent_chat_model_and_more.py +62 -0
- khoj/database/migrations/0078_khojuser_email_verification_code_expiry.py +17 -0
- khoj/database/migrations/__init__.py +0 -0
- khoj/database/models/__init__.py +725 -0
- khoj/database/tests.py +3 -0
- khoj/interface/compiled/404/index.html +1 -0
- khoj/interface/compiled/_next/static/Tg-vU1p1B-YKT5Qv8KSHt/_buildManifest.js +1 -0
- khoj/interface/compiled/_next/static/Tg-vU1p1B-YKT5Qv8KSHt/_ssgManifest.js +1 -0
- khoj/interface/compiled/_next/static/chunks/1010-8f39bb4648b5ba10.js +1 -0
- khoj/interface/compiled/_next/static/chunks/182-f1c48a203dc91e0e.js +20 -0
- khoj/interface/compiled/_next/static/chunks/1915-d3c36ad6ce697ce7.js +1 -0
- khoj/interface/compiled/_next/static/chunks/2117-165ef4747a5b836b.js +2 -0
- khoj/interface/compiled/_next/static/chunks/2581-455000f8aeb08fc3.js +1 -0
- khoj/interface/compiled/_next/static/chunks/3727.dcea8f2193111552.js +1 -0
- khoj/interface/compiled/_next/static/chunks/3789-a09e37a819171a9d.js +1 -0
- khoj/interface/compiled/_next/static/chunks/4124-6c28322ce218d2d5.js +1 -0
- khoj/interface/compiled/_next/static/chunks/5427-b52d95253e692bfa.js +1 -0
- khoj/interface/compiled/_next/static/chunks/5473-b1cf56dedac6577a.js +1 -0
- khoj/interface/compiled/_next/static/chunks/5477-0bbddb79c25a54a7.js +1 -0
- khoj/interface/compiled/_next/static/chunks/6065-64db9ad305ba0bcd.js +1 -0
- khoj/interface/compiled/_next/static/chunks/6293-469dd16402ea8a6f.js +3 -0
- khoj/interface/compiled/_next/static/chunks/688-b5b4391bbc0376f1.js +1 -0
- khoj/interface/compiled/_next/static/chunks/8667-b6bf63c72b2d76eb.js +1 -0
- khoj/interface/compiled/_next/static/chunks/9259-1172dbaca0515237.js +1 -0
- khoj/interface/compiled/_next/static/chunks/94ca1967.1d9b42d929a1ee8c.js +1 -0
- khoj/interface/compiled/_next/static/chunks/9597.83583248dfbf6e73.js +1 -0
- khoj/interface/compiled/_next/static/chunks/964ecbae.51d6faf8801d15e6.js +1 -0
- khoj/interface/compiled/_next/static/chunks/9665-391df1e5c51c960a.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/_not-found/page-a834eddae3e235df.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/agents/layout-e00fb81dca656a10.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/agents/page-28ce086a1129bca2.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/automations/layout-1fe1537449f43496.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/automations/page-bf365a60829d347f.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/chat/layout-33934fc2d6ae6838.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/chat/page-0e476e57eb2015e3.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/layout-30e7fda7262713ce.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/page-a5515ea71aec5ef0.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/search/layout-c02531d586972d7d.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/search/page-9140541e67ea307d.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/settings/layout-d09d6510a45cd4bd.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/settings/page-951ba40b5b94b23a.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/share/chat/layout-e8e5db7830bf3f47.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/share/chat/page-1beb80d8d741c932.js +1 -0
- khoj/interface/compiled/_next/static/chunks/d3ac728e-44ebd2a0c99b12a0.js +1 -0
- khoj/interface/compiled/_next/static/chunks/fd9d1056-4482b99a36fd1673.js +1 -0
- khoj/interface/compiled/_next/static/chunks/framework-8e0e0f4a6b83a956.js +1 -0
- khoj/interface/compiled/_next/static/chunks/main-app-de1f09df97a3cfc7.js +1 -0
- khoj/interface/compiled/_next/static/chunks/main-db4bfac6b0a8d00b.js +1 -0
- khoj/interface/compiled/_next/static/chunks/pages/_app-3c9ca398d360b709.js +1 -0
- khoj/interface/compiled/_next/static/chunks/pages/_error-cf5ca766ac8f493f.js +1 -0
- khoj/interface/compiled/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- khoj/interface/compiled/_next/static/chunks/webpack-a03962458328b163.js +1 -0
- khoj/interface/compiled/_next/static/css/089de1d8526b96e9.css +1 -0
- khoj/interface/compiled/_next/static/css/37a73b87f02df402.css +1 -0
- khoj/interface/compiled/_next/static/css/4e4e6a4a1c920d06.css +1 -0
- khoj/interface/compiled/_next/static/css/8d02837c730f8d13.css +25 -0
- khoj/interface/compiled/_next/static/css/8e6a3ca11a60b189.css +1 -0
- khoj/interface/compiled/_next/static/css/9c164d9727dd8092.css +1 -0
- khoj/interface/compiled/_next/static/css/dac88c17aaee5fcf.css +1 -0
- khoj/interface/compiled/_next/static/css/df4b47a2d0d85eae.css +1 -0
- khoj/interface/compiled/_next/static/css/e4eb883b5265d372.css +1 -0
- khoj/interface/compiled/_next/static/media/1d8a05b60287ae6c-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/6f22fce21a7c433c-s.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/77c207b095007c34-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/82ef96de0e8f4d8c-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_AMS-Regular.1608a09b.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_AMS-Regular.4aafdb68.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_AMS-Regular.a79f1c31.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Bold.b6770918.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Bold.cce5b8ec.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Bold.ec17d132.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Regular.07ef19e7.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Regular.55fac258.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Caligraphic-Regular.dad44a7f.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Bold.9f256b85.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Bold.b18f59e1.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Bold.d42a5579.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Regular.7c187121.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Regular.d3c882a6.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Fraktur-Regular.ed38e79f.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Main-Bold.b74a1a8b.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Main-Bold.c3fb5ac2.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Main-Bold.d181c465.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Main-BoldItalic.6f2bb1df.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Main-BoldItalic.70d8b0a5.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Main-BoldItalic.e3f82f9d.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Main-Italic.47373d1e.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Main-Italic.8916142b.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Main-Italic.9024d815.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Main-Regular.0462f03b.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Main-Regular.7f51fe03.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Main-Regular.b7f8fe9b.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Math-BoldItalic.572d331f.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Math-BoldItalic.a879cf83.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Math-BoldItalic.f1035d8d.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Math-Italic.5295ba48.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Math-Italic.939bc644.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Math-Italic.f28c23ac.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Bold.8c5b5494.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Bold.94e1e8dc.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Bold.bf59d231.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Italic.3b1e59b3.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Italic.7c9bc82b.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Italic.b4c20c84.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Regular.74048478.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Regular.ba21ed5f.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_SansSerif-Regular.d4d7ba48.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Script-Regular.03e9641d.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Script-Regular.07505710.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Script-Regular.fe9cbbe1.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Size1-Regular.e1e279cb.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Size1-Regular.eae34984.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Size1-Regular.fabc004a.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Size2-Regular.57727022.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Size2-Regular.5916a24f.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Size2-Regular.d6b476ec.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Size3-Regular.9acaf01c.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Size3-Regular.a144ef58.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Size3-Regular.b4230e7e.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Size4-Regular.10d95fd3.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Size4-Regular.7a996c9d.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Size4-Regular.fbccdabe.ttf +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Typewriter-Regular.6258592b.woff +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Typewriter-Regular.a8709e36.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/KaTeX_Typewriter-Regular.d97aaf4a.ttf +0 -0
- khoj/interface/compiled/_next/static/media/a6ecd16fa044d500-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/bd82c78e5b7b3fe9-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/c32c8052c071fc42-s.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/c4250770ab8708b6-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/e098aaaecc9cfbb2-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/flags.3afdda2f.webp +0 -0
- khoj/interface/compiled/_next/static/media/flags@2x.5fbe9fc1.webp +0 -0
- khoj/interface/compiled/_next/static/media/globe.98e105ca.webp +0 -0
- khoj/interface/compiled/_next/static/media/globe@2x.974df6f8.webp +0 -0
- khoj/interface/compiled/agents/index.html +1 -0
- khoj/interface/compiled/agents/index.txt +7 -0
- khoj/interface/compiled/agents.svg +6 -0
- khoj/interface/compiled/assets/icons/khoj_lantern.ico +0 -0
- khoj/interface/compiled/assets/icons/khoj_lantern.svg +100 -0
- khoj/interface/compiled/assets/icons/khoj_lantern_1200x1200.png +0 -0
- khoj/interface/compiled/assets/icons/khoj_lantern_128x128.png +0 -0
- khoj/interface/compiled/assets/icons/khoj_lantern_128x128_dark.png +0 -0
- khoj/interface/compiled/assets/icons/khoj_lantern_256x256.png +0 -0
- khoj/interface/compiled/assets/icons/khoj_lantern_512x512.png +0 -0
- khoj/interface/compiled/assets/icons/khoj_lantern_logomarktype_1200x630.png +0 -0
- khoj/interface/compiled/assets/samples/desktop-browse-draw-sample.png +0 -0
- khoj/interface/compiled/assets/samples/desktop-plain-chat-sample.png +0 -0
- khoj/interface/compiled/assets/samples/desktop-remember-plan-sample.png +0 -0
- khoj/interface/compiled/assets/samples/phone-browse-draw-sample.png +0 -0
- khoj/interface/compiled/assets/samples/phone-plain-chat-sample.png +0 -0
- khoj/interface/compiled/assets/samples/phone-remember-plan-sample.png +0 -0
- khoj/interface/compiled/automation.svg +37 -0
- khoj/interface/compiled/automations/index.html +1 -0
- khoj/interface/compiled/automations/index.txt +8 -0
- khoj/interface/compiled/chat/index.html +1 -0
- khoj/interface/compiled/chat/index.txt +7 -0
- khoj/interface/compiled/chat.svg +24 -0
- khoj/interface/compiled/close.svg +5 -0
- khoj/interface/compiled/copy-button-success.svg +6 -0
- khoj/interface/compiled/copy-button.svg +5 -0
- khoj/interface/compiled/index.html +1 -0
- khoj/interface/compiled/index.txt +7 -0
- khoj/interface/compiled/khoj.webmanifest +76 -0
- khoj/interface/compiled/logo.svg +24 -0
- khoj/interface/compiled/search/index.html +1 -0
- khoj/interface/compiled/search/index.txt +7 -0
- khoj/interface/compiled/send.svg +1 -0
- khoj/interface/compiled/settings/index.html +1 -0
- khoj/interface/compiled/settings/index.txt +9 -0
- khoj/interface/compiled/share/chat/index.html +1 -0
- khoj/interface/compiled/share/chat/index.txt +7 -0
- khoj/interface/compiled/share.svg +8 -0
- khoj/interface/compiled/thumbs-down.svg +6 -0
- khoj/interface/compiled/thumbs-up.svg +6 -0
- khoj/interface/email/feedback.html +34 -0
- khoj/interface/email/magic_link.html +40 -0
- khoj/interface/email/task.html +37 -0
- khoj/interface/email/welcome.html +90 -0
- khoj/interface/web/.well-known/assetlinks.json +11 -0
- khoj/interface/web/assets/icons/agents.svg +19 -0
- khoj/interface/web/assets/icons/automation.svg +43 -0
- khoj/interface/web/assets/icons/chat.svg +24 -0
- khoj/interface/web/assets/icons/github.svg +1 -0
- khoj/interface/web/assets/icons/khoj-logo-sideways-200.png +0 -0
- khoj/interface/web/assets/icons/khoj-logo-sideways-500.png +0 -0
- khoj/interface/web/assets/icons/khoj-logo-sideways.svg +32 -0
- khoj/interface/web/assets/icons/khoj.svg +26 -0
- khoj/interface/web/assets/icons/logotype.svg +1 -0
- khoj/interface/web/assets/icons/search.svg +57 -0
- khoj/interface/web/assets/icons/sync.svg +4 -0
- khoj/interface/web/assets/khoj.css +237 -0
- khoj/interface/web/assets/utils.js +33 -0
- khoj/interface/web/base_config.html +445 -0
- khoj/interface/web/content_source_github_input.html +208 -0
- khoj/interface/web/login.html +310 -0
- khoj/interface/web/utils.html +48 -0
- khoj/main.py +249 -0
- khoj/manage.py +22 -0
- khoj/migrations/__init__.py +0 -0
- khoj/migrations/migrate_offline_chat_default_model.py +69 -0
- khoj/migrations/migrate_offline_chat_default_model_2.py +71 -0
- khoj/migrations/migrate_offline_chat_schema.py +83 -0
- khoj/migrations/migrate_offline_model.py +29 -0
- khoj/migrations/migrate_processor_config_openai.py +67 -0
- khoj/migrations/migrate_server_pg.py +132 -0
- khoj/migrations/migrate_version.py +17 -0
- khoj/processor/__init__.py +0 -0
- khoj/processor/content/__init__.py +0 -0
- khoj/processor/content/docx/__init__.py +0 -0
- khoj/processor/content/docx/docx_to_entries.py +111 -0
- khoj/processor/content/github/__init__.py +0 -0
- khoj/processor/content/github/github_to_entries.py +226 -0
- khoj/processor/content/images/__init__.py +0 -0
- khoj/processor/content/images/image_to_entries.py +117 -0
- khoj/processor/content/markdown/__init__.py +0 -0
- khoj/processor/content/markdown/markdown_to_entries.py +160 -0
- khoj/processor/content/notion/notion_to_entries.py +259 -0
- khoj/processor/content/org_mode/__init__.py +0 -0
- khoj/processor/content/org_mode/org_to_entries.py +226 -0
- khoj/processor/content/org_mode/orgnode.py +532 -0
- khoj/processor/content/pdf/__init__.py +0 -0
- khoj/processor/content/pdf/pdf_to_entries.py +119 -0
- khoj/processor/content/plaintext/__init__.py +0 -0
- khoj/processor/content/plaintext/plaintext_to_entries.py +117 -0
- khoj/processor/content/text_to_entries.py +296 -0
- khoj/processor/conversation/__init__.py +0 -0
- khoj/processor/conversation/anthropic/__init__.py +0 -0
- khoj/processor/conversation/anthropic/anthropic_chat.py +243 -0
- khoj/processor/conversation/anthropic/utils.py +217 -0
- khoj/processor/conversation/google/__init__.py +0 -0
- khoj/processor/conversation/google/gemini_chat.py +253 -0
- khoj/processor/conversation/google/utils.py +260 -0
- khoj/processor/conversation/offline/__init__.py +0 -0
- khoj/processor/conversation/offline/chat_model.py +308 -0
- khoj/processor/conversation/offline/utils.py +80 -0
- khoj/processor/conversation/offline/whisper.py +15 -0
- khoj/processor/conversation/openai/__init__.py +0 -0
- khoj/processor/conversation/openai/gpt.py +243 -0
- khoj/processor/conversation/openai/utils.py +232 -0
- khoj/processor/conversation/openai/whisper.py +13 -0
- khoj/processor/conversation/prompts.py +1188 -0
- khoj/processor/conversation/utils.py +867 -0
- khoj/processor/embeddings.py +122 -0
- khoj/processor/image/generate.py +215 -0
- khoj/processor/speech/__init__.py +0 -0
- khoj/processor/speech/text_to_speech.py +51 -0
- khoj/processor/tools/__init__.py +0 -0
- khoj/processor/tools/online_search.py +472 -0
- khoj/processor/tools/run_code.py +179 -0
- khoj/routers/__init__.py +0 -0
- khoj/routers/api.py +760 -0
- khoj/routers/api_agents.py +295 -0
- khoj/routers/api_chat.py +1273 -0
- khoj/routers/api_content.py +634 -0
- khoj/routers/api_model.py +123 -0
- khoj/routers/api_phone.py +86 -0
- khoj/routers/api_subscription.py +144 -0
- khoj/routers/auth.py +307 -0
- khoj/routers/email.py +135 -0
- khoj/routers/helpers.py +2333 -0
- khoj/routers/notion.py +85 -0
- khoj/routers/research.py +364 -0
- khoj/routers/storage.py +63 -0
- khoj/routers/twilio.py +36 -0
- khoj/routers/web_client.py +141 -0
- khoj/search_filter/__init__.py +0 -0
- khoj/search_filter/base_filter.py +15 -0
- khoj/search_filter/date_filter.py +215 -0
- khoj/search_filter/file_filter.py +32 -0
- khoj/search_filter/word_filter.py +29 -0
- khoj/search_type/__init__.py +0 -0
- khoj/search_type/text_search.py +255 -0
- khoj/utils/__init__.py +0 -0
- khoj/utils/cli.py +101 -0
- khoj/utils/config.py +81 -0
- khoj/utils/constants.py +51 -0
- khoj/utils/fs_syncer.py +252 -0
- khoj/utils/helpers.py +627 -0
- khoj/utils/initialization.py +301 -0
- khoj/utils/jsonl.py +43 -0
- khoj/utils/models.py +47 -0
- khoj/utils/rawconfig.py +208 -0
- khoj/utils/state.py +48 -0
- khoj/utils/yaml.py +47 -0
- khoj-1.33.3.dev32.dist-info/METADATA +190 -0
- khoj-1.33.3.dev32.dist-info/RECORD +393 -0
- khoj-1.33.3.dev32.dist-info/WHEEL +4 -0
- khoj-1.33.3.dev32.dist-info/entry_points.txt +2 -0
- khoj-1.33.3.dev32.dist-info/licenses/LICENSE +661 -0
@@ -0,0 +1,122 @@
|
|
1
|
+
import logging
|
2
|
+
from typing import List
|
3
|
+
|
4
|
+
import requests
|
5
|
+
import tqdm
|
6
|
+
from sentence_transformers import CrossEncoder, SentenceTransformer
|
7
|
+
from tenacity import (
|
8
|
+
before_sleep_log,
|
9
|
+
retry,
|
10
|
+
retry_if_exception_type,
|
11
|
+
stop_after_attempt,
|
12
|
+
wait_random_exponential,
|
13
|
+
)
|
14
|
+
from torch import nn
|
15
|
+
|
16
|
+
from khoj.utils.helpers import fix_json_dict, get_device, merge_dicts, timer
|
17
|
+
from khoj.utils.rawconfig import SearchResponse
|
18
|
+
|
19
|
+
logger = logging.getLogger(__name__)
|
20
|
+
|
21
|
+
|
22
|
+
class EmbeddingsModel:
|
23
|
+
def __init__(
|
24
|
+
self,
|
25
|
+
model_name: str = "thenlper/gte-small",
|
26
|
+
embeddings_inference_endpoint: str = None,
|
27
|
+
embeddings_inference_endpoint_api_key: str = None,
|
28
|
+
query_encode_kwargs: dict = {},
|
29
|
+
docs_encode_kwargs: dict = {},
|
30
|
+
model_kwargs: dict = {},
|
31
|
+
):
|
32
|
+
default_query_encode_kwargs = {"show_progress_bar": False, "normalize_embeddings": True}
|
33
|
+
default_docs_encode_kwargs = {"show_progress_bar": True, "normalize_embeddings": True}
|
34
|
+
self.query_encode_kwargs = merge_dicts(fix_json_dict(query_encode_kwargs), default_query_encode_kwargs)
|
35
|
+
self.docs_encode_kwargs = merge_dicts(fix_json_dict(docs_encode_kwargs), default_docs_encode_kwargs)
|
36
|
+
self.model_kwargs = merge_dicts(fix_json_dict(model_kwargs), {"device": get_device()})
|
37
|
+
self.model_name = model_name
|
38
|
+
self.inference_endpoint = embeddings_inference_endpoint
|
39
|
+
self.api_key = embeddings_inference_endpoint_api_key
|
40
|
+
with timer(f"Loaded embedding model {self.model_name}", logger):
|
41
|
+
self.embeddings_model = SentenceTransformer(self.model_name, **self.model_kwargs)
|
42
|
+
|
43
|
+
def inference_server_enabled(self) -> bool:
|
44
|
+
return self.api_key is not None and self.inference_endpoint is not None
|
45
|
+
|
46
|
+
def embed_query(self, query):
|
47
|
+
if self.inference_server_enabled():
|
48
|
+
return self.embed_with_api([query])[0]
|
49
|
+
return self.embeddings_model.encode([query], **self.query_encode_kwargs)[0]
|
50
|
+
|
51
|
+
@retry(
|
52
|
+
retry=retry_if_exception_type(requests.exceptions.HTTPError),
|
53
|
+
wait=wait_random_exponential(multiplier=1, max=10),
|
54
|
+
stop=stop_after_attempt(5),
|
55
|
+
before_sleep=before_sleep_log(logger, logging.DEBUG),
|
56
|
+
)
|
57
|
+
def embed_with_api(self, docs):
|
58
|
+
payload = {"inputs": docs}
|
59
|
+
headers = {
|
60
|
+
"Authorization": f"Bearer {self.api_key}",
|
61
|
+
"Content-Type": "application/json",
|
62
|
+
}
|
63
|
+
try:
|
64
|
+
response = requests.post(self.inference_endpoint, json=payload, headers=headers)
|
65
|
+
response.raise_for_status()
|
66
|
+
except requests.exceptions.HTTPError as e:
|
67
|
+
logger.error(
|
68
|
+
f" Error while calling inference endpoint {self.inference_endpoint} with error {e}, response {response.json()} ",
|
69
|
+
exc_info=True,
|
70
|
+
)
|
71
|
+
raise e
|
72
|
+
return response.json()["embeddings"]
|
73
|
+
|
74
|
+
def embed_documents(self, docs):
|
75
|
+
if self.inference_server_enabled():
|
76
|
+
if "huggingface" not in self.inference_endpoint:
|
77
|
+
logger.warning(
|
78
|
+
f"Unsupported inference endpoint: {self.inference_endpoint}. Only HuggingFace supported. Generating embeddings on device instead."
|
79
|
+
)
|
80
|
+
return self.embeddings_model.encode(docs, **self.docs_encode_kwargs).tolist()
|
81
|
+
# break up the docs payload in chunks of 1000 to avoid hitting rate limits
|
82
|
+
embeddings = []
|
83
|
+
with tqdm.tqdm(total=len(docs)) as pbar:
|
84
|
+
for i in range(0, len(docs), 1000):
|
85
|
+
docs_to_embed = docs[i : i + 1000]
|
86
|
+
generated_embeddings = self.embed_with_api(docs_to_embed)
|
87
|
+
embeddings += generated_embeddings
|
88
|
+
pbar.update(1000)
|
89
|
+
return embeddings
|
90
|
+
return self.embeddings_model.encode(docs, **self.docs_encode_kwargs).tolist() if docs else []
|
91
|
+
|
92
|
+
|
93
|
+
class CrossEncoderModel:
|
94
|
+
def __init__(
|
95
|
+
self,
|
96
|
+
model_name: str = "mixedbread-ai/mxbai-rerank-xsmall-v1",
|
97
|
+
cross_encoder_inference_endpoint: str = None,
|
98
|
+
cross_encoder_inference_endpoint_api_key: str = None,
|
99
|
+
model_kwargs: dict = {},
|
100
|
+
):
|
101
|
+
self.model_name = model_name
|
102
|
+
self.inference_endpoint = cross_encoder_inference_endpoint
|
103
|
+
self.api_key = cross_encoder_inference_endpoint_api_key
|
104
|
+
self.model_kwargs = merge_dicts(model_kwargs, {"device": get_device()})
|
105
|
+
with timer(f"Loaded cross-encoder model {self.model_name}", logger):
|
106
|
+
self.cross_encoder_model = CrossEncoder(model_name=self.model_name, **self.model_kwargs)
|
107
|
+
|
108
|
+
def inference_server_enabled(self) -> bool:
|
109
|
+
return self.api_key is not None and self.inference_endpoint is not None
|
110
|
+
|
111
|
+
def predict(self, query, hits: List[SearchResponse], key: str = "compiled"):
|
112
|
+
if self.inference_server_enabled() and "huggingface" in self.inference_endpoint:
|
113
|
+
target_url = f"{self.inference_endpoint}"
|
114
|
+
payload = {"inputs": {"query": query, "passages": [hit.additional[key] for hit in hits]}}
|
115
|
+
headers = {"Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json"}
|
116
|
+
response = requests.post(target_url, json=payload, headers=headers)
|
117
|
+
response.raise_for_status()
|
118
|
+
return response.json()["scores"]
|
119
|
+
|
120
|
+
cross_inp = [[query, hit.additional[key]] for hit in hits]
|
121
|
+
cross_scores = self.cross_encoder_model.predict(cross_inp, activation_fct=nn.Sigmoid())
|
122
|
+
return cross_scores
|
@@ -0,0 +1,215 @@
|
|
1
|
+
import base64
|
2
|
+
import io
|
3
|
+
import logging
|
4
|
+
import time
|
5
|
+
from typing import Any, Callable, Dict, List, Optional
|
6
|
+
|
7
|
+
import openai
|
8
|
+
import requests
|
9
|
+
|
10
|
+
from khoj.database.adapters import ConversationAdapters
|
11
|
+
from khoj.database.models import Agent, KhojUser, TextToImageModelConfig
|
12
|
+
from khoj.routers.helpers import ChatEvent, generate_better_image_prompt
|
13
|
+
from khoj.routers.storage import upload_image
|
14
|
+
from khoj.utils import state
|
15
|
+
from khoj.utils.helpers import convert_image_to_webp, timer
|
16
|
+
from khoj.utils.rawconfig import LocationData
|
17
|
+
|
18
|
+
logger = logging.getLogger(__name__)
|
19
|
+
|
20
|
+
|
21
|
+
async def text_to_image(
|
22
|
+
message: str,
|
23
|
+
user: KhojUser,
|
24
|
+
conversation_log: dict,
|
25
|
+
location_data: LocationData,
|
26
|
+
references: List[Dict[str, Any]],
|
27
|
+
online_results: Dict[str, Any],
|
28
|
+
send_status_func: Optional[Callable] = None,
|
29
|
+
query_images: Optional[List[str]] = None,
|
30
|
+
agent: Agent = None,
|
31
|
+
query_files: str = None,
|
32
|
+
tracer: dict = {},
|
33
|
+
):
|
34
|
+
status_code = 200
|
35
|
+
image = None
|
36
|
+
image_url = None
|
37
|
+
|
38
|
+
text_to_image_config = await ConversationAdapters.aget_user_text_to_image_model(user)
|
39
|
+
if not text_to_image_config:
|
40
|
+
# If the user has not configured a text to image model, return an unsupported on server error
|
41
|
+
status_code = 501
|
42
|
+
message = "Failed to generate image. Setup image generation on the server."
|
43
|
+
yield image_url or image, status_code, message
|
44
|
+
return
|
45
|
+
|
46
|
+
text2image_model = text_to_image_config.model_name
|
47
|
+
chat_history = ""
|
48
|
+
for chat in conversation_log.get("chat", [])[-4:]:
|
49
|
+
if chat["by"] == "khoj" and chat["intent"].get("type") in ["remember", "reminder"]:
|
50
|
+
chat_history += f"Q: {chat['intent']['query']}\n"
|
51
|
+
chat_history += f"A: {chat['message']}\n"
|
52
|
+
elif chat["by"] == "khoj" and chat.get("images"):
|
53
|
+
chat_history += f"Q: {chat['intent']['query']}\n"
|
54
|
+
chat_history += f"A: Improved Prompt: {chat['intent']['inferred-queries'][0]}\n"
|
55
|
+
|
56
|
+
if send_status_func:
|
57
|
+
async for event in send_status_func("**Enhancing the Painting Prompt**"):
|
58
|
+
yield {ChatEvent.STATUS: event}
|
59
|
+
|
60
|
+
# Generate a better image prompt
|
61
|
+
# Use the user's message, chat history, and other context
|
62
|
+
image_prompt = await generate_better_image_prompt(
|
63
|
+
message,
|
64
|
+
chat_history,
|
65
|
+
location_data=location_data,
|
66
|
+
note_references=references,
|
67
|
+
online_results=online_results,
|
68
|
+
model_type=text_to_image_config.model_type,
|
69
|
+
query_images=query_images,
|
70
|
+
user=user,
|
71
|
+
agent=agent,
|
72
|
+
query_files=query_files,
|
73
|
+
tracer=tracer,
|
74
|
+
)
|
75
|
+
|
76
|
+
if send_status_func:
|
77
|
+
async for event in send_status_func(f"**Painting to Imagine**:\n{image_prompt}"):
|
78
|
+
yield {ChatEvent.STATUS: event}
|
79
|
+
|
80
|
+
# Generate image using the configured model and API
|
81
|
+
with timer(f"Generate image with {text_to_image_config.model_type}", logger):
|
82
|
+
try:
|
83
|
+
if text_to_image_config.model_type == TextToImageModelConfig.ModelType.OPENAI:
|
84
|
+
webp_image_bytes = generate_image_with_openai(image_prompt, text_to_image_config, text2image_model)
|
85
|
+
elif text_to_image_config.model_type == TextToImageModelConfig.ModelType.STABILITYAI:
|
86
|
+
webp_image_bytes = generate_image_with_stability(image_prompt, text_to_image_config, text2image_model)
|
87
|
+
elif text_to_image_config.model_type == TextToImageModelConfig.ModelType.REPLICATE:
|
88
|
+
webp_image_bytes = generate_image_with_replicate(image_prompt, text_to_image_config, text2image_model)
|
89
|
+
except openai.OpenAIError or openai.BadRequestError or openai.APIConnectionError as e:
|
90
|
+
if "content_policy_violation" in e.message:
|
91
|
+
logger.error(f"Image Generation blocked by OpenAI: {e}")
|
92
|
+
status_code = e.status_code # type: ignore
|
93
|
+
message = f"Image generation blocked by OpenAI due to policy violation" # type: ignore
|
94
|
+
yield image_url or image, status_code, message
|
95
|
+
return
|
96
|
+
else:
|
97
|
+
logger.error(f"Image Generation failed with {e}", exc_info=True)
|
98
|
+
message = f"Image generation failed using OpenAI" # type: ignore
|
99
|
+
status_code = e.status_code # type: ignore
|
100
|
+
yield image_url or image, status_code, message
|
101
|
+
return
|
102
|
+
except requests.RequestException as e:
|
103
|
+
logger.error(f"Image Generation failed with {e}", exc_info=True)
|
104
|
+
message = f"Image generation using {text2image_model} via {text_to_image_config.model_type} failed due to a network error."
|
105
|
+
status_code = 502
|
106
|
+
yield image_url or image, status_code, message
|
107
|
+
return
|
108
|
+
|
109
|
+
# Decide how to store the generated image
|
110
|
+
with timer("Upload image to S3", logger):
|
111
|
+
image_url = upload_image(webp_image_bytes, user.uuid)
|
112
|
+
|
113
|
+
if not image_url:
|
114
|
+
image = base64.b64encode(webp_image_bytes).decode("utf-8")
|
115
|
+
|
116
|
+
yield image_url or image, status_code, image_prompt
|
117
|
+
|
118
|
+
|
119
|
+
def generate_image_with_openai(
|
120
|
+
improved_image_prompt: str, text_to_image_config: TextToImageModelConfig, text2image_model: str
|
121
|
+
):
|
122
|
+
"Generate image using OpenAI API"
|
123
|
+
|
124
|
+
# Get the API key from the user's configuration
|
125
|
+
if text_to_image_config.api_key:
|
126
|
+
api_key = text_to_image_config.api_key
|
127
|
+
elif text_to_image_config.ai_model_api:
|
128
|
+
api_key = text_to_image_config.ai_model_api.api_key
|
129
|
+
elif state.openai_client:
|
130
|
+
api_key = state.openai_client.api_key
|
131
|
+
auth_header = {"Authorization": f"Bearer {api_key}"} if api_key else {}
|
132
|
+
|
133
|
+
# Generate image using OpenAI API
|
134
|
+
OPENAI_IMAGE_GEN_STYLE = "vivid"
|
135
|
+
response = state.openai_client.images.generate(
|
136
|
+
prompt=improved_image_prompt,
|
137
|
+
model=text2image_model,
|
138
|
+
style=OPENAI_IMAGE_GEN_STYLE,
|
139
|
+
response_format="b64_json",
|
140
|
+
extra_headers=auth_header,
|
141
|
+
)
|
142
|
+
|
143
|
+
# Extract the base64 image from the response
|
144
|
+
image = response.data[0].b64_json
|
145
|
+
# Decode base64 png and convert it to webp for faster loading
|
146
|
+
return convert_image_to_webp(base64.b64decode(image))
|
147
|
+
|
148
|
+
|
149
|
+
def generate_image_with_stability(
|
150
|
+
improved_image_prompt: str, text_to_image_config: TextToImageModelConfig, text2image_model: str
|
151
|
+
):
|
152
|
+
"Generate image using Stability AI"
|
153
|
+
|
154
|
+
# Call Stability AI API to generate image
|
155
|
+
response = requests.post(
|
156
|
+
f"https://api.stability.ai/v2beta/stable-image/generate/sd3",
|
157
|
+
headers={"authorization": f"Bearer {text_to_image_config.api_key}", "accept": "image/*"},
|
158
|
+
files={"none": ""},
|
159
|
+
data={
|
160
|
+
"prompt": improved_image_prompt,
|
161
|
+
"model": text2image_model,
|
162
|
+
"mode": "text-to-image",
|
163
|
+
"output_format": "png",
|
164
|
+
"aspect_ratio": "1:1",
|
165
|
+
},
|
166
|
+
)
|
167
|
+
# Convert png to webp for faster loading
|
168
|
+
return convert_image_to_webp(response.content)
|
169
|
+
|
170
|
+
|
171
|
+
def generate_image_with_replicate(
|
172
|
+
improved_image_prompt: str, text_to_image_config: TextToImageModelConfig, text2image_model: str
|
173
|
+
):
|
174
|
+
"Generate image using Replicate API"
|
175
|
+
|
176
|
+
# Create image generation task on Replicate
|
177
|
+
replicate_create_prediction_url = f"https://api.replicate.com/v1/models/{text2image_model}/predictions"
|
178
|
+
headers = {
|
179
|
+
"Authorization": f"Bearer {text_to_image_config.api_key}",
|
180
|
+
"Content-Type": "application/json",
|
181
|
+
}
|
182
|
+
json = {
|
183
|
+
"input": {
|
184
|
+
"prompt": improved_image_prompt,
|
185
|
+
"num_outputs": 1,
|
186
|
+
"aspect_ratio": "1:1",
|
187
|
+
"output_format": "webp",
|
188
|
+
"output_quality": 100,
|
189
|
+
}
|
190
|
+
}
|
191
|
+
create_prediction = requests.post(replicate_create_prediction_url, headers=headers, json=json).json()
|
192
|
+
|
193
|
+
# Get status of image generation task
|
194
|
+
get_prediction_url = create_prediction["urls"]["get"]
|
195
|
+
get_prediction = requests.get(get_prediction_url, headers=headers).json()
|
196
|
+
status = get_prediction["status"]
|
197
|
+
retry_count = 1
|
198
|
+
|
199
|
+
# Poll the image generation task for completion status
|
200
|
+
while status not in ["succeeded", "failed", "canceled"] and retry_count < 20:
|
201
|
+
time.sleep(2)
|
202
|
+
get_prediction = requests.get(get_prediction_url, headers=headers).json()
|
203
|
+
status = get_prediction["status"]
|
204
|
+
retry_count += 1
|
205
|
+
|
206
|
+
# Raise exception if the image generation task fails
|
207
|
+
if status != "succeeded":
|
208
|
+
error = get_prediction.get("error")
|
209
|
+
if retry_count >= 10:
|
210
|
+
raise requests.RequestException("Image generation timed out")
|
211
|
+
raise requests.RequestException(f"Image generation failed with status: {status}, message: {error}")
|
212
|
+
|
213
|
+
# Get the generated image
|
214
|
+
image_url = get_prediction["output"][0] if isinstance(get_prediction["output"], list) else get_prediction["output"]
|
215
|
+
return io.BytesIO(requests.get(image_url).content).getvalue()
|
File without changes
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import json # Used for working with JSON data
|
2
|
+
import os
|
3
|
+
|
4
|
+
import requests # Used for making HTTP requests
|
5
|
+
from bs4 import BeautifulSoup
|
6
|
+
from markdown_it import MarkdownIt
|
7
|
+
|
8
|
+
# Define constants for the script
|
9
|
+
CHUNK_SIZE = 1024 # Size of chunks to read/write at a time
|
10
|
+
ELEVEN_LABS_API_KEY = os.getenv("ELEVEN_LABS_API_KEY", None) # Your API key for authentication
|
11
|
+
VOICE_ID = "RPEIZnKMqlQiZyZd1Dae" # ID of the voice model to use. MALE - Christopher - friendly guy next door.
|
12
|
+
ELEVEN_API_URL = "https://api.elevenlabs.io/v1/text-to-speech" # Base URL for the Text-to-Speech API
|
13
|
+
|
14
|
+
markdown_renderer = MarkdownIt()
|
15
|
+
|
16
|
+
|
17
|
+
def is_eleven_labs_enabled():
|
18
|
+
return ELEVEN_LABS_API_KEY is not None
|
19
|
+
|
20
|
+
|
21
|
+
def generate_text_to_speech(
|
22
|
+
text_to_speak: str,
|
23
|
+
voice_id: str = VOICE_ID,
|
24
|
+
):
|
25
|
+
if not is_eleven_labs_enabled():
|
26
|
+
return "Eleven Labs API key is not set"
|
27
|
+
|
28
|
+
# Convert the incoming text from markdown format to plain text
|
29
|
+
html = markdown_renderer.render(text_to_speak)
|
30
|
+
text = "".join(BeautifulSoup(html, features="lxml").findAll(text=True))
|
31
|
+
|
32
|
+
# Construct the URL for the Text-to-Speech API request
|
33
|
+
tts_url = f"{ELEVEN_API_URL}/{voice_id}/stream"
|
34
|
+
|
35
|
+
# Set up headers for the API request, including the API key for authentication
|
36
|
+
headers = {"Accept": "application/json", "xi-api-key": ELEVEN_LABS_API_KEY}
|
37
|
+
|
38
|
+
# Set up the data payload for the API request, including the text and voice settings
|
39
|
+
data = {
|
40
|
+
"text": text,
|
41
|
+
# "model_id": "eleven_multilingual_v2",
|
42
|
+
"voice_settings": {"stability": 0.5, "similarity_boost": 0.8, "style": 0.0, "use_speaker_boost": True},
|
43
|
+
}
|
44
|
+
|
45
|
+
# Make the POST request to the TTS API with headers and data, enabling streaming response
|
46
|
+
response = requests.post(tts_url, headers=headers, json=data, stream=True)
|
47
|
+
|
48
|
+
if response.ok:
|
49
|
+
return response
|
50
|
+
else:
|
51
|
+
raise Exception(f"Failed to generate text-to-speech: {response.text}")
|
File without changes
|