khoj 1.28.4.dev13__py3-none-any.whl → 1.28.4.dev23__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.
Files changed (30) hide show
  1. khoj/interface/compiled/404/index.html +1 -1
  2. khoj/interface/compiled/_next/static/chunks/{webpack-d3a4ebfc304496fb.js → webpack-c9799fdebf88abb6.js} +1 -1
  3. khoj/interface/compiled/_next/static/css/{798b0de12852bd20.css → 9d45de78fba367c1.css} +1 -1
  4. khoj/interface/compiled/agents/index.html +1 -1
  5. khoj/interface/compiled/agents/index.txt +1 -1
  6. khoj/interface/compiled/automations/index.html +1 -1
  7. khoj/interface/compiled/automations/index.txt +1 -1
  8. khoj/interface/compiled/chat/index.html +1 -1
  9. khoj/interface/compiled/chat/index.txt +1 -1
  10. khoj/interface/compiled/index.html +1 -1
  11. khoj/interface/compiled/index.txt +1 -1
  12. khoj/interface/compiled/search/index.html +1 -1
  13. khoj/interface/compiled/search/index.txt +1 -1
  14. khoj/interface/compiled/settings/index.html +1 -1
  15. khoj/interface/compiled/settings/index.txt +1 -1
  16. khoj/interface/compiled/share/chat/index.html +1 -1
  17. khoj/interface/compiled/share/chat/index.txt +1 -1
  18. khoj/processor/conversation/utils.py +7 -1
  19. khoj/processor/tools/online_search.py +49 -15
  20. khoj/routers/api.py +3 -1
  21. khoj/routers/api_chat.py +16 -9
  22. khoj/routers/helpers.py +50 -17
  23. khoj/routers/research.py +64 -29
  24. {khoj-1.28.4.dev13.dist-info → khoj-1.28.4.dev23.dist-info}/METADATA +1 -3
  25. {khoj-1.28.4.dev13.dist-info → khoj-1.28.4.dev23.dist-info}/RECORD +30 -30
  26. {khoj-1.28.4.dev13.dist-info → khoj-1.28.4.dev23.dist-info}/WHEEL +1 -1
  27. /khoj/interface/compiled/_next/static/{FPLh9rnKQbUWwU3fdzk6T → s_mKS5kELaw2v4a7_yWNP}/_buildManifest.js +0 -0
  28. /khoj/interface/compiled/_next/static/{FPLh9rnKQbUWwU3fdzk6T → s_mKS5kELaw2v4a7_yWNP}/_ssgManifest.js +0 -0
  29. {khoj-1.28.4.dev13.dist-info → khoj-1.28.4.dev23.dist-info}/entry_points.txt +0 -0
  30. {khoj-1.28.4.dev13.dist-info → khoj-1.28.4.dev23.dist-info}/licenses/LICENSE +0 -0
khoj/routers/helpers.py CHANGED
@@ -20,6 +20,7 @@ from typing import (
20
20
  Iterator,
21
21
  List,
22
22
  Optional,
23
+ Set,
23
24
  Tuple,
24
25
  Union,
25
26
  )
@@ -494,7 +495,7 @@ async def generate_online_subqueries(
494
495
  query_images: List[str] = None,
495
496
  agent: Agent = None,
496
497
  tracer: dict = {},
497
- ) -> List[str]:
498
+ ) -> Set[str]:
498
499
  """
499
500
  Generate subqueries from the given query
500
501
  """
@@ -529,14 +530,14 @@ async def generate_online_subqueries(
529
530
  try:
530
531
  response = clean_json(response)
531
532
  response = json.loads(response)
532
- response = [q.strip() for q in response["queries"] if q.strip()]
533
- if not isinstance(response, list) or not response or len(response) == 0:
533
+ response = {q.strip() for q in response["queries"] if q.strip()}
534
+ if not isinstance(response, set) or not response or len(response) == 0:
534
535
  logger.error(f"Invalid response for constructing subqueries: {response}. Returning original query: {q}")
535
- return [q]
536
+ return {q}
536
537
  return response
537
538
  except Exception as e:
538
539
  logger.error(f"Invalid response for constructing subqueries: {response}. Returning original query: {q}")
539
- return [q]
540
+ return {q}
540
541
 
541
542
 
542
543
  async def schedule_query(
@@ -1128,9 +1129,6 @@ def generate_chat_response(
1128
1129
 
1129
1130
  metadata = {}
1130
1131
  agent = AgentAdapters.get_conversation_agent_by_id(conversation.agent.id) if conversation.agent else None
1131
- query_to_run = q
1132
- if meta_research:
1133
- query_to_run = f"AI Research: {meta_research} {q}"
1134
1132
  try:
1135
1133
  partial_completion = partial(
1136
1134
  save_to_conversation_log,
@@ -1148,6 +1146,13 @@ def generate_chat_response(
1148
1146
  train_of_thought=train_of_thought,
1149
1147
  )
1150
1148
 
1149
+ query_to_run = q
1150
+ if meta_research:
1151
+ query_to_run = f"<query>{q}</query>\n<collected_research>\n{meta_research}\n</collected_research>"
1152
+ compiled_references = []
1153
+ online_results = {}
1154
+ code_results = {}
1155
+
1151
1156
  conversation_config = ConversationAdapters.get_valid_conversation_config(user, conversation)
1152
1157
  vision_available = conversation_config.vision_enabled
1153
1158
  if not vision_available and query_images:
@@ -1306,25 +1311,28 @@ class ApiUserRateLimiter:
1306
1311
  # Check if the user has exceeded the rate limit
1307
1312
  if subscribed and count_requests >= self.subscribed_requests:
1308
1313
  logger.info(
1309
- f"Rate limit: {count_requests} requests in {self.window} seconds for user: {user}. Limit is {self.subscribed_requests} requests."
1314
+ f"Rate limit: {count_requests}/{self.subscribed_requests} requests not allowed in {self.window} seconds for subscribed user: {user}."
1315
+ )
1316
+ raise HTTPException(
1317
+ status_code=429,
1318
+ detail="I'm glad you're enjoying interacting with me! You've unfortunately exceeded your usage limit for today. But let's chat more tomorrow?",
1310
1319
  )
1311
- raise HTTPException(status_code=429, detail="Slow down! Too Many Requests")
1312
1320
  if not subscribed and count_requests >= self.requests:
1313
1321
  if self.requests >= self.subscribed_requests:
1314
1322
  logger.info(
1315
- f"Rate limit: {count_requests} requests in {self.window} seconds for user: {user}. Limit is {self.subscribed_requests} requests."
1323
+ f"Rate limit: {count_requests}/{self.subscribed_requests} requests not allowed in {self.window} seconds for user: {user}."
1316
1324
  )
1317
1325
  raise HTTPException(
1318
1326
  status_code=429,
1319
- detail="Slow down! Too Many Requests",
1327
+ detail="I'm glad you're enjoying interacting with me! You've unfortunately exceeded your usage limit for today. But let's chat more tomorrow?",
1320
1328
  )
1321
1329
 
1322
1330
  logger.info(
1323
- f"Rate limit: {count_requests} requests in {self.window} seconds for user: {user}. Limit is {self.subscribed_requests} requests."
1331
+ f"Rate limit: {count_requests}/{self.requests} requests not allowed in {self.window} seconds for user: {user}."
1324
1332
  )
1325
1333
  raise HTTPException(
1326
1334
  status_code=429,
1327
- detail="I'm glad you're enjoying interacting with me! But you've exceeded your usage limit for today. Come back tomorrow or subscribe to increase your usage limit via [your settings](https://app.khoj.dev/settings).",
1335
+ detail="I'm glad you're enjoying interacting with me! You've unfortunately exceeded your usage limit for today. You can subscribe to increase your usage limit via [your settings](https://app.khoj.dev/settings) or we can continue our conversation tomorrow?",
1328
1336
  )
1329
1337
 
1330
1338
  # Add the current request to the cache
@@ -1350,6 +1358,7 @@ class ApiImageRateLimiter:
1350
1358
 
1351
1359
  # Check number of images
1352
1360
  if len(body.images) > self.max_images:
1361
+ logger.info(f"Rate limit: {len(body.images)}/{self.max_images} images not allowed per message.")
1353
1362
  raise HTTPException(
1354
1363
  status_code=429,
1355
1364
  detail=f"Those are way too many images for me! I can handle up to {self.max_images} images per message.",
@@ -1370,6 +1379,7 @@ class ApiImageRateLimiter:
1370
1379
  total_size_mb += len(image_bytes) / (1024 * 1024) # Convert bytes to MB
1371
1380
 
1372
1381
  if total_size_mb > self.max_combined_size_mb:
1382
+ logger.info(f"Data limit: {total_size_mb}MB/{self.max_combined_size_mb}MB size not allowed per message.")
1373
1383
  raise HTTPException(
1374
1384
  status_code=429,
1375
1385
  detail=f"Those images are way too large for me! I can handle up to {self.max_combined_size_mb}MB of images per message.",
@@ -1405,13 +1415,19 @@ class ConversationCommandRateLimiter:
1405
1415
 
1406
1416
  if subscribed and count_requests >= self.subscribed_rate_limit:
1407
1417
  logger.info(
1408
- f"Rate limit: {count_requests} requests in 24 hours for user: {user}. Limit is {self.subscribed_rate_limit} requests."
1418
+ f"Rate limit: {count_requests}/{self.subscribed_rate_limit} requests not allowed in 24 hours for subscribed user: {user}."
1419
+ )
1420
+ raise HTTPException(
1421
+ status_code=429,
1422
+ detail=f"I'm glad you're enjoying interacting with me! You've unfortunately exceeded your `/{conversation_command.value}` command usage limit for today. Maybe we can talk about something else for today?",
1409
1423
  )
1410
- raise HTTPException(status_code=429, detail="Slow down! Too Many Requests")
1411
1424
  if not subscribed and count_requests >= self.trial_rate_limit:
1425
+ logger.info(
1426
+ f"Rate limit: {count_requests}/{self.trial_rate_limit} requests not allowed in 24 hours for user: {user}."
1427
+ )
1412
1428
  raise HTTPException(
1413
1429
  status_code=429,
1414
- detail=f"We're glad you're enjoying Khoj! You've exceeded your `/{conversation_command.value}` command usage limit for today. Subscribe to increase your usage limit via [your settings](https://app.khoj.dev/settings).",
1430
+ detail=f"I'm glad you're enjoying interacting with me! You've unfortunately exceeded your `/{conversation_command.value}` command usage limit for today. You can subscribe to increase your usage limit via [your settings](https://app.khoj.dev/settings) or we can talk about something else for today?",
1415
1431
  )
1416
1432
  await UserRequests.objects.acreate(user=user, slug=command_slug)
1417
1433
  return
@@ -1457,16 +1473,28 @@ class ApiIndexedDataLimiter:
1457
1473
  logger.info(f"Deleted {num_deleted_entries} entries for user: {user}.")
1458
1474
 
1459
1475
  if subscribed and incoming_data_size_mb >= self.subscribed_num_entries_size:
1476
+ logger.info(
1477
+ f"Data limit: {incoming_data_size_mb}MB incoming will exceed {self.subscribed_num_entries_size}MB allowed for subscribed user: {user}."
1478
+ )
1460
1479
  raise HTTPException(status_code=429, detail="Too much data indexed.")
1461
1480
  if not subscribed and incoming_data_size_mb >= self.num_entries_size:
1481
+ logger.info(
1482
+ f"Data limit: {incoming_data_size_mb}MB incoming will exceed {self.num_entries_size}MB allowed for user: {user}."
1483
+ )
1462
1484
  raise HTTPException(
1463
1485
  status_code=429, detail="Too much data indexed. Subscribe to increase your data index limit."
1464
1486
  )
1465
1487
 
1466
1488
  user_size_data = EntryAdapters.get_size_of_indexed_data_in_mb(user)
1467
1489
  if subscribed and user_size_data + incoming_data_size_mb >= self.subscribed_total_entries_size:
1490
+ logger.info(
1491
+ f"Data limit: {incoming_data_size_mb}MB incoming + {user_size_data}MB existing will exceed {self.subscribed_total_entries_size}MB allowed for subscribed user: {user}."
1492
+ )
1468
1493
  raise HTTPException(status_code=429, detail="Too much data indexed.")
1469
1494
  if not subscribed and user_size_data + incoming_data_size_mb >= self.total_entries_size_limit:
1495
+ logger.info(
1496
+ f"Data limit: {incoming_data_size_mb}MB incoming + {user_size_data}MB existing will exceed {self.subscribed_total_entries_size}MB allowed for non subscribed user: {user}."
1497
+ )
1470
1498
  raise HTTPException(
1471
1499
  status_code=429, detail="Too much data indexed. Subscribe to increase your data index limit."
1472
1500
  )
@@ -1554,6 +1582,11 @@ def scheduled_chat(
1554
1582
  # encode the conversation_id to avoid any issues with special characters
1555
1583
  query_dict["conversation_id"] = [quote(str(conversation_id))]
1556
1584
 
1585
+ # validate that the conversation id exists. If not, delete the automation and exit.
1586
+ if not ConversationAdapters.get_conversation_by_id(conversation_id):
1587
+ AutomationAdapters.delete_automation(user, job_id)
1588
+ return
1589
+
1557
1590
  # Restructure the original query_dict into a valid JSON payload for the chat API
1558
1591
  json_payload = {key: values[0] for key, values in query_dict.items()}
1559
1592
 
khoj/routers/research.py CHANGED
@@ -43,38 +43,35 @@ async def apick_next_tool(
43
43
  location: LocationData = None,
44
44
  user_name: str = None,
45
45
  agent: Agent = None,
46
- previous_iterations_history: str = None,
46
+ previous_iterations: List[InformationCollectionIteration] = [],
47
47
  max_iterations: int = 5,
48
48
  send_status_func: Optional[Callable] = None,
49
49
  tracer: dict = {},
50
50
  ):
51
- """
52
- Given a query, determine which of the available tools the agent should use in order to answer appropriately. One at a time, and it's able to use subsequent iterations to refine the answer.
53
- """
51
+ """Given a query, determine which of the available tools the agent should use in order to answer appropriately."""
54
52
 
53
+ # Construct tool options for the agent to choose from
55
54
  tool_options = dict()
56
55
  tool_options_str = ""
57
-
58
56
  agent_tools = agent.input_tools if agent else []
59
-
60
57
  for tool, description in function_calling_description_for_llm.items():
61
58
  tool_options[tool.value] = description
62
59
  if len(agent_tools) == 0 or tool.value in agent_tools:
63
60
  tool_options_str += f'- "{tool.value}": "{description}"\n'
64
61
 
62
+ # Construct chat history with user and iteration history with researcher agent for context
65
63
  chat_history = construct_chat_history(conversation_history, agent_name=agent.name if agent else "Khoj")
64
+ previous_iterations_history = construct_iteration_history(previous_iterations, prompts.previous_iteration)
66
65
 
67
66
  if query_images:
68
67
  query = f"[placeholder for user attached images]\n{query}"
69
68
 
69
+ today = datetime.today()
70
+ location_data = f"{location}" if location else "Unknown"
70
71
  personality_context = (
71
72
  prompts.personality_context.format(personality=agent.personality) if agent and agent.personality else ""
72
73
  )
73
74
 
74
- # Extract Past User Message and Inferred Questions from Conversation Log
75
- today = datetime.today()
76
- location_data = f"{location}" if location else "Unknown"
77
-
78
75
  function_planning_prompt = prompts.plan_function_execution.format(
79
76
  tools=tool_options_str,
80
77
  chat_history=chat_history,
@@ -87,15 +84,24 @@ async def apick_next_tool(
87
84
  max_iterations=max_iterations,
88
85
  )
89
86
 
90
- with timer("Chat actor: Infer information sources to refer", logger):
91
- response = await send_message_to_model_wrapper(
92
- query=query,
93
- context=function_planning_prompt,
94
- response_type="json_object",
95
- user=user,
96
- query_images=query_images,
97
- tracer=tracer,
87
+ try:
88
+ with timer("Chat actor: Infer information sources to refer", logger):
89
+ response = await send_message_to_model_wrapper(
90
+ query=query,
91
+ context=function_planning_prompt,
92
+ response_type="json_object",
93
+ user=user,
94
+ query_images=query_images,
95
+ tracer=tracer,
96
+ )
97
+ except Exception as e:
98
+ logger.error(f"Failed to infer information sources to refer: {e}", exc_info=True)
99
+ yield InformationCollectionIteration(
100
+ tool=None,
101
+ query=None,
102
+ warning="Failed to infer information sources to refer. Skipping iteration. Try again.",
98
103
  )
104
+ return
99
105
 
100
106
  try:
101
107
  response = clean_json(response)
@@ -103,8 +109,15 @@ async def apick_next_tool(
103
109
  selected_tool = response.get("tool", None)
104
110
  generated_query = response.get("query", None)
105
111
  scratchpad = response.get("scratchpad", None)
112
+ warning = None
106
113
  logger.info(f"Response for determining relevant tools: {response}")
107
- if send_status_func:
114
+
115
+ # Detect selection of previously used query, tool combination.
116
+ previous_tool_query_combinations = {(i.tool, i.query) for i in previous_iterations}
117
+ if (selected_tool, generated_query) in previous_tool_query_combinations:
118
+ warning = f"Repeated tool, query combination detected. Skipping iteration. Try something different."
119
+ # Only send client status updates if we'll execute this iteration
120
+ elif send_status_func:
108
121
  determined_tool_message = "**Determined Tool**: "
109
122
  determined_tool_message += f"{selected_tool}({generated_query})." if selected_tool else "respond."
110
123
  determined_tool_message += f"\nReason: {scratchpad}" if scratchpad else ""
@@ -114,13 +127,14 @@ async def apick_next_tool(
114
127
  yield InformationCollectionIteration(
115
128
  tool=selected_tool,
116
129
  query=generated_query,
130
+ warning=warning,
117
131
  )
118
-
119
132
  except Exception as e:
120
133
  logger.error(f"Invalid response for determining relevant tools: {response}. {e}", exc_info=True)
121
134
  yield InformationCollectionIteration(
122
135
  tool=None,
123
136
  query=None,
137
+ warning=f"Invalid response for determining relevant tools: {response}. Skipping iteration. Fix error: {e}",
124
138
  )
125
139
 
126
140
 
@@ -147,7 +161,6 @@ async def execute_information_collection(
147
161
  document_results: List[Dict[str, str]] = []
148
162
  summarize_files: str = ""
149
163
  this_iteration = InformationCollectionIteration(tool=None, query=query)
150
- previous_iterations_history = construct_iteration_history(previous_iterations, prompts.previous_iteration)
151
164
 
152
165
  async for result in apick_next_tool(
153
166
  query,
@@ -157,7 +170,7 @@ async def execute_information_collection(
157
170
  location,
158
171
  user_name,
159
172
  agent,
160
- previous_iterations_history,
173
+ previous_iterations,
161
174
  MAX_ITERATIONS,
162
175
  send_status_func,
163
176
  tracer=tracer,
@@ -167,9 +180,16 @@ async def execute_information_collection(
167
180
  elif isinstance(result, InformationCollectionIteration):
168
181
  this_iteration = result
169
182
 
170
- if this_iteration.tool == ConversationCommand.Notes:
183
+ # Skip running iteration if warning present in iteration
184
+ if this_iteration.warning:
185
+ logger.warning(f"Research mode: {this_iteration.warning}.")
186
+
187
+ elif this_iteration.tool == ConversationCommand.Notes:
171
188
  this_iteration.context = []
172
189
  document_results = []
190
+ previous_inferred_queries = {
191
+ c["query"] for iteration in previous_iterations if iteration.context for c in iteration.context
192
+ }
173
193
  async for result in extract_references_and_questions(
174
194
  request,
175
195
  construct_tool_chat_history(previous_iterations, ConversationCommand.Notes),
@@ -181,6 +201,7 @@ async def execute_information_collection(
181
201
  location,
182
202
  send_status_func,
183
203
  query_images,
204
+ previous_inferred_queries=previous_inferred_queries,
184
205
  agent=agent,
185
206
  tracer=tracer,
186
207
  ):
@@ -204,6 +225,12 @@ async def execute_information_collection(
204
225
  logger.error(f"Error extracting document references: {e}", exc_info=True)
205
226
 
206
227
  elif this_iteration.tool == ConversationCommand.Online:
228
+ previous_subqueries = {
229
+ subquery
230
+ for iteration in previous_iterations
231
+ if iteration.onlineContext
232
+ for subquery in iteration.onlineContext.keys()
233
+ }
207
234
  async for result in search_online(
208
235
  this_iteration.query,
209
236
  construct_tool_chat_history(previous_iterations, ConversationCommand.Online),
@@ -213,11 +240,16 @@ async def execute_information_collection(
213
240
  [],
214
241
  max_webpages_to_read=0,
215
242
  query_images=query_images,
243
+ previous_subqueries=previous_subqueries,
216
244
  agent=agent,
217
245
  tracer=tracer,
218
246
  ):
219
247
  if isinstance(result, dict) and ChatEvent.STATUS in result:
220
248
  yield result[ChatEvent.STATUS]
249
+ elif is_none_or_empty(result):
250
+ this_iteration.warning = (
251
+ "Detected previously run online search queries. Skipping iteration. Try something different."
252
+ )
221
253
  else:
222
254
  online_results: Dict[str, Dict] = result # type: ignore
223
255
  this_iteration.onlineContext = online_results
@@ -302,16 +334,19 @@ async def execute_information_collection(
302
334
 
303
335
  current_iteration += 1
304
336
 
305
- if document_results or online_results or code_results or summarize_files:
306
- results_data = f"**Results**:\n"
337
+ if document_results or online_results or code_results or summarize_files or this_iteration.warning:
338
+ results_data = f"\n<iteration>{current_iteration}\n<tool>{this_iteration.tool}</tool>\n<query>{this_iteration.query}</query>\n<results>"
307
339
  if document_results:
308
- results_data += f"**Document References**:\n{yaml.dump(document_results, allow_unicode=True, sort_keys=False, default_flow_style=False)}\n"
340
+ results_data += f"\n<document_references>\n{yaml.dump(document_results, allow_unicode=True, sort_keys=False, default_flow_style=False)}\n</document_references>"
309
341
  if online_results:
310
- results_data += f"**Online Results**:\n{yaml.dump(online_results, allow_unicode=True, sort_keys=False, default_flow_style=False)}\n"
342
+ results_data += f"\n<online_results>\n{yaml.dump(online_results, allow_unicode=True, sort_keys=False, default_flow_style=False)}\n</online_results>"
311
343
  if code_results:
312
- results_data += f"**Code Results**:\n{yaml.dump(code_results, allow_unicode=True, sort_keys=False, default_flow_style=False)}\n"
344
+ results_data += f"\n<code_results>\n{yaml.dump(code_results, allow_unicode=True, sort_keys=False, default_flow_style=False)}\n</code_results>"
313
345
  if summarize_files:
314
- results_data += f"**Summarized Files**:\n{yaml.dump(summarize_files, allow_unicode=True, sort_keys=False, default_flow_style=False)}\n"
346
+ results_data += f"\n<summarized_files>\n{yaml.dump(summarize_files, allow_unicode=True, sort_keys=False, default_flow_style=False)}\n</summarized_files>"
347
+ if this_iteration.warning:
348
+ results_data += f"\n<warning>\n{this_iteration.warning}\n</warning>"
349
+ results_data += "\n</results>\n</iteration>"
315
350
 
316
351
  # intermediate_result = await extract_relevant_info(this_iteration.query, results_data, agent)
317
352
  this_iteration.summarizedResult = results_data
@@ -1,13 +1,11 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: khoj
3
- Version: 1.28.4.dev13
3
+ Version: 1.28.4.dev23
4
4
  Summary: Your Second Brain
5
5
  Project-URL: Homepage, https://khoj.dev
6
6
  Project-URL: Documentation, https://docs.khoj.dev
7
7
  Project-URL: Code, https://github.com/khoj-ai/khoj
8
8
  Author: Debanjum Singh Solanky, Saba Imran
9
- License-Expression: AGPL-3.0-or-later
10
- License-File: LICENSE
11
9
  Keywords: AI,NLP,images,markdown,org-mode,pdf,productivity,search,semantic-search
12
10
  Classifier: Development Status :: 5 - Production/Stable
13
11
  Classifier: Intended Audience :: Information Technology
@@ -110,17 +110,15 @@ khoj/interface/compiled/chat.svg,sha256=l2JoYRRgk201adTTdvJ-buKUrc0WGfsudix5xEvt
110
110
  khoj/interface/compiled/close.svg,sha256=hQ2iFLkNzHk0_iyTrSbwnWAeXYlgA-c2Eof2Iqh76n4,417
111
111
  khoj/interface/compiled/copy-button-success.svg,sha256=byqWAYD3Pn9IOXRjOKudJ-TJbP2UESbQGvtLWazNGjY,829
112
112
  khoj/interface/compiled/copy-button.svg,sha256=05bKM2eRxksfBlAPT7yMaoNJEk85bZCxQg67EVrPeHo,669
113
- khoj/interface/compiled/index.html,sha256=RcRSLCbSASi2GMwbMjaXqMg3skPTFHjNfUHZCXbpZE4,12184
114
- khoj/interface/compiled/index.txt,sha256=gp4xlyMW2HGp4adRk5QysVor0LTFEilSi4Bz9OFGHeE,5625
113
+ khoj/interface/compiled/index.html,sha256=qME4n1Ihsq3R7K4I2oPNmX-uS7zrGbNxF8UMyTGyE0o,12184
114
+ khoj/interface/compiled/index.txt,sha256=SUPF0b46a_CuN6zzE8fRlgeBsTGIi2XuTOi67YgFGUo,5625
115
115
  khoj/interface/compiled/khoj.webmanifest,sha256=lsknYkvEdMbRTOUYKXPM_8krN2gamJmM4u3qj8u9lrU,1682
116
116
  khoj/interface/compiled/logo.svg,sha256=_QCKVYM4WT2Qhcf7aVFImjq_s5CwjynGXYAOgI7yf8w,8059
117
117
  khoj/interface/compiled/send.svg,sha256=VdavOWkVddcwcGcld6pdfmwfz7S91M-9O28cfeiKJkM,635
118
118
  khoj/interface/compiled/share.svg,sha256=91lwo75PvMDrgocuZQab6EQ62CxRbubh9Bhw7CWMKbg,1221
119
119
  khoj/interface/compiled/thumbs-down.svg,sha256=JGNl-DwoRmH2XFMPWwFFklmoYtKxaQbkLE3nuYKe8ZY,1019
120
120
  khoj/interface/compiled/thumbs-up.svg,sha256=yS1wxTRtiztkN-6nZciLoYQUB_KTYNPV8xFRwH2TQFw,1036
121
- khoj/interface/compiled/404/index.html,sha256=CaXZdYNgi-kcRPwrSsgrApKqybd5BRwBOjJAaxPPN-I,12051
122
- khoj/interface/compiled/_next/static/FPLh9rnKQbUWwU3fdzk6T/_buildManifest.js,sha256=6I9QUstNpJnhe3leR2Daw0pSXwzcbBscv6h2jmmPpms,224
123
- khoj/interface/compiled/_next/static/FPLh9rnKQbUWwU3fdzk6T/_ssgManifest.js,sha256=Z49s4suAsf5y_GfnQSvm4qtq2ggxEbZPfEDTXjy6XgA,80
121
+ khoj/interface/compiled/404/index.html,sha256=OR8BtNZ4G242aT1oWLBFEsurN-pz2cSFEKBDPGgtgCQ,12051
124
122
  khoj/interface/compiled/_next/static/chunks/1210.132a7e1910006bbb.js,sha256=2dJueIfOg5qlQdanOM9HrgwcfrUXCD57bfd8Iv7iJcU,2104
125
123
  khoj/interface/compiled/_next/static/chunks/1279-f37ee4a388ebf544.js,sha256=U_1WaocOdgJ4HZB8tRx_izzYGD1EZlCohC1uLCffCWc,45582
126
124
  khoj/interface/compiled/_next/static/chunks/1459.690bf20e7d7b7090.js,sha256=z-ruZPxF_Z3ef_WOThd9Ox36AMhxaW3znizVivNnA34,34239
@@ -149,7 +147,7 @@ khoj/interface/compiled/_next/static/chunks/framework-8e0e0f4a6b83a956.js,sha256
149
147
  khoj/interface/compiled/_next/static/chunks/main-1ea5c2e0fdef4626.js,sha256=8_u87PGI3PahFbDfGWGvpD-a18J7X7ChUqWIeqxVq7g,111061
150
148
  khoj/interface/compiled/_next/static/chunks/main-app-6d6ee3495efe03d4.js,sha256=i52E7sWOcSq1G8eYZL3mtTxbUbwRNxcAbSWQ6uWpMsY,475
151
149
  khoj/interface/compiled/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js,sha256=6QPOwdWeAVe8x-SsiDrm-Ga6u2DkqgG5SFqglrlyIgA,91381
152
- khoj/interface/compiled/_next/static/chunks/webpack-d3a4ebfc304496fb.js,sha256=4W8e6VbNih5VrlG4t7jslX1H1vt8uOvpe-W04JxNFXs,4054
150
+ khoj/interface/compiled/_next/static/chunks/webpack-c9799fdebf88abb6.js,sha256=dZ5rJCf_vZpW-T6jTzDlyIzqJuaFQ1bxlyO79BYi_7Y,4054
153
151
  khoj/interface/compiled/_next/static/chunks/app/layout-86561d2fac35a91a.js,sha256=2EWsyKE2kcC5uDvsOtgG5OP0hHCX8sCph4NqhUU2rCg,442
154
152
  khoj/interface/compiled/_next/static/chunks/app/page-322c37514a3a613a.js,sha256=6Ns7ULOLSbEuw7_LjRd0sMsiioPtq2jgT0KCs1HP3aE,29487
155
153
  khoj/interface/compiled/_next/static/chunks/app/_not-found/page-07ff4ab42b07845e.js,sha256=3mCUnxfMxyK44eqk21TVBrC6u--WSbvx31fTmQuOvMQ,1755
@@ -172,8 +170,8 @@ khoj/interface/compiled/_next/static/css/1f293605f2871853.css,sha256=G2b3Wx4e0DR
172
170
  khoj/interface/compiled/_next/static/css/3cf13271869a4aeb.css,sha256=sGjJTeMeN6wbQF4OCPgWYgJmSLLSHyzIH2rSVstWx7k,1857
173
171
  khoj/interface/compiled/_next/static/css/4cae6c0e5c72fb2d.css,sha256=3CjTMmtMrm_MYt1ywtUh2MHEjSLSl356SQLl4hdBuYw,534
174
172
  khoj/interface/compiled/_next/static/css/5a400c87d295e68a.css,sha256=ojDUPJ9fJpEo9DzTAsEa-k1cg7Bef-nSTfpszMiqknQ,17711
175
- khoj/interface/compiled/_next/static/css/798b0de12852bd20.css,sha256=W8665WxP8h0XuZJ_HkEOnSD0ncCHomCi1O7ABCe_RuA,8785
176
173
  khoj/interface/compiled/_next/static/css/80bd6301fc657983.css,sha256=T7_aQHcWpQBQLKadauHNzjYGw713FtRNTlUqmJjsL6I,1634
174
+ khoj/interface/compiled/_next/static/css/9d45de78fba367c1.css,sha256=TGW4CbYNGAfDm8sAwMbO2zxxIdxxKJq5fhxVpHgRW0E,8829
177
175
  khoj/interface/compiled/_next/static/css/d2bc549245313f26.css,sha256=qWp5cJlw4rOWHy1fnNQsCrnTzvaEtCzihIVem9ocN1o,3055444
178
176
  khoj/interface/compiled/_next/static/media/5455839c73f146e7-s.p.woff2,sha256=BUeNjYxyX7Bu76aNlJrZtW3PwYgcH-kp8syFdODZoyc,35788
179
177
  khoj/interface/compiled/_next/static/media/5984b96ba4822821-s.woff2,sha256=RFrf6fMTduuQwEe78qK6_Y_Mnj97HmRDG-VujYxwA90,99368
@@ -247,8 +245,10 @@ khoj/interface/compiled/_next/static/media/flags.3afdda2f.webp,sha256=M2AW_HLpBn
247
245
  khoj/interface/compiled/_next/static/media/flags@2x.5fbe9fc1.webp,sha256=BBeRPBZkxY3-aKkMnYv5TSkxmbeMbyUH4VRIPfrWg1E,137406
248
246
  khoj/interface/compiled/_next/static/media/globe.98e105ca.webp,sha256=g3ofb8-W9GM75zIhlvQhaS8I2py9TtrovOKR3_7Jf04,514
249
247
  khoj/interface/compiled/_next/static/media/globe@2x.974df6f8.webp,sha256=I_N7Yke3IOoS-0CC6XD8o0IUWG8PdPbrHmf6lpgWlZY,1380
250
- khoj/interface/compiled/agents/index.html,sha256=bIz3RguDeq9piDEbtUAJn3Y_XSb7rEz_s80uy1WYlTc,12658
251
- khoj/interface/compiled/agents/index.txt,sha256=s4R7VKjJeP-B0NWWzZioFKz7RLiFwWQRCpWBK-HlyaE,6045
248
+ khoj/interface/compiled/_next/static/s_mKS5kELaw2v4a7_yWNP/_buildManifest.js,sha256=6I9QUstNpJnhe3leR2Daw0pSXwzcbBscv6h2jmmPpms,224
249
+ khoj/interface/compiled/_next/static/s_mKS5kELaw2v4a7_yWNP/_ssgManifest.js,sha256=Z49s4suAsf5y_GfnQSvm4qtq2ggxEbZPfEDTXjy6XgA,80
250
+ khoj/interface/compiled/agents/index.html,sha256=p18mncdGQBEzY6aK3DuSgoKUes74Y2RWMjadFvQBq2c,12658
251
+ khoj/interface/compiled/agents/index.txt,sha256=vhWdqUu5I_QZGCpuzloGb_nb3MGzyjKiGeRpi_vBsUc,6045
252
252
  khoj/interface/compiled/assets/icons/khoj_lantern.ico,sha256=eggu-B_v3z1R53EjOFhIqqPnICBGdoaw1xnc0NrzHck,174144
253
253
  khoj/interface/compiled/assets/icons/khoj_lantern_128x128.png,sha256=aTxivDb3CYyThkVZWz8A19xl_dNut5DbkXhODWF3A9Q,5640
254
254
  khoj/interface/compiled/assets/icons/khoj_lantern_256x256.png,sha256=xPCMLHiaL7lYOdQLZrKwWE-Qjn5ZaysSZB0ScYv4UZU,12312
@@ -259,16 +259,16 @@ khoj/interface/compiled/assets/samples/desktop-remember-plan-sample.png,sha256=i
259
259
  khoj/interface/compiled/assets/samples/phone-browse-draw-sample.png,sha256=Dd4fPwtFl6BWqnHjeb1mCK_ND0hhHsWtx8sNE7EiMuE,406179
260
260
  khoj/interface/compiled/assets/samples/phone-plain-chat-sample.png,sha256=DEDaNRCkfEWUeh3kYZWIQDTVK1a6KKnYdwj5ZWisN_Q,82985
261
261
  khoj/interface/compiled/assets/samples/phone-remember-plan-sample.png,sha256=Ma3blirRmq3X4oYSsDbbT7MDn29rymDrjwmUfA9BMuM,236285
262
- khoj/interface/compiled/automations/index.html,sha256=TEMTeteYNEyek3dDnzLsORsTXhemrMj0gN8hd3bbhdk,30941
263
- khoj/interface/compiled/automations/index.txt,sha256=Qccaky8WW4sY9wKdRzhy7VIPVTzEo15gPpoVk858tlY,5633
264
- khoj/interface/compiled/chat/index.html,sha256=Yg2A4sIXYrKRbjtg35KejDZ7yCE0L4v14V2dKf5cZ94,13860
265
- khoj/interface/compiled/chat/index.txt,sha256=PodjSYJ-d0ltiBH_spR5wskE4TPpoFBDWz5z29UEyL4,6590
266
- khoj/interface/compiled/search/index.html,sha256=cM6tkfLrQR7EBN-3MhnRELiIto225E_a3LRak3HBzkY,30161
267
- khoj/interface/compiled/search/index.txt,sha256=cMgmc_9A4ly4zl_nfnkkeDj3_vwTpZRf67Y1biQNjSU,5256
268
- khoj/interface/compiled/settings/index.html,sha256=SzQ9JqZ358iqwVAPj1VjWB_MfDXRjaWBRJUJw4v_IZY,12831
269
- khoj/interface/compiled/settings/index.txt,sha256=naImhGCk3VYqoCSGIWn-lN5y99RhbbDG3pnNPdm39iU,6078
270
- khoj/interface/compiled/share/chat/index.html,sha256=qBdUQJ6CV_dAu7myAZgRTBLcNV0i6JivueJ2MDV9LTQ,15185
271
- khoj/interface/compiled/share/chat/index.txt,sha256=VmNaxfA_velCbT0cMRbdjFGFAkf3DPeunYq2trRQVUM,7401
262
+ khoj/interface/compiled/automations/index.html,sha256=f8sA_n5WU93aF1L50Tn5eK65t0o1aH_SUIF-sinDO94,30941
263
+ khoj/interface/compiled/automations/index.txt,sha256=sDg8majXdwMHiAM5sZV2c-bn8Ul3GCWy8-ytpMqRrnU,5633
264
+ khoj/interface/compiled/chat/index.html,sha256=9PBxMsKwfOVUj0_Pa65jT115DOQ9EPpXgio5iXuZKMQ,13860
265
+ khoj/interface/compiled/chat/index.txt,sha256=8QxpFJ_SZnpXfVBgT4psOU2UyuFY7vIlcDG82OvnKTM,6590
266
+ khoj/interface/compiled/search/index.html,sha256=0pvJkHtdhNbpUUhXNKeO0DwPMLiMjKAsyK93L-Qo9QY,30161
267
+ khoj/interface/compiled/search/index.txt,sha256=SFu48rVx-Z-8EgZcqmmKxOpKGmDhrU0rfXcktv3fM0A,5256
268
+ khoj/interface/compiled/settings/index.html,sha256=AaIjpZdVW8g3ALG7e1Q3Om2B-K7-5rfaPxVvrSx-U_Y,12831
269
+ khoj/interface/compiled/settings/index.txt,sha256=hT6CX1YqwCd8sElU5VBNGmSzXgP5iVJ1X1GoETLJQ2Y,6078
270
+ khoj/interface/compiled/share/chat/index.html,sha256=6DoAT0pWrpiAz1cxJrJ-heSpDqtxHd2miuB7w5HYCGw,15185
271
+ khoj/interface/compiled/share/chat/index.txt,sha256=TTrCeXN7thqdjeNiSAsdvuyK82-VpQvP-6Ve6OFJBf0,7401
272
272
  khoj/interface/email/feedback.html,sha256=xksuPFamx4hGWyTTxZKRgX_eiYQQEuv-eK9Xmkt-nwU,1216
273
273
  khoj/interface/email/magic_link.html,sha256=EoGKQucfPj3xQrWXhSZAzPFOYCHF_ZX94TWCd1XHl1M,941
274
274
  khoj/interface/email/task.html,sha256=tY7a0gzVeQ2lSQNu7WyXR_s7VYeWTrxWEj1iHVuoVE4,2813
@@ -321,7 +321,7 @@ khoj/processor/content/plaintext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRk
321
321
  khoj/processor/content/plaintext/plaintext_to_entries.py,sha256=97i7Cm0DTY7jW4iqKOT_oVc2ooa_XhQ8iImsljp1Kek,4994
322
322
  khoj/processor/conversation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
323
323
  khoj/processor/conversation/prompts.py,sha256=ec_sldNbX-FHrc1h824_2_MREnwbbRpcYHFZhU_sOg4,46807
324
- khoj/processor/conversation/utils.py,sha256=EY25pM0RpAHrPBU718pe2Uc4iACWwQZXrN0GHsWFWs8,25462
324
+ khoj/processor/conversation/utils.py,sha256=OBM_rUymlhs71nkD0RTq8_xLFmJxY6cPtmA0Ed617Nk,25626
325
325
  khoj/processor/conversation/anthropic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
326
326
  khoj/processor/conversation/anthropic/anthropic_chat.py,sha256=jWmko9jzYqaojQmv_u8Iow5GzU0FPbCEslP4z9XufWQ,8521
327
327
  khoj/processor/conversation/anthropic/utils.py,sha256=6_FnsfLRqjkubkfMVmPTEEBzvMUOAccIz5AHV6B9mU8,6623
@@ -340,21 +340,21 @@ khoj/processor/image/generate.py,sha256=sSviN4d5jPCayEqVY-VgePf1bac9ljbpAJ3_g1ri
340
340
  khoj/processor/speech/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
341
341
  khoj/processor/speech/text_to_speech.py,sha256=Q7sapi5Hv6woXOumtrGqR0t6izZrFBkWXFOGrHM6dJ4,1929
342
342
  khoj/processor/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
343
- khoj/processor/tools/online_search.py,sha256=33r3Huwh7RaBKCdHASgVP_qjpr8VhvNqnqrmRe2QINw,14627
343
+ khoj/processor/tools/online_search.py,sha256=5HnaKlE2eRO7swz_b73dppEmUre4THLfbtzfyqNGibY,16085
344
344
  khoj/processor/tools/run_code.py,sha256=BmGIO8vBBkDSVJ_CnjcC-DKm_23Irht5w2DVNQHf548,4851
345
345
  khoj/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
346
- khoj/routers/api.py,sha256=aBr3AKMnloxcvmXIYommebpCQt_Kz1-CDdaG77vpy2c,28168
346
+ khoj/routers/api.py,sha256=kD0HPmPzuAdfkGAIRfNPDyyKcMg9_bDb6GAyLTiK1R8,28296
347
347
  khoj/routers/api_agents.py,sha256=4T0osmOGFmYC-BhdAkT5HpT2zaktlL7Agj47-To-jxo,9773
348
- khoj/routers/api_chat.py,sha256=PK6sJlSigQlW9psZWMxsPWS3OWhK6_4VLis7aa9vO3Q,46383
348
+ khoj/routers/api_chat.py,sha256=jNbzOLD_t9sAmDJPr-iV7n7tKIQJaZHrMxpVTjxPSRk,46551
349
349
  khoj/routers/api_content.py,sha256=lWunOwVWYvnl1ue_D81g9ZSwBc0UxHmBIrdJoVPxN_A,17900
350
350
  khoj/routers/api_model.py,sha256=KDsxNwHspC94eTcv6l3ehr773EOvgc670UnZLE1WZ4o,3642
351
351
  khoj/routers/api_phone.py,sha256=p9yfc4WeMHDC0hg3aQk60a2VBy8rZPdEnz9wdJ7DzkU,2208
352
352
  khoj/routers/api_subscription.py,sha256=sR5_XxQ4e_1hk3K4g0i3S8PZeULP23lnGtrWnfjhNDI,5307
353
353
  khoj/routers/auth.py,sha256=HO54PR-BkWA_iJIktEobUrObcXVYG-00jpnIcEVdR5s,6564
354
354
  khoj/routers/email.py,sha256=SGYNPQvfcvYeHf70F0YqpY0FLMRElF2ZekROXdwGI18,3821
355
- khoj/routers/helpers.py,sha256=h8jUteTfU4_v0yNc4H_DkbyBJyOC7Dvde_VKAAzNOKY,77745
355
+ khoj/routers/helpers.py,sha256=rDQLUN-OybUlEBhyduUyMF0un4nLi2fASaUXQG6fy3k,79938
356
356
  khoj/routers/notion.py,sha256=Lp67xP9rVgpAF9BQoGTjZFcVdF1HYtvPP0kjq6uurKU,2802
357
- khoj/routers/research.py,sha256=vxnvG54VtB7bpVt-D2fbVJXz7Irjfb6rclDE0fxAUFU,13094
357
+ khoj/routers/research.py,sha256=RKGJRaSxNxbd7tguR3CXp7rs0pogMWrSrLeUxVlQZ8I,15390
358
358
  khoj/routers/storage.py,sha256=tJrwhFRVWv0MHv7V7huMc1Diwm-putZSwnZXJ3tqT_c,2338
359
359
  khoj/routers/twilio.py,sha256=MLsuCm4--ETvr3sLxbF0CL_ehlg_l2rKBSLR2Qh2Xls,1081
360
360
  khoj/routers/web_client.py,sha256=frH03Sh0AR7c2MvRyc5a3tOFyxyVak3d1pl1sLcLLD4,4212
@@ -377,8 +377,8 @@ khoj/utils/models.py,sha256=Q5tcC9-z25sCiub048fLnvZ6_IIO1bcPNxt5payekk0,2009
377
377
  khoj/utils/rawconfig.py,sha256=kURDuk7x0MDtniGLU4x1IsvU4UIBS-V9dSM4GD8X-LY,4274
378
378
  khoj/utils/state.py,sha256=x4GTewP1YhOA6c_32N4wOjnV-3AA3xG_qbY1-wC2Uxc,1559
379
379
  khoj/utils/yaml.py,sha256=qy1Tkc61rDMesBw_Cyx2vOR6H-Hngcsm5kYfjwQBwkE,1543
380
- khoj-1.28.4.dev13.dist-info/METADATA,sha256=JdZNe94JInE-cH-5QJFNHcXZZoprFXdCUGQy-mH_dKk,7153
381
- khoj-1.28.4.dev13.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
382
- khoj-1.28.4.dev13.dist-info/entry_points.txt,sha256=KBIcez5N_jCgq_ER4Uxf-e1lxTBMTE_BBjMwwfeZyAg,39
383
- khoj-1.28.4.dev13.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
384
- khoj-1.28.4.dev13.dist-info/RECORD,,
380
+ khoj-1.28.4.dev23.dist-info/METADATA,sha256=vDU-U6W0STCi-teSeQkX0IDL4EZLiXKkI3xFBLYfGH8,7093
381
+ khoj-1.28.4.dev23.dist-info/WHEEL,sha256=3U_NnUcV_1B1kPkYaPzN-irRckL5VW_lytn0ytO_kRY,87
382
+ khoj-1.28.4.dev23.dist-info/entry_points.txt,sha256=KBIcez5N_jCgq_ER4Uxf-e1lxTBMTE_BBjMwwfeZyAg,39
383
+ khoj-1.28.4.dev23.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
384
+ khoj-1.28.4.dev23.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.25.0
2
+ Generator: hatchling 1.26.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any