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.
- khoj/configure.py +2 -0
- khoj/database/adapters/__init__.py +9 -7
- khoj/database/models/__init__.py +9 -9
- khoj/interface/compiled/404/index.html +2 -2
- khoj/interface/compiled/_next/static/chunks/{2117-5a41630a2bd2eae8.js → 2117-056a00add390772b.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/7127-79a3af5138960272.js +1 -0
- khoj/interface/compiled/_next/static/chunks/{5138-2cce449fd2454abf.js → 7211-7fedd2ee3655239c.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/agents/layout-1b6273baddb72146.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/agents/{page-774c78ff0f55a228.js → page-2fac1d5ac7192e73.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/automations/page-ef89ac958e78aa81.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/chat/page-d71351493e1f7c2b.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/{page-f7a0286dfc31ad6b.js → page-4bbe55de8b080c1f.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/search/layout-4505b79deb734a30.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/search/{page-f1a7f278c89e09b6.js → page-afb5e7ed13d221c1.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/settings/{page-5d9134d4a97f8834.js → page-8fb6cc97be8774a7.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/share/chat/layout-e8e5db7830bf3f47.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/share/chat/{page-32cd0ceb9ffbd777.js → page-e3f49c25480e3be4.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/{main-876327ac335776ab.js → main-63d6432f34cdf74b.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/{webpack-97e712397e673897.js → webpack-e4c73eaddc365142.js} +1 -1
- khoj/interface/compiled/_next/static/css/2945c4a857922f3b.css +1 -0
- khoj/interface/compiled/_next/static/css/2b1cdb68b799b876.css +1 -0
- khoj/interface/compiled/_next/static/css/440ae0f0f650dc35.css +1 -0
- khoj/interface/compiled/_next/static/css/{9c223d337a984468.css → 7017ee76c2f2cd87.css} +1 -1
- khoj/interface/compiled/agents/index.html +2 -2
- khoj/interface/compiled/agents/index.txt +2 -2
- khoj/interface/compiled/automations/index.html +2 -2
- khoj/interface/compiled/automations/index.txt +2 -2
- khoj/interface/compiled/chat/index.html +2 -2
- khoj/interface/compiled/chat/index.txt +2 -2
- khoj/interface/compiled/index.html +2 -2
- khoj/interface/compiled/index.txt +2 -2
- khoj/interface/compiled/search/index.html +2 -2
- khoj/interface/compiled/search/index.txt +2 -2
- khoj/interface/compiled/settings/index.html +2 -2
- khoj/interface/compiled/settings/index.txt +2 -2
- khoj/interface/compiled/share/chat/index.html +2 -2
- khoj/interface/compiled/share/chat/index.txt +2 -2
- khoj/processor/conversation/anthropic/anthropic_chat.py +19 -134
- khoj/processor/conversation/anthropic/utils.py +1 -1
- khoj/processor/conversation/google/gemini_chat.py +20 -141
- khoj/processor/conversation/offline/chat_model.py +23 -153
- khoj/processor/conversation/openai/gpt.py +14 -128
- khoj/processor/conversation/prompts.py +2 -63
- khoj/processor/conversation/utils.py +94 -89
- khoj/processor/image/generate.py +16 -11
- khoj/processor/operator/__init__.py +2 -3
- khoj/processor/operator/operator_agent_binary.py +11 -11
- khoj/processor/operator/operator_environment_computer.py +2 -2
- khoj/processor/tools/online_search.py +9 -3
- khoj/processor/tools/run_code.py +5 -5
- khoj/routers/api.py +5 -527
- khoj/routers/api_automation.py +243 -0
- khoj/routers/api_chat.py +48 -129
- khoj/routers/helpers.py +373 -121
- khoj/routers/research.py +13 -43
- khoj/utils/helpers.py +0 -6
- {khoj-1.42.1.dev8.dist-info → khoj-1.42.2.dist-info}/METADATA +3 -3
- {khoj-1.42.1.dev8.dist-info → khoj-1.42.2.dist-info}/RECORD +63 -62
- khoj/interface/compiled/_next/static/chunks/7127-d3199617463d45f0.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/agents/layout-4e2a134ec26aa606.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/automations/page-4454891c5007b870.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/chat/page-3c299bf8e6b1afd3.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/search/layout-f5881c7ae3ba0795.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/share/chat/layout-abb6c5f4239ad7be.js +0 -1
- khoj/interface/compiled/_next/static/css/0db53bacf81896f5.css +0 -1
- khoj/interface/compiled/_next/static/css/76c658ee459140a9.css +0 -1
- khoj/interface/compiled/_next/static/css/93eeacc43e261162.css +0 -1
- /khoj/interface/compiled/_next/static/{TrHI4J6qnG7RYFl2Irnqj → BDHACq0ud8EERJ3YZ4aWo}/_buildManifest.js +0 -0
- /khoj/interface/compiled/_next/static/{TrHI4J6qnG7RYFl2Irnqj → BDHACq0ud8EERJ3YZ4aWo}/_ssgManifest.js +0 -0
- {khoj-1.42.1.dev8.dist-info → khoj-1.42.2.dist-info}/WHEEL +0 -0
- {khoj-1.42.1.dev8.dist-info → khoj-1.42.2.dist-info}/entry_points.txt +0 -0
- {khoj-1.42.1.dev8.dist-info → khoj-1.42.2.dist-info}/licenses/LICENSE +0 -0
khoj/routers/helpers.py
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
import asyncio
|
1
2
|
import base64
|
3
|
+
import concurrent.futures
|
2
4
|
import hashlib
|
3
5
|
import json
|
4
6
|
import logging
|
5
7
|
import math
|
6
8
|
import os
|
7
9
|
import re
|
10
|
+
import time
|
8
11
|
from datetime import datetime, timedelta, timezone
|
9
|
-
from functools import partial
|
10
12
|
from random import random
|
11
13
|
from typing import (
|
12
14
|
Annotated,
|
@@ -46,6 +48,7 @@ from khoj.database.adapters import (
|
|
46
48
|
aget_user_by_email,
|
47
49
|
ais_user_subscribed,
|
48
50
|
create_khoj_token,
|
51
|
+
get_default_search_model,
|
49
52
|
get_khoj_tokens,
|
50
53
|
get_user_name,
|
51
54
|
get_user_notion_config,
|
@@ -55,6 +58,7 @@ from khoj.database.adapters import (
|
|
55
58
|
)
|
56
59
|
from khoj.database.models import (
|
57
60
|
Agent,
|
61
|
+
ChatMessageModel,
|
58
62
|
ChatModel,
|
59
63
|
ClientApplication,
|
60
64
|
Conversation,
|
@@ -100,12 +104,16 @@ from khoj.processor.conversation.utils import (
|
|
100
104
|
clean_json,
|
101
105
|
clean_mermaidjs,
|
102
106
|
construct_chat_history,
|
107
|
+
construct_question_history,
|
108
|
+
defilter_query,
|
103
109
|
generate_chatml_messages_with_context,
|
104
|
-
save_to_conversation_log,
|
105
110
|
)
|
106
111
|
from khoj.processor.speech.text_to_speech import is_eleven_labs_enabled
|
107
112
|
from khoj.routers.email import is_resend_enabled, send_task_email
|
108
113
|
from khoj.routers.twilio import is_twilio_enabled
|
114
|
+
from khoj.search_filter.date_filter import DateFilter
|
115
|
+
from khoj.search_filter.file_filter import FileFilter
|
116
|
+
from khoj.search_filter.word_filter import WordFilter
|
109
117
|
from khoj.search_type import text_search
|
110
118
|
from khoj.utils import state
|
111
119
|
from khoj.utils.config import OfflineChatProcessorModel
|
@@ -122,7 +130,14 @@ from khoj.utils.helpers import (
|
|
122
130
|
timer,
|
123
131
|
tool_descriptions_for_llm,
|
124
132
|
)
|
125
|
-
from khoj.utils.rawconfig import
|
133
|
+
from khoj.utils.rawconfig import (
|
134
|
+
ChatRequestBody,
|
135
|
+
FileAttachment,
|
136
|
+
FileData,
|
137
|
+
LocationData,
|
138
|
+
SearchResponse,
|
139
|
+
)
|
140
|
+
from khoj.utils.state import SearchType
|
126
141
|
|
127
142
|
logger = logging.getLogger(__name__)
|
128
143
|
|
@@ -236,8 +251,6 @@ def get_next_url(request: Request) -> str:
|
|
236
251
|
def get_conversation_command(query: str) -> ConversationCommand:
|
237
252
|
if query.startswith("/notes"):
|
238
253
|
return ConversationCommand.Notes
|
239
|
-
elif query.startswith("/help"):
|
240
|
-
return ConversationCommand.Help
|
241
254
|
elif query.startswith("/general"):
|
242
255
|
return ConversationCommand.General
|
243
256
|
elif query.startswith("/online"):
|
@@ -248,8 +261,6 @@ def get_conversation_command(query: str) -> ConversationCommand:
|
|
248
261
|
return ConversationCommand.Image
|
249
262
|
elif query.startswith("/automated_task"):
|
250
263
|
return ConversationCommand.AutomatedTask
|
251
|
-
elif query.startswith("/summarize"):
|
252
|
-
return ConversationCommand.Summarize
|
253
264
|
elif query.startswith("/diagram"):
|
254
265
|
return ConversationCommand.Diagram
|
255
266
|
elif query.startswith("/code"):
|
@@ -285,7 +296,7 @@ async def acreate_title_from_history(
|
|
285
296
|
"""
|
286
297
|
Create a title from the given conversation history
|
287
298
|
"""
|
288
|
-
chat_history = construct_chat_history(conversation.
|
299
|
+
chat_history = construct_chat_history(conversation.messages)
|
289
300
|
|
290
301
|
title_generation_prompt = prompts.conversation_title_generation.format(chat_history=chat_history)
|
291
302
|
|
@@ -345,7 +356,7 @@ async def acheck_if_safe_prompt(system_prompt: str, user: KhojUser = None, lax:
|
|
345
356
|
|
346
357
|
async def aget_data_sources_and_output_format(
|
347
358
|
query: str,
|
348
|
-
|
359
|
+
chat_history: list[ChatMessageModel],
|
349
360
|
is_task: bool,
|
350
361
|
user: KhojUser,
|
351
362
|
query_images: List[str] = None,
|
@@ -379,14 +390,11 @@ async def aget_data_sources_and_output_format(
|
|
379
390
|
agent_outputs = agent.output_modes if agent else []
|
380
391
|
|
381
392
|
for output, description in mode_descriptions_for_llm.items():
|
382
|
-
# Do not allow tasks to schedule another task
|
383
|
-
if is_task and output == ConversationCommand.Automation:
|
384
|
-
continue
|
385
393
|
output_options[output.value] = description
|
386
394
|
if len(agent_outputs) == 0 or output.value in agent_outputs:
|
387
395
|
output_options_str += f'- "{output.value}": "{description}"\n'
|
388
396
|
|
389
|
-
|
397
|
+
chat_history_str = construct_chat_history(chat_history, n=6)
|
390
398
|
|
391
399
|
if query_images:
|
392
400
|
query = f"[placeholder for {len(query_images)} user attached images]\n{query}"
|
@@ -399,7 +407,7 @@ async def aget_data_sources_and_output_format(
|
|
399
407
|
query=query,
|
400
408
|
sources=source_options_str,
|
401
409
|
outputs=output_options_str,
|
402
|
-
chat_history=
|
410
|
+
chat_history=chat_history_str,
|
403
411
|
personality_context=personality_context,
|
404
412
|
)
|
405
413
|
|
@@ -462,7 +470,7 @@ async def aget_data_sources_and_output_format(
|
|
462
470
|
async def infer_webpage_urls(
|
463
471
|
q: str,
|
464
472
|
max_webpages: int,
|
465
|
-
|
473
|
+
chat_history: List[ChatMessageModel],
|
466
474
|
location_data: LocationData,
|
467
475
|
user: KhojUser,
|
468
476
|
query_images: List[str] = None,
|
@@ -475,7 +483,7 @@ async def infer_webpage_urls(
|
|
475
483
|
"""
|
476
484
|
location = f"{location_data}" if location_data else "Unknown"
|
477
485
|
username = prompts.user_name.format(name=user.get_full_name()) if user.get_full_name() else ""
|
478
|
-
|
486
|
+
chat_history_str = construct_chat_history(chat_history)
|
479
487
|
|
480
488
|
utc_date = datetime.now(timezone.utc).strftime("%Y-%m-%d")
|
481
489
|
personality_context = (
|
@@ -485,7 +493,7 @@ async def infer_webpage_urls(
|
|
485
493
|
online_queries_prompt = prompts.infer_webpages_to_read.format(
|
486
494
|
query=q,
|
487
495
|
max_webpages=max_webpages,
|
488
|
-
chat_history=
|
496
|
+
chat_history=chat_history_str,
|
489
497
|
current_date=utc_date,
|
490
498
|
location=location,
|
491
499
|
username=username,
|
@@ -526,7 +534,7 @@ async def infer_webpage_urls(
|
|
526
534
|
|
527
535
|
async def generate_online_subqueries(
|
528
536
|
q: str,
|
529
|
-
|
537
|
+
chat_history: List[ChatMessageModel],
|
530
538
|
location_data: LocationData,
|
531
539
|
user: KhojUser,
|
532
540
|
query_images: List[str] = None,
|
@@ -540,7 +548,7 @@ async def generate_online_subqueries(
|
|
540
548
|
"""
|
541
549
|
location = f"{location_data}" if location_data else "Unknown"
|
542
550
|
username = prompts.user_name.format(name=user.get_full_name()) if user.get_full_name() else ""
|
543
|
-
|
551
|
+
chat_history_str = construct_chat_history(chat_history)
|
544
552
|
|
545
553
|
utc_date = datetime.now(timezone.utc).strftime("%Y-%m-%d")
|
546
554
|
personality_context = (
|
@@ -549,7 +557,7 @@ async def generate_online_subqueries(
|
|
549
557
|
|
550
558
|
online_queries_prompt = prompts.online_search_conversation_subqueries.format(
|
551
559
|
query=q,
|
552
|
-
chat_history=
|
560
|
+
chat_history=chat_history_str,
|
553
561
|
max_queries=max_queries,
|
554
562
|
current_date=utc_date,
|
555
563
|
location=location,
|
@@ -591,16 +599,16 @@ async def generate_online_subqueries(
|
|
591
599
|
|
592
600
|
|
593
601
|
def schedule_query(
|
594
|
-
q: str,
|
602
|
+
q: str, chat_history: List[ChatMessageModel], user: KhojUser, query_images: List[str] = None, tracer: dict = {}
|
595
603
|
) -> Tuple[str, str, str]:
|
596
604
|
"""
|
597
605
|
Schedule the date, time to run the query. Assume the server timezone is UTC.
|
598
606
|
"""
|
599
|
-
|
607
|
+
chat_history_str = construct_chat_history(chat_history)
|
600
608
|
|
601
609
|
crontime_prompt = prompts.crontime_prompt.format(
|
602
610
|
query=q,
|
603
|
-
chat_history=
|
611
|
+
chat_history=chat_history_str,
|
604
612
|
)
|
605
613
|
|
606
614
|
raw_response = send_message_to_model_wrapper_sync(
|
@@ -619,16 +627,16 @@ def schedule_query(
|
|
619
627
|
|
620
628
|
|
621
629
|
async def aschedule_query(
|
622
|
-
q: str,
|
630
|
+
q: str, chat_history: List[ChatMessageModel], user: KhojUser, query_images: List[str] = None, tracer: dict = {}
|
623
631
|
) -> Tuple[str, str, str]:
|
624
632
|
"""
|
625
633
|
Schedule the date, time to run the query. Assume the server timezone is UTC.
|
626
634
|
"""
|
627
|
-
|
635
|
+
chat_history_str = construct_chat_history(chat_history)
|
628
636
|
|
629
637
|
crontime_prompt = prompts.crontime_prompt.format(
|
630
638
|
query=q,
|
631
|
-
chat_history=
|
639
|
+
chat_history=chat_history_str,
|
632
640
|
)
|
633
641
|
|
634
642
|
raw_response = await send_message_to_model_wrapper(
|
@@ -681,7 +689,7 @@ async def extract_relevant_info(
|
|
681
689
|
async def extract_relevant_summary(
|
682
690
|
q: str,
|
683
691
|
corpus: str,
|
684
|
-
|
692
|
+
chat_history: List[ChatMessageModel] = [],
|
685
693
|
query_images: List[str] = None,
|
686
694
|
user: KhojUser = None,
|
687
695
|
agent: Agent = None,
|
@@ -698,11 +706,11 @@ async def extract_relevant_summary(
|
|
698
706
|
prompts.personality_context.format(personality=agent.personality) if agent and agent.personality else ""
|
699
707
|
)
|
700
708
|
|
701
|
-
|
709
|
+
chat_history_str = construct_chat_history(chat_history)
|
702
710
|
|
703
711
|
extract_relevant_information = prompts.extract_relevant_summary.format(
|
704
712
|
query=q,
|
705
|
-
chat_history=
|
713
|
+
chat_history=chat_history_str,
|
706
714
|
corpus=corpus.strip(),
|
707
715
|
personality_context=personality_context,
|
708
716
|
)
|
@@ -725,7 +733,7 @@ async def generate_summary_from_files(
|
|
725
733
|
q: str,
|
726
734
|
user: KhojUser,
|
727
735
|
file_filters: List[str],
|
728
|
-
|
736
|
+
chat_history: List[ChatMessageModel] = [],
|
729
737
|
query_images: List[str] = None,
|
730
738
|
agent: Agent = None,
|
731
739
|
send_status_func: Optional[Callable] = None,
|
@@ -766,7 +774,7 @@ async def generate_summary_from_files(
|
|
766
774
|
response = await extract_relevant_summary(
|
767
775
|
q,
|
768
776
|
contextual_data,
|
769
|
-
|
777
|
+
chat_history=chat_history,
|
770
778
|
query_images=query_images,
|
771
779
|
user=user,
|
772
780
|
agent=agent,
|
@@ -782,7 +790,7 @@ async def generate_summary_from_files(
|
|
782
790
|
|
783
791
|
async def generate_excalidraw_diagram(
|
784
792
|
q: str,
|
785
|
-
|
793
|
+
chat_history: List[ChatMessageModel],
|
786
794
|
location_data: LocationData,
|
787
795
|
note_references: List[Dict[str, Any]],
|
788
796
|
online_results: Optional[dict] = None,
|
@@ -799,7 +807,7 @@ async def generate_excalidraw_diagram(
|
|
799
807
|
|
800
808
|
better_diagram_description_prompt = await generate_better_diagram_description(
|
801
809
|
q=q,
|
802
|
-
|
810
|
+
chat_history=chat_history,
|
803
811
|
location_data=location_data,
|
804
812
|
note_references=note_references,
|
805
813
|
online_results=online_results,
|
@@ -834,7 +842,7 @@ async def generate_excalidraw_diagram(
|
|
834
842
|
|
835
843
|
async def generate_better_diagram_description(
|
836
844
|
q: str,
|
837
|
-
|
845
|
+
chat_history: List[ChatMessageModel],
|
838
846
|
location_data: LocationData,
|
839
847
|
note_references: List[Dict[str, Any]],
|
840
848
|
online_results: Optional[dict] = None,
|
@@ -857,7 +865,7 @@ async def generate_better_diagram_description(
|
|
857
865
|
|
858
866
|
user_references = "\n\n".join([f"# {item['compiled']}" for item in note_references])
|
859
867
|
|
860
|
-
|
868
|
+
chat_history_str = construct_chat_history(chat_history)
|
861
869
|
|
862
870
|
simplified_online_results = {}
|
863
871
|
|
@@ -870,7 +878,7 @@ async def generate_better_diagram_description(
|
|
870
878
|
|
871
879
|
improve_diagram_description_prompt = prompts.improve_excalidraw_diagram_description_prompt.format(
|
872
880
|
query=q,
|
873
|
-
chat_history=
|
881
|
+
chat_history=chat_history_str,
|
874
882
|
location=location,
|
875
883
|
current_date=today_date,
|
876
884
|
references=user_references,
|
@@ -939,7 +947,7 @@ async def generate_excalidraw_diagram_from_description(
|
|
939
947
|
|
940
948
|
async def generate_mermaidjs_diagram(
|
941
949
|
q: str,
|
942
|
-
|
950
|
+
chat_history: List[ChatMessageModel],
|
943
951
|
location_data: LocationData,
|
944
952
|
note_references: List[Dict[str, Any]],
|
945
953
|
online_results: Optional[dict] = None,
|
@@ -956,7 +964,7 @@ async def generate_mermaidjs_diagram(
|
|
956
964
|
|
957
965
|
better_diagram_description_prompt = await generate_better_mermaidjs_diagram_description(
|
958
966
|
q=q,
|
959
|
-
|
967
|
+
chat_history=chat_history,
|
960
968
|
location_data=location_data,
|
961
969
|
note_references=note_references,
|
962
970
|
online_results=online_results,
|
@@ -985,7 +993,7 @@ async def generate_mermaidjs_diagram(
|
|
985
993
|
|
986
994
|
async def generate_better_mermaidjs_diagram_description(
|
987
995
|
q: str,
|
988
|
-
|
996
|
+
chat_history: List[ChatMessageModel],
|
989
997
|
location_data: LocationData,
|
990
998
|
note_references: List[Dict[str, Any]],
|
991
999
|
online_results: Optional[dict] = None,
|
@@ -1008,7 +1016,7 @@ async def generate_better_mermaidjs_diagram_description(
|
|
1008
1016
|
|
1009
1017
|
user_references = "\n\n".join([f"# {item['compiled']}" for item in note_references])
|
1010
1018
|
|
1011
|
-
|
1019
|
+
chat_history_str = construct_chat_history(chat_history)
|
1012
1020
|
|
1013
1021
|
simplified_online_results = {}
|
1014
1022
|
|
@@ -1021,7 +1029,7 @@ async def generate_better_mermaidjs_diagram_description(
|
|
1021
1029
|
|
1022
1030
|
improve_diagram_description_prompt = prompts.improve_mermaid_js_diagram_description_prompt.format(
|
1023
1031
|
query=q,
|
1024
|
-
chat_history=
|
1032
|
+
chat_history=chat_history_str,
|
1025
1033
|
location=location,
|
1026
1034
|
current_date=today_date,
|
1027
1035
|
references=user_references,
|
@@ -1150,6 +1158,276 @@ async def generate_better_image_prompt(
|
|
1150
1158
|
return response
|
1151
1159
|
|
1152
1160
|
|
1161
|
+
async def search_documents(
|
1162
|
+
user: KhojUser,
|
1163
|
+
chat_history: list[ChatMessageModel],
|
1164
|
+
q: str,
|
1165
|
+
n: int,
|
1166
|
+
d: float,
|
1167
|
+
conversation_id: str,
|
1168
|
+
conversation_commands: List[ConversationCommand] = [ConversationCommand.Default],
|
1169
|
+
location_data: LocationData = None,
|
1170
|
+
send_status_func: Optional[Callable] = None,
|
1171
|
+
query_images: Optional[List[str]] = None,
|
1172
|
+
previous_inferred_queries: Set = set(),
|
1173
|
+
agent: Agent = None,
|
1174
|
+
query_files: str = None,
|
1175
|
+
tracer: dict = {},
|
1176
|
+
):
|
1177
|
+
# Initialize Variables
|
1178
|
+
compiled_references: List[dict[str, str]] = []
|
1179
|
+
inferred_queries: List[str] = []
|
1180
|
+
|
1181
|
+
agent_has_entries = False
|
1182
|
+
|
1183
|
+
if agent:
|
1184
|
+
agent_has_entries = await sync_to_async(EntryAdapters.agent_has_entries)(agent=agent)
|
1185
|
+
|
1186
|
+
if (
|
1187
|
+
not ConversationCommand.Notes in conversation_commands
|
1188
|
+
and not ConversationCommand.Default in conversation_commands
|
1189
|
+
and not agent_has_entries
|
1190
|
+
):
|
1191
|
+
yield compiled_references, inferred_queries, q
|
1192
|
+
return
|
1193
|
+
|
1194
|
+
# If Notes or Default is not in the conversation command, then the search should be restricted to the agent's knowledge base
|
1195
|
+
should_limit_to_agent_knowledge = (
|
1196
|
+
ConversationCommand.Notes not in conversation_commands
|
1197
|
+
and ConversationCommand.Default not in conversation_commands
|
1198
|
+
)
|
1199
|
+
|
1200
|
+
if not await sync_to_async(EntryAdapters.user_has_entries)(user=user):
|
1201
|
+
if not agent_has_entries:
|
1202
|
+
logger.debug("No documents in knowledge base. Use a Khoj client to sync and chat with your docs.")
|
1203
|
+
yield compiled_references, inferred_queries, q
|
1204
|
+
return
|
1205
|
+
|
1206
|
+
# Extract filter terms from user message
|
1207
|
+
defiltered_query = defilter_query(q)
|
1208
|
+
filters_in_query = q.replace(defiltered_query, "").strip()
|
1209
|
+
conversation = await sync_to_async(ConversationAdapters.get_conversation_by_id)(conversation_id)
|
1210
|
+
|
1211
|
+
if not conversation:
|
1212
|
+
logger.error(f"Conversation with id {conversation_id} not found when extracting references.")
|
1213
|
+
yield compiled_references, inferred_queries, defiltered_query
|
1214
|
+
return
|
1215
|
+
|
1216
|
+
filters_in_query += " ".join([f'file:"{filter}"' for filter in conversation.file_filters])
|
1217
|
+
if is_none_or_empty(filters_in_query):
|
1218
|
+
logger.debug(f"Filters in query: {filters_in_query}")
|
1219
|
+
|
1220
|
+
personality_context = prompts.personality_context.format(personality=agent.personality) if agent else ""
|
1221
|
+
|
1222
|
+
# Infer search queries from user message
|
1223
|
+
with timer("Extracting search queries took", logger):
|
1224
|
+
inferred_queries = await extract_questions(
|
1225
|
+
query=defiltered_query,
|
1226
|
+
user=user,
|
1227
|
+
personality_context=personality_context,
|
1228
|
+
chat_history=chat_history,
|
1229
|
+
location_data=location_data,
|
1230
|
+
query_images=query_images,
|
1231
|
+
query_files=query_files,
|
1232
|
+
tracer=tracer,
|
1233
|
+
)
|
1234
|
+
|
1235
|
+
# Collate search results as context for the LLM
|
1236
|
+
inferred_queries = list(set(inferred_queries) - previous_inferred_queries)
|
1237
|
+
with timer("Searching knowledge base took", logger):
|
1238
|
+
search_results = []
|
1239
|
+
logger.info(f"🔍 Searching knowledge base with queries: {inferred_queries}")
|
1240
|
+
if send_status_func:
|
1241
|
+
inferred_queries_str = "\n- " + "\n- ".join(inferred_queries)
|
1242
|
+
async for event in send_status_func(f"**Searching Documents for:** {inferred_queries_str}"):
|
1243
|
+
yield {ChatEvent.STATUS: event}
|
1244
|
+
for query in inferred_queries:
|
1245
|
+
search_results.extend(
|
1246
|
+
await execute_search(
|
1247
|
+
user if not should_limit_to_agent_knowledge else None,
|
1248
|
+
f"{query} {filters_in_query}",
|
1249
|
+
n=n,
|
1250
|
+
t=SearchType.All,
|
1251
|
+
r=True,
|
1252
|
+
max_distance=d,
|
1253
|
+
dedupe=False,
|
1254
|
+
agent=agent,
|
1255
|
+
)
|
1256
|
+
)
|
1257
|
+
search_results = text_search.deduplicated_search_responses(search_results)
|
1258
|
+
compiled_references = [
|
1259
|
+
{"query": q, "compiled": item.additional["compiled"], "file": item.additional["file"]}
|
1260
|
+
for q, item in zip(inferred_queries, search_results)
|
1261
|
+
]
|
1262
|
+
|
1263
|
+
yield compiled_references, inferred_queries, defiltered_query
|
1264
|
+
|
1265
|
+
|
1266
|
+
async def extract_questions(
|
1267
|
+
query: str,
|
1268
|
+
user: KhojUser,
|
1269
|
+
personality_context: str = "",
|
1270
|
+
chat_history: List[ChatMessageModel] = [],
|
1271
|
+
location_data: LocationData = None,
|
1272
|
+
query_images: Optional[List[str]] = None,
|
1273
|
+
query_files: str = None,
|
1274
|
+
tracer: dict = {},
|
1275
|
+
):
|
1276
|
+
"""
|
1277
|
+
Infer document search queries from user message and provided context
|
1278
|
+
"""
|
1279
|
+
# Shared context setup
|
1280
|
+
location = f"{location_data}" if location_data else "N/A"
|
1281
|
+
username = prompts.user_name.format(name=user.get_full_name()) if user and user.get_full_name() else ""
|
1282
|
+
|
1283
|
+
# Date variables for prompt formatting
|
1284
|
+
today = datetime.today()
|
1285
|
+
current_new_year = today.replace(month=1, day=1)
|
1286
|
+
last_new_year = current_new_year.replace(year=today.year - 1)
|
1287
|
+
yesterday = (today - timedelta(days=1)).strftime("%Y-%m-%d")
|
1288
|
+
|
1289
|
+
# Common prompt setup for API-based models (using Anthropic prompts for consistency)
|
1290
|
+
chat_history_str = construct_question_history(chat_history, query_prefix="User", agent_name="Assistant")
|
1291
|
+
|
1292
|
+
system_prompt = prompts.extract_questions_system_prompt.format(
|
1293
|
+
current_date=today.strftime("%Y-%m-%d"),
|
1294
|
+
day_of_week=today.strftime("%A"),
|
1295
|
+
current_month=today.strftime("%Y-%m"),
|
1296
|
+
last_new_year=last_new_year.strftime("%Y"),
|
1297
|
+
last_new_year_date=last_new_year.strftime("%Y-%m-%d"),
|
1298
|
+
current_new_year_date=current_new_year.strftime("%Y-%m-%d"),
|
1299
|
+
yesterday_date=yesterday,
|
1300
|
+
location=location,
|
1301
|
+
username=username,
|
1302
|
+
personality_context=personality_context,
|
1303
|
+
)
|
1304
|
+
|
1305
|
+
prompt = prompts.extract_questions_user_message.format(text=query, chat_history=chat_history_str)
|
1306
|
+
|
1307
|
+
class DocumentQueries(BaseModel):
|
1308
|
+
"""Choose searches to run on user documents."""
|
1309
|
+
|
1310
|
+
queries: List[str] = Field(..., min_items=1, description="List of search queries to run on user documents.")
|
1311
|
+
|
1312
|
+
raw_response = await send_message_to_model_wrapper(
|
1313
|
+
system_message=system_prompt,
|
1314
|
+
query=prompt,
|
1315
|
+
query_images=query_images,
|
1316
|
+
query_files=query_files,
|
1317
|
+
chat_history=chat_history,
|
1318
|
+
response_type="json_object",
|
1319
|
+
response_schema=DocumentQueries,
|
1320
|
+
user=user,
|
1321
|
+
tracer=tracer,
|
1322
|
+
)
|
1323
|
+
|
1324
|
+
# Extract questions from the response
|
1325
|
+
try:
|
1326
|
+
response = clean_json(raw_response)
|
1327
|
+
response = pyjson5.loads(response)
|
1328
|
+
queries = [q.strip() for q in response["queries"] if q.strip()]
|
1329
|
+
if not isinstance(queries, list) or not queries:
|
1330
|
+
logger.error(f"Invalid response for constructing subqueries: {response}")
|
1331
|
+
return [query]
|
1332
|
+
return queries
|
1333
|
+
except:
|
1334
|
+
logger.warning(f"LLM returned invalid JSON. Falling back to using user message as search query.")
|
1335
|
+
return [query]
|
1336
|
+
|
1337
|
+
|
1338
|
+
async def execute_search(
|
1339
|
+
user: KhojUser,
|
1340
|
+
q: str,
|
1341
|
+
n: Optional[int] = 5,
|
1342
|
+
t: Optional[SearchType] = None,
|
1343
|
+
r: Optional[bool] = False,
|
1344
|
+
max_distance: Optional[Union[float, None]] = None,
|
1345
|
+
dedupe: Optional[bool] = True,
|
1346
|
+
agent: Optional[Agent] = None,
|
1347
|
+
):
|
1348
|
+
# Run validation checks
|
1349
|
+
results: List[SearchResponse] = []
|
1350
|
+
|
1351
|
+
start_time = time.time()
|
1352
|
+
|
1353
|
+
# Ensure the agent, if present, is accessible by the user
|
1354
|
+
if user and agent and not await AgentAdapters.ais_agent_accessible(agent, user):
|
1355
|
+
logger.error(f"Agent {agent.slug} is not accessible by user {user}")
|
1356
|
+
return results
|
1357
|
+
|
1358
|
+
if q is None or q == "":
|
1359
|
+
logger.warning(f"No query param (q) passed in API call to initiate search")
|
1360
|
+
return results
|
1361
|
+
|
1362
|
+
# initialize variables
|
1363
|
+
user_query = q.strip()
|
1364
|
+
results_count = n or 5
|
1365
|
+
t = t or state.SearchType.All
|
1366
|
+
search_tasks = []
|
1367
|
+
|
1368
|
+
# return cached results, if available
|
1369
|
+
if user:
|
1370
|
+
query_cache_key = f"{user_query}-{n}-{t}-{r}-{max_distance}-{dedupe}"
|
1371
|
+
if query_cache_key in state.query_cache[user.uuid]:
|
1372
|
+
logger.debug(f"Return response from query cache")
|
1373
|
+
return state.query_cache[user.uuid][query_cache_key]
|
1374
|
+
|
1375
|
+
# Encode query with filter terms removed
|
1376
|
+
defiltered_query = user_query
|
1377
|
+
for filter in [DateFilter(), WordFilter(), FileFilter()]:
|
1378
|
+
defiltered_query = filter.defilter(defiltered_query)
|
1379
|
+
|
1380
|
+
encoded_asymmetric_query = None
|
1381
|
+
if t.value != SearchType.Image.value:
|
1382
|
+
with timer("Encoding query took", logger=logger):
|
1383
|
+
search_model = await sync_to_async(get_default_search_model)()
|
1384
|
+
encoded_asymmetric_query = state.embeddings_model[search_model.name].embed_query(defiltered_query)
|
1385
|
+
|
1386
|
+
# Use asyncio to run searches in parallel
|
1387
|
+
if t.value in [
|
1388
|
+
SearchType.All.value,
|
1389
|
+
SearchType.Org.value,
|
1390
|
+
SearchType.Markdown.value,
|
1391
|
+
SearchType.Github.value,
|
1392
|
+
SearchType.Notion.value,
|
1393
|
+
SearchType.Plaintext.value,
|
1394
|
+
SearchType.Pdf.value,
|
1395
|
+
]:
|
1396
|
+
# query markdown notes
|
1397
|
+
search_tasks.append(
|
1398
|
+
text_search.query(
|
1399
|
+
user_query,
|
1400
|
+
user,
|
1401
|
+
t,
|
1402
|
+
question_embedding=encoded_asymmetric_query,
|
1403
|
+
max_distance=max_distance,
|
1404
|
+
agent=agent,
|
1405
|
+
)
|
1406
|
+
)
|
1407
|
+
|
1408
|
+
# Query across each requested content types in parallel
|
1409
|
+
with timer("Query took", logger):
|
1410
|
+
if search_tasks:
|
1411
|
+
hits_list = await asyncio.gather(*search_tasks)
|
1412
|
+
for hits in hits_list:
|
1413
|
+
# Collate results
|
1414
|
+
results += text_search.collate_results(hits, dedupe=dedupe)
|
1415
|
+
|
1416
|
+
# Sort results across all content types and take top results
|
1417
|
+
results = text_search.rerank_and_sort_results(
|
1418
|
+
results, query=defiltered_query, rank_results=r, search_model_name=search_model.name
|
1419
|
+
)[:results_count]
|
1420
|
+
|
1421
|
+
# Cache results
|
1422
|
+
if user:
|
1423
|
+
state.query_cache[user.uuid][query_cache_key] = results
|
1424
|
+
|
1425
|
+
end_time = time.time()
|
1426
|
+
logger.debug(f"🔍 Search took: {end_time - start_time:.3f} seconds")
|
1427
|
+
|
1428
|
+
return results
|
1429
|
+
|
1430
|
+
|
1153
1431
|
async def send_message_to_model_wrapper(
|
1154
1432
|
query: str,
|
1155
1433
|
system_message: str = "",
|
@@ -1160,7 +1438,7 @@ async def send_message_to_model_wrapper(
|
|
1160
1438
|
query_images: List[str] = None,
|
1161
1439
|
context: str = "",
|
1162
1440
|
query_files: str = None,
|
1163
|
-
|
1441
|
+
chat_history: list[ChatMessageModel] = [],
|
1164
1442
|
agent_chat_model: ChatModel = None,
|
1165
1443
|
tracer: dict = {},
|
1166
1444
|
):
|
@@ -1193,7 +1471,7 @@ async def send_message_to_model_wrapper(
|
|
1193
1471
|
user_message=query,
|
1194
1472
|
context_message=context,
|
1195
1473
|
system_message=system_message,
|
1196
|
-
|
1474
|
+
chat_history=chat_history,
|
1197
1475
|
model_name=chat_model_name,
|
1198
1476
|
loaded_model=loaded_model,
|
1199
1477
|
tokenizer_name=tokenizer,
|
@@ -1260,7 +1538,7 @@ def send_message_to_model_wrapper_sync(
|
|
1260
1538
|
user: KhojUser = None,
|
1261
1539
|
query_images: List[str] = None,
|
1262
1540
|
query_files: str = "",
|
1263
|
-
|
1541
|
+
chat_history: List[ChatMessageModel] = [],
|
1264
1542
|
tracer: dict = {},
|
1265
1543
|
):
|
1266
1544
|
chat_model: ChatModel = ConversationAdapters.get_default_chat_model(user)
|
@@ -1284,7 +1562,7 @@ def send_message_to_model_wrapper_sync(
|
|
1284
1562
|
truncated_messages = generate_chatml_messages_with_context(
|
1285
1563
|
user_message=message,
|
1286
1564
|
system_message=system_message,
|
1287
|
-
|
1565
|
+
chat_history=chat_history,
|
1288
1566
|
model_name=chat_model_name,
|
1289
1567
|
loaded_model=loaded_model,
|
1290
1568
|
max_prompt_size=max_tokens,
|
@@ -1342,61 +1620,31 @@ def send_message_to_model_wrapper_sync(
|
|
1342
1620
|
|
1343
1621
|
async def agenerate_chat_response(
|
1344
1622
|
q: str,
|
1345
|
-
|
1623
|
+
chat_history: List[ChatMessageModel],
|
1346
1624
|
conversation: Conversation,
|
1347
1625
|
compiled_references: List[Dict] = [],
|
1348
1626
|
online_results: Dict[str, Dict] = {},
|
1349
1627
|
code_results: Dict[str, Dict] = {},
|
1350
1628
|
operator_results: List[OperatorRun] = [],
|
1351
1629
|
research_results: List[ResearchIteration] = [],
|
1352
|
-
inferred_queries: List[str] = [],
|
1353
|
-
conversation_commands: List[ConversationCommand] = [ConversationCommand.Default],
|
1354
1630
|
user: KhojUser = None,
|
1355
|
-
client_application: ClientApplication = None,
|
1356
1631
|
location_data: LocationData = None,
|
1357
1632
|
user_name: Optional[str] = None,
|
1358
1633
|
query_images: Optional[List[str]] = None,
|
1359
|
-
train_of_thought: List[Any] = [],
|
1360
1634
|
query_files: str = None,
|
1361
|
-
raw_query_files: List[FileAttachment] = None,
|
1362
|
-
generated_images: List[str] = None,
|
1363
1635
|
raw_generated_files: List[FileAttachment] = [],
|
1364
|
-
generated_mermaidjs_diagram: str = None,
|
1365
1636
|
program_execution_context: List[str] = [],
|
1366
1637
|
generated_asset_results: Dict[str, Dict] = {},
|
1367
1638
|
is_subscribed: bool = False,
|
1368
1639
|
tracer: dict = {},
|
1369
|
-
) -> Tuple[AsyncGenerator[
|
1640
|
+
) -> Tuple[AsyncGenerator[ResponseWithThought, None], Dict[str, str]]:
|
1370
1641
|
# Initialize Variables
|
1371
|
-
chat_response_generator: AsyncGenerator[
|
1372
|
-
logger.debug(f"Conversation Types: {conversation_commands}")
|
1642
|
+
chat_response_generator: AsyncGenerator[ResponseWithThought, None] = None
|
1373
1643
|
|
1374
1644
|
metadata = {}
|
1375
1645
|
agent = await AgentAdapters.aget_conversation_agent_by_id(conversation.agent.id) if conversation.agent else None
|
1376
1646
|
|
1377
1647
|
try:
|
1378
|
-
partial_completion = partial(
|
1379
|
-
save_to_conversation_log,
|
1380
|
-
q,
|
1381
|
-
user=user,
|
1382
|
-
meta_log=meta_log,
|
1383
|
-
compiled_references=compiled_references,
|
1384
|
-
online_results=online_results,
|
1385
|
-
code_results=code_results,
|
1386
|
-
operator_results=operator_results,
|
1387
|
-
research_results=research_results,
|
1388
|
-
inferred_queries=inferred_queries,
|
1389
|
-
client_application=client_application,
|
1390
|
-
conversation_id=str(conversation.id),
|
1391
|
-
query_images=query_images,
|
1392
|
-
train_of_thought=train_of_thought,
|
1393
|
-
raw_query_files=raw_query_files,
|
1394
|
-
generated_images=generated_images,
|
1395
|
-
raw_generated_files=raw_generated_files,
|
1396
|
-
generated_mermaidjs_diagram=generated_mermaidjs_diagram,
|
1397
|
-
tracer=tracer,
|
1398
|
-
)
|
1399
|
-
|
1400
1648
|
query_to_run = q
|
1401
1649
|
deepthought = False
|
1402
1650
|
if research_results:
|
@@ -1420,22 +1668,23 @@ async def agenerate_chat_response(
|
|
1420
1668
|
if chat_model.model_type == "offline":
|
1421
1669
|
loaded_model = state.offline_chat_processor_config.loaded_model
|
1422
1670
|
chat_response_generator = converse_offline(
|
1671
|
+
# Query
|
1423
1672
|
user_query=query_to_run,
|
1673
|
+
# Context
|
1424
1674
|
references=compiled_references,
|
1425
1675
|
online_results=online_results,
|
1676
|
+
generated_files=raw_generated_files,
|
1677
|
+
generated_asset_results=generated_asset_results,
|
1678
|
+
location_data=location_data,
|
1679
|
+
user_name=user_name,
|
1680
|
+
query_files=query_files,
|
1681
|
+
chat_history=chat_history,
|
1682
|
+
# Model
|
1426
1683
|
loaded_model=loaded_model,
|
1427
|
-
conversation_log=meta_log,
|
1428
|
-
completion_func=partial_completion,
|
1429
|
-
conversation_commands=conversation_commands,
|
1430
1684
|
model_name=chat_model.name,
|
1431
1685
|
max_prompt_size=chat_model.max_prompt_size,
|
1432
1686
|
tokenizer_name=chat_model.tokenizer,
|
1433
|
-
location_data=location_data,
|
1434
|
-
user_name=user_name,
|
1435
1687
|
agent=agent,
|
1436
|
-
query_files=query_files,
|
1437
|
-
generated_files=raw_generated_files,
|
1438
|
-
generated_asset_results=generated_asset_results,
|
1439
1688
|
tracer=tracer,
|
1440
1689
|
)
|
1441
1690
|
|
@@ -1444,28 +1693,29 @@ async def agenerate_chat_response(
|
|
1444
1693
|
api_key = openai_chat_config.api_key
|
1445
1694
|
chat_model_name = chat_model.name
|
1446
1695
|
chat_response_generator = converse_openai(
|
1696
|
+
# Query
|
1447
1697
|
query_to_run,
|
1448
|
-
|
1449
|
-
|
1698
|
+
# Context
|
1699
|
+
references=compiled_references,
|
1450
1700
|
online_results=online_results,
|
1451
1701
|
code_results=code_results,
|
1452
1702
|
operator_results=operator_results,
|
1453
|
-
|
1703
|
+
query_images=query_images,
|
1704
|
+
query_files=query_files,
|
1705
|
+
generated_files=raw_generated_files,
|
1706
|
+
generated_asset_results=generated_asset_results,
|
1707
|
+
program_execution_context=program_execution_context,
|
1708
|
+
location_data=location_data,
|
1709
|
+
user_name=user_name,
|
1710
|
+
chat_history=chat_history,
|
1711
|
+
# Model
|
1454
1712
|
model=chat_model_name,
|
1455
1713
|
api_key=api_key,
|
1456
1714
|
api_base_url=openai_chat_config.api_base_url,
|
1457
|
-
completion_func=partial_completion,
|
1458
|
-
conversation_commands=conversation_commands,
|
1459
1715
|
max_prompt_size=chat_model.max_prompt_size,
|
1460
1716
|
tokenizer_name=chat_model.tokenizer,
|
1461
|
-
location_data=location_data,
|
1462
|
-
user_name=user_name,
|
1463
1717
|
agent=agent,
|
1464
1718
|
vision_available=vision_available,
|
1465
|
-
query_files=query_files,
|
1466
|
-
generated_files=raw_generated_files,
|
1467
|
-
generated_asset_results=generated_asset_results,
|
1468
|
-
program_execution_context=program_execution_context,
|
1469
1719
|
deepthought=deepthought,
|
1470
1720
|
tracer=tracer,
|
1471
1721
|
)
|
@@ -1474,28 +1724,29 @@ async def agenerate_chat_response(
|
|
1474
1724
|
api_key = chat_model.ai_model_api.api_key
|
1475
1725
|
api_base_url = chat_model.ai_model_api.api_base_url
|
1476
1726
|
chat_response_generator = converse_anthropic(
|
1727
|
+
# Query
|
1477
1728
|
query_to_run,
|
1478
|
-
|
1479
|
-
|
1729
|
+
# Context
|
1730
|
+
references=compiled_references,
|
1480
1731
|
online_results=online_results,
|
1481
1732
|
code_results=code_results,
|
1482
1733
|
operator_results=operator_results,
|
1483
|
-
|
1734
|
+
query_images=query_images,
|
1735
|
+
query_files=query_files,
|
1736
|
+
generated_files=raw_generated_files,
|
1737
|
+
generated_asset_results=generated_asset_results,
|
1738
|
+
program_execution_context=program_execution_context,
|
1739
|
+
location_data=location_data,
|
1740
|
+
user_name=user_name,
|
1741
|
+
chat_history=chat_history,
|
1742
|
+
# Model
|
1484
1743
|
model=chat_model.name,
|
1485
1744
|
api_key=api_key,
|
1486
1745
|
api_base_url=api_base_url,
|
1487
|
-
completion_func=partial_completion,
|
1488
|
-
conversation_commands=conversation_commands,
|
1489
1746
|
max_prompt_size=chat_model.max_prompt_size,
|
1490
1747
|
tokenizer_name=chat_model.tokenizer,
|
1491
|
-
location_data=location_data,
|
1492
|
-
user_name=user_name,
|
1493
1748
|
agent=agent,
|
1494
1749
|
vision_available=vision_available,
|
1495
|
-
query_files=query_files,
|
1496
|
-
generated_files=raw_generated_files,
|
1497
|
-
generated_asset_results=generated_asset_results,
|
1498
|
-
program_execution_context=program_execution_context,
|
1499
1750
|
deepthought=deepthought,
|
1500
1751
|
tracer=tracer,
|
1501
1752
|
)
|
@@ -1503,28 +1754,29 @@ async def agenerate_chat_response(
|
|
1503
1754
|
api_key = chat_model.ai_model_api.api_key
|
1504
1755
|
api_base_url = chat_model.ai_model_api.api_base_url
|
1505
1756
|
chat_response_generator = converse_gemini(
|
1757
|
+
# Query
|
1506
1758
|
query_to_run,
|
1507
|
-
|
1759
|
+
# Context
|
1760
|
+
references=compiled_references,
|
1508
1761
|
online_results=online_results,
|
1509
1762
|
code_results=code_results,
|
1510
1763
|
operator_results=operator_results,
|
1511
|
-
|
1764
|
+
query_images=query_images,
|
1765
|
+
query_files=query_files,
|
1766
|
+
generated_files=raw_generated_files,
|
1767
|
+
generated_asset_results=generated_asset_results,
|
1768
|
+
program_execution_context=program_execution_context,
|
1769
|
+
location_data=location_data,
|
1770
|
+
user_name=user_name,
|
1771
|
+
chat_history=chat_history,
|
1772
|
+
# Model
|
1512
1773
|
model=chat_model.name,
|
1513
1774
|
api_key=api_key,
|
1514
1775
|
api_base_url=api_base_url,
|
1515
|
-
completion_func=partial_completion,
|
1516
|
-
conversation_commands=conversation_commands,
|
1517
1776
|
max_prompt_size=chat_model.max_prompt_size,
|
1518
1777
|
tokenizer_name=chat_model.tokenizer,
|
1519
|
-
location_data=location_data,
|
1520
|
-
user_name=user_name,
|
1521
1778
|
agent=agent,
|
1522
|
-
query_images=query_images,
|
1523
1779
|
vision_available=vision_available,
|
1524
|
-
query_files=query_files,
|
1525
|
-
generated_files=raw_generated_files,
|
1526
|
-
generated_asset_results=generated_asset_results,
|
1527
|
-
program_execution_context=program_execution_context,
|
1528
1780
|
deepthought=deepthought,
|
1529
1781
|
tracer=tracer,
|
1530
1782
|
)
|
@@ -2005,11 +2257,11 @@ async def create_automation(
|
|
2005
2257
|
timezone: str,
|
2006
2258
|
user: KhojUser,
|
2007
2259
|
calling_url: URL,
|
2008
|
-
|
2260
|
+
chat_history: List[ChatMessageModel] = [],
|
2009
2261
|
conversation_id: str = None,
|
2010
2262
|
tracer: dict = {},
|
2011
2263
|
):
|
2012
|
-
crontime, query_to_run, subject = await aschedule_query(q,
|
2264
|
+
crontime, query_to_run, subject = await aschedule_query(q, chat_history, user, tracer=tracer)
|
2013
2265
|
job = await aschedule_automation(query_to_run, subject, crontime, timezone, q, user, calling_url, conversation_id)
|
2014
2266
|
return job, crontime, query_to_run, subject
|
2015
2267
|
|