khoj 1.26.4.dev2__py3-none-any.whl → 1.26.5.dev29__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/interface/compiled/404/index.html +1 -1
- khoj/interface/compiled/_next/static/chunks/1210.132a7e1910006bbb.js +1 -0
- khoj/interface/compiled/_next/static/chunks/1279-f37ee4a388ebf544.js +1 -0
- khoj/interface/compiled/_next/static/chunks/1459.690bf20e7d7b7090.js +1 -0
- khoj/interface/compiled/_next/static/chunks/1603-b9d95833e0e025e8.js +1 -0
- khoj/interface/compiled/_next/static/chunks/1970-1d6d0c1b00b4f343.js +1 -0
- khoj/interface/compiled/_next/static/chunks/2697-61fcba89fd87eab4.js +1 -0
- khoj/interface/compiled/_next/static/chunks/3423-aad88d6c1f029135.js +1 -0
- khoj/interface/compiled/_next/static/chunks/394-6bcb8c429f168f21.js +3 -0
- khoj/interface/compiled/_next/static/chunks/4602-8eeb4b76385ad159.js +1 -0
- khoj/interface/compiled/_next/static/chunks/5512-94c7c2bbcf58c19d.js +1 -0
- khoj/interface/compiled/_next/static/chunks/7113-f2e114d7034a0835.js +1 -0
- khoj/interface/compiled/_next/static/chunks/{4086-2c74808ba38a5a0f.js → 8840-b8d7b9f0923c6651.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/9417-759984ad62caa3dc.js +1 -0
- khoj/interface/compiled/_next/static/chunks/9479-4b443fdcc99141c9.js +1 -0
- khoj/interface/compiled/_next/static/chunks/94ca1967.5584df65931cfe83.js +1 -0
- khoj/interface/compiled/_next/static/chunks/964ecbae.ea4eab2a3a835ffe.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/agents/page-5ae1e540bb5be8a9.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/automations/{page-5480731341f34450.js → page-774ae3e033f938cd.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/chat/page-97f5b61aaf46d364.js +1 -0
- khoj/interface/compiled/_next/static/chunks/app/factchecker/{page-e7b34316ec6f44de.js → page-d82403db2866bad8.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/{page-10a5aad6e04f3cf8.js → page-75bbfb564884054b.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/search/{page-d56541c746fded7d.js → page-9b64f61caa5bd7f9.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/settings/{page-e044a999468a7c5d.js → page-989cf38b87b19427.js} +1 -1
- khoj/interface/compiled/_next/static/chunks/app/share/chat/page-eb9e282691858f2e.js +1 -0
- khoj/interface/compiled/_next/static/chunks/webpack-8f4afe09848e24e1.js +1 -0
- khoj/interface/compiled/_next/static/css/{c808691c459e3887.css → 3cf13271869a4aeb.css} +1 -1
- khoj/interface/compiled/_next/static/css/4cae6c0e5c72fb2d.css +1 -0
- khoj/interface/compiled/_next/static/css/76d55eb435962b19.css +25 -0
- khoj/interface/compiled/_next/static/css/{3e1f1fdd70775091.css → 80bd6301fc657983.css} +1 -1
- khoj/interface/compiled/_next/static/css/ddcc0cf73e062476.css +1 -0
- khoj/interface/compiled/agents/index.html +1 -1
- khoj/interface/compiled/agents/index.txt +2 -2
- khoj/interface/compiled/automations/index.html +1 -1
- khoj/interface/compiled/automations/index.txt +2 -2
- khoj/interface/compiled/chat/index.html +1 -1
- khoj/interface/compiled/chat/index.txt +2 -2
- khoj/interface/compiled/factchecker/index.html +1 -1
- khoj/interface/compiled/factchecker/index.txt +2 -2
- khoj/interface/compiled/index.html +1 -1
- khoj/interface/compiled/index.txt +2 -2
- khoj/interface/compiled/search/index.html +1 -1
- khoj/interface/compiled/search/index.txt +2 -2
- khoj/interface/compiled/settings/index.html +1 -1
- khoj/interface/compiled/settings/index.txt +2 -2
- khoj/interface/compiled/share/chat/index.html +1 -1
- khoj/interface/compiled/share/chat/index.txt +2 -2
- khoj/processor/conversation/google/gemini_chat.py +28 -13
- khoj/processor/conversation/google/utils.py +34 -12
- khoj/processor/conversation/openai/gpt.py +4 -4
- khoj/processor/conversation/prompts.py +144 -0
- khoj/processor/conversation/utils.py +22 -13
- khoj/processor/image/generate.py +5 -5
- khoj/processor/tools/online_search.py +4 -4
- khoj/routers/api.py +4 -2
- khoj/routers/api_agents.py +41 -20
- khoj/routers/api_chat.py +85 -46
- khoj/routers/helpers.py +225 -29
- khoj/routers/web_client.py +0 -11
- khoj/utils/helpers.py +7 -3
- {khoj-1.26.4.dev2.dist-info → khoj-1.26.5.dev29.dist-info}/METADATA +1 -1
- {khoj-1.26.4.dev2.dist-info → khoj-1.26.5.dev29.dist-info}/RECORD +67 -62
- khoj/interface/compiled/_next/static/chunks/121-7024f479c297aef0.js +0 -1
- khoj/interface/compiled/_next/static/chunks/1603-fa3ee48860b9dc5c.js +0 -1
- khoj/interface/compiled/_next/static/chunks/2697-a38d01981ad3bdf8.js +0 -1
- khoj/interface/compiled/_next/static/chunks/4051-2cf66369d6ca0f1d.js +0 -3
- khoj/interface/compiled/_next/static/chunks/477-ec86e93db10571c1.js +0 -1
- khoj/interface/compiled/_next/static/chunks/51-e8f5bdb69b5ea421.js +0 -1
- khoj/interface/compiled/_next/static/chunks/7762-79f2205740622b5c.js +0 -1
- khoj/interface/compiled/_next/static/chunks/9178-899fe9a6b754ecfe.js +0 -1
- khoj/interface/compiled/_next/static/chunks/9417-46ed3aaa639c85ef.js +0 -1
- khoj/interface/compiled/_next/static/chunks/9479-ea776e73f549090c.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/agents/page-88aa3042711107b7.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/chat/page-702057ccbcf27881.js +0 -1
- khoj/interface/compiled/_next/static/chunks/app/share/chat/page-fbbd66a4d4633438.js +0 -1
- khoj/interface/compiled/_next/static/chunks/webpack-2651a68f46ac3cb7.js +0 -1
- khoj/interface/compiled/_next/static/css/2de69f0be774c768.css +0 -1
- khoj/interface/compiled/_next/static/css/592ca99f5122e75a.css +0 -1
- khoj/interface/compiled/_next/static/css/b9a6bf04305d98d7.css +0 -25
- /khoj/interface/compiled/_next/static/{wyjqS7cuSX-u62BTNYqhU → ZLHCGFLxZSUj0jEJSc99T}/_buildManifest.js +0 -0
- /khoj/interface/compiled/_next/static/{wyjqS7cuSX-u62BTNYqhU → ZLHCGFLxZSUj0jEJSc99T}/_ssgManifest.js +0 -0
- {khoj-1.26.4.dev2.dist-info → khoj-1.26.5.dev29.dist-info}/WHEEL +0 -0
- {khoj-1.26.4.dev2.dist-info → khoj-1.26.5.dev29.dist-info}/entry_points.txt +0 -0
- {khoj-1.26.4.dev2.dist-info → khoj-1.26.5.dev29.dist-info}/licenses/LICENSE +0 -0
khoj/routers/api_chat.py
CHANGED
@@ -30,8 +30,10 @@ from khoj.processor.speech.text_to_speech import generate_text_to_speech
|
|
30
30
|
from khoj.processor.tools.online_search import read_webpages, search_online
|
31
31
|
from khoj.routers.api import extract_references_and_questions
|
32
32
|
from khoj.routers.helpers import (
|
33
|
+
ApiImageRateLimiter,
|
33
34
|
ApiUserRateLimiter,
|
34
35
|
ChatEvent,
|
36
|
+
ChatRequestBody,
|
35
37
|
CommonQueryParams,
|
36
38
|
ConversationCommandRateLimiter,
|
37
39
|
agenerate_chat_response,
|
@@ -40,6 +42,7 @@ from khoj.routers.helpers import (
|
|
40
42
|
construct_automation_created_message,
|
41
43
|
create_automation,
|
42
44
|
extract_relevant_summary,
|
45
|
+
generate_excalidraw_diagram,
|
43
46
|
get_conversation_command,
|
44
47
|
is_query_empty,
|
45
48
|
is_ready_to_chat,
|
@@ -523,22 +526,6 @@ async def set_conversation_title(
|
|
523
526
|
)
|
524
527
|
|
525
528
|
|
526
|
-
class ChatRequestBody(BaseModel):
|
527
|
-
q: str
|
528
|
-
n: Optional[int] = 7
|
529
|
-
d: Optional[float] = None
|
530
|
-
stream: Optional[bool] = False
|
531
|
-
title: Optional[str] = None
|
532
|
-
conversation_id: Optional[str] = None
|
533
|
-
city: Optional[str] = None
|
534
|
-
region: Optional[str] = None
|
535
|
-
country: Optional[str] = None
|
536
|
-
country_code: Optional[str] = None
|
537
|
-
timezone: Optional[str] = None
|
538
|
-
image: Optional[str] = None
|
539
|
-
create_new: Optional[bool] = False
|
540
|
-
|
541
|
-
|
542
529
|
@api_chat.post("")
|
543
530
|
@requires(["authenticated"])
|
544
531
|
async def chat(
|
@@ -551,6 +538,7 @@ async def chat(
|
|
551
538
|
rate_limiter_per_day=Depends(
|
552
539
|
ApiUserRateLimiter(requests=600, subscribed_requests=6000, window=60 * 60 * 24, slug="chat_day")
|
553
540
|
),
|
541
|
+
image_rate_limiter=Depends(ApiImageRateLimiter(max_images=10, max_combined_size_mb=20)),
|
554
542
|
):
|
555
543
|
# Access the parameters from the body
|
556
544
|
q = body.q
|
@@ -564,9 +552,9 @@ async def chat(
|
|
564
552
|
country = body.country or get_country_name_from_timezone(body.timezone)
|
565
553
|
country_code = body.country_code or get_country_code_from_timezone(body.timezone)
|
566
554
|
timezone = body.timezone
|
567
|
-
|
555
|
+
raw_images = body.images
|
568
556
|
|
569
|
-
async def event_generator(q: str,
|
557
|
+
async def event_generator(q: str, images: list[str]):
|
570
558
|
start_time = time.perf_counter()
|
571
559
|
ttft = None
|
572
560
|
chat_metadata: dict = {}
|
@@ -576,16 +564,16 @@ async def chat(
|
|
576
564
|
q = unquote(q)
|
577
565
|
nonlocal conversation_id
|
578
566
|
|
579
|
-
|
580
|
-
if
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
567
|
+
uploaded_images: list[str] = []
|
568
|
+
if images:
|
569
|
+
for image in images:
|
570
|
+
decoded_string = unquote(image)
|
571
|
+
base64_data = decoded_string.split(",", 1)[1]
|
572
|
+
image_bytes = base64.b64decode(base64_data)
|
573
|
+
webp_image_bytes = convert_image_to_webp(image_bytes)
|
574
|
+
uploaded_image = upload_image_to_bucket(webp_image_bytes, request.user.object.id)
|
575
|
+
if uploaded_image:
|
576
|
+
uploaded_images.append(uploaded_image)
|
589
577
|
|
590
578
|
async def send_event(event_type: ChatEvent, data: str | dict):
|
591
579
|
nonlocal connection_alive, ttft
|
@@ -692,7 +680,7 @@ async def chat(
|
|
692
680
|
meta_log,
|
693
681
|
is_automated_task,
|
694
682
|
user=user,
|
695
|
-
|
683
|
+
query_images=uploaded_images,
|
696
684
|
agent=agent,
|
697
685
|
)
|
698
686
|
conversation_commands_str = ", ".join([cmd.value for cmd in conversation_commands])
|
@@ -701,7 +689,7 @@ async def chat(
|
|
701
689
|
):
|
702
690
|
yield result
|
703
691
|
|
704
|
-
mode = await aget_relevant_output_modes(q, meta_log, is_automated_task, user,
|
692
|
+
mode = await aget_relevant_output_modes(q, meta_log, is_automated_task, user, uploaded_images, agent)
|
705
693
|
async for result in send_event(ChatEvent.STATUS, f"**Decided Response Mode:** {mode.value}"):
|
706
694
|
yield result
|
707
695
|
if mode not in conversation_commands:
|
@@ -764,7 +752,7 @@ async def chat(
|
|
764
752
|
q,
|
765
753
|
contextual_data,
|
766
754
|
conversation_history=meta_log,
|
767
|
-
|
755
|
+
query_images=uploaded_images,
|
768
756
|
user=user,
|
769
757
|
agent=agent,
|
770
758
|
)
|
@@ -785,7 +773,7 @@ async def chat(
|
|
785
773
|
intent_type="summarize",
|
786
774
|
client_application=request.user.client_app,
|
787
775
|
conversation_id=conversation_id,
|
788
|
-
|
776
|
+
query_images=uploaded_images,
|
789
777
|
)
|
790
778
|
return
|
791
779
|
|
@@ -828,7 +816,7 @@ async def chat(
|
|
828
816
|
conversation_id=conversation_id,
|
829
817
|
inferred_queries=[query_to_run],
|
830
818
|
automation_id=automation.id,
|
831
|
-
|
819
|
+
query_images=uploaded_images,
|
832
820
|
)
|
833
821
|
async for result in send_llm_response(llm_response):
|
834
822
|
yield result
|
@@ -848,7 +836,7 @@ async def chat(
|
|
848
836
|
conversation_commands,
|
849
837
|
location,
|
850
838
|
partial(send_event, ChatEvent.STATUS),
|
851
|
-
|
839
|
+
query_images=uploaded_images,
|
852
840
|
agent=agent,
|
853
841
|
):
|
854
842
|
if isinstance(result, dict) and ChatEvent.STATUS in result:
|
@@ -892,7 +880,7 @@ async def chat(
|
|
892
880
|
user,
|
893
881
|
partial(send_event, ChatEvent.STATUS),
|
894
882
|
custom_filters,
|
895
|
-
|
883
|
+
query_images=uploaded_images,
|
896
884
|
agent=agent,
|
897
885
|
):
|
898
886
|
if isinstance(result, dict) and ChatEvent.STATUS in result:
|
@@ -916,7 +904,7 @@ async def chat(
|
|
916
904
|
location,
|
917
905
|
user,
|
918
906
|
partial(send_event, ChatEvent.STATUS),
|
919
|
-
|
907
|
+
query_images=uploaded_images,
|
920
908
|
agent=agent,
|
921
909
|
):
|
922
910
|
if isinstance(result, dict) and ChatEvent.STATUS in result:
|
@@ -966,20 +954,20 @@ async def chat(
|
|
966
954
|
references=compiled_references,
|
967
955
|
online_results=online_results,
|
968
956
|
send_status_func=partial(send_event, ChatEvent.STATUS),
|
969
|
-
|
957
|
+
query_images=uploaded_images,
|
970
958
|
agent=agent,
|
971
959
|
):
|
972
960
|
if isinstance(result, dict) and ChatEvent.STATUS in result:
|
973
961
|
yield result[ChatEvent.STATUS]
|
974
962
|
else:
|
975
|
-
|
963
|
+
generated_image, status_code, improved_image_prompt, intent_type = result
|
976
964
|
|
977
|
-
if
|
965
|
+
if generated_image is None or status_code != 200:
|
978
966
|
content_obj = {
|
979
967
|
"content-type": "application/json",
|
980
968
|
"intentType": intent_type,
|
981
969
|
"detail": improved_image_prompt,
|
982
|
-
"image":
|
970
|
+
"image": None,
|
983
971
|
}
|
984
972
|
async for result in send_llm_response(json.dumps(content_obj)):
|
985
973
|
yield result
|
@@ -987,7 +975,7 @@ async def chat(
|
|
987
975
|
|
988
976
|
await sync_to_async(save_to_conversation_log)(
|
989
977
|
q,
|
990
|
-
|
978
|
+
generated_image,
|
991
979
|
user,
|
992
980
|
meta_log,
|
993
981
|
user_message_time,
|
@@ -997,13 +985,64 @@ async def chat(
|
|
997
985
|
conversation_id=conversation_id,
|
998
986
|
compiled_references=compiled_references,
|
999
987
|
online_results=online_results,
|
1000
|
-
|
988
|
+
query_images=uploaded_images,
|
1001
989
|
)
|
1002
990
|
content_obj = {
|
1003
991
|
"intentType": intent_type,
|
1004
992
|
"inferredQueries": [improved_image_prompt],
|
1005
|
-
"image":
|
993
|
+
"image": generated_image,
|
994
|
+
}
|
995
|
+
async for result in send_llm_response(json.dumps(content_obj)):
|
996
|
+
yield result
|
997
|
+
return
|
998
|
+
|
999
|
+
if ConversationCommand.Diagram in conversation_commands:
|
1000
|
+
async for result in send_event(ChatEvent.STATUS, f"Creating diagram"):
|
1001
|
+
yield result
|
1002
|
+
|
1003
|
+
intent_type = "excalidraw"
|
1004
|
+
inferred_queries = []
|
1005
|
+
diagram_description = ""
|
1006
|
+
|
1007
|
+
async for result in generate_excalidraw_diagram(
|
1008
|
+
q=defiltered_query,
|
1009
|
+
conversation_history=meta_log,
|
1010
|
+
location_data=location,
|
1011
|
+
note_references=compiled_references,
|
1012
|
+
online_results=online_results,
|
1013
|
+
query_images=uploaded_images,
|
1014
|
+
user=user,
|
1015
|
+
agent=agent,
|
1016
|
+
send_status_func=partial(send_event, ChatEvent.STATUS),
|
1017
|
+
):
|
1018
|
+
if isinstance(result, dict) and ChatEvent.STATUS in result:
|
1019
|
+
yield result[ChatEvent.STATUS]
|
1020
|
+
else:
|
1021
|
+
better_diagram_description_prompt, excalidraw_diagram_description = result
|
1022
|
+
inferred_queries.append(better_diagram_description_prompt)
|
1023
|
+
diagram_description = excalidraw_diagram_description
|
1024
|
+
|
1025
|
+
content_obj = {
|
1026
|
+
"intentType": intent_type,
|
1027
|
+
"inferredQueries": inferred_queries,
|
1028
|
+
"image": diagram_description,
|
1006
1029
|
}
|
1030
|
+
|
1031
|
+
await sync_to_async(save_to_conversation_log)(
|
1032
|
+
q,
|
1033
|
+
excalidraw_diagram_description,
|
1034
|
+
user,
|
1035
|
+
meta_log,
|
1036
|
+
user_message_time,
|
1037
|
+
intent_type="excalidraw",
|
1038
|
+
inferred_queries=[better_diagram_description_prompt],
|
1039
|
+
client_application=request.user.client_app,
|
1040
|
+
conversation_id=conversation_id,
|
1041
|
+
compiled_references=compiled_references,
|
1042
|
+
online_results=online_results,
|
1043
|
+
query_images=uploaded_images,
|
1044
|
+
)
|
1045
|
+
|
1007
1046
|
async for result in send_llm_response(json.dumps(content_obj)):
|
1008
1047
|
yield result
|
1009
1048
|
return
|
@@ -1024,7 +1063,7 @@ async def chat(
|
|
1024
1063
|
conversation_id,
|
1025
1064
|
location,
|
1026
1065
|
user_name,
|
1027
|
-
|
1066
|
+
uploaded_images,
|
1028
1067
|
)
|
1029
1068
|
|
1030
1069
|
# Send Response
|
@@ -1050,9 +1089,9 @@ async def chat(
|
|
1050
1089
|
|
1051
1090
|
## Stream Text Response
|
1052
1091
|
if stream:
|
1053
|
-
return StreamingResponse(event_generator(q,
|
1092
|
+
return StreamingResponse(event_generator(q, images=raw_images), media_type="text/plain")
|
1054
1093
|
## Non-Streaming Text Response
|
1055
1094
|
else:
|
1056
|
-
response_iterator = event_generator(q,
|
1095
|
+
response_iterator = event_generator(q, images=raw_images)
|
1057
1096
|
response_data = await read_chat_stream(response_iterator)
|
1058
1097
|
return Response(content=json.dumps(response_data), media_type="application/json", status_code=200)
|