Merge branch 'master' into features/advanced-reasoning

This commit is contained in:
Debanjum 2024-10-28 04:07:36 -07:00
commit 50ffd7f199
12 changed files with 116 additions and 96 deletions

View file

@ -394,6 +394,11 @@ export const ChatInputArea = forwardRef<HTMLTextAreaElement, ChatInputProps>((pr
<PopoverContent <PopoverContent
onOpenAutoFocus={(e) => e.preventDefault()} onOpenAutoFocus={(e) => e.preventDefault()}
className={`${props.isMobileWidth ? "w-[100vw]" : "w-full"} rounded-md`} className={`${props.isMobileWidth ? "w-[100vw]" : "w-full"} rounded-md`}
side="top"
align="center"
/* Offset below text area on home page (i.e where conversationId is unset) */
sideOffset={props.conversationId ? 0 : 80}
alignOffset={0}
> >
<Command className="max-w-full"> <Command className="max-w-full">
<CommandInput <CommandInput

View file

@ -362,7 +362,7 @@ function ChatBodyData(props: ChatBodyDataProps) {
className={`${selectedAgent === agents[index].slug ? convertColorToBorderClass(agents[index].color) : "border-muted text-muted-foreground"} hover:cursor-pointer`} className={`${selectedAgent === agents[index].slug ? convertColorToBorderClass(agents[index].color) : "border-muted text-muted-foreground"} hover:cursor-pointer`}
> >
<CardTitle <CardTitle
className="text-center text-xs font-medium flex justify-center items-center px-1.5 py-1" className="text-center text-xs font-medium flex justify-center items-center whitespace-nowrap px-1.5 py-1"
onDoubleClick={() => onDoubleClick={() =>
openAgentEditCard(agents[index].slug) openAgentEditCard(agents[index].slug)
} }

View file

@ -19,6 +19,8 @@ from khoj.processor.embeddings import EmbeddingsModel
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
BATCH_SIZE = 1000 # Define an appropriate batch size
class Command(BaseCommand): class Command(BaseCommand):
help = "Convert all existing Entry objects to use a new default Search model." help = "Convert all existing Entry objects to use a new default Search model."
@ -42,17 +44,19 @@ class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
@transaction.atomic @transaction.atomic
def regenerate_entries(entry_filter: Q, embeddings_model: EmbeddingsModel, search_model: SearchModelConfig): def regenerate_entries(entry_filter: Q, embeddings_model: EmbeddingsModel, search_model: SearchModelConfig):
entries = Entry.objects.filter(entry_filter).all() total_entries = Entry.objects.filter(entry_filter).count()
for start in tqdm(range(0, total_entries, BATCH_SIZE)):
end = start + BATCH_SIZE
entries = Entry.objects.filter(entry_filter)[start:end]
compiled_entries = [entry.compiled for entry in entries] compiled_entries = [entry.compiled for entry in entries]
updated_entries: List[Entry] = [] updated_entries: List[Entry] = []
try: try:
embeddings = embeddings_model.embed_documents(compiled_entries) embeddings = embeddings_model.embed_documents(compiled_entries)
except Exception as e: except Exception as e:
logger.error(f"Error embedding documents: {e}") logger.error(f"Error embedding documents: {e}")
return return
for i, entry in enumerate(tqdm(entries)): for i, entry in enumerate(entries):
entry.embeddings = embeddings[i] entry.embeddings = embeddings[i]
entry.search_model_id = search_model.id entry.search_model_id = search_model.id
updated_entries.append(entry) updated_entries.append(entry)

View file

@ -152,9 +152,7 @@ def converse_anthropic(
""" """
# Initialize Variables # Initialize Variables
current_date = datetime.now() current_date = datetime.now()
compiled_references = "\n\n".join({f"# {item}" for item in references}) compiled_references = "\n\n".join({f"# File: {item['file']}\n## {item['compiled']}\n" for item in references})
conversation_primer = prompts.query_prompt.format(query=user_query)
if agent and agent.personality: if agent and agent.personality:
system_prompt = prompts.custom_personality.format( system_prompt = prompts.custom_personality.format(
@ -185,20 +183,19 @@ def converse_anthropic(
completion_func(chat_response=prompts.no_online_results_found.format()) completion_func(chat_response=prompts.no_online_results_found.format())
return iter([prompts.no_online_results_found.format()]) return iter([prompts.no_online_results_found.format()])
if ConversationCommand.Code in conversation_commands and not is_none_or_empty(code_results): context_message = ""
conversation_primer = (
f"{prompts.code_executed_context.format(code_results=str(code_results))}\n{conversation_primer}"
)
if ConversationCommand.Online in conversation_commands or ConversationCommand.Webpage in conversation_commands:
conversation_primer = (
f"{prompts.online_search_conversation.format(online_results=str(online_results))}\n{conversation_primer}"
)
if not is_none_or_empty(compiled_references): if not is_none_or_empty(compiled_references):
conversation_primer = f"{prompts.notes_conversation.format(query=user_query, references=compiled_references)}\n\n{conversation_primer}" context_message = f"{prompts.notes_conversation.format(query=user_query, references=compiled_references)}\n\n"
if ConversationCommand.Online in conversation_commands or ConversationCommand.Webpage in conversation_commands:
context_message += f"{prompts.online_search_conversation.format(online_results=str(online_results))}\n\n"
if ConversationCommand.Code in conversation_commands and not is_none_or_empty(code_results):
context_message += f"{prompts.code_executed_context.format(code_results=str(code_results))}\n\n"
context_message = context_message.strip()
# Setup Prompt with Primer or Conversation History # Setup Prompt with Primer or Conversation History
messages = generate_chatml_messages_with_context( messages = generate_chatml_messages_with_context(
conversation_primer, user_query,
context_message=context_message,
conversation_log=conversation_log, conversation_log=conversation_log,
model_name=model, model_name=model,
max_prompt_size=max_prompt_size, max_prompt_size=max_prompt_size,

View file

@ -157,9 +157,7 @@ def converse_gemini(
""" """
# Initialize Variables # Initialize Variables
current_date = datetime.now() current_date = datetime.now()
compiled_references = "\n\n".join({f"# {item}" for item in references}) compiled_references = "\n\n".join({f"# File: {item['file']}\n## {item['compiled']}\n" for item in references})
conversation_primer = prompts.query_prompt.format(query=user_query)
if agent and agent.personality: if agent and agent.personality:
system_prompt = prompts.custom_personality.format( system_prompt = prompts.custom_personality.format(
@ -191,20 +189,19 @@ def converse_gemini(
completion_func(chat_response=prompts.no_online_results_found.format()) completion_func(chat_response=prompts.no_online_results_found.format())
return iter([prompts.no_online_results_found.format()]) return iter([prompts.no_online_results_found.format()])
if ConversationCommand.Code in conversation_commands and not is_none_or_empty(code_results): context_message = ""
conversation_primer = (
f"{prompts.code_executed_context.format(code_results=str(code_results))}\n{conversation_primer}"
)
if ConversationCommand.Online in conversation_commands or ConversationCommand.Webpage in conversation_commands:
conversation_primer = (
f"{prompts.online_search_conversation.format(online_results=str(online_results))}\n{conversation_primer}"
)
if not is_none_or_empty(compiled_references): if not is_none_or_empty(compiled_references):
conversation_primer = f"{prompts.notes_conversation.format(query=user_query, references=compiled_references)}\n\n{conversation_primer}" context_message = f"{prompts.notes_conversation.format(query=user_query, references=compiled_references)}\n\n"
if ConversationCommand.Online in conversation_commands or ConversationCommand.Webpage in conversation_commands:
context_message += f"{prompts.online_search_conversation.format(online_results=str(online_results))}\n\n"
if ConversationCommand.Code in conversation_commands and not is_none_or_empty(code_results):
context_message += f"{prompts.code_executed_context.format(code_results=str(code_results))}\n\n"
context_message = context_message.strip()
# Setup Prompt with Primer or Conversation History # Setup Prompt with Primer or Conversation History
messages = generate_chatml_messages_with_context( messages = generate_chatml_messages_with_context(
conversation_primer, user_query,
context_message=context_message,
conversation_log=conversation_log, conversation_log=conversation_log,
model_name=model, model_name=model,
max_prompt_size=max_prompt_size, max_prompt_size=max_prompt_size,

View file

@ -158,7 +158,7 @@ def converse_offline(
# Initialize Variables # Initialize Variables
assert loaded_model is None or isinstance(loaded_model, Llama), "loaded_model must be of type Llama, if configured" assert loaded_model is None or isinstance(loaded_model, Llama), "loaded_model must be of type Llama, if configured"
offline_chat_model = loaded_model or download_model(model, max_tokens=max_prompt_size) offline_chat_model = loaded_model or download_model(model, max_tokens=max_prompt_size)
compiled_references_message = "\n\n".join({f"{item['compiled']}" for item in references}) compiled_references = "\n\n".join({f"# File: {item['file']}\n## {item['compiled']}\n" for item in references})
tracer["chat_model"] = model tracer["chat_model"] = model
current_date = datetime.now() current_date = datetime.now()
@ -176,8 +176,6 @@ def converse_offline(
day_of_week=current_date.strftime("%A"), day_of_week=current_date.strftime("%A"),
) )
conversation_primer = prompts.query_prompt.format(query=user_query)
if location_data: if location_data:
location_prompt = prompts.user_location.format(location=f"{location_data}") location_prompt = prompts.user_location.format(location=f"{location_data}")
system_prompt = f"{system_prompt}\n{location_prompt}" system_prompt = f"{system_prompt}\n{location_prompt}"
@ -187,31 +185,34 @@ def converse_offline(
system_prompt = f"{system_prompt}\n{user_name_prompt}" system_prompt = f"{system_prompt}\n{user_name_prompt}"
# Get Conversation Primer appropriate to Conversation Type # Get Conversation Primer appropriate to Conversation Type
if conversation_commands == [ConversationCommand.Notes] and is_none_or_empty(compiled_references_message): if conversation_commands == [ConversationCommand.Notes] and is_none_or_empty(compiled_references):
return iter([prompts.no_notes_found.format()]) return iter([prompts.no_notes_found.format()])
elif conversation_commands == [ConversationCommand.Online] and is_none_or_empty(online_results): elif conversation_commands == [ConversationCommand.Online] and is_none_or_empty(online_results):
completion_func(chat_response=prompts.no_online_results_found.format()) completion_func(chat_response=prompts.no_online_results_found.format())
return iter([prompts.no_online_results_found.format()]) return iter([prompts.no_online_results_found.format()])
if ConversationCommand.Code in conversation_commands and not is_none_or_empty(code_results): context_message = ""
conversation_primer = ( if not is_none_or_empty(compiled_references):
f"{prompts.code_executed_context.format(code_results=str(code_results))}\n{conversation_primer}" context_message = f"{prompts.notes_conversation_offline.format(references=compiled_references)}\n\n"
) if ConversationCommand.Online in conversation_commands or ConversationCommand.Webpage in conversation_commands:
if ConversationCommand.Online in conversation_commands:
simplified_online_results = online_results.copy() simplified_online_results = online_results.copy()
for result in online_results: for result in online_results:
if online_results[result].get("webpages"): if online_results[result].get("webpages"):
simplified_online_results[result] = online_results[result]["webpages"] simplified_online_results[result] = online_results[result]["webpages"]
conversation_primer = f"{prompts.online_search_conversation_offline.format(online_results=str(simplified_online_results))}\n{conversation_primer}" context_message += (
if not is_none_or_empty(compiled_references_message): f"{prompts.online_search_conversation_offline.format(online_results=str(simplified_online_results))}\n\n"
conversation_primer = f"{prompts.notes_conversation_offline.format(references=compiled_references_message)}\n\n{conversation_primer}" )
if ConversationCommand.Code in conversation_commands and not is_none_or_empty(code_results):
context_message += f"{prompts.code_executed_context.format(code_results=str(code_results))}\n\n"
context_message = context_message.strip()
# Setup Prompt with Primer or Conversation History # Setup Prompt with Primer or Conversation History
messages = generate_chatml_messages_with_context( messages = generate_chatml_messages_with_context(
conversation_primer, user_query,
system_prompt, system_prompt,
conversation_log, conversation_log,
context_message=context_message,
model_name=model, model_name=model,
loaded_model=offline_chat_model, loaded_model=offline_chat_model,
max_prompt_size=max_prompt_size, max_prompt_size=max_prompt_size,

View file

@ -155,9 +155,7 @@ def converse(
""" """
# Initialize Variables # Initialize Variables
current_date = datetime.now() current_date = datetime.now()
compiled_references = "\n\n".join({f"# {item['compiled']}" for item in references}) compiled_references = "\n\n".join({f"# File: {item['file']}\n## {item['compiled']}\n" for item in references})
conversation_primer = prompts.query_prompt.format(query=user_query)
if agent and agent.personality: if agent and agent.personality:
system_prompt = prompts.custom_personality.format( system_prompt = prompts.custom_personality.format(
@ -188,22 +186,21 @@ def converse(
completion_func(chat_response=prompts.no_online_results_found.format()) completion_func(chat_response=prompts.no_online_results_found.format())
return iter([prompts.no_online_results_found.format()]) return iter([prompts.no_online_results_found.format()])
if not is_none_or_empty(code_results): context_message = ""
conversation_primer = (
f"{prompts.code_executed_context.format(code_results=str(code_results))}\n{conversation_primer}"
)
if not is_none_or_empty(online_results):
conversation_primer = (
f"{prompts.online_search_conversation.format(online_results=str(online_results))}\n{conversation_primer}"
)
if not is_none_or_empty(compiled_references): if not is_none_or_empty(compiled_references):
conversation_primer = f"{prompts.notes_conversation.format(query=user_query, references=compiled_references)}\n\n{conversation_primer}" context_message = f"{prompts.notes_conversation.format(references=compiled_references)}\n\n"
if not is_none_or_empty(online_results):
context_message += f"{prompts.online_search_conversation.format(online_results=str(online_results))}\n\n"
if not is_none_or_empty(code_results):
context_message += f"{prompts.code_executed_context.format(code_results=str(code_results))}\n\n"
context_message = context_message.strip()
# Setup Prompt with Primer or Conversation History # Setup Prompt with Primer or Conversation History
messages = generate_chatml_messages_with_context( messages = generate_chatml_messages_with_context(
conversation_primer, user_query,
system_prompt, system_prompt,
conversation_log, conversation_log,
context_message=context_message,
model_name=model, model_name=model,
max_prompt_size=max_prompt_size, max_prompt_size=max_prompt_size,
tokenizer_name=tokenizer_name, tokenizer_name=tokenizer_name,

View file

@ -118,6 +118,7 @@ Use my personal notes and our past conversations to inform your response.
Ask crisp follow-up questions to get additional context, when a helpful response cannot be provided from the provided notes or past conversations. Ask crisp follow-up questions to get additional context, when a helpful response cannot be provided from the provided notes or past conversations.
User's Notes: User's Notes:
-----
{references} {references}
""".strip() """.strip()
) )
@ -127,6 +128,7 @@ notes_conversation_offline = PromptTemplate.from_template(
Use my personal notes and our past conversations to inform your response. Use my personal notes and our past conversations to inform your response.
User's Notes: User's Notes:
-----
{references} {references}
""".strip() """.strip()
) )
@ -328,6 +330,7 @@ Use this up-to-date information from the internet to inform your response.
Ask crisp follow-up questions to get additional context, when a helpful response cannot be provided from the online data or past conversations. Ask crisp follow-up questions to get additional context, when a helpful response cannot be provided from the online data or past conversations.
Information from the internet: Information from the internet:
-----
{online_results} {online_results}
""".strip() """.strip()
) )
@ -337,6 +340,7 @@ online_search_conversation_offline = PromptTemplate.from_template(
Use this up-to-date information from the internet to inform your response. Use this up-to-date information from the internet to inform your response.
Information from the internet: Information from the internet:
-----
{online_results} {online_results}
""".strip() """.strip()
) )

View file

@ -22,6 +22,7 @@ from transformers import AutoTokenizer
from khoj.database.adapters import ConversationAdapters, ais_user_subscribed from khoj.database.adapters import ConversationAdapters, ais_user_subscribed
from khoj.database.models import ChatModelOptions, ClientApplication, KhojUser from khoj.database.models import ChatModelOptions, ClientApplication, KhojUser
from khoj.processor.conversation import prompts
from khoj.processor.conversation.offline.utils import download_model, infer_max_tokens from khoj.processor.conversation.offline.utils import download_model, infer_max_tokens
from khoj.search_filter.date_filter import DateFilter from khoj.search_filter.date_filter import DateFilter
from khoj.search_filter.file_filter import FileFilter from khoj.search_filter.file_filter import FileFilter
@ -259,8 +260,9 @@ def generate_chatml_messages_with_context(
query_images=None, query_images=None,
vision_enabled=False, vision_enabled=False,
model_type="", model_type="",
context_message="",
): ):
"""Generate messages for ChatGPT with context from previous conversation""" """Generate chat messages with appropriate context from previous conversation to send to the chat model"""
# Set max prompt size from user config or based on pre-configured for model and machine specs # Set max prompt size from user config or based on pre-configured for model and machine specs
if not max_prompt_size: if not max_prompt_size:
if loaded_model: if loaded_model:
@ -274,21 +276,27 @@ def generate_chatml_messages_with_context(
# Extract Chat History for Context # Extract Chat History for Context
chatml_messages: List[ChatMessage] = [] chatml_messages: List[ChatMessage] = []
for chat in conversation_log.get("chat", []): for chat in conversation_log.get("chat", []):
message_notes = f'\n\n Notes:\n{chat.get("context")}' if chat.get("context") else "\n" message_context = ""
if chat["by"] == "khoj" and "excalidraw" in chat["intent"].get("type", ""):
message_context += chat.get("intent").get("inferred-queries")[0]
if not is_none_or_empty(chat.get("context")):
references = "\n\n".join(
{f"# File: {item['file']}\n## {item['compiled']}\n" for item in chat.get("context") or []}
)
message_context += f"{prompts.notes_conversation.format(references=references)}\n\n"
if not is_none_or_empty(chat.get("onlineContext")):
message_context += f"{prompts.online_search_conversation.format(online_results=chat.get('onlineContext'))}"
if not is_none_or_empty(message_context):
reconstructed_context_message = ChatMessage(content=message_context, role="user")
chatml_messages.insert(0, reconstructed_context_message)
role = "user" if chat["by"] == "you" else "assistant" role = "user" if chat["by"] == "you" else "assistant"
message_content = construct_structured_message(chat["message"], chat.get("images"), model_type, vision_enabled)
if chat["by"] == "khoj" and "excalidraw" in chat["intent"].get("type"):
message_content = chat.get("intent").get("inferred-queries")[0] + message_notes
else:
message_content = chat["message"] + message_notes
message_content = construct_structured_message(message_content, chat.get("images"), model_type, vision_enabled)
reconstructed_message = ChatMessage(content=message_content, role=role) reconstructed_message = ChatMessage(content=message_content, role=role)
chatml_messages.insert(0, reconstructed_message) chatml_messages.insert(0, reconstructed_message)
if len(chatml_messages) >= 2 * lookback_turns: if len(chatml_messages) >= 3 * lookback_turns:
break break
messages = [] messages = []
@ -299,6 +307,8 @@ def generate_chatml_messages_with_context(
role="user", role="user",
) )
) )
if not is_none_or_empty(context_message):
messages.append(ChatMessage(content=context_message, role="user"))
if len(chatml_messages) > 0: if len(chatml_messages) > 0:
messages += chatml_messages messages += chatml_messages
if not is_none_or_empty(system_message): if not is_none_or_empty(system_message):

View file

@ -120,7 +120,7 @@ def add_files_filter(request: Request, filter: FilesFilterRequest):
file_filters = ConversationAdapters.add_files_to_filter(request.user.object, conversation_id, files_filter) file_filters = ConversationAdapters.add_files_to_filter(request.user.object, conversation_id, files_filter)
return Response(content=json.dumps(file_filters), media_type="application/json", status_code=200) return Response(content=json.dumps(file_filters), media_type="application/json", status_code=200)
except Exception as e: except Exception as e:
logger.error(f"Error adding file filter {filter.filename}: {e}", exc_info=True) logger.error(f"Error adding file filter {filter.filenames}: {e}", exc_info=True)
raise HTTPException(status_code=422, detail=str(e)) raise HTTPException(status_code=422, detail=str(e))

View file

@ -214,7 +214,7 @@ def test_answer_from_chat_history_and_previously_retrieved_content():
( (
"When was I born?", "When was I born?",
"You were born on 1st April 1984.", "You were born on 1st April 1984.",
["Testatron was born on 1st April 1984 in Testville."], [{"compiled": "Testatron was born on 1st April 1984 in Testville.", "file": "birth.org"}],
), ),
] ]
@ -415,15 +415,18 @@ def test_ask_for_clarification_if_not_enough_context_in_question():
context = [ context = [
{ {
"compiled": f"""# Ramya "compiled": f"""# Ramya
My sister, Ramya, is married to Kali Devi. They have 2 kids, Ravi and Rani.""" My sister, Ramya, is married to Kali Devi. They have 2 kids, Ravi and Rani.""",
"file": "Family.md",
}, },
{ {
"compiled": f"""# Fang "compiled": f"""# Fang
My sister, Fang Liu is married to Xi Li. They have 1 kid, Xiao Li.""" My sister, Fang Liu is married to Xi Li. They have 1 kid, Xiao Li.""",
"file": "Family.md",
}, },
{ {
"compiled": f"""# Aiyla "compiled": f"""# Aiyla
My sister, Aiyla is married to Tolga. They have 3 kids, Yildiz, Ali and Ahmet.""" My sister, Aiyla is married to Tolga. They have 3 kids, Yildiz, Ali and Ahmet.""",
"file": "Family.md",
}, },
] ]
@ -608,9 +611,11 @@ async def test_infer_webpage_urls_actor_extracts_correct_links(chat_client, defa
), ),
], ],
) )
async def test_infer_task_scheduling_request(chat_client, user_query, expected_crontime, expected_qs, unexpected_qs): async def test_infer_task_scheduling_request(
chat_client, user_query, expected_crontime, expected_qs, unexpected_qs, default_user2
):
# Act # Act
crontime, inferred_query, _ = await schedule_query(user_query, {}) crontime, inferred_query, _ = await schedule_query(user_query, {}, default_user2)
inferred_query = inferred_query.lower() inferred_query = inferred_query.lower()
# Assert # Assert
@ -630,7 +635,7 @@ async def test_infer_task_scheduling_request(chat_client, user_query, expected_c
"scheduling_query, executing_query, generated_response, expected_should_notify", "scheduling_query, executing_query, generated_response, expected_should_notify",
[ [
( (
"Notify me if it is going to rain tomorrow?", "Notify me only if it is going to rain tomorrow?",
"What's the weather forecast for tomorrow?", "What's the weather forecast for tomorrow?",
"It is sunny and warm tomorrow.", "It is sunny and warm tomorrow.",
False, False,
@ -656,10 +661,10 @@ async def test_infer_task_scheduling_request(chat_client, user_query, expected_c
], ],
) )
def test_decision_on_when_to_notify_scheduled_task_results( def test_decision_on_when_to_notify_scheduled_task_results(
chat_client, scheduling_query, executing_query, generated_response, expected_should_notify chat_client, default_user2, scheduling_query, executing_query, generated_response, expected_should_notify
): ):
# Act # Act
generated_should_notify = should_notify(scheduling_query, executing_query, generated_response) generated_should_notify = should_notify(scheduling_query, executing_query, generated_response, default_user2)
# Assert # Assert
assert generated_should_notify == expected_should_notify assert generated_should_notify == expected_should_notify

View file

@ -307,7 +307,7 @@ def test_summarize_one_file(chat_client, default_user2: KhojUser):
json={"filename": summarization_file, "conversation_id": str(conversation.id)}, json={"filename": summarization_file, "conversation_id": str(conversation.id)},
) )
query = "/summarize" query = "/summarize"
response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": conversation.id}) response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": str(conversation.id)})
response_message = response.json()["response"] response_message = response.json()["response"]
# Assert # Assert
assert response_message != "" assert response_message != ""
@ -339,7 +339,7 @@ def test_summarize_extra_text(chat_client, default_user2: KhojUser):
json={"filename": summarization_file, "conversation_id": str(conversation.id)}, json={"filename": summarization_file, "conversation_id": str(conversation.id)},
) )
query = "/summarize tell me about Xiu" query = "/summarize tell me about Xiu"
response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": conversation.id}) response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": str(conversation.id)})
response_message = response.json()["response"] response_message = response.json()["response"]
# Assert # Assert
assert response_message != "" assert response_message != ""
@ -367,7 +367,7 @@ def test_summarize_multiple_files(chat_client, default_user2: KhojUser):
) )
query = "/summarize" query = "/summarize"
response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": conversation.id}) response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": str(conversation.id)})
response_message = response.json()["response"] response_message = response.json()["response"]
# Assert # Assert
@ -383,7 +383,7 @@ def test_summarize_no_files(chat_client, default_user2: KhojUser):
# Act # Act
query = "/summarize" query = "/summarize"
response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": conversation.id}) response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": str(conversation.id)})
response_message = response.json()["response"] response_message = response.json()["response"]
# Assert # Assert
@ -418,11 +418,11 @@ def test_summarize_different_conversation(chat_client, default_user2: KhojUser):
# Act # Act
query = "/summarize" query = "/summarize"
response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": conversation2.id}) response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": str(conversation2.id)})
response_message_conv2 = response.json()["response"] response_message_conv2 = response.json()["response"]
# now make sure that the file filter is still in conversation 1 # now make sure that the file filter is still in conversation 1
response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": conversation1.id}) response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": str(conversation1.id)})
response_message_conv1 = response.json()["response"] response_message_conv1 = response.json()["response"]
# Assert # Assert
@ -449,7 +449,7 @@ def test_summarize_nonexistant_file(chat_client, default_user2: KhojUser):
json={"filename": "imaginary.markdown", "conversation_id": str(conversation.id)}, json={"filename": "imaginary.markdown", "conversation_id": str(conversation.id)},
) )
query = urllib.parse.quote("/summarize") query = urllib.parse.quote("/summarize")
response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": conversation.id}) response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": str(conversation.id)})
response_message = response.json()["response"] response_message = response.json()["response"]
# Assert # Assert
assert response_message == "No files selected for summarization. Please add files using the section on the left." assert response_message == "No files selected for summarization. Please add files using the section on the left."
@ -481,7 +481,7 @@ def test_summarize_diff_user_file(chat_client, default_user: KhojUser, pdf_confi
# Act # Act
query = "/summarize" query = "/summarize"
response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": conversation.id}) response = chat_client.post(f"/api/chat", json={"q": query, "conversation_id": str(conversation.id)})
response_message = response.json()["response"] response_message = response.json()["response"]
# Assert # Assert