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.
- khoj/app/settings.py +7 -2
- khoj/configure.py +21 -0
- khoj/database/adapters/__init__.py +9 -5
- khoj/database/admin.py +2 -0
- khoj/database/migrations/0055_alter_agent_style_icon.py +37 -0
- khoj/database/models/__init__.py +2 -0
- khoj/interface/compiled/404/index.html +1 -0
- khoj/interface/compiled/_next/static/chunks/1603-fb2d80ae73990df3.js +1 -0
- khoj/interface/compiled/_next/static/chunks/2614-7cf01576d4457a75.js +3 -0
- khoj/interface/compiled/_next/static/chunks/3062-a42d847c919a9ea4.js +29 -0
- khoj/interface/compiled/_next/static/chunks/3678-8c0e55c3b5d83a22.js +25 -0
- khoj/interface/compiled/_next/static/chunks/4504-1629487c8bc82203.js +1 -0
- khoj/interface/compiled/_next/static/chunks/6297-d1c842ed3f714ab0.js +1 -0
- khoj/interface/compiled/_next/static/chunks/6648-ff677e51f1b2bcf1.js +1 -0
- khoj/interface/compiled/_next/static/chunks/7023-52c1be60135eb057.js +2 -0
- khoj/interface/compiled/_next/static/chunks/7071-b4711cecca6619a8.js +1 -0
- khoj/interface/compiled/_next/static/chunks/743-1a64254447cda71f.js +1 -0
- khoj/interface/compiled/_next/static/chunks/8423-132ea64eac83fd43.js +1 -0
- khoj/interface/compiled/_next/static/chunks/9001-acbca3e19b1a5ddf.js +21 -0
- khoj/interface/compiled/_next/static/chunks/9162-4a6d0d0dc5e27618.js +11 -0
- khoj/interface/compiled/_next/static/chunks/9178-859894e0d9d67aa5.js +1 -0
- khoj/interface/compiled/_next/static/chunks/9417-2e54c6fd056982d8.js +1 -0
- khoj/interface/compiled/_next/static/chunks/9693-91b03052c5cabded.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/_not-found/page-07ff4ab42b07845e.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/agents/layout-e71c8e913cccf792.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/agents/page-922694b75f1fb67b.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/automations/layout-27c28e923c9b1ff0.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/automations/page-46913728bcb8f4c6.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/chat/layout-8102549127db3067.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/chat/page-51ab7c4b766ff344.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/factchecker/layout-7b30c541c05fb904.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/factchecker/page-60be5e3295e2c0bc.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/layout-f3e40d346da53112.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/page-635b30b582201b05.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/search/layout-3720f1362310bebb.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/search/page-dcd385f03255ef36.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/settings/layout-6f9314b0d7a26046.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/settings/page-e83f6fa32691ca64.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/share/chat/layout-39f03f9e32399f0f.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/share/chat/page-699b364dc6fbf139.js +1 -0
- khoj/interface/compiled/_next/static/chunks/d3ac728e-a9e3522eef9b6b28.js +1 -0
- khoj/interface/compiled/_next/static/chunks/fd9d1056-2b978342deb60015.js +1 -0
- khoj/interface/compiled/_next/static/chunks/framework-8e0e0f4a6b83a956.js +33 -0
- khoj/interface/compiled/_next/static/chunks/main-175c164f5e0f026c.js +1 -0
- khoj/interface/compiled/_next/static/chunks/main-app-6d6ee3495efe03d4.js +1 -0
- khoj/interface/compiled/_next/static/chunks/pages/_app-f870474a17b7f2fd.js +1 -0
- khoj/interface/compiled/_next/static/chunks/pages/_error-c66a4e8afc46f17b.js +1 -0
- khoj/interface/compiled/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js +1 -0
- khoj/interface/compiled/_next/static/chunks/webpack-97d9516936918753.js +1 -0
- khoj/interface/compiled/_next/static/css/1538cedb321e3a97.css +1 -0
- khoj/interface/compiled/_next/static/css/1de368beed21dfba.css +25 -0
- khoj/interface/compiled/_next/static/css/2272c73fc7a3b571.css +1 -0
- khoj/interface/compiled/_next/static/css/4cae6c0e5c72fb2d.css +1 -0
- khoj/interface/compiled/_next/static/css/553f9cdcc7a2bcd6.css +1 -0
- khoj/interface/compiled/_next/static/css/a22d83f18a32957e.css +1 -0
- khoj/interface/compiled/_next/static/css/a3530ec58b0b660f.css +1 -0
- khoj/interface/compiled/_next/static/css/b81e909d403fb2df.css +1 -0
- khoj/interface/compiled/_next/static/css/df6f4c34ec280d53.css +1 -0
- khoj/interface/compiled/_next/static/iCI2Ycgat9pFGG9HeJvvH/_buildManifest.js +1 -0
- khoj/interface/compiled/_next/static/iCI2Ycgat9pFGG9HeJvvH/_ssgManifest.js +1 -0
- khoj/interface/compiled/_next/static/media/0e790e04fd40ad16-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/4221e1667cd19c7d-s.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/6c276159aa0eb14b-s.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/6cc0b9500e4f9168-s.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/9d9319a7a2ac39c6-s.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/a75c8ea86756d52d-s.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/abce7c400ca31a51-s.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/f759c939737fb668-s.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/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/close.svg +5 -0
- khoj/interface/compiled/factchecker/index.html +1 -0
- khoj/interface/compiled/factchecker/index.txt +7 -0
- khoj/interface/compiled/favicon.ico +0 -0
- khoj/interface/compiled/index.html +1 -0
- khoj/interface/compiled/index.txt +7 -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/settings/index.html +1 -0
- khoj/interface/compiled/settings/index.txt +8 -0
- khoj/interface/compiled/share/chat/index.html +1 -0
- khoj/interface/compiled/share/chat/index.txt +7 -0
- khoj/interface/web/assets/icons/agents.svg +17 -5
- khoj/interface/web/assets/icons/automation.svg +40 -35
- khoj/interface/web/assets/icons/search.svg +40 -8
- khoj/interface/web/login.html +1 -1
- khoj/routers/api_chat.py +5 -16
- khoj/routers/helpers.py +74 -0
- khoj/routers/web_client.py +30 -131
- khoj/utils/constants.py +1 -0
- {khoj-1.17.1.dev229.dist-info → khoj-1.20.3.dist-info}/METADATA +1 -1
- khoj-1.20.3.dist-info/RECORD +353 -0
- khoj/interface/web/404.html +0 -56
- khoj/interface/web/agent.html +0 -312
- khoj/interface/web/agents.html +0 -276
- khoj/interface/web/assets/icons/cancel.svg +0 -3
- khoj/interface/web/assets/icons/collapse.svg +0 -17
- khoj/interface/web/assets/icons/computer.png +0 -0
- khoj/interface/web/assets/icons/confirm-icon.svg +0 -1
- khoj/interface/web/assets/icons/credit-card.png +0 -0
- khoj/interface/web/assets/icons/delete.svg +0 -26
- khoj/interface/web/assets/icons/docx.svg +0 -7
- khoj/interface/web/assets/icons/edit.svg +0 -4
- khoj/interface/web/assets/icons/key.svg +0 -4
- khoj/interface/web/assets/icons/markdown.svg +0 -1
- khoj/interface/web/assets/icons/new.svg +0 -23
- khoj/interface/web/assets/icons/notion.svg +0 -4
- khoj/interface/web/assets/icons/openai-logomark.svg +0 -1
- khoj/interface/web/assets/icons/org.svg +0 -1
- khoj/interface/web/assets/icons/pdf.svg +0 -23
- khoj/interface/web/assets/icons/pencil-edit.svg +0 -5
- khoj/interface/web/assets/icons/plaintext.svg +0 -1
- khoj/interface/web/assets/icons/question-mark-icon.svg +0 -1
- khoj/interface/web/assets/icons/speaker.svg +0 -4
- khoj/interface/web/assets/icons/stop-solid.svg +0 -37
- khoj/interface/web/assets/icons/user-silhouette.svg +0 -4
- khoj/interface/web/assets/icons/voice.svg +0 -8
- khoj/interface/web/assets/icons/web.svg +0 -2
- khoj/interface/web/assets/icons/whatsapp.svg +0 -17
- khoj/interface/web/assets/markdown-it.min.js +0 -8476
- khoj/interface/web/assets/natural-cron.min.js +0 -1
- khoj/interface/web/assets/org.min.js +0 -1823
- khoj/interface/web/assets/pico.min.css +0 -5
- khoj/interface/web/assets/purify.min.js +0 -3
- khoj/interface/web/chat.html +0 -3436
- khoj/interface/web/config_automation.html +0 -1103
- khoj/interface/web/content_source_computer_input.html +0 -139
- khoj/interface/web/content_source_notion_input.html +0 -94
- khoj/interface/web/public_conversation.html +0 -2006
- khoj/interface/web/search.html +0 -470
- khoj/interface/web/settings.html +0 -1011
- khoj-1.17.1.dev229.dist-info/RECORD +0 -244
- /khoj/interface/{web/assets/icons → compiled}/chat.svg +0 -0
- /khoj/interface/{web/assets/icons → compiled}/copy-button-success.svg +0 -0
- /khoj/interface/{web/assets/icons → compiled}/copy-button.svg +0 -0
- /khoj/interface/{web/assets/icons → compiled}/send.svg +0 -0
- /khoj/interface/{web/assets/icons → compiled}/share.svg +0 -0
- /khoj/interface/{web/assets/icons/thumbs-down-svgrepo-com.svg → compiled/thumbs-down.svg} +0 -0
- /khoj/interface/{web/assets/icons/thumbs-up-svgrepo-com.svg → compiled/thumbs-up.svg} +0 -0
- {khoj-1.17.1.dev229.dist-info → khoj-1.20.3.dist-info}/WHEEL +0 -0
- {khoj-1.17.1.dev229.dist-info → khoj-1.20.3.dist-info}/entry_points.txt +0 -0
- {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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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>
|
khoj/interface/web/login.html
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
941
|
-
|
|
942
|
-
|
|
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"])
|
khoj/routers/web_client.py
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
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
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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"
|