khoj 1.30.11.dev13__py3-none-any.whl → 1.30.11.dev56__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 +21 -0
- khoj/configure.py +3 -3
- khoj/database/adapters/__init__.py +15 -15
- khoj/database/admin.py +50 -40
- 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/models/__init__.py +171 -42
- khoj/interface/compiled/404/index.html +1 -1
- khoj/interface/compiled/_next/static/chunks/1603-e40aadd1e56ab030.js +1 -0
- khoj/interface/compiled/_next/static/chunks/5538-0ea2d3944ca051e1.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/agents/layout-1878cc328ea380bd.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/agents/{page-8eead7920b0ff92a.js → page-f5c0801b27a8e95e.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/automations/layout-7f1b79a2c67af0b4.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/automations/{page-b5800b5286306140.js → page-8691f6c09a0acd44.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/chat/layout-9219a85f3477e722.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/chat/{page-d7d2ab93e519f0b2.js → page-135d56dd4263e40d.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/layout-6310c57b674dd6f5.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/{page-3c32ad5472f75965.js → page-e79ace822d51557b.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/search/{page-faa998c71eb7ca8e.js → page-e8b578d155550386.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/settings/layout-f285795bc3154b8c.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/settings/{page-cbe7f56b1f87d77a.js → page-b6c835050c970be7.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/share/chat/layout-6f4879fbbf8b90f7.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/share/chat/{page-cd5757199539bbf2.js → page-635635e4fb39fe29.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/{webpack-3a2dfd74acf6e193.js → webpack-5203c3872078c10c.js} +1 -1
- khoj/interface/compiled/_next/static/css/{bedf49fbfc598358.css → 089de1d8526b96e9.css} +1 -1
- khoj/interface/compiled/_next/static/css/4cae6c0e5c72fb2d.css +1 -0
- khoj/interface/compiled/_next/static/css/edd3abaf11580924.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/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/agents/index.html +1 -1
- khoj/interface/compiled/agents/index.txt +2 -2
- khoj/interface/compiled/assets/icons/khoj_lantern.svg +100 -0
- khoj/interface/compiled/assets/icons/khoj_lantern_128x128_dark.png +0 -0
- khoj/interface/compiled/automations/index.html +1 -1
- khoj/interface/compiled/automations/index.txt +3 -3
- khoj/interface/compiled/chat/index.html +1 -1
- khoj/interface/compiled/chat/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 +5 -4
- khoj/interface/compiled/share/chat/index.html +1 -1
- khoj/interface/compiled/share/chat/index.txt +2 -2
- khoj/migrations/migrate_server_pg.py +3 -9
- khoj/processor/conversation/anthropic/anthropic_chat.py +11 -3
- khoj/processor/conversation/google/gemini_chat.py +11 -3
- khoj/processor/conversation/offline/chat_model.py +6 -2
- khoj/processor/conversation/openai/gpt.py +10 -2
- khoj/processor/conversation/openai/utils.py +1 -6
- khoj/processor/conversation/prompts.py +18 -0
- khoj/processor/conversation/utils.py +82 -26
- khoj/processor/image/generate.py +12 -15
- khoj/routers/api.py +5 -5
- khoj/routers/api_chat.py +49 -98
- khoj/routers/helpers.py +52 -12
- khoj/utils/initialization.py +10 -12
- {khoj-1.30.11.dev13.dist-info → khoj-1.30.11.dev56.dist-info}/METADATA +2 -1
- {khoj-1.30.11.dev13.dist-info → khoj-1.30.11.dev56.dist-info}/RECORD +71 -67
- khoj/interface/compiled/_next/static/chunks/1603-c68d44bc4ae6039a.js +0 -1
- khoj/interface/compiled/_next/static/chunks/5538-e5f3c9f4d67a64b9.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/agents/layout-f2ea2b26fc0e78b1.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/automations/layout-f1050c1f20a3af67.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/chat/layout-1072c3b0ab136e74.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/layout-72ec1be8afd0b1ab.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/settings/layout-fe8a2f65ccafd142.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/share/chat/layout-dc97434f0354a74e.js +0 -1
- khoj/interface/compiled/_next/static/css/2d097a35da6bfe8d.css +0 -1
- khoj/interface/compiled/_next/static/css/80bd6301fc657983.css +0 -1
- khoj/interface/compiled/_next/static/media/5455839c73f146e7-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/5984b96ba4822821-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/684adc3dde1b03f1-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/82e3b9a1bdaf0c26-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/8d1ea331386a0db8-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/91475f6526542a4f-s.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/b98b13dbc1c3b59c-s.p.woff2 +0 -0
- khoj/interface/compiled/_next/static/media/c824d7a20139e39d-s.woff2 +0 -0
- /khoj/interface/compiled/_next/static/{K_WyVARSz0loPVvwOW1gg → J7Vqh1vjCleYuVLeTaJL6}/_buildManifest.js +0 -0
- /khoj/interface/compiled/_next/static/{K_WyVARSz0loPVvwOW1gg → J7Vqh1vjCleYuVLeTaJL6}/_ssgManifest.js +0 -0
- {khoj-1.30.11.dev13.dist-info → khoj-1.30.11.dev56.dist-info}/WHEEL +0 -0
- {khoj-1.30.11.dev13.dist-info → khoj-1.30.11.dev56.dist-info}/entry_points.txt +0 -0
- {khoj-1.30.11.dev13.dist-info → khoj-1.30.11.dev56.dist-info}/licenses/LICENSE +0 -0
khoj/app/settings.py
CHANGED
@@ -13,6 +13,8 @@ https://docs.djangoproject.com/en/4.2/ref/settings/
|
|
13
13
|
import os
|
14
14
|
from pathlib import Path
|
15
15
|
|
16
|
+
from django.templatetags.static import static
|
17
|
+
|
16
18
|
from khoj.utils.helpers import in_debug_mode, is_env_var_true
|
17
19
|
|
18
20
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
@@ -72,6 +74,7 @@ INSTALLED_APPS = [
|
|
72
74
|
"django.contrib.auth",
|
73
75
|
"django.contrib.contenttypes",
|
74
76
|
"khoj.database.apps.DatabaseConfig",
|
77
|
+
"unfold",
|
75
78
|
"django.contrib.admin",
|
76
79
|
"django.contrib.sessions",
|
77
80
|
"django.contrib.messages",
|
@@ -195,3 +198,21 @@ APSCHEDULER_DATETIME_FORMAT = "N j, Y, f:s a"
|
|
195
198
|
# that supports multiple background worker processes instead (e.g. Dramatiq, Celery, Django-RQ,
|
196
199
|
# etc. See: https://djangopackages.org/grids/g/workers-queues-tasks/ for popular options).
|
197
200
|
APSCHEDULER_RUN_NOW_TIMEOUT = 240 # Seconds
|
201
|
+
|
202
|
+
UNFOLD = {
|
203
|
+
"SITE_TITLE": "Khoj Admin Panel",
|
204
|
+
"SITE_HEADER": "Khoj Admin Panel",
|
205
|
+
"SITE_URL": "/",
|
206
|
+
"SITE_ICON": {
|
207
|
+
"light": lambda request: static("assets/icons/khoj_lantern_128x128.png"),
|
208
|
+
"dark": lambda request: static("assets/icons/khoj_lantern_128x128_dark.png"),
|
209
|
+
},
|
210
|
+
"SITE_FAVICONS": [
|
211
|
+
{
|
212
|
+
"rel": "icon",
|
213
|
+
"sizes": "32x32",
|
214
|
+
"type": "image/svg+xml",
|
215
|
+
"href": lambda request: static("assets/icons/khoj_lantern.svg"),
|
216
|
+
},
|
217
|
+
],
|
218
|
+
}
|
khoj/configure.py
CHANGED
@@ -232,9 +232,9 @@ def configure_server(
|
|
232
232
|
config = FullConfig()
|
233
233
|
state.config = config
|
234
234
|
|
235
|
-
if ConversationAdapters.
|
236
|
-
|
237
|
-
state.openai_client = openai.OpenAI(api_key=
|
235
|
+
if ConversationAdapters.has_valid_ai_model_api():
|
236
|
+
ai_model_api = ConversationAdapters.get_ai_model_api()
|
237
|
+
state.openai_client = openai.OpenAI(api_key=ai_model_api.api_key)
|
238
238
|
|
239
239
|
# Initialize Search Models from Config and initialize content
|
240
240
|
try:
|
@@ -35,6 +35,7 @@ from torch import Tensor
|
|
35
35
|
|
36
36
|
from khoj.database.models import (
|
37
37
|
Agent,
|
38
|
+
AiModelApi,
|
38
39
|
ChatModelOptions,
|
39
40
|
ClientApplication,
|
40
41
|
Conversation,
|
@@ -46,7 +47,6 @@ from khoj.database.models import (
|
|
46
47
|
KhojApiUser,
|
47
48
|
KhojUser,
|
48
49
|
NotionConfig,
|
49
|
-
OpenAIProcessorConversationConfig,
|
50
50
|
ProcessLock,
|
51
51
|
PublicConversation,
|
52
52
|
ReflectiveQuestion,
|
@@ -981,7 +981,7 @@ class ConversationAdapters:
|
|
981
981
|
|
982
982
|
@staticmethod
|
983
983
|
async def aget_all_conversation_configs():
|
984
|
-
return await sync_to_async(list)(ChatModelOptions.objects.prefetch_related("
|
984
|
+
return await sync_to_async(list)(ChatModelOptions.objects.prefetch_related("ai_model_api").all())
|
985
985
|
|
986
986
|
@staticmethod
|
987
987
|
def get_vision_enabled_config():
|
@@ -1000,12 +1000,12 @@ class ConversationAdapters:
|
|
1000
1000
|
return None
|
1001
1001
|
|
1002
1002
|
@staticmethod
|
1003
|
-
def
|
1004
|
-
return
|
1003
|
+
def get_ai_model_api():
|
1004
|
+
return AiModelApi.objects.filter().first()
|
1005
1005
|
|
1006
1006
|
@staticmethod
|
1007
|
-
def
|
1008
|
-
return
|
1007
|
+
def has_valid_ai_model_api():
|
1008
|
+
return AiModelApi.objects.filter().exists()
|
1009
1009
|
|
1010
1010
|
@staticmethod
|
1011
1011
|
@arequire_valid_user
|
@@ -1093,7 +1093,7 @@ class ConversationAdapters:
|
|
1093
1093
|
server_chat_settings: ServerChatSettings = (
|
1094
1094
|
await ServerChatSettings.objects.filter()
|
1095
1095
|
.prefetch_related(
|
1096
|
-
"chat_default", "
|
1096
|
+
"chat_default", "chat_default__ai_model_api", "chat_advanced", "chat_advanced__ai_model_api"
|
1097
1097
|
)
|
1098
1098
|
.afirst()
|
1099
1099
|
)
|
@@ -1109,7 +1109,7 @@ class ConversationAdapters:
|
|
1109
1109
|
|
1110
1110
|
# Get the user's chat settings, if the server chat settings are not set
|
1111
1111
|
user_chat_settings = (
|
1112
|
-
(await UserConversationConfig.objects.filter(user=user).prefetch_related("
|
1112
|
+
(await UserConversationConfig.objects.filter(user=user).prefetch_related("setting__ai_model_api").afirst())
|
1113
1113
|
if user
|
1114
1114
|
else None
|
1115
1115
|
)
|
@@ -1117,7 +1117,7 @@ class ConversationAdapters:
|
|
1117
1117
|
return user_chat_settings.setting
|
1118
1118
|
|
1119
1119
|
# Get the first chat model if even the user chat settings are not set
|
1120
|
-
return await ChatModelOptions.objects.filter().prefetch_related("
|
1120
|
+
return await ChatModelOptions.objects.filter().prefetch_related("ai_model_api").afirst()
|
1121
1121
|
|
1122
1122
|
@staticmethod
|
1123
1123
|
def get_advanced_conversation_config(user: KhojUser):
|
@@ -1130,7 +1130,7 @@ class ConversationAdapters:
|
|
1130
1130
|
async def aget_advanced_conversation_config(user: KhojUser = None):
|
1131
1131
|
server_chat_settings: ServerChatSettings = (
|
1132
1132
|
await ServerChatSettings.objects.filter()
|
1133
|
-
.prefetch_related("chat_advanced", "
|
1133
|
+
.prefetch_related("chat_advanced", "chat_advanced__ai_model_api")
|
1134
1134
|
.afirst()
|
1135
1135
|
)
|
1136
1136
|
if server_chat_settings is not None and server_chat_settings.chat_advanced is not None:
|
@@ -1258,7 +1258,7 @@ class ConversationAdapters:
|
|
1258
1258
|
@staticmethod
|
1259
1259
|
async def aget_user_conversation_config(user: KhojUser):
|
1260
1260
|
config = (
|
1261
|
-
await UserConversationConfig.objects.filter(user=user).prefetch_related("
|
1261
|
+
await UserConversationConfig.objects.filter(user=user).prefetch_related("setting__ai_model_api").afirst()
|
1262
1262
|
)
|
1263
1263
|
if not config:
|
1264
1264
|
return None
|
@@ -1313,7 +1313,7 @@ class ConversationAdapters:
|
|
1313
1313
|
ChatModelOptions.ModelType.OPENAI,
|
1314
1314
|
ChatModelOptions.ModelType.GOOGLE,
|
1315
1315
|
]
|
1316
|
-
) and conversation_config.
|
1316
|
+
) and conversation_config.ai_model_api:
|
1317
1317
|
return conversation_config
|
1318
1318
|
|
1319
1319
|
else:
|
@@ -1321,7 +1321,7 @@ class ConversationAdapters:
|
|
1321
1321
|
|
1322
1322
|
@staticmethod
|
1323
1323
|
async def aget_text_to_image_model_config():
|
1324
|
-
return await TextToImageModelConfig.objects.filter().prefetch_related("
|
1324
|
+
return await TextToImageModelConfig.objects.filter().prefetch_related("ai_model_api").afirst()
|
1325
1325
|
|
1326
1326
|
@staticmethod
|
1327
1327
|
def get_text_to_image_model_config():
|
@@ -1343,9 +1343,9 @@ class ConversationAdapters:
|
|
1343
1343
|
|
1344
1344
|
@staticmethod
|
1345
1345
|
async def aget_user_text_to_image_model(user: KhojUser) -> Optional[TextToImageModelConfig]:
|
1346
|
-
# Create a custom queryset for prefetching
|
1346
|
+
# Create a custom queryset for prefetching settings__ai_model_api, handling null cases
|
1347
1347
|
settings_prefetch = Prefetch(
|
1348
|
-
"setting", queryset=TextToImageModelConfig.objects.prefetch_related("
|
1348
|
+
"setting", queryset=TextToImageModelConfig.objects.prefetch_related("ai_model_api")
|
1349
1349
|
)
|
1350
1350
|
|
1351
1351
|
config = await UserTextToImageModelConfig.objects.filter(user=user).prefetch_related(settings_prefetch).afirst()
|
khoj/database/admin.py
CHANGED
@@ -1,17 +1,21 @@
|
|
1
1
|
import csv
|
2
2
|
import json
|
3
|
-
from datetime import
|
3
|
+
from datetime import datetime, timedelta
|
4
4
|
|
5
5
|
from apscheduler.job import Job
|
6
6
|
from django.contrib import admin, messages
|
7
|
-
from django.contrib.auth.admin import
|
7
|
+
from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin
|
8
|
+
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
9
|
+
from django.contrib.auth.models import Group
|
8
10
|
from django.http import HttpResponse
|
9
|
-
from django_apscheduler.admin import DjangoJobAdmin
|
11
|
+
from django_apscheduler.admin import DjangoJobAdmin, DjangoJobExecutionAdmin
|
10
12
|
from django_apscheduler.jobstores import DjangoJobStore
|
11
|
-
from django_apscheduler.models import DjangoJob
|
13
|
+
from django_apscheduler.models import DjangoJob, DjangoJobExecution
|
14
|
+
from unfold import admin as unfold_admin
|
12
15
|
|
13
16
|
from khoj.database.models import (
|
14
17
|
Agent,
|
18
|
+
AiModelApi,
|
15
19
|
ChatModelOptions,
|
16
20
|
ClientApplication,
|
17
21
|
Conversation,
|
@@ -19,7 +23,6 @@ from khoj.database.models import (
|
|
19
23
|
GithubConfig,
|
20
24
|
KhojUser,
|
21
25
|
NotionConfig,
|
22
|
-
OpenAIProcessorConversationConfig,
|
23
26
|
ProcessLock,
|
24
27
|
ReflectiveQuestion,
|
25
28
|
SearchModelConfig,
|
@@ -35,10 +38,8 @@ from khoj.database.models import (
|
|
35
38
|
)
|
36
39
|
from khoj.utils.helpers import ImageIntentType
|
37
40
|
|
38
|
-
admin.site.unregister(DjangoJob)
|
39
|
-
|
40
41
|
|
41
|
-
class KhojDjangoJobAdmin(DjangoJobAdmin):
|
42
|
+
class KhojDjangoJobAdmin(DjangoJobAdmin, unfold_admin.ModelAdmin):
|
42
43
|
list_display = (
|
43
44
|
"id",
|
44
45
|
"next_run_time",
|
@@ -62,10 +63,25 @@ class KhojDjangoJobAdmin(DjangoJobAdmin):
|
|
62
63
|
return queryset, use_distinct
|
63
64
|
|
64
65
|
|
66
|
+
class KhojDjangoJobExecutionAdmin(DjangoJobExecutionAdmin, unfold_admin.ModelAdmin):
|
67
|
+
pass
|
68
|
+
|
69
|
+
|
70
|
+
admin.site.unregister(DjangoJob)
|
65
71
|
admin.site.register(DjangoJob, KhojDjangoJobAdmin)
|
72
|
+
admin.site.unregister(DjangoJobExecution)
|
73
|
+
admin.site.register(DjangoJobExecution, KhojDjangoJobExecutionAdmin)
|
66
74
|
|
67
75
|
|
68
|
-
class
|
76
|
+
class GroupAdmin(BaseGroupAdmin, unfold_admin.ModelAdmin):
|
77
|
+
pass
|
78
|
+
|
79
|
+
|
80
|
+
class UserAdmin(BaseUserAdmin, unfold_admin.ModelAdmin):
|
81
|
+
pass
|
82
|
+
|
83
|
+
|
84
|
+
class KhojUserAdmin(UserAdmin, unfold_admin.ModelAdmin):
|
69
85
|
class DateJoinedAfterFilter(admin.SimpleListFilter):
|
70
86
|
title = "Joined after"
|
71
87
|
parameter_name = "joined_after"
|
@@ -137,21 +153,22 @@ class KhojUserAdmin(UserAdmin):
|
|
137
153
|
get_email_login_url.short_description = "Get email login URL" # type: ignore
|
138
154
|
|
139
155
|
|
156
|
+
admin.site.unregister(Group)
|
140
157
|
admin.site.register(KhojUser, KhojUserAdmin)
|
141
158
|
|
142
|
-
admin.site.register(ProcessLock)
|
143
|
-
admin.site.register(SpeechToTextModelOptions)
|
144
|
-
admin.site.register(ReflectiveQuestion)
|
145
|
-
admin.site.register(ClientApplication)
|
146
|
-
admin.site.register(GithubConfig)
|
147
|
-
admin.site.register(NotionConfig)
|
148
|
-
admin.site.register(UserVoiceModelConfig)
|
149
|
-
admin.site.register(VoiceModelOption)
|
150
|
-
admin.site.register(UserRequests)
|
159
|
+
admin.site.register(ProcessLock, unfold_admin.ModelAdmin)
|
160
|
+
admin.site.register(SpeechToTextModelOptions, unfold_admin.ModelAdmin)
|
161
|
+
admin.site.register(ReflectiveQuestion, unfold_admin.ModelAdmin)
|
162
|
+
admin.site.register(ClientApplication, unfold_admin.ModelAdmin)
|
163
|
+
admin.site.register(GithubConfig, unfold_admin.ModelAdmin)
|
164
|
+
admin.site.register(NotionConfig, unfold_admin.ModelAdmin)
|
165
|
+
admin.site.register(UserVoiceModelConfig, unfold_admin.ModelAdmin)
|
166
|
+
admin.site.register(VoiceModelOption, unfold_admin.ModelAdmin)
|
167
|
+
admin.site.register(UserRequests, unfold_admin.ModelAdmin)
|
151
168
|
|
152
169
|
|
153
170
|
@admin.register(Agent)
|
154
|
-
class AgentAdmin(
|
171
|
+
class AgentAdmin(unfold_admin.ModelAdmin):
|
155
172
|
list_display = (
|
156
173
|
"id",
|
157
174
|
"name",
|
@@ -161,7 +178,7 @@ class AgentAdmin(admin.ModelAdmin):
|
|
161
178
|
|
162
179
|
|
163
180
|
@admin.register(Entry)
|
164
|
-
class EntryAdmin(
|
181
|
+
class EntryAdmin(unfold_admin.ModelAdmin):
|
165
182
|
list_display = (
|
166
183
|
"id",
|
167
184
|
"created_at",
|
@@ -183,7 +200,7 @@ class EntryAdmin(admin.ModelAdmin):
|
|
183
200
|
|
184
201
|
|
185
202
|
@admin.register(Subscription)
|
186
|
-
class KhojUserSubscription(
|
203
|
+
class KhojUserSubscription(unfold_admin.ModelAdmin):
|
187
204
|
list_display = (
|
188
205
|
"id",
|
189
206
|
"user",
|
@@ -195,7 +212,7 @@ class KhojUserSubscription(admin.ModelAdmin):
|
|
195
212
|
|
196
213
|
|
197
214
|
@admin.register(ChatModelOptions)
|
198
|
-
class ChatModelOptionsAdmin(
|
215
|
+
class ChatModelOptionsAdmin(unfold_admin.ModelAdmin):
|
199
216
|
list_display = (
|
200
217
|
"id",
|
201
218
|
"chat_model",
|
@@ -206,7 +223,7 @@ class ChatModelOptionsAdmin(admin.ModelAdmin):
|
|
206
223
|
|
207
224
|
|
208
225
|
@admin.register(TextToImageModelConfig)
|
209
|
-
class TextToImageModelOptionsAdmin(
|
226
|
+
class TextToImageModelOptionsAdmin(unfold_admin.ModelAdmin):
|
210
227
|
list_display = (
|
211
228
|
"id",
|
212
229
|
"model_name",
|
@@ -215,8 +232,8 @@ class TextToImageModelOptionsAdmin(admin.ModelAdmin):
|
|
215
232
|
search_fields = ("id", "model_name", "model_type")
|
216
233
|
|
217
234
|
|
218
|
-
@admin.register(
|
219
|
-
class
|
235
|
+
@admin.register(AiModelApi)
|
236
|
+
class AiModelApiAdmin(unfold_admin.ModelAdmin):
|
220
237
|
list_display = (
|
221
238
|
"id",
|
222
239
|
"name",
|
@@ -227,7 +244,7 @@ class OpenAIProcessorConversationConfigAdmin(admin.ModelAdmin):
|
|
227
244
|
|
228
245
|
|
229
246
|
@admin.register(SearchModelConfig)
|
230
|
-
class SearchModelConfigAdmin(
|
247
|
+
class SearchModelConfigAdmin(unfold_admin.ModelAdmin):
|
231
248
|
list_display = (
|
232
249
|
"id",
|
233
250
|
"name",
|
@@ -238,7 +255,7 @@ class SearchModelConfigAdmin(admin.ModelAdmin):
|
|
238
255
|
|
239
256
|
|
240
257
|
@admin.register(ServerChatSettings)
|
241
|
-
class ServerChatSettingsAdmin(
|
258
|
+
class ServerChatSettingsAdmin(unfold_admin.ModelAdmin):
|
242
259
|
list_display = (
|
243
260
|
"chat_default",
|
244
261
|
"chat_advanced",
|
@@ -247,7 +264,7 @@ class ServerChatSettingsAdmin(admin.ModelAdmin):
|
|
247
264
|
|
248
265
|
|
249
266
|
@admin.register(WebScraper)
|
250
|
-
class WebScraperAdmin(
|
267
|
+
class WebScraperAdmin(unfold_admin.ModelAdmin):
|
251
268
|
list_display = (
|
252
269
|
"priority",
|
253
270
|
"name",
|
@@ -261,7 +278,7 @@ class WebScraperAdmin(admin.ModelAdmin):
|
|
261
278
|
|
262
279
|
|
263
280
|
@admin.register(Conversation)
|
264
|
-
class ConversationAdmin(
|
281
|
+
class ConversationAdmin(unfold_admin.ModelAdmin):
|
265
282
|
list_display = (
|
266
283
|
"id",
|
267
284
|
"user",
|
@@ -286,17 +303,10 @@ class ConversationAdmin(admin.ModelAdmin):
|
|
286
303
|
modified_log = conversation.conversation_log
|
287
304
|
chat_log = modified_log.get("chat", [])
|
288
305
|
for idx, log in enumerate(chat_log):
|
289
|
-
if
|
290
|
-
log["
|
291
|
-
and log["intent"]
|
292
|
-
and log["intent"]["type"]
|
293
|
-
and (
|
294
|
-
log["intent"]["type"] == ImageIntentType.TEXT_TO_IMAGE.value
|
295
|
-
or log["intent"]["type"] == ImageIntentType.TEXT_TO_IMAGE_V3.value
|
296
|
-
)
|
297
|
-
):
|
298
|
-
log["message"] = "inline image redacted for space"
|
306
|
+
if log["by"] == "khoj" and log["images"]:
|
307
|
+
log["images"] = ["inline image redacted for space"]
|
299
308
|
chat_log[idx] = log
|
309
|
+
|
300
310
|
modified_log["chat"] = chat_log
|
301
311
|
|
302
312
|
writer.writerow(
|
@@ -367,7 +377,7 @@ class ConversationAdmin(admin.ModelAdmin):
|
|
367
377
|
|
368
378
|
|
369
379
|
@admin.register(UserConversationConfig)
|
370
|
-
class UserConversationConfigAdmin(
|
380
|
+
class UserConversationConfigAdmin(unfold_admin.ModelAdmin):
|
371
381
|
list_display = (
|
372
382
|
"id",
|
373
383
|
"get_user_email",
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Made manually by sabaimran for use by Django 5.0.9 on 2024-12-01 16:59
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
|
5
|
+
# This script was written alongside when Pydantic validation was added to the Conversation conversation_log field.
|
6
|
+
|
7
|
+
|
8
|
+
def migrate_generated_assets(apps, schema_editor):
|
9
|
+
Conversation = apps.get_model("database", "Conversation")
|
10
|
+
|
11
|
+
# Process conversations in chunks
|
12
|
+
for conversation in Conversation.objects.iterator():
|
13
|
+
try:
|
14
|
+
meta_log = conversation.conversation_log
|
15
|
+
modified = False
|
16
|
+
|
17
|
+
for chat in meta_log.get("chat", []):
|
18
|
+
intent_type = chat.get("intent", {}).get("type")
|
19
|
+
|
20
|
+
if intent_type and chat["by"] == "khoj":
|
21
|
+
if intent_type and "text-to-image" in intent_type:
|
22
|
+
# Migrate the generated image to the new format
|
23
|
+
chat["images"] = [chat.get("message")]
|
24
|
+
chat["message"] = chat["intent"]["inferred-queries"][0]
|
25
|
+
modified = True
|
26
|
+
|
27
|
+
if intent_type and "excalidraw" in intent_type:
|
28
|
+
# Migrate the generated excalidraw to the new format
|
29
|
+
chat["excalidrawDiagram"] = chat.get("message")
|
30
|
+
chat["message"] = chat["intent"]["inferred-queries"][0]
|
31
|
+
modified = True
|
32
|
+
|
33
|
+
# Only save if changes were made
|
34
|
+
if modified:
|
35
|
+
conversation.conversation_log = meta_log
|
36
|
+
conversation.save()
|
37
|
+
|
38
|
+
except Exception as e:
|
39
|
+
print(f"Error processing conversation {conversation.id}: {str(e)}")
|
40
|
+
continue
|
41
|
+
|
42
|
+
|
43
|
+
def reverse_migration(apps, schema_editor):
|
44
|
+
Conversation = apps.get_model("database", "Conversation")
|
45
|
+
|
46
|
+
# Process conversations in chunks
|
47
|
+
for conversation in Conversation.objects.iterator():
|
48
|
+
try:
|
49
|
+
meta_log = conversation.conversation_log
|
50
|
+
modified = False
|
51
|
+
|
52
|
+
for chat in meta_log.get("chat", []):
|
53
|
+
intent_type = chat.get("intent", {}).get("type")
|
54
|
+
|
55
|
+
if intent_type and chat["by"] == "khoj":
|
56
|
+
if intent_type and "text-to-image" in intent_type:
|
57
|
+
# Migrate the generated image back to the old format
|
58
|
+
chat["message"] = chat.get("images", [])[0]
|
59
|
+
chat.pop("images", None)
|
60
|
+
modified = True
|
61
|
+
|
62
|
+
if intent_type and "excalidraw" in intent_type:
|
63
|
+
# Migrate the generated excalidraw back to the old format
|
64
|
+
chat["message"] = chat.get("excalidrawDiagram")
|
65
|
+
chat.pop("excalidrawDiagram", None)
|
66
|
+
modified = True
|
67
|
+
|
68
|
+
# Only save if changes were made
|
69
|
+
if modified:
|
70
|
+
conversation.conversation_log = meta_log
|
71
|
+
conversation.save()
|
72
|
+
|
73
|
+
except Exception as e:
|
74
|
+
print(f"Error processing conversation {conversation.id}: {str(e)}")
|
75
|
+
continue
|
76
|
+
|
77
|
+
|
78
|
+
class Migration(migrations.Migration):
|
79
|
+
dependencies = [
|
80
|
+
("database", "0074_alter_conversation_title"),
|
81
|
+
]
|
82
|
+
|
83
|
+
operations = [
|
84
|
+
migrations.RunPython(migrate_generated_assets, reverse_migration),
|
85
|
+
]
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Generated by Django 5.0.9 on 2024-12-05 09:00
|
2
|
+
|
3
|
+
from django.db import migrations
|
4
|
+
|
5
|
+
|
6
|
+
class Migration(migrations.Migration):
|
7
|
+
dependencies = [
|
8
|
+
("database", "0075_migrate_generated_assets_and_validate"),
|
9
|
+
]
|
10
|
+
|
11
|
+
operations = [
|
12
|
+
migrations.RenameModel(
|
13
|
+
old_name="OpenAIProcessorConversationConfig",
|
14
|
+
new_name="AiModelApi",
|
15
|
+
),
|
16
|
+
migrations.RenameField(
|
17
|
+
model_name="chatmodeloptions",
|
18
|
+
old_name="openai_config",
|
19
|
+
new_name="ai_model_api",
|
20
|
+
),
|
21
|
+
migrations.RenameField(
|
22
|
+
model_name="texttoimagemodelconfig",
|
23
|
+
old_name="openai_config",
|
24
|
+
new_name="ai_model_api",
|
25
|
+
),
|
26
|
+
]
|