khoj 1.42.1.dev8__py3-none-any.whl → 1.42.2__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 (72) hide show
  1. khoj/configure.py +2 -0
  2. khoj/database/adapters/__init__.py +9 -7
  3. khoj/database/models/__init__.py +9 -9
  4. khoj/interface/compiled/404/index.html +2 -2
  5. khoj/interface/compiled/_next/static/chunks/{2117-5a41630a2bd2eae8.js → 2117-056a00add390772b.js} +1 -1
  6. khoj/interface/compiled/_next/static/chunks/7127-79a3af5138960272.js +1 -0
  7. khoj/interface/compiled/_next/static/chunks/{5138-2cce449fd2454abf.js → 7211-7fedd2ee3655239c.js} +1 -1
  8. khoj/interface/compiled/_next/static/chunks/app/agents/layout-1b6273baddb72146.js +1 -0
  9. khoj/interface/compiled/_next/static/chunks/app/agents/{page-774c78ff0f55a228.js → page-2fac1d5ac7192e73.js} +1 -1
  10. khoj/interface/compiled/_next/static/chunks/app/automations/page-ef89ac958e78aa81.js +1 -0
  11. khoj/interface/compiled/_next/static/chunks/app/chat/page-d71351493e1f7c2b.js +1 -0
  12. khoj/interface/compiled/_next/static/chunks/app/{page-f7a0286dfc31ad6b.js → page-4bbe55de8b080c1f.js} +1 -1
  13. khoj/interface/compiled/_next/static/chunks/app/search/layout-4505b79deb734a30.js +1 -0
  14. khoj/interface/compiled/_next/static/chunks/app/search/{page-f1a7f278c89e09b6.js → page-afb5e7ed13d221c1.js} +1 -1
  15. khoj/interface/compiled/_next/static/chunks/app/settings/{page-5d9134d4a97f8834.js → page-8fb6cc97be8774a7.js} +1 -1
  16. khoj/interface/compiled/_next/static/chunks/app/share/chat/layout-e8e5db7830bf3f47.js +1 -0
  17. khoj/interface/compiled/_next/static/chunks/app/share/chat/{page-32cd0ceb9ffbd777.js → page-e3f49c25480e3be4.js} +1 -1
  18. khoj/interface/compiled/_next/static/chunks/{main-876327ac335776ab.js → main-63d6432f34cdf74b.js} +1 -1
  19. khoj/interface/compiled/_next/static/chunks/{webpack-97e712397e673897.js → webpack-e4c73eaddc365142.js} +1 -1
  20. khoj/interface/compiled/_next/static/css/2945c4a857922f3b.css +1 -0
  21. khoj/interface/compiled/_next/static/css/2b1cdb68b799b876.css +1 -0
  22. khoj/interface/compiled/_next/static/css/440ae0f0f650dc35.css +1 -0
  23. khoj/interface/compiled/_next/static/css/{9c223d337a984468.css → 7017ee76c2f2cd87.css} +1 -1
  24. khoj/interface/compiled/agents/index.html +2 -2
  25. khoj/interface/compiled/agents/index.txt +2 -2
  26. khoj/interface/compiled/automations/index.html +2 -2
  27. khoj/interface/compiled/automations/index.txt +2 -2
  28. khoj/interface/compiled/chat/index.html +2 -2
  29. khoj/interface/compiled/chat/index.txt +2 -2
  30. khoj/interface/compiled/index.html +2 -2
  31. khoj/interface/compiled/index.txt +2 -2
  32. khoj/interface/compiled/search/index.html +2 -2
  33. khoj/interface/compiled/search/index.txt +2 -2
  34. khoj/interface/compiled/settings/index.html +2 -2
  35. khoj/interface/compiled/settings/index.txt +2 -2
  36. khoj/interface/compiled/share/chat/index.html +2 -2
  37. khoj/interface/compiled/share/chat/index.txt +2 -2
  38. khoj/processor/conversation/anthropic/anthropic_chat.py +19 -134
  39. khoj/processor/conversation/anthropic/utils.py +1 -1
  40. khoj/processor/conversation/google/gemini_chat.py +20 -141
  41. khoj/processor/conversation/offline/chat_model.py +23 -153
  42. khoj/processor/conversation/openai/gpt.py +14 -128
  43. khoj/processor/conversation/prompts.py +2 -63
  44. khoj/processor/conversation/utils.py +94 -89
  45. khoj/processor/image/generate.py +16 -11
  46. khoj/processor/operator/__init__.py +2 -3
  47. khoj/processor/operator/operator_agent_binary.py +11 -11
  48. khoj/processor/operator/operator_environment_computer.py +2 -2
  49. khoj/processor/tools/online_search.py +9 -3
  50. khoj/processor/tools/run_code.py +5 -5
  51. khoj/routers/api.py +5 -527
  52. khoj/routers/api_automation.py +243 -0
  53. khoj/routers/api_chat.py +48 -129
  54. khoj/routers/helpers.py +373 -121
  55. khoj/routers/research.py +13 -43
  56. khoj/utils/helpers.py +0 -6
  57. {khoj-1.42.1.dev8.dist-info → khoj-1.42.2.dist-info}/METADATA +3 -3
  58. {khoj-1.42.1.dev8.dist-info → khoj-1.42.2.dist-info}/RECORD +63 -62
  59. khoj/interface/compiled/_next/static/chunks/7127-d3199617463d45f0.js +0 -1
  60. khoj/interface/compiled/_next/static/chunks/app/agents/layout-4e2a134ec26aa606.js +0 -1
  61. khoj/interface/compiled/_next/static/chunks/app/automations/page-4454891c5007b870.js +0 -1
  62. khoj/interface/compiled/_next/static/chunks/app/chat/page-3c299bf8e6b1afd3.js +0 -1
  63. khoj/interface/compiled/_next/static/chunks/app/search/layout-f5881c7ae3ba0795.js +0 -1
  64. khoj/interface/compiled/_next/static/chunks/app/share/chat/layout-abb6c5f4239ad7be.js +0 -1
  65. khoj/interface/compiled/_next/static/css/0db53bacf81896f5.css +0 -1
  66. khoj/interface/compiled/_next/static/css/76c658ee459140a9.css +0 -1
  67. khoj/interface/compiled/_next/static/css/93eeacc43e261162.css +0 -1
  68. /khoj/interface/compiled/_next/static/{TrHI4J6qnG7RYFl2Irnqj → BDHACq0ud8EERJ3YZ4aWo}/_buildManifest.js +0 -0
  69. /khoj/interface/compiled/_next/static/{TrHI4J6qnG7RYFl2Irnqj → BDHACq0ud8EERJ3YZ4aWo}/_ssgManifest.js +0 -0
  70. {khoj-1.42.1.dev8.dist-info → khoj-1.42.2.dist-info}/WHEEL +0 -0
  71. {khoj-1.42.1.dev8.dist-info → khoj-1.42.2.dist-info}/entry_points.txt +0 -0
  72. {khoj-1.42.1.dev8.dist-info → khoj-1.42.2.dist-info}/licenses/LICENSE +0 -0
@@ -10,7 +10,12 @@ from google import genai
10
10
  from google.genai import types as gtypes
11
11
 
12
12
  from khoj.database.adapters import ConversationAdapters
13
- from khoj.database.models import Agent, KhojUser, TextToImageModelConfig
13
+ from khoj.database.models import (
14
+ Agent,
15
+ ChatMessageModel,
16
+ KhojUser,
17
+ TextToImageModelConfig,
18
+ )
14
19
  from khoj.routers.helpers import ChatEvent, generate_better_image_prompt
15
20
  from khoj.routers.storage import upload_generated_image_to_bucket
16
21
  from khoj.utils import state
@@ -23,7 +28,7 @@ logger = logging.getLogger(__name__)
23
28
  async def text_to_image(
24
29
  message: str,
25
30
  user: KhojUser,
26
- conversation_log: dict,
31
+ chat_history: List[ChatMessageModel],
27
32
  location_data: LocationData,
28
33
  references: List[Dict[str, Any]],
29
34
  online_results: Dict[str, Any],
@@ -46,14 +51,14 @@ async def text_to_image(
46
51
  return
47
52
 
48
53
  text2image_model = text_to_image_config.model_name
49
- chat_history = ""
50
- for chat in conversation_log.get("chat", [])[-4:]:
51
- if chat["by"] == "khoj" and chat["intent"].get("type") in ["remember", "reminder"]:
52
- chat_history += f"Q: {chat['intent']['query']}\n"
53
- chat_history += f"A: {chat['message']}\n"
54
- elif chat["by"] == "khoj" and chat.get("images"):
55
- chat_history += f"Q: {chat['intent']['query']}\n"
56
- chat_history += f"A: Improved Prompt: {chat['intent']['inferred-queries'][0]}\n"
54
+ chat_history_str = ""
55
+ for chat in chat_history[-4:]:
56
+ if chat.by == "khoj" and chat.intent and chat.intent.type in ["remember", "reminder"]:
57
+ chat_history_str += f"Q: {chat.intent.query or ''}\n"
58
+ chat_history_str += f"A: {chat.message}\n"
59
+ elif chat.by == "khoj" and chat.images:
60
+ chat_history_str += f"Q: {chat.intent.query}\n"
61
+ chat_history_str += f"A: Improved Prompt: {chat.intent.inferred_queries[0]}\n"
57
62
 
58
63
  if send_status_func:
59
64
  async for event in send_status_func("**Enhancing the Painting Prompt**"):
@@ -63,7 +68,7 @@ async def text_to_image(
63
68
  # Use the user's message, chat history, and other context
64
69
  image_prompt = await generate_better_image_prompt(
65
70
  message,
66
- chat_history,
71
+ chat_history_str,
67
72
  location_data=location_data,
68
73
  note_references=references,
69
74
  online_results=online_results,
@@ -5,10 +5,9 @@ import os
5
5
  from typing import Callable, List, Optional
6
6
 
7
7
  from khoj.database.adapters import AgentAdapters, ConversationAdapters
8
- from khoj.database.models import Agent, ChatModel, KhojUser
8
+ from khoj.database.models import Agent, ChatMessageModel, ChatModel, KhojUser
9
9
  from khoj.processor.conversation.utils import (
10
10
  OperatorRun,
11
- construct_chat_history,
12
11
  construct_chat_history_for_operator,
13
12
  )
14
13
  from khoj.processor.operator.operator_actions import *
@@ -34,7 +33,7 @@ logger = logging.getLogger(__name__)
34
33
  async def operate_environment(
35
34
  query: str,
36
35
  user: KhojUser,
37
- conversation_log: dict,
36
+ conversation_log: List[ChatMessageModel],
38
37
  location_data: LocationData,
39
38
  previous_trajectory: Optional[OperatorRun] = None,
40
39
  environment_type: EnvironmentType = EnvironmentType.COMPUTER,
@@ -4,7 +4,7 @@ from datetime import datetime
4
4
  from textwrap import dedent
5
5
  from typing import List, Optional
6
6
 
7
- from khoj.database.models import ChatModel
7
+ from khoj.database.models import ChatMessageModel, ChatModel
8
8
  from khoj.processor.conversation.utils import (
9
9
  AgentMessage,
10
10
  OperatorRun,
@@ -119,13 +119,13 @@ class BinaryOperatorAgent(OperatorAgent):
119
119
  query_screenshot = self._get_message_images(current_message)
120
120
 
121
121
  # Construct input for visual reasoner history
122
- visual_reasoner_history = {"chat": self._format_message_for_api(self.messages)}
122
+ visual_reasoner_history = self._format_message_for_api(self.messages)
123
123
  try:
124
124
  natural_language_action = await send_message_to_model_wrapper(
125
125
  query=query_text,
126
126
  query_images=query_screenshot,
127
127
  system_message=reasoning_system_prompt,
128
- conversation_log=visual_reasoner_history,
128
+ chat_history=visual_reasoner_history,
129
129
  agent_chat_model=self.reasoning_model,
130
130
  tracer=self.tracer,
131
131
  )
@@ -238,11 +238,11 @@ class BinaryOperatorAgent(OperatorAgent):
238
238
 
239
239
  async def summarize(self, env_state: EnvState, summarize_prompt: str = None) -> str:
240
240
  summarize_prompt = summarize_prompt or self.summarize_prompt
241
- conversation_history = {"chat": self._format_message_for_api(self.messages)}
241
+ conversation_history = self._format_message_for_api(self.messages)
242
242
  try:
243
243
  summary = await send_message_to_model_wrapper(
244
244
  query=summarize_prompt,
245
- conversation_log=conversation_history,
245
+ chat_history=conversation_history,
246
246
  agent_chat_model=self.reasoning_model,
247
247
  tracer=self.tracer,
248
248
  )
@@ -296,14 +296,14 @@ class BinaryOperatorAgent(OperatorAgent):
296
296
  images = [item["image_url"]["url"] for item in message.content if item["type"] == "image_url"]
297
297
  return images
298
298
 
299
- def _format_message_for_api(self, messages: list[AgentMessage]) -> List[dict]:
299
+ def _format_message_for_api(self, messages: list[AgentMessage]) -> List[ChatMessageModel]:
300
300
  """Format operator agent messages into the Khoj conversation history format."""
301
301
  formatted_messages = [
302
- {
303
- "message": self._get_message_text(message),
304
- "images": self._get_message_images(message),
305
- "by": "you" if message.role in ["user", "environment"] else message.role,
306
- }
302
+ ChatMessageModel(
303
+ message=self._get_message_text(message),
304
+ images=self._get_message_images(message),
305
+ by="you" if message.role in ["user", "environment"] else message.role,
306
+ )
307
307
  for message in messages
308
308
  ]
309
309
  return formatted_messages
@@ -222,9 +222,9 @@ class ComputerEnvironment(Environment):
222
222
  elif action.scroll_direction == "down":
223
223
  await self._execute("scroll", -total_scroll_clicks)
224
224
  elif action.scroll_direction == "left":
225
- await self._execute("hscroll", -total_scroll_clicks)
225
+ await self._execute("hscroll", -total_scroll_clicks * 3)
226
226
  elif action.scroll_direction == "right":
227
- await self._execute("hscroll", total_scroll_clicks)
227
+ await self._execute("hscroll", total_scroll_clicks * 3)
228
228
  output = f"Scrolled {action.scroll_direction} by {amount} units at ({target_x}, {target_y})"
229
229
  else:
230
230
  error = "Scroll action requires either scroll_x/y or scroll_direction"
@@ -10,7 +10,13 @@ from bs4 import BeautifulSoup
10
10
  from markdownify import markdownify
11
11
 
12
12
  from khoj.database.adapters import ConversationAdapters
13
- from khoj.database.models import Agent, KhojUser, ServerChatSettings, WebScraper
13
+ from khoj.database.models import (
14
+ Agent,
15
+ ChatMessageModel,
16
+ KhojUser,
17
+ ServerChatSettings,
18
+ WebScraper,
19
+ )
14
20
  from khoj.processor.conversation import prompts
15
21
  from khoj.routers.helpers import (
16
22
  ChatEvent,
@@ -59,7 +65,7 @@ OLOSTEP_QUERY_PARAMS = {
59
65
 
60
66
  async def search_online(
61
67
  query: str,
62
- conversation_history: dict,
68
+ conversation_history: List[ChatMessageModel],
63
69
  location: LocationData,
64
70
  user: KhojUser,
65
71
  send_status_func: Optional[Callable] = None,
@@ -361,7 +367,7 @@ async def search_with_serper(query: str, location: LocationData) -> Tuple[str, D
361
367
 
362
368
  async def read_webpages(
363
369
  query: str,
364
- conversation_history: dict,
370
+ conversation_history: List[ChatMessageModel],
365
371
  location: LocationData,
366
372
  user: KhojUser,
367
373
  send_status_func: Optional[Callable] = None,
@@ -20,7 +20,7 @@ from tenacity import (
20
20
  )
21
21
 
22
22
  from khoj.database.adapters import FileObjectAdapters
23
- from khoj.database.models import Agent, FileObject, KhojUser
23
+ from khoj.database.models import Agent, ChatMessageModel, FileObject, KhojUser
24
24
  from khoj.processor.conversation import prompts
25
25
  from khoj.processor.conversation.utils import (
26
26
  ChatEvent,
@@ -50,7 +50,7 @@ class GeneratedCode(NamedTuple):
50
50
 
51
51
  async def run_code(
52
52
  query: str,
53
- conversation_history: dict,
53
+ conversation_history: List[ChatMessageModel],
54
54
  context: str,
55
55
  location_data: LocationData,
56
56
  user: KhojUser,
@@ -116,7 +116,7 @@ async def run_code(
116
116
 
117
117
  async def generate_python_code(
118
118
  q: str,
119
- conversation_history: dict,
119
+ chat_history: List[ChatMessageModel],
120
120
  context: str,
121
121
  location_data: LocationData,
122
122
  user: KhojUser,
@@ -127,7 +127,7 @@ async def generate_python_code(
127
127
  ) -> GeneratedCode:
128
128
  location = f"{location_data}" if location_data else "Unknown"
129
129
  username = prompts.user_name.format(name=user.get_full_name()) if user.get_full_name() else ""
130
- chat_history = construct_chat_history(conversation_history)
130
+ chat_history_str = construct_chat_history(chat_history)
131
131
 
132
132
  utc_date = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d")
133
133
  personality_context = (
@@ -143,7 +143,7 @@ async def generate_python_code(
143
143
 
144
144
  code_generation_prompt = prompts.python_code_generation_prompt.format(
145
145
  query=q,
146
- chat_history=chat_history,
146
+ chat_history=chat_history_str,
147
147
  context=context,
148
148
  has_network_access=network_access_context,
149
149
  current_date=utc_date,