khoj 1.23.3.dev1__py3-none-any.whl → 1.23.4.dev1__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/database/adapters/__init__.py +8 -8
- 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/models/__init__.py +1 -0
- khoj/interface/compiled/404/index.html +1 -1
- khoj/interface/compiled/_next/static/chunks/1603-d643510c2c0b8871.js +1 -0
- khoj/interface/compiled/_next/static/chunks/{1906-1747a36c336df02c.js → 4051-3dc2df557ccb5213.js} +2 -2
- khoj/interface/compiled/_next/static/chunks/8423-62ac6c832be2461b.js +1 -0
- khoj/interface/compiled/_next/static/chunks/9178-421e47df97ff0213.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/agents/page-f8ad4d2944dbcf91.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/automations/{page-85e9176b460c5e33.js → page-cc875a656df43713.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/chat/page-3e75b0e0aa3aaaf5.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/factchecker/{page-21cf46aca7e6d487.js → page-bb320ff7d4dee716.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/{page-b406302925829b15.js → page-60193524cf570002.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/search/page-4bceb5b0df9cfd66.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/settings/page-532ed8b778a0b40d.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/share/chat/page-b5e63aabfd573dba.js +1 -0
- khoj/interface/compiled/_next/static/chunks/{webpack-f162a207b26413cd.js → webpack-de28762883e5816d.js} +1 -1
- khoj/interface/compiled/_next/static/css/1105696872e3f20c.css +25 -0
- khoj/interface/compiled/_next/static/css/ab57702ed2b98214.css +1 -0
- khoj/interface/compiled/_next/static/css/e41ec62af8ee4e38.css +1 -0
- khoj/interface/compiled/agents/index.html +1 -1
- khoj/interface/compiled/agents/index.txt +2 -2
- khoj/interface/compiled/automations/index.html +1 -1
- khoj/interface/compiled/automations/index.txt +2 -2
- khoj/interface/compiled/chat/index.html +1 -1
- khoj/interface/compiled/chat/index.txt +2 -2
- khoj/interface/compiled/factchecker/index.html +1 -1
- khoj/interface/compiled/factchecker/index.txt +2 -2
- khoj/interface/compiled/index.html +1 -1
- khoj/interface/compiled/index.txt +2 -2
- khoj/interface/compiled/search/index.html +1 -1
- khoj/interface/compiled/search/index.txt +2 -2
- khoj/interface/compiled/settings/index.html +1 -1
- khoj/interface/compiled/settings/index.txt +2 -2
- khoj/interface/compiled/share/chat/index.html +1 -1
- khoj/interface/compiled/share/chat/index.txt +2 -2
- khoj/interface/email/task.html +31 -34
- khoj/interface/email/welcome.html +82 -53
- khoj/main.py +1 -1
- khoj/processor/content/images/image_to_entries.py +6 -4
- khoj/processor/conversation/utils.py +13 -8
- khoj/routers/api.py +1 -1
- khoj/routers/api_chat.py +13 -15
- khoj/routers/helpers.py +12 -7
- khoj/utils/cli.py +6 -0
- khoj/utils/constants.py +9 -2
- khoj/utils/initialization.py +158 -71
- {khoj-1.23.3.dev1.dist-info → khoj-1.23.4.dev1.dist-info}/METADATA +2 -2
- {khoj-1.23.3.dev1.dist-info → khoj-1.23.4.dev1.dist-info}/RECORD +56 -54
- khoj/interface/compiled/_next/static/chunks/1603-fb2d80ae73990df3.js +0 -1
- khoj/interface/compiled/_next/static/chunks/8423-14fc72aec9104ce9.js +0 -1
- khoj/interface/compiled/_next/static/chunks/9178-c153fc402c970365.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/agents/page-1ac024e05374f91f.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/chat/page-ababf339318a3b50.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/search/page-fde8c956cc33a187.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/settings/page-88737126debb4712.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/share/chat/page-f11b4fb0f2bc3381.js +0 -1
- khoj/interface/compiled/_next/static/css/17e284bae7dc4881.css +0 -1
- khoj/interface/compiled/_next/static/css/3e49e5ee49c6bda1.css +0 -25
- khoj/interface/compiled/_next/static/css/592ca99f5122e75a.css +0 -1
- /khoj/interface/compiled/_next/static/chunks/{7023-52c1be60135eb057.js → 7023-1074a582ec989284.js} +0 -0
- /khoj/interface/compiled/_next/static/{BtK3cBCv0oGm04ZdaAvMB → u496AO3jlFBPp2apVnMkP}/_buildManifest.js +0 -0
- /khoj/interface/compiled/_next/static/{BtK3cBCv0oGm04ZdaAvMB → u496AO3jlFBPp2apVnMkP}/_ssgManifest.js +0 -0
- {khoj-1.23.3.dev1.dist-info → khoj-1.23.4.dev1.dist-info}/WHEEL +0 -0
- {khoj-1.23.3.dev1.dist-info → khoj-1.23.4.dev1.dist-info}/entry_points.txt +0 -0
- {khoj-1.23.3.dev1.dist-info → khoj-1.23.4.dev1.dist-info}/licenses/LICENSE +0 -0
@@ -1,61 +1,90 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
<
|
7
|
-
<
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
<div
|
13
|
-
|
14
|
-
<
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
<
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
2
|
+
<html lang="en">
|
3
|
+
|
4
|
+
<head>
|
5
|
+
<meta charset="UTF-8">
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7
|
+
<title>Welcome to Khoj</title>
|
8
|
+
</head>
|
9
|
+
|
10
|
+
<body
|
11
|
+
style="font-family: 'Arial', sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f5f5f5;">
|
12
|
+
<div
|
13
|
+
style="background-color: #ffffff; border-radius: 10px; box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); padding: 30px;">
|
14
|
+
<a href="https://khoj.dev" target="_blank"
|
15
|
+
style="display: block; text-align: center; margin-bottom: 20px; text-decoration: none;">
|
16
|
+
<img src="https://assets.khoj.dev/khoj_logo.png" alt="Khoj Logo" style="width: 120px;">
|
17
|
+
</a>
|
18
|
+
|
19
|
+
<h1
|
20
|
+
style="font-size: 24px; color: #2c3e50; margin-bottom: 20px; text-align: center; border-bottom: 2px solid #FFA07A; padding-bottom: 10px;">
|
21
|
+
Merge AI with your brain</h1>
|
22
|
+
|
23
|
+
<p style="font-size: 16px; color: #333; margin-bottom: 20px;">Hi {{name}}! We are psyched to be part of your
|
24
|
+
journey with personal AI. To better help you, we're committed to staying transparent, accessible, and
|
25
|
+
completely open-source.</p>
|
26
|
+
|
27
|
+
<a href="https://app.khoj.dev" target="_blank"
|
28
|
+
style="display: block; width: 200px; text-align: center; padding: 10px; margin: 20px auto; background-color: #FFA07A; color: #ffffff; text-decoration: none; border-radius: 5px; font-weight: bold; font-size: 16px; text-transform: uppercase;">Get
|
29
|
+
Started</a>
|
30
|
+
|
31
|
+
<p style="font-size: 16px; color: #333; margin-bottom: 20px;">You're about to get a whole lot more productive.
|
32
|
+
</p>
|
33
|
+
<a href="https://docs.khoj.dev/features/online_search"
|
34
|
+
style="color: #FFA07A; text-decoration: none; font-weight: bold; font-size: 14px;">
|
35
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 20px; margin-bottom: 20px;">
|
36
|
+
<div style="background-color: #f8f9fa; border-left: 4px solid #FFA07A; padding: 15px;">
|
37
|
+
<h3 style="color: #2c3e50; margin-top: 0; font-size: 18px;">Ditch the search bar</h3>
|
38
|
+
<p style="font-size: 14px; color: #666; margin-bottom: 0;">You don't need to click around Google
|
39
|
+
results
|
40
|
+
and sift through information yourself, because Khoj is connected to the internet.</p>
|
41
|
+
</div>
|
42
|
+
</a>
|
43
|
+
<a href="https://app.khoj.dev/agents"
|
44
|
+
style="color: #FFA07A; text-decoration: none; font-weight: bold; font-size: 14px;">
|
45
|
+
<div style="background-color: #f8f9fa; border-left: 4px solid #FFA07A; padding: 15px;">
|
46
|
+
<h3 style="color: #2c3e50; margin-top: 0; font-size: 18px;">Get a village, not just an agent</h3>
|
47
|
+
<p style="font-size: 14px; color: #666; margin-bottom: 0;">Khoj can fill the need for more specialized
|
48
|
+
assistance, such as tutoring, with its curated agents. You get a whole team, always available.</p>
|
31
49
|
</div>
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
<
|
50
|
+
</a>
|
51
|
+
<a href="https://docs.khoj.dev/category/clients"
|
52
|
+
style="color: #FFA07A; text-decoration: none; font-weight: bold; font-size: 14px;">
|
53
|
+
<div style="background-color: #f8f9fa; border-left: 4px solid #FFA07A; padding: 15px;">
|
54
|
+
<h3 style="color: #2c3e50; margin-top: 0; font-size: 18px;">Activate your data</h3>
|
55
|
+
<p style="font-size: 14px; color: #666; margin-bottom: 0;">Build on top of your digital brain. Khoj
|
56
|
+
stores whatever data you share with it, so you can get answers from your personal notes and
|
57
|
+
documents in your native language.</p>
|
37
58
|
</div>
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
<
|
59
|
+
</a>
|
60
|
+
<a href="https://blog.khoj.dev/posts/how-khoj-generates-images/"
|
61
|
+
style="color: #FFA07A; text-decoration: none; font-weight: bold; font-size: 14px;">
|
62
|
+
<div style="background-color: #f8f9fa; border-left: 4px solid #FFA07A; padding: 15px;">
|
63
|
+
<h3 style="color: #2c3e50; margin-top: 0; font-size: 18px;">Create rich, contextual images</h3>
|
64
|
+
<p style="font-size: 14px; color: #666; margin-bottom: 0;">With your shared data, Khoj can help you
|
65
|
+
create astoundingly personal images depicting scenes of what's important to you.</p>
|
43
66
|
</div>
|
44
|
-
</
|
67
|
+
</a>
|
45
68
|
</div>
|
46
|
-
</div>
|
47
|
-
<p style="color: #333; font-size: medium; margin-top: 20px; padding: 0; line-height: 1.5;">Like something? Dislike something? Searching for some other magical feature? Our inbox is always open for feedback! Reply to this email and say hi to introduce yourself 👋🏽.</p>
|
48
|
-
|
49
|
-
<p style="color: #333; font-size: large; margin-top: 20px; padding: 0; line-height: 1.5;">- The Khoj Team</p>
|
50
|
-
<table style="width: 100%; margin-top: 20px;">
|
51
|
-
<tr>
|
52
|
-
<td style="text-align: center;"><a href="https://docs.khoj.dev" target="_blank" style="padding: 8px; color: #333; background-color: #fee285; border-radius: 8px; box-shadow: 6px 6px rgba(0, 0, 0, 1.0);">Docs</a></td>
|
53
|
-
<td style="text-align: center;"><a href="https://github.com/khoj-ai/khoj" target="_blank" style="padding: 8px; color: #333; background-color: #fee285; border-radius: 8px; box-shadow: 6px 6px rgba(0, 0, 0, 1.0);">GitHub</a></td>
|
54
|
-
<td style="text-align: center;"><a href="https://twitter.com/khoj_ai" target="_blank" style="padding: 8px; color: #333; background-color: #fee285; border-radius: 8px; box-shadow: 6px 6px rgba(0, 0, 0, 1.0);">Twitter</a></td>
|
55
|
-
<td style="text-align: center;"><a href="https://www.linkedin.com/company/khoj-ai" target="_blank" style="padding: 8px; color: #333; background-color: #fee285; border-radius: 8px; box-shadow: 6px 6px rgba(0, 0, 0, 1.0);">LinkedIn</a></td>
|
56
|
-
<td style="text-align: center;"><a href="https://discord.gg/BDgyabRM6e" target="_blank" style="padding: 8px; color: #333; background-color: #fee285; border-radius: 8px; box-shadow: 6px 6px rgba(0, 0, 0, 1.0);">Discord</a></td>
|
57
|
-
</tr>
|
58
|
-
</table>
|
59
69
|
|
70
|
+
<p style="font-size: 16px; color: #333; margin-bottom: 20px;">Like something? Dislike something? Searching for
|
71
|
+
some other magical feature? Our inbox is always open for feedback! Reply to this email and say hi to
|
72
|
+
introduce yourself 👋🏽.</p>
|
73
|
+
<div style="font-size: 18px; font-weight: bold; margin-top: 30px; text-align: right;">- The Khoj Team</div>
|
74
|
+
|
75
|
+
<div style="margin-top: 30px; text-align: center;">
|
76
|
+
<a href="https://docs.khoj.dev" target="_blank"
|
77
|
+
style="display: inline-block; margin: 0 10px; padding: 8px 15px; background-color: #FFA07A; color: #ffffff; text-decoration: none; border-radius: 5px;">Docs</a>
|
78
|
+
<a href="https://github.com/khoj-ai/khoj" target="_blank"
|
79
|
+
style="display: inline-block; margin: 0 10px; padding: 8px 15px; background-color: #FFA07A; color: #ffffff; text-decoration: none; border-radius: 5px;">GitHub</a>
|
80
|
+
<a href="https://twitter.com/khoj_ai" target="_blank"
|
81
|
+
style="display: inline-block; margin: 0 10px; padding: 8px 15px; background-color: #FFA07A; color: #ffffff; text-decoration: none; border-radius: 5px;">Twitter</a>
|
82
|
+
<a href="https://www.linkedin.com/company/khoj-ai" target="_blank"
|
83
|
+
style="display: inline-block; margin: 0 10px; padding: 8px 15px; background-color: #FFA07A; color: #ffffff; text-decoration: none; border-radius: 5px;">LinkedIn</a>
|
84
|
+
<a href="https://discord.gg/BDgyabRM6e" target="_blank"
|
85
|
+
style="display: inline-block; margin: 0 10px; padding: 8px 15px; background-color: #FFA07A; color: #ffffff; text-decoration: none; border-radius: 5px;">Discord</a>
|
86
|
+
</div>
|
87
|
+
</div>
|
60
88
|
</body>
|
89
|
+
|
61
90
|
</html>
|
khoj/main.py
CHANGED
@@ -131,7 +131,7 @@ def run(should_start_server=True):
|
|
131
131
|
logger.info(f"📦 Initializing DB:\n{db_migrate_output.getvalue().strip()}")
|
132
132
|
logger.debug(f"🌍 Initializing Web Client:\n{collectstatic_output.getvalue().strip()}")
|
133
133
|
|
134
|
-
initialization()
|
134
|
+
initialization(not args.non_interactive)
|
135
135
|
|
136
136
|
# Create app directory, if it doesn't exist
|
137
137
|
state.config_file.parent.mkdir(parents=True, exist_ok=True)
|
@@ -4,8 +4,6 @@ import os
|
|
4
4
|
from datetime import datetime
|
5
5
|
from typing import Dict, List, Tuple
|
6
6
|
|
7
|
-
from rapidocr_onnxruntime import RapidOCR
|
8
|
-
|
9
7
|
from khoj.database.models import Entry as DbEntry
|
10
8
|
from khoj.database.models import KhojUser
|
11
9
|
from khoj.processor.content.text_to_entries import TextToEntries
|
@@ -58,7 +56,6 @@ class ImageToEntries(TextToEntries):
|
|
58
56
|
entry_to_location_map: List[Tuple[str, str]] = []
|
59
57
|
for image_file in image_files:
|
60
58
|
try:
|
61
|
-
loader = RapidOCR()
|
62
59
|
bytes = image_files[image_file]
|
63
60
|
# write the image to a temporary file
|
64
61
|
timestamp_now = datetime.utcnow().timestamp()
|
@@ -71,13 +68,18 @@ class ImageToEntries(TextToEntries):
|
|
71
68
|
bytes = image_files[image_file]
|
72
69
|
f.write(bytes)
|
73
70
|
try:
|
71
|
+
from rapidocr_onnxruntime import RapidOCR
|
72
|
+
|
73
|
+
loader = RapidOCR()
|
74
74
|
image_entries_per_file = ""
|
75
75
|
result, _ = loader(tmp_file)
|
76
76
|
if result:
|
77
77
|
expanded_entries = [text[1] for text in result]
|
78
78
|
image_entries_per_file = " ".join(expanded_entries)
|
79
79
|
except ImportError:
|
80
|
-
logger.warning(
|
80
|
+
logger.warning(
|
81
|
+
f"Unable to process image or scanned file for text: {image_file}. This file will not be indexed."
|
82
|
+
)
|
81
83
|
continue
|
82
84
|
entry_to_location_map.append((image_entries_per_file, image_file))
|
83
85
|
entries.extend([image_entries_per_file])
|
@@ -18,13 +18,20 @@ from khoj.utils.helpers import is_none_or_empty, merge_dicts
|
|
18
18
|
|
19
19
|
logger = logging.getLogger(__name__)
|
20
20
|
model_to_prompt_size = {
|
21
|
+
# OpenAI Models
|
21
22
|
"gpt-3.5-turbo": 12000,
|
22
|
-
"gpt-3.5-turbo-0125": 12000,
|
23
|
-
"gpt-4-0125-preview": 20000,
|
24
23
|
"gpt-4-turbo-preview": 20000,
|
24
|
+
"gpt-4o": 20000,
|
25
25
|
"gpt-4o-mini": 20000,
|
26
26
|
"o1-preview": 20000,
|
27
27
|
"o1-mini": 20000,
|
28
|
+
# Google Models
|
29
|
+
"gemini-1.5-flash": 20000,
|
30
|
+
"gemini-1.5-pro": 20000,
|
31
|
+
# Anthropic Models
|
32
|
+
"claude-3-5-sonnet-20240620": 20000,
|
33
|
+
"claude-3-opus-20240229": 20000,
|
34
|
+
# Offline Models
|
28
35
|
"TheBloke/Mistral-7B-Instruct-v0.2-GGUF": 3500,
|
29
36
|
"NousResearch/Hermes-2-Pro-Mistral-7B-GGUF": 3500,
|
30
37
|
"bartowski/Meta-Llama-3.1-8B-Instruct-GGUF": 20000,
|
@@ -100,7 +107,7 @@ def save_to_conversation_log(
|
|
100
107
|
inferred_queries: List[str] = [],
|
101
108
|
intent_type: str = "remember",
|
102
109
|
client_application: ClientApplication = None,
|
103
|
-
conversation_id:
|
110
|
+
conversation_id: str = None,
|
104
111
|
automation_id: str = None,
|
105
112
|
uploaded_image_url: str = None,
|
106
113
|
):
|
@@ -163,7 +170,7 @@ def generate_chatml_messages_with_context(
|
|
163
170
|
if loaded_model:
|
164
171
|
max_prompt_size = infer_max_tokens(loaded_model.n_ctx(), model_to_prompt_size.get(model_name, math.inf))
|
165
172
|
else:
|
166
|
-
max_prompt_size = model_to_prompt_size.get(model_name,
|
173
|
+
max_prompt_size = model_to_prompt_size.get(model_name, 10000)
|
167
174
|
|
168
175
|
# Scale lookback turns proportional to max prompt size supported by model
|
169
176
|
lookback_turns = max_prompt_size // 750
|
@@ -291,8 +298,6 @@ def reciprocal_conversation_to_chatml(message_pair):
|
|
291
298
|
return [ChatMessage(content=message, role=role) for message, role in zip(message_pair, ["user", "assistant"])]
|
292
299
|
|
293
300
|
|
294
|
-
def remove_json_codeblock(response):
|
301
|
+
def remove_json_codeblock(response: str):
|
295
302
|
"""Remove any markdown json codeblock formatting if present. Useful for non schema enforceable models"""
|
296
|
-
|
297
|
-
response = response[7:-3]
|
298
|
-
return response
|
303
|
+
return response.removeprefix("```json").removesuffix("```")
|
khoj/routers/api.py
CHANGED
@@ -328,7 +328,7 @@ async def extract_references_and_questions(
|
|
328
328
|
q: str,
|
329
329
|
n: int,
|
330
330
|
d: float,
|
331
|
-
conversation_id:
|
331
|
+
conversation_id: str,
|
332
332
|
conversation_commands: List[ConversationCommand] = [ConversationCommand.Default],
|
333
333
|
location_data: LocationData = None,
|
334
334
|
send_status_func: Optional[Callable] = None,
|
khoj/routers/api_chat.py
CHANGED
@@ -77,9 +77,7 @@ from khoj.routers.email import send_query_feedback
|
|
77
77
|
@api_chat.get("/conversation/file-filters/{conversation_id}", response_class=Response)
|
78
78
|
@requires(["authenticated"])
|
79
79
|
def get_file_filter(request: Request, conversation_id: str) -> Response:
|
80
|
-
conversation = ConversationAdapters.get_conversation_by_user(
|
81
|
-
request.user.object, conversation_id=int(conversation_id)
|
82
|
-
)
|
80
|
+
conversation = ConversationAdapters.get_conversation_by_user(request.user.object, conversation_id=conversation_id)
|
83
81
|
if not conversation:
|
84
82
|
return Response(content=json.dumps({"status": "error", "message": "Conversation not found"}), status_code=404)
|
85
83
|
|
@@ -95,7 +93,7 @@ def get_file_filter(request: Request, conversation_id: str) -> Response:
|
|
95
93
|
@api_chat.delete("/conversation/file-filters/bulk", response_class=Response)
|
96
94
|
@requires(["authenticated"])
|
97
95
|
def remove_files_filter(request: Request, filter: FilesFilterRequest) -> Response:
|
98
|
-
conversation_id =
|
96
|
+
conversation_id = filter.conversation_id
|
99
97
|
files_filter = filter.filenames
|
100
98
|
file_filters = ConversationAdapters.remove_files_from_filter(request.user.object, conversation_id, files_filter)
|
101
99
|
return Response(content=json.dumps(file_filters), media_type="application/json", status_code=200)
|
@@ -105,7 +103,7 @@ def remove_files_filter(request: Request, filter: FilesFilterRequest) -> Respons
|
|
105
103
|
@requires(["authenticated"])
|
106
104
|
def add_files_filter(request: Request, filter: FilesFilterRequest):
|
107
105
|
try:
|
108
|
-
conversation_id =
|
106
|
+
conversation_id = filter.conversation_id
|
109
107
|
files_filter = filter.filenames
|
110
108
|
file_filters = ConversationAdapters.add_files_to_filter(request.user.object, conversation_id, files_filter)
|
111
109
|
return Response(content=json.dumps(file_filters), media_type="application/json", status_code=200)
|
@@ -118,7 +116,7 @@ def add_files_filter(request: Request, filter: FilesFilterRequest):
|
|
118
116
|
@requires(["authenticated"])
|
119
117
|
def add_file_filter(request: Request, filter: FileFilterRequest):
|
120
118
|
try:
|
121
|
-
conversation_id =
|
119
|
+
conversation_id = filter.conversation_id
|
122
120
|
files_filter = [filter.filename]
|
123
121
|
file_filters = ConversationAdapters.add_files_to_filter(request.user.object, conversation_id, files_filter)
|
124
122
|
return Response(content=json.dumps(file_filters), media_type="application/json", status_code=200)
|
@@ -130,7 +128,7 @@ def add_file_filter(request: Request, filter: FileFilterRequest):
|
|
130
128
|
@api_chat.delete("/conversation/file-filters", response_class=Response)
|
131
129
|
@requires(["authenticated"])
|
132
130
|
def remove_file_filter(request: Request, filter: FileFilterRequest) -> Response:
|
133
|
-
conversation_id =
|
131
|
+
conversation_id = filter.conversation_id
|
134
132
|
files_filter = [filter.filename]
|
135
133
|
file_filters = ConversationAdapters.remove_files_from_filter(request.user.object, conversation_id, files_filter)
|
136
134
|
return Response(content=json.dumps(file_filters), media_type="application/json", status_code=200)
|
@@ -189,7 +187,7 @@ async def chat_starters(
|
|
189
187
|
def chat_history(
|
190
188
|
request: Request,
|
191
189
|
common: CommonQueryParams,
|
192
|
-
conversation_id: Optional[
|
190
|
+
conversation_id: Optional[str] = None,
|
193
191
|
n: Optional[int] = None,
|
194
192
|
):
|
195
193
|
user = request.user.object
|
@@ -312,7 +310,7 @@ def get_shared_chat(
|
|
312
310
|
async def clear_chat_history(
|
313
311
|
request: Request,
|
314
312
|
common: CommonQueryParams,
|
315
|
-
conversation_id: Optional[
|
313
|
+
conversation_id: Optional[str] = None,
|
316
314
|
):
|
317
315
|
user = request.user.object
|
318
316
|
|
@@ -375,7 +373,7 @@ def fork_public_conversation(
|
|
375
373
|
def duplicate_chat_history_public_conversation(
|
376
374
|
request: Request,
|
377
375
|
common: CommonQueryParams,
|
378
|
-
conversation_id:
|
376
|
+
conversation_id: str,
|
379
377
|
):
|
380
378
|
user = request.user.object
|
381
379
|
domain = request.headers.get("host")
|
@@ -423,7 +421,7 @@ def chat_sessions(
|
|
423
421
|
|
424
422
|
session_values = [
|
425
423
|
{
|
426
|
-
"conversation_id": session[0],
|
424
|
+
"conversation_id": str(session[0]),
|
427
425
|
"slug": session[2] or session[1],
|
428
426
|
"agent_name": session[4],
|
429
427
|
"agent_avatar": session[5],
|
@@ -455,7 +453,7 @@ async def create_chat_session(
|
|
455
453
|
# Create new Conversation Session
|
456
454
|
conversation = await ConversationAdapters.acreate_conversation_session(user, request.user.client_app, agent_slug)
|
457
455
|
|
458
|
-
response = {"conversation_id": conversation.id}
|
456
|
+
response = {"conversation_id": str(conversation.id)}
|
459
457
|
|
460
458
|
conversation_metadata = {
|
461
459
|
"agent": agent_slug,
|
@@ -497,7 +495,7 @@ async def set_conversation_title(
|
|
497
495
|
request: Request,
|
498
496
|
common: CommonQueryParams,
|
499
497
|
title: str,
|
500
|
-
conversation_id: Optional[
|
498
|
+
conversation_id: Optional[str] = None,
|
501
499
|
) -> Response:
|
502
500
|
user = request.user.object
|
503
501
|
title = title.strip()[:200]
|
@@ -527,7 +525,7 @@ class ChatRequestBody(BaseModel):
|
|
527
525
|
d: Optional[float] = None
|
528
526
|
stream: Optional[bool] = False
|
529
527
|
title: Optional[str] = None
|
530
|
-
conversation_id: Optional[
|
528
|
+
conversation_id: Optional[str] = None
|
531
529
|
city: Optional[str] = None
|
532
530
|
region: Optional[str] = None
|
533
531
|
country: Optional[str] = None
|
@@ -1016,7 +1014,7 @@ async def get_chat(
|
|
1016
1014
|
d: float = None,
|
1017
1015
|
stream: Optional[bool] = False,
|
1018
1016
|
title: Optional[str] = None,
|
1019
|
-
conversation_id: Optional[
|
1017
|
+
conversation_id: Optional[str] = None,
|
1020
1018
|
city: Optional[str] = None,
|
1021
1019
|
region: Optional[str] = None,
|
1022
1020
|
country: Optional[str] = None,
|
khoj/routers/helpers.py
CHANGED
@@ -21,7 +21,7 @@ from typing import (
|
|
21
21
|
Tuple,
|
22
22
|
Union,
|
23
23
|
)
|
24
|
-
from urllib.parse import parse_qs, urljoin, urlparse
|
24
|
+
from urllib.parse import parse_qs, quote, urljoin, urlparse
|
25
25
|
|
26
26
|
import cron_descriptor
|
27
27
|
import pytz
|
@@ -632,6 +632,7 @@ async def send_message_to_model_wrapper(
|
|
632
632
|
messages=truncated_messages,
|
633
633
|
loaded_model=loaded_model,
|
634
634
|
model=chat_model,
|
635
|
+
max_prompt_size=max_tokens,
|
635
636
|
streaming=False,
|
636
637
|
response_type=response_type,
|
637
638
|
)
|
@@ -721,6 +722,7 @@ def send_message_to_model_wrapper_sync(
|
|
721
722
|
system_message=system_message,
|
722
723
|
model_name=chat_model,
|
723
724
|
loaded_model=loaded_model,
|
725
|
+
max_prompt_size=max_tokens,
|
724
726
|
vision_enabled=vision_available,
|
725
727
|
model_type=conversation_config.model_type,
|
726
728
|
)
|
@@ -729,6 +731,7 @@ def send_message_to_model_wrapper_sync(
|
|
729
731
|
messages=truncated_messages,
|
730
732
|
loaded_model=loaded_model,
|
731
733
|
model=chat_model,
|
734
|
+
max_prompt_size=max_tokens,
|
732
735
|
streaming=False,
|
733
736
|
response_type=response_type,
|
734
737
|
)
|
@@ -739,6 +742,7 @@ def send_message_to_model_wrapper_sync(
|
|
739
742
|
user_message=message,
|
740
743
|
system_message=system_message,
|
741
744
|
model_name=chat_model,
|
745
|
+
max_prompt_size=max_tokens,
|
742
746
|
vision_enabled=vision_available,
|
743
747
|
model_type=conversation_config.model_type,
|
744
748
|
)
|
@@ -795,7 +799,7 @@ def generate_chat_response(
|
|
795
799
|
conversation_commands: List[ConversationCommand] = [ConversationCommand.Default],
|
796
800
|
user: KhojUser = None,
|
797
801
|
client_application: ClientApplication = None,
|
798
|
-
conversation_id:
|
802
|
+
conversation_id: str = None,
|
799
803
|
location_data: LocationData = None,
|
800
804
|
user_name: Optional[str] = None,
|
801
805
|
uploaded_image_url: Optional[str] = None,
|
@@ -1098,7 +1102,7 @@ def scheduled_chat(
|
|
1098
1102
|
user: KhojUser,
|
1099
1103
|
calling_url: URL,
|
1100
1104
|
job_id: str = None,
|
1101
|
-
conversation_id:
|
1105
|
+
conversation_id: str = None,
|
1102
1106
|
):
|
1103
1107
|
logger.info(f"Processing scheduled_chat: {query_to_run}")
|
1104
1108
|
if job_id:
|
@@ -1127,7 +1131,8 @@ def scheduled_chat(
|
|
1127
1131
|
|
1128
1132
|
# Replace the original conversation_id with the conversation_id
|
1129
1133
|
if conversation_id:
|
1130
|
-
|
1134
|
+
# encode the conversation_id to avoid any issues with special characters
|
1135
|
+
query_dict["conversation_id"] = [quote(conversation_id)]
|
1131
1136
|
|
1132
1137
|
# Restructure the original query_dict into a valid JSON payload for the chat API
|
1133
1138
|
json_payload = {key: values[0] for key, values in query_dict.items()}
|
@@ -1181,7 +1186,7 @@ def scheduled_chat(
|
|
1181
1186
|
|
1182
1187
|
|
1183
1188
|
async def create_automation(
|
1184
|
-
q: str, timezone: str, user: KhojUser, calling_url: URL, meta_log: dict = {}, conversation_id:
|
1189
|
+
q: str, timezone: str, user: KhojUser, calling_url: URL, meta_log: dict = {}, conversation_id: str = None
|
1185
1190
|
):
|
1186
1191
|
crontime, query_to_run, subject = await schedule_query(q, meta_log)
|
1187
1192
|
job = await schedule_automation(query_to_run, subject, crontime, timezone, q, user, calling_url, conversation_id)
|
@@ -1196,7 +1201,7 @@ async def schedule_automation(
|
|
1196
1201
|
scheduling_request: str,
|
1197
1202
|
user: KhojUser,
|
1198
1203
|
calling_url: URL,
|
1199
|
-
conversation_id:
|
1204
|
+
conversation_id: str,
|
1200
1205
|
):
|
1201
1206
|
# Disable minute level automation recurrence
|
1202
1207
|
minute_value = crontime.split(" ")[0]
|
@@ -1214,7 +1219,7 @@ async def schedule_automation(
|
|
1214
1219
|
"scheduling_request": scheduling_request,
|
1215
1220
|
"subject": subject,
|
1216
1221
|
"crontime": crontime,
|
1217
|
-
"conversation_id": conversation_id,
|
1222
|
+
"conversation_id": str(conversation_id),
|
1218
1223
|
}
|
1219
1224
|
)
|
1220
1225
|
query_id = hashlib.md5(f"{query_to_run}_{crontime}".encode("utf-8")).hexdigest()
|
khoj/utils/cli.py
CHANGED
@@ -50,6 +50,12 @@ def cli(args=None):
|
|
50
50
|
default=False,
|
51
51
|
help="Run Khoj in anonymous mode. This does not require any login for connecting users.",
|
52
52
|
)
|
53
|
+
parser.add_argument(
|
54
|
+
"--non-interactive",
|
55
|
+
action="store_true",
|
56
|
+
default=False,
|
57
|
+
help="Start Khoj in non-interactive mode. Assumes interactive shell unavailable for config. E.g when run via Docker.",
|
58
|
+
)
|
53
59
|
|
54
60
|
args, remaining_args = parser.parse_known_args(args)
|
55
61
|
|
khoj/utils/constants.py
CHANGED
@@ -8,8 +8,15 @@ empty_escape_sequences = "\n|\r|\t| "
|
|
8
8
|
app_env_filepath = "~/.khoj/env"
|
9
9
|
telemetry_server = "https://khoj.beta.haletic.com/v1/telemetry"
|
10
10
|
content_directory = "~/.khoj/content/"
|
11
|
-
|
12
|
-
|
11
|
+
default_offline_chat_models = [
|
12
|
+
"bartowski/Meta-Llama-3.1-8B-Instruct-GGUF",
|
13
|
+
"bartowski/gemma-2-9b-it-GGUF",
|
14
|
+
"bartowski/gemma-2-2b-it-GGUF",
|
15
|
+
"bartowski/Phi-3.5-mini-instruct-GGUF",
|
16
|
+
]
|
17
|
+
default_openai_chat_models = ["gpt-4o-mini", "gpt-4o"]
|
18
|
+
default_gemini_chat_models = ["gemini-1.5-flash", "gemini-1.5-pro"]
|
19
|
+
default_anthropic_chat_models = ["claude-3-5-sonnet-20240620", "claude-3-opus-20240229"]
|
13
20
|
|
14
21
|
empty_config = {
|
15
22
|
"search-type": {
|