khoj 1.27.2.dev29__py3-none-any.whl → 1.28.1.dev1__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 (75) hide show
  1. khoj/configure.py +1 -1
  2. khoj/database/adapters/__init__.py +50 -12
  3. khoj/interface/compiled/404/index.html +1 -1
  4. khoj/interface/compiled/_next/static/chunks/1034-da58b679fcbb79c1.js +1 -0
  5. khoj/interface/compiled/_next/static/chunks/1467-b331e469fe411347.js +1 -0
  6. khoj/interface/compiled/_next/static/chunks/1603-c1568f45947e9f2c.js +1 -0
  7. khoj/interface/compiled/_next/static/chunks/3423-ff7402ae1dd66592.js +1 -0
  8. khoj/interface/compiled/_next/static/chunks/8423-e80647edf6c92c27.js +1 -0
  9. khoj/interface/compiled/_next/static/chunks/app/agents/{page-5ae1e540bb5be8a9.js → page-2beaba7c9bb750bd.js} +1 -1
  10. khoj/interface/compiled/_next/static/chunks/app/automations/{page-774ae3e033f938cd.js → page-9b5c77e0b0dd772c.js} +1 -1
  11. khoj/interface/compiled/_next/static/chunks/app/chat/page-bfc70b16ba5e51b4.js +1 -0
  12. khoj/interface/compiled/_next/static/chunks/app/factchecker/page-340bcf53abf6a2cc.js +1 -0
  13. khoj/interface/compiled/_next/static/chunks/app/{page-4dc472cf6d674004.js → page-f249666a0cbdaa0d.js} +1 -1
  14. khoj/interface/compiled/_next/static/chunks/app/search/{page-9b64f61caa5bd7f9.js → page-ab2995529ece3140.js} +1 -1
  15. khoj/interface/compiled/_next/static/chunks/app/settings/{page-7a8c382af2a7e870.js → page-89e6737b2cc9fb3a.js} +1 -1
  16. khoj/interface/compiled/_next/static/chunks/app/share/chat/{page-eb9e282691858f2e.js → page-505b07bce608b34e.js} +1 -1
  17. khoj/interface/compiled/_next/static/chunks/{webpack-2b720658ccc746f2.js → webpack-878569182b3af4c6.js} +1 -1
  18. khoj/interface/compiled/_next/static/css/{2272c73fc7a3b571.css → 26c1c33d0423a7d8.css} +1 -1
  19. khoj/interface/compiled/_next/static/css/592ca99f5122e75a.css +1 -0
  20. khoj/interface/compiled/_next/static/css/a795ee88875f4853.css +25 -0
  21. khoj/interface/compiled/_next/static/css/d738728883c68af8.css +1 -0
  22. khoj/interface/compiled/agents/index.html +1 -1
  23. khoj/interface/compiled/agents/index.txt +2 -2
  24. khoj/interface/compiled/automations/index.html +1 -1
  25. khoj/interface/compiled/automations/index.txt +2 -2
  26. khoj/interface/compiled/chat/index.html +1 -1
  27. khoj/interface/compiled/chat/index.txt +2 -2
  28. khoj/interface/compiled/factchecker/index.html +1 -1
  29. khoj/interface/compiled/factchecker/index.txt +2 -2
  30. khoj/interface/compiled/index.html +1 -1
  31. khoj/interface/compiled/index.txt +2 -2
  32. khoj/interface/compiled/search/index.html +1 -1
  33. khoj/interface/compiled/search/index.txt +2 -2
  34. khoj/interface/compiled/settings/index.html +1 -1
  35. khoj/interface/compiled/settings/index.txt +2 -2
  36. khoj/interface/compiled/share/chat/index.html +1 -1
  37. khoj/interface/compiled/share/chat/index.txt +2 -2
  38. khoj/processor/conversation/anthropic/anthropic_chat.py +14 -10
  39. khoj/processor/conversation/anthropic/utils.py +13 -2
  40. khoj/processor/conversation/google/gemini_chat.py +15 -11
  41. khoj/processor/conversation/offline/chat_model.py +18 -10
  42. khoj/processor/conversation/openai/gpt.py +11 -8
  43. khoj/processor/conversation/openai/utils.py +7 -0
  44. khoj/processor/conversation/prompts.py +156 -49
  45. khoj/processor/conversation/utils.py +146 -13
  46. khoj/processor/embeddings.py +4 -4
  47. khoj/processor/tools/online_search.py +13 -7
  48. khoj/processor/tools/run_code.py +144 -0
  49. khoj/routers/api.py +6 -6
  50. khoj/routers/api_chat.py +193 -112
  51. khoj/routers/helpers.py +107 -48
  52. khoj/routers/research.py +320 -0
  53. khoj/search_filter/date_filter.py +1 -3
  54. khoj/search_filter/file_filter.py +1 -2
  55. khoj/search_type/text_search.py +3 -3
  56. khoj/utils/helpers.py +24 -2
  57. khoj/utils/yaml.py +4 -0
  58. {khoj-1.27.2.dev29.dist-info → khoj-1.28.1.dev1.dist-info}/METADATA +3 -3
  59. {khoj-1.27.2.dev29.dist-info → khoj-1.28.1.dev1.dist-info}/RECORD +66 -63
  60. khoj/interface/compiled/_next/static/chunks/1603-5138bb7c8035d9a6.js +0 -1
  61. khoj/interface/compiled/_next/static/chunks/2697-61fcba89fd87eab4.js +0 -1
  62. khoj/interface/compiled/_next/static/chunks/3423-0b533af8bf6ac218.js +0 -1
  63. khoj/interface/compiled/_next/static/chunks/9479-ff7d8c4dae2014d1.js +0 -1
  64. khoj/interface/compiled/_next/static/chunks/app/chat/page-97f5b61aaf46d364.js +0 -1
  65. khoj/interface/compiled/_next/static/chunks/app/factchecker/page-d82403db2866bad8.js +0 -1
  66. khoj/interface/compiled/_next/static/css/4cae6c0e5c72fb2d.css +0 -1
  67. khoj/interface/compiled/_next/static/css/76d55eb435962b19.css +0 -25
  68. khoj/interface/compiled/_next/static/css/ddcc0cf73e062476.css +0 -1
  69. /khoj/interface/compiled/_next/static/{atzIseFarmC7TIwq2BgHC → K7ZigmRDrBfpIN7jxKQsA}/_buildManifest.js +0 -0
  70. /khoj/interface/compiled/_next/static/{atzIseFarmC7TIwq2BgHC → K7ZigmRDrBfpIN7jxKQsA}/_ssgManifest.js +0 -0
  71. /khoj/interface/compiled/_next/static/chunks/{1970-60c96aed937a4928.js → 1970-90dd510762d820ba.js} +0 -0
  72. /khoj/interface/compiled/_next/static/chunks/{9417-2ca87207387fc790.js → 9417-951f46451a8dd6d7.js} +0 -0
  73. {khoj-1.27.2.dev29.dist-info → khoj-1.28.1.dev1.dist-info}/WHEEL +0 -0
  74. {khoj-1.27.2.dev29.dist-info → khoj-1.28.1.dev1.dist-info}/entry_points.txt +0 -0
  75. {khoj-1.27.2.dev29.dist-info → khoj-1.28.1.dev1.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,6 @@
1
1
  import json
2
2
  import logging
3
+ import os
3
4
  from datetime import datetime, timedelta
4
5
  from threading import Thread
5
6
  from typing import Any, Iterator, List, Optional, Union
@@ -19,6 +20,7 @@ from khoj.utils import state
19
20
  from khoj.utils.constants import empty_escape_sequences
20
21
  from khoj.utils.helpers import ConversationCommand, in_debug_mode, is_none_or_empty
21
22
  from khoj.utils.rawconfig import LocationData
23
+ from khoj.utils.yaml import yaml_dump
22
24
 
23
25
  logger = logging.getLogger(__name__)
24
26
 
@@ -138,7 +140,8 @@ def filter_questions(questions: List[str]):
138
140
  def converse_offline(
139
141
  user_query,
140
142
  references=[],
141
- online_results=[],
143
+ online_results={},
144
+ code_results={},
142
145
  conversation_log={},
143
146
  model: str = "bartowski/Meta-Llama-3.1-8B-Instruct-GGUF",
144
147
  loaded_model: Union[Any, None] = None,
@@ -158,8 +161,6 @@ def converse_offline(
158
161
  assert loaded_model is None or isinstance(loaded_model, Llama), "loaded_model must be of type Llama, if configured"
159
162
  offline_chat_model = loaded_model or download_model(model, max_tokens=max_prompt_size)
160
163
  tracer["chat_model"] = model
161
-
162
- compiled_references = "\n\n".join({f"# File: {item['file']}\n## {item['compiled']}\n" for item in references})
163
164
  current_date = datetime.now()
164
165
 
165
166
  if agent and agent.personality:
@@ -184,24 +185,25 @@ def converse_offline(
184
185
  system_prompt = f"{system_prompt}\n{user_name_prompt}"
185
186
 
186
187
  # Get Conversation Primer appropriate to Conversation Type
187
- if conversation_commands == [ConversationCommand.Notes] and is_none_or_empty(compiled_references):
188
+ if conversation_commands == [ConversationCommand.Notes] and is_none_or_empty(references):
188
189
  return iter([prompts.no_notes_found.format()])
189
190
  elif conversation_commands == [ConversationCommand.Online] and is_none_or_empty(online_results):
190
191
  completion_func(chat_response=prompts.no_online_results_found.format())
191
192
  return iter([prompts.no_online_results_found.format()])
192
193
 
193
194
  context_message = ""
194
- if not is_none_or_empty(compiled_references):
195
- context_message += f"{prompts.notes_conversation_offline.format(references=compiled_references)}\n\n"
195
+ if not is_none_or_empty(references):
196
+ context_message = f"{prompts.notes_conversation_offline.format(references=yaml_dump(references))}\n\n"
196
197
  if ConversationCommand.Online in conversation_commands or ConversationCommand.Webpage in conversation_commands:
197
198
  simplified_online_results = online_results.copy()
198
199
  for result in online_results:
199
200
  if online_results[result].get("webpages"):
200
201
  simplified_online_results[result] = online_results[result]["webpages"]
201
202
 
202
- context_message += (
203
- f"{prompts.online_search_conversation_offline.format(online_results=str(simplified_online_results))}"
204
- )
203
+ context_message += f"{prompts.online_search_conversation_offline.format(online_results=yaml_dump(simplified_online_results))}\n\n"
204
+ if ConversationCommand.Code in conversation_commands and not is_none_or_empty(code_results):
205
+ context_message += f"{prompts.code_executed_context.format(code_results=str(code_results))}\n\n"
206
+ context_message = context_message.strip()
205
207
 
206
208
  # Setup Prompt with Primer or Conversation History
207
209
  messages = generate_chatml_messages_with_context(
@@ -262,8 +264,14 @@ def send_message_to_model_offline(
262
264
  assert loaded_model is None or isinstance(loaded_model, Llama), "loaded_model must be of type Llama, if configured"
263
265
  offline_chat_model = loaded_model or download_model(model, max_tokens=max_prompt_size)
264
266
  messages_dict = [{"role": message.role, "content": message.content} for message in messages]
267
+ seed = int(os.getenv("KHOJ_LLM_SEED")) if os.getenv("KHOJ_LLM_SEED") else None
265
268
  response = offline_chat_model.create_chat_completion(
266
- messages_dict, stop=stop, stream=streaming, temperature=temperature, response_format={"type": response_type}
269
+ messages_dict,
270
+ stop=stop,
271
+ stream=streaming,
272
+ temperature=temperature,
273
+ response_format={"type": response_type},
274
+ seed=seed,
267
275
  )
268
276
 
269
277
  if streaming:
@@ -12,12 +12,13 @@ from khoj.processor.conversation.openai.utils import (
12
12
  completion_with_backoff,
13
13
  )
14
14
  from khoj.processor.conversation.utils import (
15
+ clean_json,
15
16
  construct_structured_message,
16
17
  generate_chatml_messages_with_context,
17
- remove_json_codeblock,
18
18
  )
19
19
  from khoj.utils.helpers import ConversationCommand, is_none_or_empty
20
20
  from khoj.utils.rawconfig import LocationData
21
+ from khoj.utils.yaml import yaml_dump
21
22
 
22
23
  logger = logging.getLogger(__name__)
23
24
 
@@ -94,8 +95,7 @@ def extract_questions(
94
95
 
95
96
  # Extract, Clean Message from GPT's Response
96
97
  try:
97
- response = response.strip()
98
- response = remove_json_codeblock(response)
98
+ response = clean_json(response)
99
99
  response = json.loads(response)
100
100
  response = [q.strip() for q in response["queries"] if q.strip()]
101
101
  if not isinstance(response, list) or not response:
@@ -133,6 +133,7 @@ def converse(
133
133
  references,
134
134
  user_query,
135
135
  online_results: Optional[Dict[str, Dict]] = None,
136
+ code_results: Optional[Dict[str, Dict]] = None,
136
137
  conversation_log={},
137
138
  model: str = "gpt-4o-mini",
138
139
  api_key: Optional[str] = None,
@@ -154,7 +155,6 @@ def converse(
154
155
  """
155
156
  # Initialize Variables
156
157
  current_date = datetime.now()
157
- compiled_references = "\n\n".join({f"# File: {item['file']}\n## {item['compiled']}\n" for item in references})
158
158
 
159
159
  if agent and agent.personality:
160
160
  system_prompt = prompts.custom_personality.format(
@@ -178,7 +178,7 @@ def converse(
178
178
  system_prompt = f"{system_prompt}\n{user_name_prompt}"
179
179
 
180
180
  # Get Conversation Primer appropriate to Conversation Type
181
- if conversation_commands == [ConversationCommand.Notes] and is_none_or_empty(compiled_references):
181
+ if conversation_commands == [ConversationCommand.Notes] and is_none_or_empty(references):
182
182
  completion_func(chat_response=prompts.no_notes_found.format())
183
183
  return iter([prompts.no_notes_found.format()])
184
184
  elif conversation_commands == [ConversationCommand.Online] and is_none_or_empty(online_results):
@@ -186,10 +186,13 @@ def converse(
186
186
  return iter([prompts.no_online_results_found.format()])
187
187
 
188
188
  context_message = ""
189
- if not is_none_or_empty(compiled_references):
190
- context_message = f"{prompts.notes_conversation.format(references=compiled_references)}\n\n"
189
+ if not is_none_or_empty(references):
190
+ context_message = f"{prompts.notes_conversation.format(references=yaml_dump(references))}\n\n"
191
191
  if not is_none_or_empty(online_results):
192
- context_message += f"{prompts.online_search_conversation.format(online_results=str(online_results))}"
192
+ context_message += f"{prompts.online_search_conversation.format(online_results=yaml_dump(online_results))}\n\n"
193
+ if not is_none_or_empty(code_results):
194
+ context_message += f"{prompts.code_executed_context.format(code_results=str(code_results))}\n\n"
195
+ context_message = context_message.strip()
193
196
 
194
197
  # Setup Prompt with Primer or Conversation History
195
198
  messages = generate_chatml_messages_with_context(
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import os
2
3
  from threading import Thread
3
4
  from typing import Dict
4
5
 
@@ -60,6 +61,9 @@ def completion_with_backoff(
60
61
  model_kwargs.pop("stop", None)
61
62
  model_kwargs.pop("response_format", None)
62
63
 
64
+ if os.getenv("KHOJ_LLM_SEED"):
65
+ model_kwargs["seed"] = int(os.getenv("KHOJ_LLM_SEED"))
66
+
63
67
  chat = client.chat.completions.create(
64
68
  stream=stream,
65
69
  messages=formatted_messages, # type: ignore
@@ -157,6 +161,9 @@ def llm_thread(
157
161
  model_kwargs.pop("stop", None)
158
162
  model_kwargs.pop("response_format", None)
159
163
 
164
+ if os.getenv("KHOJ_LLM_SEED"):
165
+ model_kwargs["seed"] = int(os.getenv("KHOJ_LLM_SEED"))
166
+
160
167
  chat = client.chat.completions.create(
161
168
  stream=stream,
162
169
  messages=formatted_messages,
@@ -394,21 +394,23 @@ Q: {query}
394
394
 
395
395
  extract_questions = PromptTemplate.from_template(
396
396
  """
397
- You are Khoj, an extremely smart and helpful document search assistant with only the ability to retrieve information from the user's notes. Disregard online search requests.
397
+ You are Khoj, an extremely smart and helpful document search assistant with only the ability to retrieve information from the user's notes and documents.
398
398
  Construct search queries to retrieve relevant information to answer the user's question.
399
- - You will be provided past questions(Q) and answers(A) for context.
399
+ - You will be provided example and actual past user questions(Q), search queries(Khoj) and answers(A) for context.
400
400
  - Add as much context from the previous questions and answers as required into your search queries.
401
- - Break messages into multiple search queries when required to retrieve the relevant information.
401
+ - Break your search down into multiple search queries from a diverse set of lenses to retrieve all related documents.
402
402
  - Add date filters to your search queries from questions and answers when required to retrieve the relevant information.
403
403
  - When asked a meta, vague or random questions, search for a variety of broad topics to answer the user's question.
404
404
  {personality_context}
405
- What searches will you perform to answer the users question? Respond with search queries as list of strings in a JSON object.
405
+ What searches will you perform to answer the user's question? Respond with search queries as list of strings in a JSON object.
406
406
  Current Date: {day_of_week}, {current_date}
407
407
  User's Location: {location}
408
408
  {username}
409
409
 
410
+ Examples
411
+ ---
410
412
  Q: How was my trip to Cambodia?
411
- Khoj: {{"queries": ["How was my trip to Cambodia?"]}}
413
+ Khoj: {{"queries": ["How was my trip to Cambodia?", "Angkor Wat temple visit", "Flight to Phnom Penh", "Expenses in Cambodia", "Stay in Cambodia"]}}
412
414
  A: The trip was amazing. You went to the Angkor Wat temple and it was beautiful.
413
415
 
414
416
  Q: Who did i visit that temple with?
@@ -443,6 +445,8 @@ Q: Who all did I meet here yesterday?
443
445
  Khoj: {{"queries": ["Met in {location} on {yesterday_date} dt>='{yesterday_date}' dt<'{current_date}'"]}}
444
446
  A: Yesterday's note mentions your visit to your local beach with Ram and Shyam.
445
447
 
448
+ Actual
449
+ ---
446
450
  {chat_history}
447
451
  Q: {text}
448
452
  Khoj:
@@ -451,11 +455,11 @@ Khoj:
451
455
 
452
456
  extract_questions_anthropic_system_prompt = PromptTemplate.from_template(
453
457
  """
454
- You are Khoj, an extremely smart and helpful document search assistant with only the ability to retrieve information from the user's notes. Disregard online search requests.
458
+ You are Khoj, an extremely smart and helpful document search assistant with only the ability to retrieve information from the user's notes.
455
459
  Construct search queries to retrieve relevant information to answer the user's question.
456
- - You will be provided past questions(User), extracted queries(Assistant) and answers(A) for context.
460
+ - You will be provided past questions(User), search queries(Assistant) and answers(A) for context.
457
461
  - Add as much context from the previous questions and answers as required into your search queries.
458
- - Break messages into multiple search queries when required to retrieve the relevant information.
462
+ - Break your search down into multiple search queries from a diverse set of lenses to retrieve all related documents.
459
463
  - Add date filters to your search queries from questions and answers when required to retrieve the relevant information.
460
464
  - When asked a meta, vague or random questions, search for a variety of broad topics to answer the user's question.
461
465
  {personality_context}
@@ -468,7 +472,7 @@ User's Location: {location}
468
472
  Here are some examples of how you can construct search queries to answer the user's question:
469
473
 
470
474
  User: How was my trip to Cambodia?
471
- Assistant: {{"queries": ["How was my trip to Cambodia?"]}}
475
+ Assistant: {{"queries": ["How was my trip to Cambodia?", "Angkor Wat temple visit", "Flight to Phnom Penh", "Expenses in Cambodia", "Stay in Cambodia"]}}
472
476
  A: The trip was amazing. You went to the Angkor Wat temple and it was beautiful.
473
477
 
474
478
  User: What national parks did I go to last year?
@@ -501,17 +505,14 @@ Assistant:
501
505
  )
502
506
 
503
507
  system_prompt_extract_relevant_information = """
504
- As a professional analyst, create a comprehensive report of the most relevant information from a web page in response to a user's query.
505
- The text provided is directly from within the web page.
506
- The report you create should be multiple paragraphs, and it should represent the content of the website.
507
- Tell the user exactly what the website says in response to their query, while adhering to these guidelines:
508
-
509
- 1. Answer the user's query as specifically as possible. Include many supporting details from the website.
510
- 2. Craft a report that is detailed, thorough, in-depth, and complex, while maintaining clarity.
511
- 3. Rely strictly on the provided text, without including external information.
512
- 4. Format the report in multiple paragraphs with a clear structure.
513
- 5. Be as specific as possible in your answer to the user's query.
514
- 6. Reproduce as much of the provided text as possible, while maintaining readability.
508
+ As a professional analyst, your job is to extract all pertinent information from documents to help answer user's query.
509
+ You will be provided raw text directly from within the document.
510
+ Adhere to these guidelines while extracting information from the provided documents:
511
+
512
+ 1. Extract all relevant text and links from the document that can assist with further research or answer the user's query.
513
+ 2. Craft a comprehensive but compact report with all the necessary data from the document to generate an informed response.
514
+ 3. Rely strictly on the provided text to generate your summary, without including external information.
515
+ 4. Provide specific, important snippets from the document in your report to establish trust in your summary.
515
516
  """.strip()
516
517
 
517
518
  extract_relevant_information = PromptTemplate.from_template(
@@ -519,10 +520,10 @@ extract_relevant_information = PromptTemplate.from_template(
519
520
  {personality_context}
520
521
  Target Query: {query}
521
522
 
522
- Web Pages:
523
+ Document:
523
524
  {corpus}
524
525
 
525
- Collate only relevant information from the website to answer the target query.
526
+ Collate only relevant information from the document to answer the target query.
526
527
  """.strip()
527
528
  )
528
529
 
@@ -617,6 +618,67 @@ Khoj:
617
618
  """.strip()
618
619
  )
619
620
 
621
+ plan_function_execution = PromptTemplate.from_template(
622
+ """
623
+ You are Khoj, a smart, creative and methodical researcher. Use the provided tool AIs to investigate information to answer query.
624
+ Create a multi-step plan and intelligently iterate on the plan based on the retrieved information to find the requested information.
625
+ {personality_context}
626
+
627
+ # Instructions
628
+ - Ask highly diverse, detailed queries to the tool AIs, one tool AI at a time, to discover required information or run calculations. Their response will be shown to you in the next iteration.
629
+ - Break down your research process into independent, self-contained steps that can be executed sequentially using the available tool AIs to answer the user's query. Write your step-by-step plan in the scratchpad.
630
+ - Always ask a new query that was not asked to the tool AI in a previous iteration. Build on the results of the previous iterations.
631
+ - Ensure that all required context is passed to the tool AIs for successful execution. They only know the context provided in your query.
632
+ - Think step by step to come up with creative strategies when the previous iteration did not yield useful results.
633
+ - You are allowed upto {max_iterations} iterations to use the help of the provided tool AIs to answer the user's question.
634
+ - Stop when you have the required information by returning a JSON object with an empty "tool" field. E.g., {{scratchpad: "I have all I need", tool: "", query: ""}}
635
+
636
+ # Examples
637
+ Assuming you can search the user's notes and the internet.
638
+ - When the user asks for the population of their hometown
639
+ 1. Try look up their hometown in their notes. Ask the note search AI to search for their birth certificate, childhood memories, school, resume etc.
640
+ 2. If not found in their notes, try infer their hometown from their online social media profiles. Ask the online search AI to look for {username}'s biography, school, resume on linkedin, facebook, website etc.
641
+ 3. Only then try find the latest population of their hometown by reading official websites with the help of the online search and web page reading AI.
642
+ - When the user asks for their computer's specs
643
+ 1. Try find their computer model in their notes.
644
+ 2. Now find webpages with their computer model's spec online.
645
+ 3. Ask the the webpage tool AI to extract the required information from the relevant webpages.
646
+ - When the user asks what clothes to carry for their upcoming trip
647
+ 1. Find the itinerary of their upcoming trip in their notes.
648
+ 2. Next find the weather forecast at the destination online.
649
+ 3. Then find if they mentioned what clothes they own in their notes.
650
+
651
+ # Background Context
652
+ - Current Date: {day_of_week}, {current_date}
653
+ - User Location: {location}
654
+ - User Name: {username}
655
+
656
+ # Available Tool AIs
657
+ Which of the tool AIs listed below would you use to answer the user's question? You **only** have access to the following tool AIs:
658
+
659
+ {tools}
660
+
661
+ # Previous Iterations
662
+ {previous_iterations}
663
+
664
+ # Chat History:
665
+ {chat_history}
666
+
667
+ Return the next tool AI to use and the query to ask it. Your response should always be a valid JSON object. Do not say anything else.
668
+ Response format:
669
+ {{"scratchpad": "<your_scratchpad_to_reason_about_which_tool_to_use>", "query": "<your_detailed_query_for_the_tool_ai>", "tool": "<name_of_tool_ai>"}}
670
+ """.strip()
671
+ )
672
+
673
+ previous_iteration = PromptTemplate.from_template(
674
+ """
675
+ ## Iteration {index}:
676
+ - tool: {tool}
677
+ - query: {query}
678
+ - result: {result}
679
+ """
680
+ )
681
+
620
682
  pick_relevant_information_collection_tools = PromptTemplate.from_template(
621
683
  """
622
684
  You are Khoj, an extremely smart and helpful search assistant.
@@ -736,8 +798,8 @@ Khoj:
736
798
  online_search_conversation_subqueries = PromptTemplate.from_template(
737
799
  """
738
800
  You are Khoj, an advanced web search assistant. You are tasked with constructing **up to three** google search queries to answer the user's question.
739
- - You will receive the conversation history as context.
740
- - Add as much context from the previous questions and answers as required into your search queries.
801
+ - You will receive the actual chat history as context.
802
+ - Add as much context from the chat history as required into your search queries.
741
803
  - Break messages into multiple search queries when required to retrieve the relevant information.
742
804
  - Use site: google search operator when appropriate
743
805
  - You have access to the the whole internet to retrieve information.
@@ -750,62 +812,107 @@ User's Location: {location}
750
812
  {username}
751
813
 
752
814
  Here are some examples:
753
- History:
815
+ Example Chat History:
754
816
  User: I like to use Hacker News to get my tech news.
817
+ Khoj: {{queries: ["what is Hacker News?", "Hacker News website for tech news"]}}
755
818
  AI: Hacker News is an online forum for sharing and discussing the latest tech news. It is a great place to learn about new technologies and startups.
756
819
 
757
- Q: Summarize the top posts on HackerNews
820
+ User: Summarize the top posts on HackerNews
758
821
  Khoj: {{"queries": ["top posts on HackerNews"]}}
759
822
 
760
- History:
761
-
762
- Q: Tell me the latest news about the farmers protest in Colombia and China on Reuters
823
+ Example Chat History:
824
+ User: Tell me the latest news about the farmers protest in Colombia and China on Reuters
763
825
  Khoj: {{"queries": ["site:reuters.com farmers protest Colombia", "site:reuters.com farmers protest China"]}}
764
826
 
765
- History:
827
+ Example Chat History:
766
828
  User: I'm currently living in New York but I'm thinking about moving to San Francisco.
829
+ Khoj: {{"queries": ["New York city vs San Francisco life", "San Francisco living cost", "New York city living cost"]}}
767
830
  AI: New York is a great city to live in. It has a lot of great restaurants and museums. San Francisco is also a great city to live in. It has good access to nature and a great tech scene.
768
831
 
769
- Q: What is the climate like in those cities?
770
- Khoj: {{"queries": ["climate in new york city", "climate in san francisco"]}}
832
+ User: What is the climate like in those cities?
833
+ Khoj: {{"queries": ["climate in New York city", "climate in San Francisco"]}}
771
834
 
772
- History:
773
- AI: Hey, how is it going?
774
- User: Going well. Ananya is in town tonight!
835
+ Example Chat History:
836
+ User: Hey, Ananya is in town tonight!
837
+ Khoj: {{"queries": ["events in {location} tonight", "best restaurants in {location}", "places to visit in {location}"]}}
775
838
  AI: Oh that's awesome! What are your plans for the evening?
776
839
 
777
- Q: She wants to see a movie. Any decent sci-fi movies playing at the local theater?
840
+ User: She wants to see a movie. Any decent sci-fi movies playing at the local theater?
778
841
  Khoj: {{"queries": ["new sci-fi movies in theaters near {location}"]}}
779
842
 
780
- History:
843
+ Example Chat History:
781
844
  User: Can I chat with you over WhatsApp?
782
- AI: Yes, you can chat with me using WhatsApp.
783
-
784
- Q: How
785
845
  Khoj: {{"queries": ["site:khoj.dev chat with Khoj on Whatsapp"]}}
846
+ AI: Yes, you can chat with me using WhatsApp.
786
847
 
787
- History:
788
-
789
-
790
- Q: How do I share my files with you?
848
+ Example Chat History:
849
+ User: How do I share my files with Khoj?
791
850
  Khoj: {{"queries": ["site:khoj.dev sync files with Khoj"]}}
792
851
 
793
- History:
852
+ Example Chat History:
794
853
  User: I need to transport a lot of oranges to the moon. Are there any rockets that can fit a lot of oranges?
854
+ Khoj: {{"queries": ["current rockets with large cargo capacity", "rocket rideshare cost by cargo capacity"]}}
795
855
  AI: NASA's Saturn V rocket frequently makes lunar trips and has a large cargo capacity.
796
856
 
797
- Q: How many oranges would fit in NASA's Saturn V rocket?
798
- Khoj: {{"queries": ["volume of an orange", "volume of saturn v rocket"]}}
857
+ User: How many oranges would fit in NASA's Saturn V rocket?
858
+ Khoj: {{"queries": ["volume of an orange", "volume of Saturn V rocket"]}}
799
859
 
800
860
  Now it's your turn to construct Google search queries to answer the user's question. Provide them as a list of strings in a JSON object. Do not say anything else.
801
- History:
861
+ Actual Chat History:
802
862
  {chat_history}
803
863
 
804
- Q: {query}
864
+ User: {query}
865
+ Khoj:
866
+ """.strip()
867
+ )
868
+
869
+ # Code Generation
870
+ # --
871
+ python_code_generation_prompt = PromptTemplate.from_template(
872
+ """
873
+ You are Khoj, an advanced python programmer. You are tasked with constructing **up to three** python programs to best answer the user query.
874
+ - The python program will run in a pyodide python sandbox with no network access.
875
+ - You can write programs to run complex calculations, analyze data, create charts, generate documents to meticulously answer the query
876
+ - The sandbox has access to the standard library, matplotlib, panda, numpy, scipy, bs4, sympy, brotli, cryptography, fast-parquet
877
+ - Do not try display images or plots in the code directly. The code should save the image or plot to a file instead.
878
+ - Write any document, charts etc. to be shared with the user to file. These files can be seen by the user.
879
+ - Use as much context from the previous questions and answers as required to generate your code.
880
+ {personality_context}
881
+ What code will you need to write, if any, to answer the user's question?
882
+ Provide code programs as a list of strings in a JSON object with key "codes".
883
+ Current Date: {current_date}
884
+ User's Location: {location}
885
+ {username}
886
+
887
+ The JSON schema is of the form {{"codes": ["code1", "code2", "code3"]}}
888
+ For example:
889
+ {{"codes": ["print('Hello, World!')", "print('Goodbye, World!')"]}}
890
+
891
+ Now it's your turn to construct python programs to answer the user's question. Provide them as a list of strings in a JSON object. Do not say anything else.
892
+ Context:
893
+ ---
894
+ {context}
895
+
896
+ Chat History:
897
+ ---
898
+ {chat_history}
899
+
900
+ User: {query}
805
901
  Khoj:
806
902
  """.strip()
807
903
  )
808
904
 
905
+ code_executed_context = PromptTemplate.from_template(
906
+ """
907
+ Use the provided code executions to inform your response.
908
+ Ask crisp follow-up questions to get additional context, when a helpful response cannot be provided from the provided code execution results or past conversations.
909
+
910
+ Code Execution Results:
911
+ {code_results}
912
+ """.strip()
913
+ )
914
+
915
+
809
916
  # Automations
810
917
  # --
811
918
  crontime_prompt = PromptTemplate.from_template(