khoj 2.0.0b12.dev5__py3-none-any.whl → 2.0.0b13__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 (187) hide show
  1. khoj/app/README.md +1 -1
  2. khoj/app/urls.py +1 -0
  3. khoj/configure.py +21 -54
  4. khoj/database/adapters/__init__.py +6 -15
  5. khoj/database/management/commands/delete_orphaned_fileobjects.py +0 -1
  6. khoj/database/migrations/0064_remove_conversation_temp_id_alter_conversation_id.py +1 -1
  7. khoj/database/migrations/0075_migrate_generated_assets_and_validate.py +1 -1
  8. khoj/database/migrations/0092_alter_chatmodel_model_type_alter_chatmodel_name_and_more.py +36 -0
  9. khoj/database/migrations/0093_remove_localorgconfig_user_and_more.py +36 -0
  10. khoj/database/models/__init__.py +10 -40
  11. khoj/database/tests.py +0 -2
  12. khoj/interface/compiled/404/index.html +2 -2
  13. khoj/interface/compiled/_next/static/chunks/{9245.a04e92d034540234.js → 1225.ecac11e7421504c4.js} +3 -3
  14. khoj/interface/compiled/_next/static/chunks/1320.ae930ad00affe685.js +5 -0
  15. khoj/interface/compiled/_next/static/chunks/{1327-1a9107b9a2a04a98.js → 1327-e254819a9172cfa7.js} +1 -1
  16. khoj/interface/compiled/_next/static/chunks/1626.15a8acc0d6639ec6.js +1 -0
  17. khoj/interface/compiled/_next/static/chunks/{3489.c523fe96a2eee74f.js → 1940.d082758bd04e08ae.js} +1 -1
  18. khoj/interface/compiled/_next/static/chunks/{2327-ea623ca2d22f78e9.js → 2327-438aaec1657c5ada.js} +1 -1
  19. khoj/interface/compiled/_next/static/chunks/2475.57a0d0fd93d07af0.js +93 -0
  20. khoj/interface/compiled/_next/static/chunks/2481.5ce6524ba0a73f90.js +55 -0
  21. khoj/interface/compiled/_next/static/chunks/297.4c4c823ff6e3255b.js +174 -0
  22. khoj/interface/compiled/_next/static/chunks/{5639-09e2009a2adedf8b.js → 3260-82d2521fab032ff1.js} +68 -23
  23. khoj/interface/compiled/_next/static/chunks/3353.1c6d553216a1acae.js +1 -0
  24. khoj/interface/compiled/_next/static/chunks/3855.f7b8131f78af046e.js +1 -0
  25. khoj/interface/compiled/_next/static/chunks/3973.dc54a39586ab48be.js +1 -0
  26. khoj/interface/compiled/_next/static/chunks/4241.c1cd170f7f37ac59.js +24 -0
  27. khoj/interface/compiled/_next/static/chunks/{4327.8d2a1b8f1ea78208.js → 4327.f3704dc398c67113.js} +19 -19
  28. khoj/interface/compiled/_next/static/chunks/4505.f09454a346269c3f.js +117 -0
  29. khoj/interface/compiled/_next/static/chunks/4801.96a152d49742b644.js +1 -0
  30. khoj/interface/compiled/_next/static/chunks/5427-a95ec748e52abb75.js +1 -0
  31. khoj/interface/compiled/_next/static/chunks/549.2bd27f59a91a9668.js +148 -0
  32. khoj/interface/compiled/_next/static/chunks/5765.71b1e1207b76b03f.js +1 -0
  33. khoj/interface/compiled/_next/static/chunks/584.d7ce3505f169b706.js +1 -0
  34. khoj/interface/compiled/_next/static/chunks/6240.34f7c1fa692edd61.js +24 -0
  35. khoj/interface/compiled/_next/static/chunks/6d3fe5a5-f9f3c16e0bc0cdf9.js +10 -0
  36. khoj/interface/compiled/_next/static/chunks/{7127-0f4a2a77d97fb5fa.js → 7127-97b83757db125ba6.js} +1 -1
  37. khoj/interface/compiled/_next/static/chunks/7200-93ab0072359b8028.js +1 -0
  38. khoj/interface/compiled/_next/static/chunks/{2612.bcf5a623b3da209e.js → 7553.f5ad54b1f6e92c49.js} +2 -2
  39. khoj/interface/compiled/_next/static/chunks/7626-1b630f1654172341.js +1 -0
  40. khoj/interface/compiled/_next/static/chunks/764.dadd316e8e16d191.js +63 -0
  41. khoj/interface/compiled/_next/static/chunks/78.08169ab541abab4f.js +43 -0
  42. khoj/interface/compiled/_next/static/chunks/784.e03acf460df213d1.js +1 -0
  43. khoj/interface/compiled/_next/static/chunks/{9537-d9ab442ce15d1e20.js → 8072-e1440cb482a0940e.js} +1 -1
  44. khoj/interface/compiled/_next/static/chunks/{3265.924139c4146ee344.js → 8086.8d39887215807fcd.js} +1 -1
  45. khoj/interface/compiled/_next/static/chunks/8168.f074ab8c7c16d82d.js +59 -0
  46. khoj/interface/compiled/_next/static/chunks/{8694.2bd9c2f65d8c5847.js → 8223.1705878fa7a09292.js} +1 -1
  47. khoj/interface/compiled/_next/static/chunks/8483.94f6c9e2bee86f50.js +215 -0
  48. khoj/interface/compiled/_next/static/chunks/{8888.ebe0e552b59e7fed.js → 8810.fc0e479de78c7c61.js} +1 -1
  49. khoj/interface/compiled/_next/static/chunks/8828.bc74dc4ce94e78f6.js +1 -0
  50. khoj/interface/compiled/_next/static/chunks/{7303.d0612f812a967a08.js → 8909.14ac3f43d0070cf1.js} +5 -5
  51. khoj/interface/compiled/_next/static/chunks/90542734.b1a1629065ba199b.js +1 -0
  52. khoj/interface/compiled/_next/static/chunks/9167.098534184f03fe92.js +56 -0
  53. khoj/interface/compiled/_next/static/chunks/{4980.63500d68b3bb1222.js → 9537.e934ce37bf314509.js} +5 -5
  54. khoj/interface/compiled/_next/static/chunks/9574.3fe8e26e95bf1c34.js +1 -0
  55. khoj/interface/compiled/_next/static/chunks/9599.ec50b5296c27dae9.js +1 -0
  56. khoj/interface/compiled/_next/static/chunks/9643.b34248df52ffc77c.js +262 -0
  57. khoj/interface/compiled/_next/static/chunks/9747.2fd9065b1435abb1.js +1 -0
  58. khoj/interface/compiled/_next/static/chunks/9922.98f2b2a9959b4ebe.js +1 -0
  59. khoj/interface/compiled/_next/static/chunks/app/agents/layout-e49165209d2e406c.js +1 -0
  60. khoj/interface/compiled/_next/static/chunks/app/agents/page-e291b49977f43880.js +1 -0
  61. khoj/interface/compiled/_next/static/chunks/app/automations/page-198b26df6e09bbb0.js +1 -0
  62. khoj/interface/compiled/_next/static/chunks/app/chat/{page-8e1c4f2af3c9429e.js → page-dfcc1e8e2ad62873.js} +1 -1
  63. khoj/interface/compiled/_next/static/chunks/app/{page-2b3056cba8aa96ce.js → page-1567cac7b79a7c59.js} +1 -1
  64. khoj/interface/compiled/_next/static/chunks/app/settings/{page-8be3b35178abf2ec.js → page-6081362437c82470.js} +1 -1
  65. khoj/interface/compiled/_next/static/chunks/app/share/chat/layout-6fb51c5c80f8ec67.js +1 -0
  66. khoj/interface/compiled/_next/static/chunks/app/share/chat/{page-4a4b0c0f4749c2b2.js → page-e0dcb1762f8c8f88.js} +1 -1
  67. khoj/interface/compiled/_next/static/chunks/webpack-5393aad3d824e0cb.js +1 -0
  68. khoj/interface/compiled/agents/index.html +2 -2
  69. khoj/interface/compiled/agents/index.txt +3 -3
  70. khoj/interface/compiled/automations/index.html +2 -2
  71. khoj/interface/compiled/automations/index.txt +3 -3
  72. khoj/interface/compiled/chat/index.html +2 -2
  73. khoj/interface/compiled/chat/index.txt +3 -3
  74. khoj/interface/compiled/index.html +2 -2
  75. khoj/interface/compiled/index.txt +3 -3
  76. khoj/interface/compiled/search/index.html +2 -2
  77. khoj/interface/compiled/search/index.txt +3 -3
  78. khoj/interface/compiled/settings/index.html +2 -2
  79. khoj/interface/compiled/settings/index.txt +3 -3
  80. khoj/interface/compiled/share/chat/index.html +2 -2
  81. khoj/interface/compiled/share/chat/index.txt +3 -3
  82. khoj/main.py +7 -9
  83. khoj/manage.py +1 -0
  84. khoj/processor/content/github/github_to_entries.py +6 -7
  85. khoj/processor/content/images/image_to_entries.py +0 -1
  86. khoj/processor/content/markdown/markdown_to_entries.py +2 -3
  87. khoj/processor/content/notion/notion_to_entries.py +5 -6
  88. khoj/processor/content/org_mode/org_to_entries.py +4 -5
  89. khoj/processor/content/org_mode/orgnode.py +4 -4
  90. khoj/processor/content/plaintext/plaintext_to_entries.py +1 -2
  91. khoj/processor/content/text_to_entries.py +1 -3
  92. khoj/processor/conversation/google/utils.py +3 -3
  93. khoj/processor/conversation/openai/gpt.py +65 -28
  94. khoj/processor/conversation/openai/utils.py +359 -28
  95. khoj/processor/conversation/prompts.py +16 -41
  96. khoj/processor/conversation/utils.py +29 -39
  97. khoj/processor/embeddings.py +0 -2
  98. khoj/processor/image/generate.py +3 -3
  99. khoj/processor/operator/__init__.py +2 -3
  100. khoj/processor/operator/grounding_agent.py +15 -2
  101. khoj/processor/operator/grounding_agent_uitars.py +34 -23
  102. khoj/processor/operator/operator_agent_anthropic.py +29 -4
  103. khoj/processor/operator/operator_agent_base.py +1 -1
  104. khoj/processor/operator/operator_agent_binary.py +4 -4
  105. khoj/processor/operator/operator_agent_openai.py +21 -6
  106. khoj/processor/operator/operator_environment_browser.py +1 -1
  107. khoj/processor/operator/operator_environment_computer.py +1 -1
  108. khoj/processor/speech/text_to_speech.py +0 -1
  109. khoj/processor/tools/online_search.py +1 -1
  110. khoj/processor/tools/run_code.py +1 -1
  111. khoj/routers/api.py +2 -15
  112. khoj/routers/api_agents.py +1 -2
  113. khoj/routers/api_automation.py +1 -1
  114. khoj/routers/api_chat.py +10 -16
  115. khoj/routers/api_content.py +3 -111
  116. khoj/routers/api_model.py +0 -1
  117. khoj/routers/api_subscription.py +1 -1
  118. khoj/routers/email.py +4 -4
  119. khoj/routers/helpers.py +44 -103
  120. khoj/routers/research.py +8 -8
  121. khoj/search_filter/base_filter.py +2 -4
  122. khoj/search_type/text_search.py +1 -2
  123. khoj/utils/cli.py +5 -53
  124. khoj/utils/config.py +0 -65
  125. khoj/utils/constants.py +6 -7
  126. khoj/utils/helpers.py +10 -18
  127. khoj/utils/initialization.py +7 -48
  128. khoj/utils/models.py +2 -4
  129. khoj/utils/rawconfig.py +1 -69
  130. khoj/utils/state.py +2 -8
  131. khoj/utils/yaml.py +0 -39
  132. {khoj-2.0.0b12.dev5.dist-info → khoj-2.0.0b13.dist-info}/METADATA +3 -3
  133. {khoj-2.0.0b12.dev5.dist-info → khoj-2.0.0b13.dist-info}/RECORD +139 -148
  134. khoj/interface/compiled/_next/static/chunks/1191.b547ec13349b4aed.js +0 -1
  135. khoj/interface/compiled/_next/static/chunks/1588.f0558a0bdffc4761.js +0 -117
  136. khoj/interface/compiled/_next/static/chunks/1918.925cb4a35518d258.js +0 -43
  137. khoj/interface/compiled/_next/static/chunks/2849.dc00ae5ba7219cfc.js +0 -1
  138. khoj/interface/compiled/_next/static/chunks/303.fe76de943e930fbd.js +0 -1
  139. khoj/interface/compiled/_next/static/chunks/4533.586e74b45a2bde25.js +0 -55
  140. khoj/interface/compiled/_next/static/chunks/4551.82ce1476b5516bc2.js +0 -5
  141. khoj/interface/compiled/_next/static/chunks/4748.0edd37cba3ea2809.js +0 -59
  142. khoj/interface/compiled/_next/static/chunks/5210.cd35a1c1ec594a20.js +0 -93
  143. khoj/interface/compiled/_next/static/chunks/5329.f8b3c5b3d16159cd.js +0 -1
  144. khoj/interface/compiled/_next/static/chunks/5427-13d6ffd380fdfab7.js +0 -1
  145. khoj/interface/compiled/_next/static/chunks/558-c14e76cff03f6a60.js +0 -1
  146. khoj/interface/compiled/_next/static/chunks/5830.8876eccb82da9b7d.js +0 -262
  147. khoj/interface/compiled/_next/static/chunks/6230.88a71d8145347b3f.js +0 -1
  148. khoj/interface/compiled/_next/static/chunks/7161.77e0530a40ad5ca8.js +0 -1
  149. khoj/interface/compiled/_next/static/chunks/7200-ac3b2e37ff30e126.js +0 -1
  150. khoj/interface/compiled/_next/static/chunks/7505.c31027a3695bdebb.js +0 -148
  151. khoj/interface/compiled/_next/static/chunks/7760.35649cc21d9585bd.js +0 -56
  152. khoj/interface/compiled/_next/static/chunks/83.48e2db193a940052.js +0 -1
  153. khoj/interface/compiled/_next/static/chunks/8427.844694e06133fb51.js +0 -1
  154. khoj/interface/compiled/_next/static/chunks/8665.4db7e6b2e8933497.js +0 -174
  155. khoj/interface/compiled/_next/static/chunks/872.caf84cc1a39ae59f.js +0 -1
  156. khoj/interface/compiled/_next/static/chunks/8890.6e8a59e4de6978bc.js +0 -215
  157. khoj/interface/compiled/_next/static/chunks/8950.5f2272e0ac923f9e.js +0 -1
  158. khoj/interface/compiled/_next/static/chunks/90542734.2c21f16f18b22411.js +0 -1
  159. khoj/interface/compiled/_next/static/chunks/9202.c703864fcedc8d1f.js +0 -63
  160. khoj/interface/compiled/_next/static/chunks/9320.6aca4885d541aa44.js +0 -24
  161. khoj/interface/compiled/_next/static/chunks/9535.f78cd92d03331e55.js +0 -1
  162. khoj/interface/compiled/_next/static/chunks/9968.b111fc002796da81.js +0 -1
  163. khoj/interface/compiled/_next/static/chunks/app/agents/layout-e00fb81dca656a10.js +0 -1
  164. khoj/interface/compiled/_next/static/chunks/app/agents/page-9a4610474cd59a71.js +0 -1
  165. khoj/interface/compiled/_next/static/chunks/app/automations/page-f7bb9d777b7745d4.js +0 -1
  166. khoj/interface/compiled/_next/static/chunks/app/share/chat/layout-e8e5db7830bf3f47.js +0 -1
  167. khoj/interface/compiled/_next/static/chunks/f3e3247b-1758d4651e4457c2.js +0 -10
  168. khoj/interface/compiled/_next/static/chunks/webpack-338a5000c912cc94.js +0 -1
  169. khoj/migrations/__init__.py +0 -0
  170. khoj/migrations/migrate_offline_chat_default_model.py +0 -69
  171. khoj/migrations/migrate_offline_chat_default_model_2.py +0 -71
  172. khoj/migrations/migrate_offline_chat_schema.py +0 -83
  173. khoj/migrations/migrate_offline_model.py +0 -29
  174. khoj/migrations/migrate_processor_config_openai.py +0 -67
  175. khoj/migrations/migrate_server_pg.py +0 -132
  176. khoj/migrations/migrate_version.py +0 -17
  177. khoj/processor/conversation/offline/__init__.py +0 -0
  178. khoj/processor/conversation/offline/chat_model.py +0 -224
  179. khoj/processor/conversation/offline/utils.py +0 -80
  180. khoj/processor/conversation/offline/whisper.py +0 -15
  181. khoj/utils/fs_syncer.py +0 -252
  182. /khoj/interface/compiled/_next/static/{7GoMcE8WpP9fbfYZXv4Nv → RYbQvo3AvgOR0bEVVfxF4}/_buildManifest.js +0 -0
  183. /khoj/interface/compiled/_next/static/{7GoMcE8WpP9fbfYZXv4Nv → RYbQvo3AvgOR0bEVVfxF4}/_ssgManifest.js +0 -0
  184. /khoj/interface/compiled/_next/static/chunks/app/search/{page-4885df3cd175c957.js → page-3639e50ec3e9acfd.js} +0 -0
  185. {khoj-2.0.0b12.dev5.dist-info → khoj-2.0.0b13.dist-info}/WHEEL +0 -0
  186. {khoj-2.0.0b12.dev5.dist-info → khoj-2.0.0b13.dist-info}/entry_points.txt +0 -0
  187. {khoj-2.0.0b12.dev5.dist-info → khoj-2.0.0b13.dist-info}/licenses/LICENSE +0 -0
@@ -8,7 +8,6 @@ from khoj.database.models import KhojUser
8
8
  from khoj.processor.content.org_mode import orgnode
9
9
  from khoj.processor.content.org_mode.orgnode import Orgnode
10
10
  from khoj.processor.content.text_to_entries import TextToEntries
11
- from khoj.utils import state
12
11
  from khoj.utils.helpers import timer
13
12
  from khoj.utils.rawconfig import Entry
14
13
 
@@ -103,7 +102,7 @@ class OrgToEntries(TextToEntries):
103
102
  # If content is small or content has no children headings, save it as a single entry
104
103
  # Note: This is the terminating condition for this recursive function
105
104
  if len(TextToEntries.tokenizer(org_content_with_ancestry)) <= max_tokens or not re.search(
106
- rf"^\*{{{len(ancestry)+1},}}\s", org_content, re.MULTILINE
105
+ rf"^\*{{{len(ancestry) + 1},}}\s", org_content, re.MULTILINE
107
106
  ):
108
107
  orgnode_content_with_ancestry = orgnode.makelist(
109
108
  org_content_with_ancestry, org_file, start_line=start_line, ancestry_lines=len(ancestry)
@@ -195,7 +194,7 @@ class OrgToEntries(TextToEntries):
195
194
  if not entry_heading and parsed_entry.level > 0:
196
195
  base_level = parsed_entry.level
197
196
  # Indent entry by 1 heading level as ancestry is prepended as top level heading
198
- heading = f"{'*' * (parsed_entry.level-base_level+2)} {todo_str}" if parsed_entry.level > 0 else ""
197
+ heading = f"{'*' * (parsed_entry.level - base_level + 2)} {todo_str}" if parsed_entry.level > 0 else ""
199
198
  if parsed_entry.heading:
200
199
  heading += f"{parsed_entry.heading}."
201
200
 
@@ -212,10 +211,10 @@ class OrgToEntries(TextToEntries):
212
211
  compiled += f"\t {tags_str}."
213
212
 
214
213
  if parsed_entry.closed:
215
- compiled += f'\n Closed on {parsed_entry.closed.strftime("%Y-%m-%d")}.'
214
+ compiled += f"\n Closed on {parsed_entry.closed.strftime('%Y-%m-%d')}."
216
215
 
217
216
  if parsed_entry.scheduled:
218
- compiled += f'\n Scheduled for {parsed_entry.scheduled.strftime("%Y-%m-%d")}.'
217
+ compiled += f"\n Scheduled for {parsed_entry.scheduled.strftime('%Y-%m-%d')}."
219
218
 
220
219
  if parsed_entry.hasBody:
221
220
  compiled += f"\n {parsed_entry.body}"
@@ -65,7 +65,7 @@ def makelist(file, filename, start_line: int = 1, ancestry_lines: int = 0) -> Li
65
65
  """
66
66
  ctr = 0
67
67
 
68
- if type(file) == str:
68
+ if isinstance(file, str):
69
69
  f = file.splitlines()
70
70
  else:
71
71
  f = file
@@ -512,11 +512,11 @@ class Orgnode(object):
512
512
  if self._closed or self._scheduled or self._deadline:
513
513
  n = n + indent
514
514
  if self._closed:
515
- n = n + f'CLOSED: [{self._closed.strftime("%Y-%m-%d %a")}] '
515
+ n = n + f"CLOSED: [{self._closed.strftime('%Y-%m-%d %a')}] "
516
516
  if self._scheduled:
517
- n = n + f'SCHEDULED: <{self._scheduled.strftime("%Y-%m-%d %a")}> '
517
+ n = n + f"SCHEDULED: <{self._scheduled.strftime('%Y-%m-%d %a')}> "
518
518
  if self._deadline:
519
- n = n + f'DEADLINE: <{self._deadline.strftime("%Y-%m-%d %a")}> '
519
+ n = n + f"DEADLINE: <{self._deadline.strftime('%Y-%m-%d %a')}> "
520
520
  if self._closed or self._scheduled or self._deadline:
521
521
  n = n + "\n"
522
522
 
@@ -1,6 +1,5 @@
1
1
  import logging
2
2
  import re
3
- from pathlib import Path
4
3
  from typing import Dict, List, Tuple
5
4
 
6
5
  import urllib3
@@ -97,7 +96,7 @@ class PlaintextToEntries(TextToEntries):
97
96
  for parsed_entry in parsed_entries:
98
97
  raw_filename = entry_to_file_map[parsed_entry]
99
98
  # Check if raw_filename is a URL. If so, save it as is. If not, convert it to a Path.
100
- if type(raw_filename) == str and re.search(r"^https?://", raw_filename):
99
+ if isinstance(raw_filename, str) and re.search(r"^https?://", raw_filename):
101
100
  # Escape the URL to avoid issues with special characters
102
101
  entry_filename = urllib3.util.parse_url(raw_filename).url
103
102
  else:
@@ -27,12 +27,10 @@ logger = logging.getLogger(__name__)
27
27
  class TextToEntries(ABC):
28
28
  def __init__(self, config: Any = None):
29
29
  self.embeddings_model = state.embeddings_model
30
- self.config = config
31
30
  self.date_filter = DateFilter()
32
31
 
33
32
  @abstractmethod
34
- def process(self, files: dict[str, str], user: KhojUser, regenerate: bool = False) -> Tuple[int, int]:
35
- ...
33
+ def process(self, files: dict[str, str], user: KhojUser, regenerate: bool = False) -> Tuple[int, int]: ...
36
34
 
37
35
  @staticmethod
38
36
  def hash_func(key: str) -> Callable:
@@ -194,7 +194,7 @@ def gemini_completion_with_backoff(
194
194
  or not response.candidates[0].content
195
195
  or response.candidates[0].content.parts is None
196
196
  ):
197
- raise ValueError(f"Failed to get response from model.")
197
+ raise ValueError("Failed to get response from model.")
198
198
  raw_content = [part.model_dump() for part in response.candidates[0].content.parts]
199
199
  if response.function_calls:
200
200
  function_calls = [
@@ -212,7 +212,7 @@ def gemini_completion_with_backoff(
212
212
  response = None
213
213
  # Handle 429 rate limit errors directly
214
214
  if e.code == 429:
215
- response_text = f"My brain is exhausted. Can you please try again in a bit?"
215
+ response_text = "My brain is exhausted. Can you please try again in a bit?"
216
216
  # Log the full error details for debugging
217
217
  logger.error(f"Gemini ClientError: {e.code} {e.status}. Details: {e.details}")
218
218
  # Handle other errors
@@ -361,7 +361,7 @@ def handle_gemini_response(
361
361
 
362
362
  # Ensure we have a proper list of candidates
363
363
  if not isinstance(candidates, list):
364
- message = f"\nUnexpected response format. Try again."
364
+ message = "\nUnexpected response format. Try again."
365
365
  stopped = True
366
366
  return message, stopped
367
367
 
@@ -9,6 +9,9 @@ from khoj.processor.conversation.openai.utils import (
9
9
  clean_response_schema,
10
10
  completion_with_backoff,
11
11
  get_structured_output_support,
12
+ is_openai_api,
13
+ responses_chat_completion_with_backoff,
14
+ responses_completion_with_backoff,
12
15
  to_openai_tools,
13
16
  )
14
17
  from khoj.processor.conversation.utils import (
@@ -43,31 +46,52 @@ def send_message_to_model(
43
46
  model_kwargs: Dict[str, Any] = {}
44
47
  json_support = get_structured_output_support(model, api_base_url)
45
48
  if tools and json_support == StructuredOutputSupport.TOOL:
46
- model_kwargs["tools"] = to_openai_tools(tools)
49
+ model_kwargs["tools"] = to_openai_tools(tools, use_responses_api=is_openai_api(api_base_url))
47
50
  elif response_schema and json_support >= StructuredOutputSupport.SCHEMA:
48
51
  # Drop unsupported fields from schema passed to OpenAI APi
49
52
  cleaned_response_schema = clean_response_schema(response_schema)
50
- model_kwargs["response_format"] = {
51
- "type": "json_schema",
52
- "json_schema": {
53
- "schema": cleaned_response_schema,
54
- "name": response_schema.__name__,
55
- "strict": True,
56
- },
57
- }
53
+ if is_openai_api(api_base_url):
54
+ model_kwargs["text"] = {
55
+ "format": {
56
+ "type": "json_schema",
57
+ "strict": True,
58
+ "name": response_schema.__name__,
59
+ "schema": cleaned_response_schema,
60
+ }
61
+ }
62
+ else:
63
+ model_kwargs["response_format"] = {
64
+ "type": "json_schema",
65
+ "json_schema": {
66
+ "schema": cleaned_response_schema,
67
+ "name": response_schema.__name__,
68
+ "strict": True,
69
+ },
70
+ }
58
71
  elif response_type == "json_object" and json_support == StructuredOutputSupport.OBJECT:
59
72
  model_kwargs["response_format"] = {"type": response_type}
60
73
 
61
74
  # Get Response from GPT
62
- return completion_with_backoff(
63
- messages=messages,
64
- model_name=model,
65
- openai_api_key=api_key,
66
- api_base_url=api_base_url,
67
- deepthought=deepthought,
68
- model_kwargs=model_kwargs,
69
- tracer=tracer,
70
- )
75
+ if is_openai_api(api_base_url):
76
+ return responses_completion_with_backoff(
77
+ messages=messages,
78
+ model_name=model,
79
+ openai_api_key=api_key,
80
+ api_base_url=api_base_url,
81
+ deepthought=deepthought,
82
+ model_kwargs=model_kwargs,
83
+ tracer=tracer,
84
+ )
85
+ else:
86
+ return completion_with_backoff(
87
+ messages=messages,
88
+ model_name=model,
89
+ openai_api_key=api_key,
90
+ api_base_url=api_base_url,
91
+ deepthought=deepthought,
92
+ model_kwargs=model_kwargs,
93
+ tracer=tracer,
94
+ )
71
95
 
72
96
 
73
97
  async def converse_openai(
@@ -163,13 +187,26 @@ async def converse_openai(
163
187
  logger.debug(f"Conversation Context for GPT: {messages_to_print(messages)}")
164
188
 
165
189
  # Get Response from GPT
166
- async for chunk in chat_completion_with_backoff(
167
- messages=messages,
168
- model_name=model,
169
- temperature=temperature,
170
- openai_api_key=api_key,
171
- api_base_url=api_base_url,
172
- deepthought=deepthought,
173
- tracer=tracer,
174
- ):
175
- yield chunk
190
+ if is_openai_api(api_base_url):
191
+ async for chunk in responses_chat_completion_with_backoff(
192
+ messages=messages,
193
+ model_name=model,
194
+ temperature=temperature,
195
+ openai_api_key=api_key,
196
+ api_base_url=api_base_url,
197
+ deepthought=deepthought,
198
+ tracer=tracer,
199
+ ):
200
+ yield chunk
201
+ else:
202
+ # For non-OpenAI APIs, use the chat completion method
203
+ async for chunk in chat_completion_with_backoff(
204
+ messages=messages,
205
+ model_name=model,
206
+ temperature=temperature,
207
+ openai_api_key=api_key,
208
+ api_base_url=api_base_url,
209
+ deepthought=deepthought,
210
+ tracer=tracer,
211
+ ):
212
+ yield chunk