Skip to content

Commit 0af54d2

Browse files
committed
Drop old code to sync files on server filesystem. Clean cli, init paths
This stale code was originally used to index files on server file system directly by server. We currently push files to sync via API. Server side syncing of remote content like Github and Notion is still supported. But old, unused code for server side sync of files on server fs is being cleaned out. New --log-file cli args allows specifying where khoj server should store logs on fs. This replaces the --config-file cli arg that was only being used as a proxy for deciding where to store the log file. - TODO - Tests are broken. They were relying on the server side content syncing for test setup
1 parent 7468e5a commit 0af54d2

21 files changed

+82
-688
lines changed

src/khoj/configure.py

Lines changed: 21 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,11 @@
4444
)
4545
from khoj.database.models import ClientApplication, KhojUser, ProcessLock, Subscription
4646
from khoj.processor.embeddings import CrossEncoderModel, EmbeddingsModel
47-
from khoj.routers.api_content import configure_content, configure_search
47+
from khoj.routers.api_content import configure_content
4848
from khoj.routers.twilio import is_twilio_enabled
4949
from khoj.utils import constants, state
5050
from khoj.utils.config import SearchType
51-
from khoj.utils.fs_syncer import collect_files
52-
from khoj.utils.helpers import is_none_or_empty, telemetry_disabled
53-
from khoj.utils.rawconfig import FullConfig
51+
from khoj.utils.helpers import is_none_or_empty
5452

5553
logger = logging.getLogger(__name__)
5654

@@ -192,14 +190,6 @@ async def authenticate(self, request: HTTPConnection):
192190
return AuthCredentials(), UnauthenticatedUser()
193191

194192

195-
def initialize_server(config: Optional[FullConfig]):
196-
try:
197-
configure_server(config, init=True)
198-
except Exception as e:
199-
logger.error(f"🚨 Failed to configure server on app load: {e}", exc_info=True)
200-
raise e
201-
202-
203193
def clean_connections(func):
204194
"""
205195
A decorator that ensures that Django database connections that have become unusable, or are obsolete, are closed
@@ -220,19 +210,7 @@ def func_wrapper(*args, **kwargs):
220210
return func_wrapper
221211

222212

223-
def configure_server(
224-
config: FullConfig,
225-
regenerate: bool = False,
226-
search_type: Optional[SearchType] = None,
227-
init=False,
228-
user: KhojUser = None,
229-
):
230-
# Update Config
231-
if config == None:
232-
logger.info(f"Initializing with default config.")
233-
config = FullConfig()
234-
state.config = config
235-
213+
def initialize_server():
236214
if ConversationAdapters.has_valid_ai_model_api():
237215
ai_model_api = ConversationAdapters.get_ai_model_api()
238216
state.openai_client = openai.OpenAI(api_key=ai_model_api.api_key, base_url=ai_model_api.api_base_url)
@@ -269,43 +247,33 @@ def configure_server(
269247
)
270248

271249
state.SearchType = configure_search_types()
272-
state.search_models = configure_search(state.search_models, state.config.search_type)
273-
setup_default_agent(user)
250+
setup_default_agent()
274251

275-
message = (
276-
"📡 Telemetry disabled"
277-
if telemetry_disabled(state.config.app, state.telemetry_disabled)
278-
else "📡 Telemetry enabled"
279-
)
252+
message = "📡 Telemetry disabled" if state.telemetry_disabled else "📡 Telemetry enabled"
280253
logger.info(message)
281254

282-
if not init:
283-
initialize_content(user, regenerate, search_type)
284-
285255
except Exception as e:
286256
logger.error(f"Failed to load some search models: {e}", exc_info=True)
287257

288258

289-
def setup_default_agent(user: KhojUser):
290-
AgentAdapters.create_default_agent(user)
259+
def setup_default_agent():
260+
AgentAdapters.create_default_agent()
291261

292262

293263
def initialize_content(user: KhojUser, regenerate: bool, search_type: Optional[SearchType] = None):
294264
# Initialize Content from Config
295-
if state.search_models:
296-
try:
297-
logger.info("📬 Updating content index...")
298-
all_files = collect_files(user=user)
299-
status = configure_content(
300-
user,
301-
all_files,
302-
regenerate,
303-
search_type,
304-
)
305-
if not status:
306-
raise RuntimeError("Failed to update content index")
307-
except Exception as e:
308-
raise e
265+
try:
266+
logger.info("📬 Updating content index...")
267+
status = configure_content(
268+
user,
269+
{},
270+
regenerate,
271+
search_type,
272+
)
273+
if not status:
274+
raise RuntimeError("Failed to update content index")
275+
except Exception as e:
276+
raise e
309277

310278

311279
def configure_routes(app):
@@ -379,8 +347,7 @@ async def dispatch(self, request: Request, call_next):
379347

380348
def update_content_index():
381349
for user in get_all_users():
382-
all_files = collect_files(user=user)
383-
success = configure_content(user, all_files)
350+
success = configure_content(user, {})
384351
if not success:
385352
raise RuntimeError("Failed to update content index")
386353
logger.info("📪 Content index updated via Scheduler")
@@ -405,7 +372,7 @@ def configure_search_types():
405372
@schedule.repeat(schedule.every(2).minutes)
406373
@clean_connections
407374
def upload_telemetry():
408-
if telemetry_disabled(state.config.app, state.telemetry_disabled) or not state.telemetry:
375+
if state.telemetry_disabled or not state.telemetry:
409376
return
410377

411378
try:

src/khoj/database/adapters/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -788,8 +788,8 @@ def get_default_agent():
788788
return Agent.objects.filter(name=AgentAdapters.DEFAULT_AGENT_NAME).first()
789789

790790
@staticmethod
791-
def create_default_agent(user: KhojUser):
792-
default_chat_model = ConversationAdapters.get_default_chat_model(user)
791+
def create_default_agent():
792+
default_chat_model = ConversationAdapters.get_default_chat_model(user=None)
793793
if default_chat_model is None:
794794
logger.info("No default conversation config found, skipping default agent creation")
795795
return None
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Generated by Django 5.1.10 on 2025-07-25 23:30
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("database", "0092_alter_chatmodel_model_type_alter_chatmodel_name_and_more"),
9+
]
10+
11+
operations = [
12+
migrations.RemoveField(
13+
model_name="localorgconfig",
14+
name="user",
15+
),
16+
migrations.RemoveField(
17+
model_name="localpdfconfig",
18+
name="user",
19+
),
20+
migrations.RemoveField(
21+
model_name="localplaintextconfig",
22+
name="user",
23+
),
24+
migrations.DeleteModel(
25+
name="LocalMarkdownConfig",
26+
),
27+
migrations.DeleteModel(
28+
name="LocalOrgConfig",
29+
),
30+
migrations.DeleteModel(
31+
name="LocalPdfConfig",
32+
),
33+
migrations.DeleteModel(
34+
name="LocalPlaintextConfig",
35+
),
36+
]

src/khoj/database/models/__init__.py

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -488,34 +488,6 @@ def save(self, *args, **kwargs):
488488
super().save(*args, **kwargs)
489489

490490

491-
class LocalOrgConfig(DbBaseModel):
492-
input_files = models.JSONField(default=list, null=True)
493-
input_filter = models.JSONField(default=list, null=True)
494-
index_heading_entries = models.BooleanField(default=False)
495-
user = models.ForeignKey(KhojUser, on_delete=models.CASCADE)
496-
497-
498-
class LocalMarkdownConfig(DbBaseModel):
499-
input_files = models.JSONField(default=list, null=True)
500-
input_filter = models.JSONField(default=list, null=True)
501-
index_heading_entries = models.BooleanField(default=False)
502-
user = models.ForeignKey(KhojUser, on_delete=models.CASCADE)
503-
504-
505-
class LocalPdfConfig(DbBaseModel):
506-
input_files = models.JSONField(default=list, null=True)
507-
input_filter = models.JSONField(default=list, null=True)
508-
index_heading_entries = models.BooleanField(default=False)
509-
user = models.ForeignKey(KhojUser, on_delete=models.CASCADE)
510-
511-
512-
class LocalPlaintextConfig(DbBaseModel):
513-
input_files = models.JSONField(default=list, null=True)
514-
input_filter = models.JSONField(default=list, null=True)
515-
index_heading_entries = models.BooleanField(default=False)
516-
user = models.ForeignKey(KhojUser, on_delete=models.CASCADE)
517-
518-
519491
class SearchModelConfig(DbBaseModel):
520492
class ModelType(models.TextChoices):
521493
TEXT = "text"

src/khoj/main.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ def run(should_start_server=True):
138138
initialization(not args.non_interactive)
139139

140140
# Create app directory, if it doesn't exist
141-
state.config_file.parent.mkdir(parents=True, exist_ok=True)
141+
state.log_file.parent.mkdir(parents=True, exist_ok=True)
142142

143143
# Set Log File
144-
fh = logging.FileHandler(state.config_file.parent / "khoj.log", encoding="utf-8")
144+
fh = logging.FileHandler(state.log_file, encoding="utf-8")
145145
fh.setLevel(logging.DEBUG)
146146
logger.addHandler(fh)
147147

@@ -194,7 +194,7 @@ def run(should_start_server=True):
194194
# Configure Middleware
195195
configure_middleware(app, state.ssl_config)
196196

197-
initialize_server(args.config)
197+
initialize_server()
198198

199199
# If the server is started through gunicorn (external to the script), don't start the server
200200
if should_start_server:
@@ -204,8 +204,7 @@ def run(should_start_server=True):
204204

205205

206206
def set_state(args):
207-
state.config_file = args.config_file
208-
state.config = args.config
207+
state.log_file = args.log_file
209208
state.verbose = args.verbose
210209
state.host = args.host
211210
state.port = args.port

src/khoj/processor/content/github/github_to_entries.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
class GithubToEntries(TextToEntries):
2222
def __init__(self, config: GithubConfig):
23-
super().__init__(config)
2423
raw_repos = config.githubrepoconfig.all()
2524
repos = []
2625
for repo in raw_repos:

src/khoj/processor/content/notion/notion_to_entries.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ class NotionBlockType(Enum):
4747

4848
class NotionToEntries(TextToEntries):
4949
def __init__(self, config: NotionConfig):
50-
super().__init__(config)
5150
self.config = NotionContentConfig(
5251
token=config.token,
5352
)

src/khoj/processor/content/text_to_entries.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
class TextToEntries(ABC):
2828
def __init__(self, config: Any = None):
2929
self.embeddings_model = state.embeddings_model
30-
self.config = config
3130
self.date_filter = DateFilter()
3231

3332
@abstractmethod

src/khoj/routers/api.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,14 @@ def update(
8787
force: Optional[bool] = False,
8888
):
8989
user = request.user.object
90-
if not state.config:
91-
error_msg = f"🚨 Khoj is not configured.\nConfigure it via http://localhost:42110/settings, plugins or by editing {state.config_file}."
92-
logger.warning(error_msg)
93-
raise HTTPException(status_code=500, detail=error_msg)
9490
try:
9591
initialize_content(user=user, regenerate=force, search_type=t)
9692
except Exception as e:
97-
error_msg = f"🚨 Failed to update server via API: {e}"
93+
error_msg = f"🚨 Failed to update server indexed content via API: {e}"
9894
logger.error(error_msg, exc_info=True)
9995
raise HTTPException(status_code=500, detail=error_msg)
10096
else:
101-
components = []
102-
if state.search_models:
103-
components.append("Search models")
104-
components_msg = ", ".join(components)
105-
logger.info(f"📪 {components_msg} updated via API")
97+
logger.info(f"📪 Server indexed content updated via API")
10698

10799
update_telemetry_state(
108100
request=request,

0 commit comments

Comments
 (0)