khoj 1.26.5.dev15__py3-none-any.whl → 1.26.5.dev35__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 +2 -2
- khoj/database/adapters/__init__.py +41 -28
- khoj/database/admin.py +2 -0
- khoj/database/management/commands/change_default_model.py +182 -0
- khoj/database/migrations/0071_subscription_enabled_trial_at_and_more.py +32 -0
- khoj/database/migrations/0072_entry_search_model.py +24 -0
- khoj/database/models/__init__.py +4 -1
- khoj/interface/compiled/404/index.html +1 -1
- khoj/interface/compiled/_next/static/chunks/1279-f37ee4a388ebf544.js +1 -0
- khoj/interface/compiled/_next/static/chunks/1603-b9d95833e0e025e8.js +1 -0
- khoj/interface/compiled/_next/static/chunks/1970-1d6d0c1b00b4f343.js +1 -0
- khoj/interface/compiled/_next/static/chunks/{3423-aad88d6c1f029135.js → 3423-8e9c420574a9fbe3.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/394-6bcb8c429f168f21.js +3 -0
- khoj/interface/compiled/_next/static/chunks/4602-8eeb4b76385ad159.js +1 -0
- khoj/interface/compiled/_next/static/chunks/5512-94c7c2bbcf58c19d.js +1 -0
- khoj/interface/compiled/_next/static/chunks/7113-f2e114d7034a0835.js +1 -0
- khoj/interface/compiled/_next/static/chunks/{3678-ef0d20e267e9f010.js → 7883-b1305ec254213afe.js} +2 -2
- khoj/interface/compiled/_next/static/chunks/9479-4b443fdcc99141c9.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/agents/page-adbf3cd470da248f.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/automations/{page-1688dead2f21270d.js → page-d3edae545a1b5393.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/chat/page-460d262a3ef77503.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/factchecker/{page-f544113d240423e9.js → page-c8e5bd563a8155eb.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/{page-88139ac728fe3533.js → page-337bba1c554d0742.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/search/{page-3ada11cda5050eeb.js → page-a5c277eff207959e.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/settings/page-60097571dd9f9d37.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/share/chat/page-97c4e60105009649.js +1 -0
- khoj/interface/compiled/_next/static/chunks/{webpack-95652a0eef2b0aeb.js → webpack-35c06f544e18305f.js} +1 -1
- khoj/interface/compiled/_next/static/css/76d55eb435962b19.css +25 -0
- khoj/interface/compiled/_next/static/css/{f84cf008d5ff4161.css → afd3d45cc65d55d8.css} +1 -1
- 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/processor/content/text_to_entries.py +4 -2
- khoj/processor/image/generate.py +3 -3
- khoj/routers/api.py +3 -2
- khoj/routers/api_agents.py +41 -20
- khoj/routers/api_model.py +0 -33
- khoj/routers/{subscription.py → api_subscription.py} +20 -2
- khoj/routers/helpers.py +10 -10
- khoj/search_type/text_search.py +6 -2
- {khoj-1.26.5.dev15.dist-info → khoj-1.26.5.dev35.dist-info}/METADATA +1 -1
- {khoj-1.26.5.dev15.dist-info → khoj-1.26.5.dev35.dist-info}/RECORD +61 -57
- khoj/interface/compiled/_next/static/chunks/121-7024f479c297aef0.js +0 -1
- khoj/interface/compiled/_next/static/chunks/1603-bfc0b26e32ad88e3.js +0 -1
- khoj/interface/compiled/_next/static/chunks/477-ec86e93db10571c1.js +0 -1
- khoj/interface/compiled/_next/static/chunks/51-e8f5bdb69b5ea421.js +0 -1
- khoj/interface/compiled/_next/static/chunks/6327-18f0b45cc5a13afb.js +0 -3
- khoj/interface/compiled/_next/static/chunks/7762-79f2205740622b5c.js +0 -1
- khoj/interface/compiled/_next/static/chunks/9479-fcce773453e472c4.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/agents/page-997bf85681256672.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/chat/page-027e61d082025c50.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/settings/page-fa11cafaec7ab39f.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/share/chat/page-511186e77624eaec.js +0 -1
- khoj/interface/compiled/_next/static/css/825406e5ebee86d3.css +0 -25
- /khoj/interface/compiled/_next/static/{l0c66lMus19JlWgScUQtj → GH1Wb7mTB8D7ZsHW6iRF6}/_buildManifest.js +0 -0
- /khoj/interface/compiled/_next/static/{l0c66lMus19JlWgScUQtj → GH1Wb7mTB8D7ZsHW6iRF6}/_ssgManifest.js +0 -0
- /khoj/interface/compiled/_next/static/chunks/{2697-37579bcc7593dd5c.js → 2697-61fcba89fd87eab4.js} +0 -0
- {khoj-1.26.5.dev15.dist-info → khoj-1.26.5.dev35.dist-info}/WHEEL +0 -0
- {khoj-1.26.5.dev15.dist-info → khoj-1.26.5.dev35.dist-info}/entry_points.txt +0 -0
- {khoj-1.26.5.dev15.dist-info → khoj-1.26.5.dev35.dist-info}/licenses/LICENSE +0 -0
khoj/configure.py
CHANGED
@@ -108,7 +108,7 @@ class UserAuthenticationBackend(AuthenticationBackend):
|
|
108
108
|
password="default",
|
109
109
|
)
|
110
110
|
renewal_date = make_aware(datetime.strptime("2100-04-01", "%Y-%m-%d"))
|
111
|
-
Subscription.objects.create(user=default_user, type=
|
111
|
+
Subscription.objects.create(user=default_user, type=Subscription.Type.STANDARD, renewal_date=renewal_date)
|
112
112
|
|
113
113
|
async def authenticate(self, request: HTTPConnection):
|
114
114
|
current_user = request.session.get("user")
|
@@ -312,7 +312,7 @@ def configure_routes(app):
|
|
312
312
|
logger.info("🔑 Enabled Authentication")
|
313
313
|
|
314
314
|
if state.billing_enabled:
|
315
|
-
from khoj.routers.
|
315
|
+
from khoj.routers.api_subscription import subscription_router
|
316
316
|
|
317
317
|
app.include_router(subscription_router, prefix="/api/subscription")
|
318
318
|
logger.info("💳 Enabled Billing")
|
@@ -70,6 +70,9 @@ from khoj.utils.helpers import (
|
|
70
70
|
logger = logging.getLogger(__name__)
|
71
71
|
|
72
72
|
|
73
|
+
LENGTH_OF_FREE_TRIAL = 7 #
|
74
|
+
|
75
|
+
|
73
76
|
class SubscriptionState(Enum):
|
74
77
|
TRIAL = "trial"
|
75
78
|
SUBSCRIBED = "subscribed"
|
@@ -168,7 +171,7 @@ async def acreate_user_by_phone_number(phone_number: str) -> KhojUser:
|
|
168
171
|
)
|
169
172
|
await user.asave()
|
170
173
|
|
171
|
-
await Subscription.objects.acreate(user=user, type=
|
174
|
+
await Subscription.objects.acreate(user=user, type=Subscription.Type.STANDARD)
|
172
175
|
|
173
176
|
return user
|
174
177
|
|
@@ -185,11 +188,29 @@ async def aget_or_create_user_by_email(email: str) -> tuple[KhojUser, bool]:
|
|
185
188
|
|
186
189
|
user_subscription = await Subscription.objects.filter(user=user).afirst()
|
187
190
|
if not user_subscription:
|
188
|
-
await Subscription.objects.acreate(user=user, type=
|
191
|
+
await Subscription.objects.acreate(user=user, type=Subscription.Type.STANDARD)
|
189
192
|
|
190
193
|
return user, is_new
|
191
194
|
|
192
195
|
|
196
|
+
async def astart_trial_subscription(user: KhojUser) -> Subscription:
|
197
|
+
subscription = await Subscription.objects.filter(user=user).afirst()
|
198
|
+
if not subscription:
|
199
|
+
raise HTTPException(status_code=400, detail="User does not have a subscription")
|
200
|
+
|
201
|
+
if subscription.type == Subscription.Type.TRIAL:
|
202
|
+
raise HTTPException(status_code=400, detail="User already has a trial subscription")
|
203
|
+
|
204
|
+
if subscription.enabled_trial_at:
|
205
|
+
raise HTTPException(status_code=400, detail="User already has a trial subscription")
|
206
|
+
|
207
|
+
subscription.type = Subscription.Type.TRIAL
|
208
|
+
subscription.enabled_trial_at = datetime.now(tz=timezone.utc)
|
209
|
+
subscription.renewal_date = datetime.now(tz=timezone.utc) + timedelta(days=LENGTH_OF_FREE_TRIAL)
|
210
|
+
await subscription.asave()
|
211
|
+
return subscription
|
212
|
+
|
213
|
+
|
193
214
|
async def aget_user_validated_by_email_verification_code(code: str) -> KhojUser:
|
194
215
|
user = await KhojUser.objects.filter(email_verification_code=code).afirst()
|
195
216
|
if not user:
|
@@ -221,7 +242,7 @@ async def create_user_by_google_token(token: dict) -> KhojUser:
|
|
221
242
|
user=user,
|
222
243
|
)
|
223
244
|
|
224
|
-
await Subscription.objects.acreate(user=user, type=
|
245
|
+
await Subscription.objects.acreate(user=user, type=Subscription.Type.STANDARD)
|
225
246
|
|
226
247
|
return user
|
227
248
|
|
@@ -279,16 +300,15 @@ def subscription_to_state(subscription: Subscription) -> str:
|
|
279
300
|
if not subscription:
|
280
301
|
return SubscriptionState.INVALID.value
|
281
302
|
elif subscription.type == Subscription.Type.TRIAL:
|
282
|
-
#
|
283
|
-
if datetime.now(tz=timezone.utc)
|
303
|
+
# Check if the trial has expired
|
304
|
+
if datetime.now(tz=timezone.utc) > subscription.renewal_date:
|
284
305
|
return SubscriptionState.EXPIRED.value
|
285
|
-
|
286
306
|
return SubscriptionState.TRIAL.value
|
287
|
-
elif subscription.is_recurring and subscription.renewal_date
|
307
|
+
elif subscription.is_recurring and subscription.renewal_date > datetime.now(tz=timezone.utc):
|
288
308
|
return SubscriptionState.SUBSCRIBED.value
|
289
309
|
elif not subscription.is_recurring and subscription.renewal_date is None:
|
290
310
|
return SubscriptionState.EXPIRED.value
|
291
|
-
elif not subscription.is_recurring and subscription.renewal_date
|
311
|
+
elif not subscription.is_recurring and subscription.renewal_date > datetime.now(tz=timezone.utc):
|
292
312
|
return SubscriptionState.UNSUBSCRIBED.value
|
293
313
|
elif not subscription.is_recurring and subscription.renewal_date < datetime.now(tz=timezone.utc):
|
294
314
|
return SubscriptionState.EXPIRED.value
|
@@ -446,18 +466,26 @@ async def set_user_github_config(user: KhojUser, pat_token: str, repos: list):
|
|
446
466
|
return config
|
447
467
|
|
448
468
|
|
449
|
-
def
|
450
|
-
|
451
|
-
return UserSearchModelConfig.objects.filter(user=user).first().setting
|
469
|
+
def get_default_search_model() -> SearchModelConfig:
|
470
|
+
default_search_model = SearchModelConfig.objects.filter(name="default").first()
|
452
471
|
|
453
|
-
if
|
454
|
-
return
|
472
|
+
if default_search_model:
|
473
|
+
return default_search_model
|
455
474
|
else:
|
456
475
|
SearchModelConfig.objects.create()
|
457
476
|
|
458
477
|
return SearchModelConfig.objects.first()
|
459
478
|
|
460
479
|
|
480
|
+
def get_user_default_search_model(user: KhojUser = None) -> SearchModelConfig:
|
481
|
+
if user:
|
482
|
+
user_search_model = UserSearchModelConfig.objects.filter(user=user).first()
|
483
|
+
if user_search_model:
|
484
|
+
return user_search_model.setting
|
485
|
+
|
486
|
+
return get_default_search_model()
|
487
|
+
|
488
|
+
|
461
489
|
def get_or_create_search_models():
|
462
490
|
search_models = SearchModelConfig.objects.all()
|
463
491
|
if search_models.count() == 0:
|
@@ -467,21 +495,6 @@ def get_or_create_search_models():
|
|
467
495
|
return search_models
|
468
496
|
|
469
497
|
|
470
|
-
async def aset_user_search_model(user: KhojUser, search_model_config_id: int):
|
471
|
-
config = await SearchModelConfig.objects.filter(id=search_model_config_id).afirst()
|
472
|
-
if not config:
|
473
|
-
return None
|
474
|
-
new_config, _ = await UserSearchModelConfig.objects.aupdate_or_create(user=user, defaults={"setting": config})
|
475
|
-
return new_config
|
476
|
-
|
477
|
-
|
478
|
-
async def aget_user_search_model(user: KhojUser):
|
479
|
-
config = await UserSearchModelConfig.objects.filter(user=user).prefetch_related("setting").afirst()
|
480
|
-
if not config:
|
481
|
-
return None
|
482
|
-
return config.setting
|
483
|
-
|
484
|
-
|
485
498
|
class ProcessLockAdapters:
|
486
499
|
@staticmethod
|
487
500
|
def get_process_lock(process_name: str):
|
khoj/database/admin.py
CHANGED
@@ -126,6 +126,7 @@ class EntryAdmin(admin.ModelAdmin):
|
|
126
126
|
"created_at",
|
127
127
|
"updated_at",
|
128
128
|
"user",
|
129
|
+
"agent",
|
129
130
|
"file_source",
|
130
131
|
"file_type",
|
131
132
|
"file_name",
|
@@ -135,6 +136,7 @@ class EntryAdmin(admin.ModelAdmin):
|
|
135
136
|
list_filter = (
|
136
137
|
"file_type",
|
137
138
|
"user__email",
|
139
|
+
"search_model__name",
|
138
140
|
)
|
139
141
|
ordering = ("-created_at",)
|
140
142
|
|
@@ -0,0 +1,182 @@
|
|
1
|
+
import logging
|
2
|
+
from typing import List
|
3
|
+
|
4
|
+
from django.core.management.base import BaseCommand
|
5
|
+
from django.db import transaction
|
6
|
+
from django.db.models import Count, Q
|
7
|
+
from tqdm import tqdm
|
8
|
+
|
9
|
+
from khoj.database.adapters import get_default_search_model
|
10
|
+
from khoj.database.models import (
|
11
|
+
Agent,
|
12
|
+
Entry,
|
13
|
+
KhojUser,
|
14
|
+
SearchModelConfig,
|
15
|
+
UserSearchModelConfig,
|
16
|
+
)
|
17
|
+
from khoj.processor.embeddings import EmbeddingsModel
|
18
|
+
|
19
|
+
logging.basicConfig(level=logging.INFO)
|
20
|
+
logger = logging.getLogger(__name__)
|
21
|
+
|
22
|
+
|
23
|
+
class Command(BaseCommand):
|
24
|
+
help = "Convert all existing Entry objects to use a new default Search model."
|
25
|
+
|
26
|
+
def add_arguments(self, parser):
|
27
|
+
# Pass default SearchModelConfig ID
|
28
|
+
parser.add_argument(
|
29
|
+
"--search_model_id",
|
30
|
+
action="store",
|
31
|
+
help="ID of the SearchModelConfig object to set as the default search model for all existing Entry objects and UserSearchModelConfig objects.",
|
32
|
+
required=True,
|
33
|
+
)
|
34
|
+
|
35
|
+
# Set the apply flag to apply the new default Search model to all existing Entry objects and UserSearchModelConfig objects.
|
36
|
+
parser.add_argument(
|
37
|
+
"--apply",
|
38
|
+
action="store_true",
|
39
|
+
help="Apply the new default Search model to all existing Entry objects and UserSearchModelConfig objects. Otherwise, only display the number of Entry objects and UserSearchModelConfig objects that will be affected.",
|
40
|
+
)
|
41
|
+
|
42
|
+
def handle(self, *args, **options):
|
43
|
+
@transaction.atomic
|
44
|
+
def regenerate_entries(entry_filter: Q, embeddings_model: EmbeddingsModel, search_model: SearchModelConfig):
|
45
|
+
entries = Entry.objects.filter(entry_filter).all()
|
46
|
+
compiled_entries = [entry.compiled for entry in entries]
|
47
|
+
updated_entries: List[Entry] = []
|
48
|
+
try:
|
49
|
+
embeddings = embeddings_model.embed_documents(compiled_entries)
|
50
|
+
|
51
|
+
except Exception as e:
|
52
|
+
logger.error(f"Error embedding documents: {e}")
|
53
|
+
return
|
54
|
+
|
55
|
+
for i, entry in enumerate(tqdm(entries)):
|
56
|
+
entry.embeddings = embeddings[i]
|
57
|
+
entry.search_model_id = search_model.id
|
58
|
+
updated_entries.append(entry)
|
59
|
+
|
60
|
+
Entry.objects.bulk_update(updated_entries, ["embeddings", "search_model_id", "file_path"])
|
61
|
+
|
62
|
+
search_model_config_id = options.get("search_model_id")
|
63
|
+
apply = options.get("apply")
|
64
|
+
|
65
|
+
logger.info(f"SearchModelConfig ID: {search_model_config_id}")
|
66
|
+
logger.info(f"Apply: {apply}")
|
67
|
+
|
68
|
+
embeddings_model = dict()
|
69
|
+
|
70
|
+
search_models = SearchModelConfig.objects.all()
|
71
|
+
for model in search_models:
|
72
|
+
embeddings_model.update(
|
73
|
+
{
|
74
|
+
model.name: EmbeddingsModel(
|
75
|
+
model.bi_encoder,
|
76
|
+
model.embeddings_inference_endpoint,
|
77
|
+
model.embeddings_inference_endpoint_api_key,
|
78
|
+
query_encode_kwargs=model.bi_encoder_query_encode_config,
|
79
|
+
docs_encode_kwargs=model.bi_encoder_docs_encode_config,
|
80
|
+
model_kwargs=model.bi_encoder_model_config,
|
81
|
+
)
|
82
|
+
}
|
83
|
+
)
|
84
|
+
|
85
|
+
new_default_search_model_config = SearchModelConfig.objects.get(id=search_model_config_id)
|
86
|
+
logger.info(f"New default Search model: {new_default_search_model_config}")
|
87
|
+
user_search_model_configs_to_update = UserSearchModelConfig.objects.exclude(
|
88
|
+
setting_id=search_model_config_id
|
89
|
+
).all()
|
90
|
+
logger.info(f"Number of UserSearchModelConfig objects to update: {user_search_model_configs_to_update.count()}")
|
91
|
+
|
92
|
+
for user_config in user_search_model_configs_to_update:
|
93
|
+
affected_user = user_config.user
|
94
|
+
entry_filter = Q(user=affected_user)
|
95
|
+
relevant_entries = Entry.objects.filter(entry_filter).all()
|
96
|
+
logger.info(f"Number of Entry objects to update for user {affected_user}: {relevant_entries.count()}")
|
97
|
+
|
98
|
+
if apply:
|
99
|
+
try:
|
100
|
+
regenerate_entries(
|
101
|
+
entry_filter,
|
102
|
+
embeddings_model[new_default_search_model_config.name],
|
103
|
+
new_default_search_model_config,
|
104
|
+
)
|
105
|
+
user_config.setting = new_default_search_model_config
|
106
|
+
user_config.save()
|
107
|
+
|
108
|
+
logger.info(
|
109
|
+
f"Updated UserSearchModelConfig object for user {affected_user} to use the new default Search model."
|
110
|
+
)
|
111
|
+
logger.info(
|
112
|
+
f"Updated {relevant_entries.count()} Entry objects for user {affected_user} to use the new default Search model."
|
113
|
+
)
|
114
|
+
|
115
|
+
except Exception as e:
|
116
|
+
logger.error(f"Error embedding documents: {e}")
|
117
|
+
|
118
|
+
logger.info("----")
|
119
|
+
|
120
|
+
# There are also plenty of users who have indexed documents without explicitly creating a UserSearchModelConfig object. You would have to migrate these users as well, if the default is different from search_model_config_id.
|
121
|
+
current_default = get_default_search_model()
|
122
|
+
if current_default.id != new_default_search_model_config.id:
|
123
|
+
users_without_user_search_model_config = KhojUser.objects.annotate(
|
124
|
+
user_search_model_config_count=Count("usersearchmodelconfig")
|
125
|
+
).filter(user_search_model_config_count=0)
|
126
|
+
|
127
|
+
logger.info(f"Number of User objects to update: {users_without_user_search_model_config.count()}")
|
128
|
+
for user in users_without_user_search_model_config:
|
129
|
+
entry_filter = Q(user=user)
|
130
|
+
relevant_entries = Entry.objects.filter(entry_filter).all()
|
131
|
+
logger.info(f"Number of Entry objects to update for user {user}: {relevant_entries.count()}")
|
132
|
+
|
133
|
+
if apply:
|
134
|
+
try:
|
135
|
+
regenerate_entries(
|
136
|
+
entry_filter,
|
137
|
+
embeddings_model[new_default_search_model_config.name],
|
138
|
+
new_default_search_model_config,
|
139
|
+
)
|
140
|
+
|
141
|
+
UserSearchModelConfig.objects.create(user=user, setting=new_default_search_model_config)
|
142
|
+
|
143
|
+
logger.info(
|
144
|
+
f"Created UserSearchModelConfig object for user {user} to use the new default Search model."
|
145
|
+
)
|
146
|
+
logger.info(
|
147
|
+
f"Updated {relevant_entries.count()} Entry objects for user {user} to use the new default Search model."
|
148
|
+
)
|
149
|
+
except Exception as e:
|
150
|
+
logger.error(f"Error embedding documents: {e}")
|
151
|
+
else:
|
152
|
+
logger.info("Default is the same as search_model_config_id.")
|
153
|
+
|
154
|
+
all_agents = Agent.objects.all()
|
155
|
+
logger.info(f"Number of Agent objects to update: {all_agents.count()}")
|
156
|
+
for agent in all_agents:
|
157
|
+
entry_filter = Q(agent=agent)
|
158
|
+
relevant_entries = Entry.objects.filter(entry_filter).all()
|
159
|
+
logger.info(f"Number of Entry objects to update for agent {agent}: {relevant_entries.count()}")
|
160
|
+
|
161
|
+
if apply:
|
162
|
+
try:
|
163
|
+
regenerate_entries(
|
164
|
+
entry_filter,
|
165
|
+
embeddings_model[new_default_search_model_config.name],
|
166
|
+
new_default_search_model_config,
|
167
|
+
)
|
168
|
+
logger.info(
|
169
|
+
f"Updated {relevant_entries.count()} Entry objects for agent {agent} to use the new default Search model."
|
170
|
+
)
|
171
|
+
except Exception as e:
|
172
|
+
logger.error(f"Error embedding documents: {e}")
|
173
|
+
if apply and current_default.id != new_default_search_model_config.id:
|
174
|
+
# Get the existing default SearchModelConfig object and update its name
|
175
|
+
current_default.name = f"prev_default_{current_default.id}"
|
176
|
+
current_default.save()
|
177
|
+
|
178
|
+
# Update the new default SearchModelConfig object's name
|
179
|
+
new_default_search_model_config.name = "default"
|
180
|
+
new_default_search_model_config.save()
|
181
|
+
if not apply:
|
182
|
+
logger.info("Run the command with the --apply flag to apply the new default Search model.")
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Generated by Django 5.0.8 on 2024-10-20 19:24
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
|
5
|
+
|
6
|
+
def set_enabled_trial_at(apps, schema_editor):
|
7
|
+
Subscription = apps.get_model("database", "Subscription")
|
8
|
+
for subscription in Subscription.objects.all():
|
9
|
+
subscription.enabled_trial_at = subscription.created_at
|
10
|
+
subscription.save()
|
11
|
+
|
12
|
+
|
13
|
+
class Migration(migrations.Migration):
|
14
|
+
dependencies = [
|
15
|
+
("database", "0070_alter_agent_input_tools_alter_agent_output_modes"),
|
16
|
+
]
|
17
|
+
|
18
|
+
operations = [
|
19
|
+
migrations.AddField(
|
20
|
+
model_name="subscription",
|
21
|
+
name="enabled_trial_at",
|
22
|
+
field=models.DateTimeField(blank=True, default=None, null=True),
|
23
|
+
),
|
24
|
+
migrations.AlterField(
|
25
|
+
model_name="subscription",
|
26
|
+
name="type",
|
27
|
+
field=models.CharField(
|
28
|
+
choices=[("trial", "Trial"), ("standard", "Standard")], default="standard", max_length=20
|
29
|
+
),
|
30
|
+
),
|
31
|
+
migrations.RunPython(set_enabled_trial_at),
|
32
|
+
]
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Generated by Django 5.0.8 on 2024-10-21 21:09
|
2
|
+
|
3
|
+
import django.db.models.deletion
|
4
|
+
from django.db import migrations, models
|
5
|
+
|
6
|
+
|
7
|
+
class Migration(migrations.Migration):
|
8
|
+
dependencies = [
|
9
|
+
("database", "0071_subscription_enabled_trial_at_and_more"),
|
10
|
+
]
|
11
|
+
|
12
|
+
operations = [
|
13
|
+
migrations.AddField(
|
14
|
+
model_name="entry",
|
15
|
+
name="search_model",
|
16
|
+
field=models.ForeignKey(
|
17
|
+
blank=True,
|
18
|
+
default=None,
|
19
|
+
null=True,
|
20
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
21
|
+
to="database.searchmodelconfig",
|
22
|
+
),
|
23
|
+
),
|
24
|
+
]
|
khoj/database/models/__init__.py
CHANGED
@@ -73,9 +73,10 @@ class Subscription(BaseModel):
|
|
73
73
|
STANDARD = "standard"
|
74
74
|
|
75
75
|
user = models.OneToOneField(KhojUser, on_delete=models.CASCADE, related_name="subscription")
|
76
|
-
type = models.CharField(max_length=20, choices=Type.choices, default=Type.
|
76
|
+
type = models.CharField(max_length=20, choices=Type.choices, default=Type.STANDARD)
|
77
77
|
is_recurring = models.BooleanField(default=False)
|
78
78
|
renewal_date = models.DateTimeField(null=True, default=None, blank=True)
|
79
|
+
enabled_trial_at = models.DateTimeField(null=True, default=None, blank=True)
|
79
80
|
|
80
81
|
|
81
82
|
class OpenAIProcessorConversationConfig(BaseModel):
|
@@ -448,6 +449,7 @@ class UserVoiceModelConfig(BaseModel):
|
|
448
449
|
setting = models.ForeignKey(VoiceModelOption, on_delete=models.CASCADE, default=None, null=True, blank=True)
|
449
450
|
|
450
451
|
|
452
|
+
# TODO Delete this model once all users have been migrated to the server's default settings
|
451
453
|
class UserSearchModelConfig(BaseModel):
|
452
454
|
user = models.OneToOneField(KhojUser, on_delete=models.CASCADE)
|
453
455
|
setting = models.ForeignKey(SearchModelConfig, on_delete=models.CASCADE)
|
@@ -534,6 +536,7 @@ class Entry(BaseModel):
|
|
534
536
|
url = models.URLField(max_length=400, default=None, null=True, blank=True)
|
535
537
|
hashed_value = models.CharField(max_length=100)
|
536
538
|
corpus_id = models.UUIDField(default=uuid.uuid4, editable=False)
|
539
|
+
search_model = models.ForeignKey(SearchModelConfig, on_delete=models.SET_NULL, default=None, null=True, blank=True)
|
537
540
|
|
538
541
|
def save(self, *args, **kwargs):
|
539
542
|
if self.user and self.agent:
|
@@ -1 +1 @@
|
|
1
|
-
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/0e790e04fd40ad16-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/467a524c75e7d7c0.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/825406e5ebee86d3.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-95652a0eef2b0aeb.js"/><script src="/_next/static/chunks/fd9d1056-2b978342deb60015.js" async=""></script><script src="/_next/static/chunks/7023-a5bf5744d19b3bd3.js" async=""></script><script src="/_next/static/chunks/main-app-6d6ee3495efe03d4.js" async=""></script><meta name="robots" content="noindex"/><meta http-equiv="Content-Security-Policy" content="default-src 'self' https://assets.khoj.dev; media-src * blob:; script-src 'self' https://assets.khoj.dev 'unsafe-inline' 'unsafe-eval'; connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110; style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com; child-src 'none'; object-src 'none';"/><title>404: This page could not be found.</title><title>Khoj AI - Home</title><meta name="description" content="Your Second Brain."/><link rel="manifest" href="/static/khoj.webmanifest" crossorigin="use-credentials"/><meta property="og:title" content="Khoj AI - Home"/><meta property="og:description" content="Your Second Brain."/><meta property="og:url" content="https://app.khoj.dev/"/><meta property="og:site_name" content="Khoj AI"/><meta property="og:image" content="https://assets.khoj.dev/khoj_lantern_256x256.png"/><meta property="og:image:width" content="256"/><meta property="og:image:height" content="256"/><meta property="og:image" content="https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:type" content="website"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:title" content="Khoj AI - Home"/><meta name="twitter:description" content="Your Second Brain."/><meta name="twitter:image" content="https://assets.khoj.dev/khoj_lantern_256x256.png"/><meta name="twitter:image:width" content="256"/><meta name="twitter:image:height" content="256"/><meta name="twitter:image" content="https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png"/><meta name="twitter:image:width" content="1200"/><meta name="twitter:image:height" content="630"/><link rel="icon" href="/static/assets/icons/khoj_lantern.ico"/><link rel="apple-touch-icon" href="/static/assets/icons/khoj_lantern_256x256.png"/><meta name="next-size-adjust"/><script src="/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js" noModule=""></script></head><body class="__className_e594dd"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><script src="/_next/static/chunks/webpack-95652a0eef2b0aeb.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/media/0e790e04fd40ad16-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/_next/static/css/467a524c75e7d7c0.css\",\"style\"]\n3:HL[\"/_next/static/css/825406e5ebee86d3.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"4:I[95751,[],\"\"]\n6:I[39275,[],\"\"]\n7:I[61343,[],\"\"]\nd:I[76130,[],\"\"]\n8:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n9:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\na:{\"display\":\"inline-block\"}\nb:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\ne:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L4\",null,{\"buildId\":\"l0c66lMus19JlWgScUQtj\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"_not-found\",\"\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L5\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L6\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L7\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/467a524c75e7d7c0.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/825406e5ebee86d3.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[[\"$\",\"meta\",null,{\"httpEquiv\":\"Content-Security-Policy\",\"content\":\"default-src 'self' https://assets.khoj.dev; media-src * blob:; script-src 'self' https://assets.khoj.dev 'unsafe-inline' 'unsafe-eval'; connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110; style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com; child-src 'none'; object-src 'none';\"}],[\"$\",\"body\",null,{\"className\":\"__className_e594dd\",\"children\":[\"$\",\"$L6\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L7\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$8\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$9\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$a\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$b\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$Lc\"],\"globalErrorComponent\":\"$d\",\"missingSlots\":\"$We\"}]\n"])</script><script>self.__next_f.push([1,"c:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"Khoj AI - Home\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Your Second Brain.\"}],[\"$\",\"link\",\"4\",{\"rel\":\"manifest\",\"href\":\"/static/khoj.webmanifest\",\"crossOrigin\":\"use-credentials\"}],[\"$\",\"meta\",\"5\",{\"property\":\"og:title\",\"content\":\"Khoj AI - Home\"}],[\"$\",\"meta\",\"6\",{\"property\":\"og:description\",\"content\":\"Your Second Brain.\"}],[\"$\",\"meta\",\"7\",{\"property\":\"og:url\",\"content\":\"https://app.khoj.dev/\"}],[\"$\",\"meta\",\"8\",{\"property\":\"og:site_name\",\"content\":\"Khoj AI\"}],[\"$\",\"meta\",\"9\",{\"property\":\"og:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_256x256.png\"}],[\"$\",\"meta\",\"10\",{\"property\":\"og:image:width\",\"content\":\"256\"}],[\"$\",\"meta\",\"11\",{\"property\":\"og:image:height\",\"content\":\"256\"}],[\"$\",\"meta\",\"12\",{\"property\":\"og:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png\"}],[\"$\",\"meta\",\"13\",{\"property\":\"og:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"14\",{\"property\":\"og:image:height\",\"content\":\"630\"}],[\"$\",\"meta\",\"15\",{\"property\":\"og:type\",\"content\":\"website\"}],[\"$\",\"meta\",\"16\",{\"name\":\"twitter:card\",\"content\":\"summary_large_image\"}],[\"$\",\"meta\",\"17\",{\"name\":\"twitter:title\",\"content\":\"Khoj AI - Home\"}],[\"$\",\"meta\",\"18\",{\"name\":\"twitter:description\",\"content\":\"Your Second Brain.\"}],[\"$\",\"meta\",\"19\",{\"name\":\"twitter:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_256x256.png\"}],[\"$\",\"meta\",\"20\",{\"name\":\"twitter:image:width\",\"content\":\"256\"}],[\"$\",\"meta\",\"21\",{\"name\":\"twitter:image:height\",\"content\":\"256\"}],[\"$\",\"meta\",\"22\",{\"name\":\"twitter:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png\"}],[\"$\",\"meta\",\"23\",{\"name\":\"twitter:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"24\",{\"name\":\"twitter:image:height\",\"content\":\"630\"}],[\"$\",\"link\",\"25\",{\"rel\":\"icon\",\"href\":\"/static/assets/icons/khoj_lantern.ico\"}],[\"$\",\"link\",\"26\",{\"rel\":\"apple-touch-icon\",\"href\":\"/static/assets/icons/khoj_lantern_256x256.png\"}],[\"$\",\"meta\",\"27\",{\"name\":\"next-size-adjust\"}]]\n"])</script><script>self.__next_f.push([1,"5:null\n"])</script></body></html>
|
1
|
+
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/0e790e04fd40ad16-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/467a524c75e7d7c0.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/76d55eb435962b19.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-35c06f544e18305f.js"/><script src="/_next/static/chunks/fd9d1056-2b978342deb60015.js" async=""></script><script src="/_next/static/chunks/7023-a5bf5744d19b3bd3.js" async=""></script><script src="/_next/static/chunks/main-app-6d6ee3495efe03d4.js" async=""></script><meta name="robots" content="noindex"/><meta http-equiv="Content-Security-Policy" content="default-src 'self' https://assets.khoj.dev; media-src * blob:; script-src 'self' https://assets.khoj.dev 'unsafe-inline' 'unsafe-eval'; connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110; style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com; child-src 'none'; object-src 'none';"/><title>404: This page could not be found.</title><title>Khoj AI - Home</title><meta name="description" content="Your Second Brain."/><link rel="manifest" href="/static/khoj.webmanifest" crossorigin="use-credentials"/><meta property="og:title" content="Khoj AI - Home"/><meta property="og:description" content="Your Second Brain."/><meta property="og:url" content="https://app.khoj.dev/"/><meta property="og:site_name" content="Khoj AI"/><meta property="og:image" content="https://assets.khoj.dev/khoj_lantern_256x256.png"/><meta property="og:image:width" content="256"/><meta property="og:image:height" content="256"/><meta property="og:image" content="https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:type" content="website"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:title" content="Khoj AI - Home"/><meta name="twitter:description" content="Your Second Brain."/><meta name="twitter:image" content="https://assets.khoj.dev/khoj_lantern_256x256.png"/><meta name="twitter:image:width" content="256"/><meta name="twitter:image:height" content="256"/><meta name="twitter:image" content="https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png"/><meta name="twitter:image:width" content="1200"/><meta name="twitter:image:height" content="630"/><link rel="icon" href="/static/assets/icons/khoj_lantern.ico"/><link rel="apple-touch-icon" href="/static/assets/icons/khoj_lantern_256x256.png"/><meta name="next-size-adjust"/><script src="/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js" noModule=""></script></head><body class="__className_e594dd"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><script src="/_next/static/chunks/webpack-35c06f544e18305f.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/media/0e790e04fd40ad16-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/_next/static/css/467a524c75e7d7c0.css\",\"style\"]\n3:HL[\"/_next/static/css/76d55eb435962b19.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"4:I[95751,[],\"\"]\n6:I[39275,[],\"\"]\n7:I[61343,[],\"\"]\nd:I[76130,[],\"\"]\n8:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n9:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\na:{\"display\":\"inline-block\"}\nb:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\ne:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L4\",null,{\"buildId\":\"GH1Wb7mTB8D7ZsHW6iRF6\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"_not-found\",\"\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L5\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L6\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L7\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/467a524c75e7d7c0.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/76d55eb435962b19.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[[\"$\",\"meta\",null,{\"httpEquiv\":\"Content-Security-Policy\",\"content\":\"default-src 'self' https://assets.khoj.dev; media-src * blob:; script-src 'self' https://assets.khoj.dev 'unsafe-inline' 'unsafe-eval'; connect-src 'self' blob: https://ipapi.co/json ws://localhost:42110; style-src 'self' https://assets.khoj.dev 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https://*.khoj.dev https://*.googleusercontent.com https://*.google.com/ https://*.gstatic.com; font-src 'self' https://assets.khoj.dev https://fonts.gstatic.com; child-src 'none'; object-src 'none';\"}],[\"$\",\"body\",null,{\"className\":\"__className_e594dd\",\"children\":[\"$\",\"$L6\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L7\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$8\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$9\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$a\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$b\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$Lc\"],\"globalErrorComponent\":\"$d\",\"missingSlots\":\"$We\"}]\n"])</script><script>self.__next_f.push([1,"c:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"Khoj AI - Home\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Your Second Brain.\"}],[\"$\",\"link\",\"4\",{\"rel\":\"manifest\",\"href\":\"/static/khoj.webmanifest\",\"crossOrigin\":\"use-credentials\"}],[\"$\",\"meta\",\"5\",{\"property\":\"og:title\",\"content\":\"Khoj AI - Home\"}],[\"$\",\"meta\",\"6\",{\"property\":\"og:description\",\"content\":\"Your Second Brain.\"}],[\"$\",\"meta\",\"7\",{\"property\":\"og:url\",\"content\":\"https://app.khoj.dev/\"}],[\"$\",\"meta\",\"8\",{\"property\":\"og:site_name\",\"content\":\"Khoj AI\"}],[\"$\",\"meta\",\"9\",{\"property\":\"og:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_256x256.png\"}],[\"$\",\"meta\",\"10\",{\"property\":\"og:image:width\",\"content\":\"256\"}],[\"$\",\"meta\",\"11\",{\"property\":\"og:image:height\",\"content\":\"256\"}],[\"$\",\"meta\",\"12\",{\"property\":\"og:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png\"}],[\"$\",\"meta\",\"13\",{\"property\":\"og:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"14\",{\"property\":\"og:image:height\",\"content\":\"630\"}],[\"$\",\"meta\",\"15\",{\"property\":\"og:type\",\"content\":\"website\"}],[\"$\",\"meta\",\"16\",{\"name\":\"twitter:card\",\"content\":\"summary_large_image\"}],[\"$\",\"meta\",\"17\",{\"name\":\"twitter:title\",\"content\":\"Khoj AI - Home\"}],[\"$\",\"meta\",\"18\",{\"name\":\"twitter:description\",\"content\":\"Your Second Brain.\"}],[\"$\",\"meta\",\"19\",{\"name\":\"twitter:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_256x256.png\"}],[\"$\",\"meta\",\"20\",{\"name\":\"twitter:image:width\",\"content\":\"256\"}],[\"$\",\"meta\",\"21\",{\"name\":\"twitter:image:height\",\"content\":\"256\"}],[\"$\",\"meta\",\"22\",{\"name\":\"twitter:image\",\"content\":\"https://assets.khoj.dev/khoj_lantern_logomarktype_1200x630.png\"}],[\"$\",\"meta\",\"23\",{\"name\":\"twitter:image:width\",\"content\":\"1200\"}],[\"$\",\"meta\",\"24\",{\"name\":\"twitter:image:height\",\"content\":\"630\"}],[\"$\",\"link\",\"25\",{\"rel\":\"icon\",\"href\":\"/static/assets/icons/khoj_lantern.ico\"}],[\"$\",\"link\",\"26\",{\"rel\":\"apple-touch-icon\",\"href\":\"/static/assets/icons/khoj_lantern_256x256.png\"}],[\"$\",\"meta\",\"27\",{\"name\":\"next-size-adjust\"}]]\n"])</script><script>self.__next_f.push([1,"5:null\n"])</script></body></html>
|