khoj 1.17.0__py3-none-any.whl → 1.17.1.dev217__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/configure.py +6 -6
- khoj/database/adapters/__init__.py +47 -2
- khoj/database/migrations/0053_agent_style_color_agent_style_icon.py +61 -0
- khoj/database/models/__init__.py +35 -0
- khoj/interface/web/assets/icons/favicon-128x128.png +0 -0
- khoj/interface/web/assets/icons/favicon-256x256.png +0 -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 +31 -5384
- khoj/interface/web/assets/icons/khoj.svg +26 -0
- khoj/interface/web/chat.html +5 -5
- khoj/interface/web/content_source_computer_input.html +3 -3
- khoj/interface/web/content_source_github_input.html +1 -1
- khoj/interface/web/content_source_notion_input.html +1 -1
- khoj/interface/web/public_conversation.html +1 -1
- khoj/interface/web/search.html +2 -2
- khoj/interface/web/{config.html → settings.html} +30 -30
- khoj/interface/web/utils.html +1 -1
- khoj/processor/content/docx/docx_to_entries.py +4 -9
- khoj/processor/content/github/github_to_entries.py +1 -3
- khoj/processor/content/images/image_to_entries.py +4 -9
- khoj/processor/content/markdown/markdown_to_entries.py +4 -9
- khoj/processor/content/notion/notion_to_entries.py +1 -3
- khoj/processor/content/org_mode/org_to_entries.py +4 -9
- khoj/processor/content/pdf/pdf_to_entries.py +4 -9
- khoj/processor/content/plaintext/plaintext_to_entries.py +4 -9
- khoj/processor/content/text_to_entries.py +1 -3
- khoj/processor/tools/online_search.py +4 -4
- khoj/routers/api.py +49 -4
- khoj/routers/api_agents.py +3 -1
- khoj/routers/api_chat.py +80 -88
- khoj/routers/api_content.py +538 -0
- khoj/routers/api_model.py +156 -0
- khoj/routers/helpers.py +308 -7
- khoj/routers/notion.py +2 -8
- khoj/routers/web_client.py +43 -256
- khoj/search_type/text_search.py +5 -4
- khoj/utils/fs_syncer.py +3 -1
- khoj/utils/rawconfig.py +6 -1
- {khoj-1.17.0.dist-info → khoj-1.17.1.dev217.dist-info}/METADATA +2 -2
- {khoj-1.17.0.dist-info → khoj-1.17.1.dev217.dist-info}/RECORD +44 -42
- khoj/routers/api_config.py +0 -434
- khoj/routers/indexer.py +0 -349
- {khoj-1.17.0.dist-info → khoj-1.17.1.dev217.dist-info}/WHEEL +0 -0
- {khoj-1.17.0.dist-info → khoj-1.17.1.dev217.dist-info}/entry_points.txt +0 -0
- {khoj-1.17.0.dist-info → khoj-1.17.1.dev217.dist-info}/licenses/LICENSE +0 -0
khoj/configure.py
CHANGED
|
@@ -42,7 +42,7 @@ from khoj.database.adapters import (
|
|
|
42
42
|
)
|
|
43
43
|
from khoj.database.models import ClientApplication, KhojUser, ProcessLock, Subscription
|
|
44
44
|
from khoj.processor.embeddings import CrossEncoderModel, EmbeddingsModel
|
|
45
|
-
from khoj.routers.
|
|
45
|
+
from khoj.routers.api_content import configure_content, configure_search
|
|
46
46
|
from khoj.routers.twilio import is_twilio_enabled
|
|
47
47
|
from khoj.utils import constants, state
|
|
48
48
|
from khoj.utils.config import SearchType
|
|
@@ -308,16 +308,16 @@ def configure_routes(app):
|
|
|
308
308
|
from khoj.routers.api import api
|
|
309
309
|
from khoj.routers.api_agents import api_agents
|
|
310
310
|
from khoj.routers.api_chat import api_chat
|
|
311
|
-
from khoj.routers.
|
|
312
|
-
from khoj.routers.
|
|
311
|
+
from khoj.routers.api_content import api_content
|
|
312
|
+
from khoj.routers.api_model import api_model
|
|
313
313
|
from khoj.routers.notion import notion_router
|
|
314
314
|
from khoj.routers.web_client import web_client
|
|
315
315
|
|
|
316
316
|
app.include_router(api, prefix="/api")
|
|
317
317
|
app.include_router(api_chat, prefix="/api/chat")
|
|
318
318
|
app.include_router(api_agents, prefix="/api/agents")
|
|
319
|
-
app.include_router(
|
|
320
|
-
app.include_router(
|
|
319
|
+
app.include_router(api_model, prefix="/api/model")
|
|
320
|
+
app.include_router(api_content, prefix="/api/content")
|
|
321
321
|
app.include_router(notion_router, prefix="/api/notion")
|
|
322
322
|
app.include_router(web_client)
|
|
323
323
|
|
|
@@ -336,7 +336,7 @@ def configure_routes(app):
|
|
|
336
336
|
if is_twilio_enabled():
|
|
337
337
|
from khoj.routers.api_phone import api_phone
|
|
338
338
|
|
|
339
|
-
app.include_router(api_phone, prefix="/api/
|
|
339
|
+
app.include_router(api_phone, prefix="/api/phone")
|
|
340
340
|
logger.info("📞 Enabled Twilio")
|
|
341
341
|
|
|
342
342
|
|
|
@@ -645,7 +645,11 @@ class ConversationAdapters:
|
|
|
645
645
|
|
|
646
646
|
@staticmethod
|
|
647
647
|
def get_conversation_sessions(user: KhojUser, client_application: ClientApplication = None):
|
|
648
|
-
return
|
|
648
|
+
return (
|
|
649
|
+
Conversation.objects.filter(user=user, client=client_application)
|
|
650
|
+
.prefetch_related("agent")
|
|
651
|
+
.order_by("-updated_at")
|
|
652
|
+
)
|
|
649
653
|
|
|
650
654
|
@staticmethod
|
|
651
655
|
async def aset_conversation_title(
|
|
@@ -798,11 +802,14 @@ class ConversationAdapters:
|
|
|
798
802
|
def create_conversation_from_public_conversation(
|
|
799
803
|
user: KhojUser, public_conversation: PublicConversation, client_app: ClientApplication
|
|
800
804
|
):
|
|
805
|
+
scrubbed_title = public_conversation.title if public_conversation.title else public_conversation.slug
|
|
806
|
+
if scrubbed_title:
|
|
807
|
+
scrubbed_title = scrubbed_title.replace("-", " ")
|
|
801
808
|
return Conversation.objects.create(
|
|
802
809
|
user=user,
|
|
803
810
|
conversation_log=public_conversation.conversation_log,
|
|
804
811
|
client=client_app,
|
|
805
|
-
slug=
|
|
812
|
+
slug=scrubbed_title,
|
|
806
813
|
title=public_conversation.title,
|
|
807
814
|
agent=public_conversation.agent,
|
|
808
815
|
)
|
|
@@ -943,6 +950,34 @@ class ConversationAdapters:
|
|
|
943
950
|
)
|
|
944
951
|
return new_config
|
|
945
952
|
|
|
953
|
+
@staticmethod
|
|
954
|
+
def add_files_to_filter(user: KhojUser, conversation_id: int, files: List[str]):
|
|
955
|
+
conversation = ConversationAdapters.get_conversation_by_user(user, conversation_id=conversation_id)
|
|
956
|
+
file_list = EntryAdapters.get_all_filenames_by_source(user, "computer")
|
|
957
|
+
for filename in files:
|
|
958
|
+
if filename in file_list and filename not in conversation.file_filters:
|
|
959
|
+
conversation.file_filters.append(filename)
|
|
960
|
+
conversation.save()
|
|
961
|
+
|
|
962
|
+
# remove files from conversation.file_filters that are not in file_list
|
|
963
|
+
conversation.file_filters = [file for file in conversation.file_filters if file in file_list]
|
|
964
|
+
conversation.save()
|
|
965
|
+
return conversation.file_filters
|
|
966
|
+
|
|
967
|
+
@staticmethod
|
|
968
|
+
def remove_files_from_filter(user: KhojUser, conversation_id: int, files: List[str]):
|
|
969
|
+
conversation = ConversationAdapters.get_conversation_by_user(user, conversation_id=conversation_id)
|
|
970
|
+
for filename in files:
|
|
971
|
+
if filename in conversation.file_filters:
|
|
972
|
+
conversation.file_filters.remove(filename)
|
|
973
|
+
conversation.save()
|
|
974
|
+
|
|
975
|
+
# remove files from conversation.file_filters that are not in file_list
|
|
976
|
+
file_list = EntryAdapters.get_all_filenames_by_source(user, "computer")
|
|
977
|
+
conversation.file_filters = [file for file in conversation.file_filters if file in file_list]
|
|
978
|
+
conversation.save()
|
|
979
|
+
return conversation.file_filters
|
|
980
|
+
|
|
946
981
|
|
|
947
982
|
class FileObjectAdapters:
|
|
948
983
|
@staticmethod
|
|
@@ -1071,6 +1106,16 @@ class EntryAdapters:
|
|
|
1071
1106
|
async def adelete_entry_by_file(user: KhojUser, file_path: str):
|
|
1072
1107
|
return await Entry.objects.filter(user=user, file_path=file_path).adelete()
|
|
1073
1108
|
|
|
1109
|
+
@staticmethod
|
|
1110
|
+
async def adelete_entries_by_filenames(user: KhojUser, filenames: List[str], batch_size=1000):
|
|
1111
|
+
deleted_count = 0
|
|
1112
|
+
for i in range(0, len(filenames), batch_size):
|
|
1113
|
+
batch = filenames[i : i + batch_size]
|
|
1114
|
+
count, _ = await Entry.objects.filter(user=user, file_path__in=batch).adelete()
|
|
1115
|
+
deleted_count += count
|
|
1116
|
+
|
|
1117
|
+
return deleted_count
|
|
1118
|
+
|
|
1074
1119
|
@staticmethod
|
|
1075
1120
|
def get_all_filenames_by_source(user: KhojUser, file_source: str):
|
|
1076
1121
|
return (
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Generated by Django 5.0.6 on 2024-07-13 16:26
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
dependencies = [
|
|
8
|
+
("database", "0052_alter_searchmodelconfig_bi_encoder_docs_encode_config_and_more"),
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
operations = [
|
|
12
|
+
migrations.AddField(
|
|
13
|
+
model_name="agent",
|
|
14
|
+
name="style_color",
|
|
15
|
+
field=models.CharField(
|
|
16
|
+
choices=[
|
|
17
|
+
("blue", "Blue"),
|
|
18
|
+
("green", "Green"),
|
|
19
|
+
("red", "Red"),
|
|
20
|
+
("yellow", "Yellow"),
|
|
21
|
+
("orange", "Orange"),
|
|
22
|
+
("purple", "Purple"),
|
|
23
|
+
("pink", "Pink"),
|
|
24
|
+
("teal", "Teal"),
|
|
25
|
+
("cyan", "Cyan"),
|
|
26
|
+
("lime", "Lime"),
|
|
27
|
+
("indigo", "Indigo"),
|
|
28
|
+
("fuschia", "Fuschia"),
|
|
29
|
+
("rose", "Rose"),
|
|
30
|
+
("sky", "Sky"),
|
|
31
|
+
("amber", "Amber"),
|
|
32
|
+
("emerald", "Emerald"),
|
|
33
|
+
],
|
|
34
|
+
default="blue",
|
|
35
|
+
max_length=200,
|
|
36
|
+
),
|
|
37
|
+
),
|
|
38
|
+
migrations.AddField(
|
|
39
|
+
model_name="agent",
|
|
40
|
+
name="style_icon",
|
|
41
|
+
field=models.CharField(
|
|
42
|
+
choices=[
|
|
43
|
+
("Lightbulb", "Lighbulb"),
|
|
44
|
+
("Health", "Health"),
|
|
45
|
+
("Robot", "Robot"),
|
|
46
|
+
("Aperture", "Aperture"),
|
|
47
|
+
("GraduationCap", "Graduation Cap"),
|
|
48
|
+
("Jeep", "Jeep"),
|
|
49
|
+
("Island", "Island"),
|
|
50
|
+
("MathOperations", "Math Operations"),
|
|
51
|
+
("Asclepius", "Asclepius"),
|
|
52
|
+
("Couch", "Couch"),
|
|
53
|
+
("Code", "Code"),
|
|
54
|
+
("Atom", "Atom"),
|
|
55
|
+
("ClockCounterClockwise", "Clock Counter Clockwise"),
|
|
56
|
+
],
|
|
57
|
+
default="Lightbulb",
|
|
58
|
+
max_length=200,
|
|
59
|
+
),
|
|
60
|
+
),
|
|
61
|
+
]
|
khoj/database/models/__init__.py
CHANGED
|
@@ -103,6 +103,39 @@ class VoiceModelOption(BaseModel):
|
|
|
103
103
|
|
|
104
104
|
|
|
105
105
|
class Agent(BaseModel):
|
|
106
|
+
class StyleColorTypes(models.TextChoices):
|
|
107
|
+
BLUE = "blue"
|
|
108
|
+
GREEN = "green"
|
|
109
|
+
RED = "red"
|
|
110
|
+
YELLOW = "yellow"
|
|
111
|
+
ORANGE = "orange"
|
|
112
|
+
PURPLE = "purple"
|
|
113
|
+
PINK = "pink"
|
|
114
|
+
TEAL = "teal"
|
|
115
|
+
CYAN = "cyan"
|
|
116
|
+
LIME = "lime"
|
|
117
|
+
INDIGO = "indigo"
|
|
118
|
+
FUSCHIA = "fuschia"
|
|
119
|
+
ROSE = "rose"
|
|
120
|
+
SKY = "sky"
|
|
121
|
+
AMBER = "amber"
|
|
122
|
+
EMERALD = "emerald"
|
|
123
|
+
|
|
124
|
+
class StyleIconTypes(models.TextChoices):
|
|
125
|
+
LIGHBULB = "Lightbulb"
|
|
126
|
+
HEALTH = "Health"
|
|
127
|
+
ROBOT = "Robot"
|
|
128
|
+
APERTURE = "Aperture"
|
|
129
|
+
GRADUATION_CAP = "GraduationCap"
|
|
130
|
+
JEEP = "Jeep"
|
|
131
|
+
ISLAND = "Island"
|
|
132
|
+
MATH_OPERATIONS = "MathOperations"
|
|
133
|
+
ASCLEPIUS = "Asclepius"
|
|
134
|
+
COUCH = "Couch"
|
|
135
|
+
CODE = "Code"
|
|
136
|
+
ATOM = "Atom"
|
|
137
|
+
CLOCK_COUNTER_CLOCKWISE = "ClockCounterClockwise"
|
|
138
|
+
|
|
106
139
|
creator = models.ForeignKey(
|
|
107
140
|
KhojUser, on_delete=models.CASCADE, default=None, null=True, blank=True
|
|
108
141
|
) # Creator will only be null when the agents are managed by admin
|
|
@@ -114,6 +147,8 @@ class Agent(BaseModel):
|
|
|
114
147
|
managed_by_admin = models.BooleanField(default=False)
|
|
115
148
|
chat_model = models.ForeignKey(ChatModelOptions, on_delete=models.CASCADE)
|
|
116
149
|
slug = models.CharField(max_length=200)
|
|
150
|
+
style_color = models.CharField(max_length=200, choices=StyleColorTypes.choices, default=StyleColorTypes.BLUE)
|
|
151
|
+
style_icon = models.CharField(max_length=200, choices=StyleIconTypes.choices, default=StyleIconTypes.LIGHBULB)
|
|
117
152
|
|
|
118
153
|
|
|
119
154
|
class ProcessLock(BaseModel):
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|