Improved Command Menu and Help Command (#774)

* The command menu (triggered by "/") now has a clickable list of possible commands, that automatically fill into the chat when pressed.
* The `/help` command now searches `khoj.dev` pages to provide useful assistance to the user.

---------

Co-authored-by: raghavt3 <raghavt3@illinois.edu>
Co-authored-by: sabaimran <65192171+sabaimran@users.noreply.github.com>
This commit is contained in:
Raghav Tirumale 2024-06-01 13:03:31 -04:00 committed by GitHub
parent 6d10f98498
commit a3934b3aaa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 51 additions and 21 deletions

View file

@ -723,6 +723,11 @@ To get started, just start typing below. You can also type / to see a list of co
}
}
function fillCommandInPrompt(command) {
let chatInput = document.getElementById("chat-input");
chatInput.value = "/" + command;
}
function onChatInput() {
let chatInput = document.getElementById("chat-input");
chatInput.value = chatInput.value.trimStart();
@ -738,7 +743,7 @@ To get started, just start typing below. You can also type / to see a list of co
const command = chatInput.value.split(" ")[0].substring(1);
for (let key in chatOptions) {
if (!!!command || key.startsWith(command)) {
helpText += "<b>/" + key + "</b>: " + chatOptions[key] + "<br>";
helpText += `<div class="helpoption" onclick="fillCommandInPrompt('${key}')"><b>/${key}</b>: ${chatOptions[key]}</div>`;
}
}
chatTooltip.innerHTML = helpText;
@ -2277,6 +2282,11 @@ To get started, just start typing below. You can also type / to see a list of co
.option:hover {
box-shadow: 0 0 11px #aaa;
}
.helpoption:hover {
background-color: #d9d9d9;
}
#chat-input {
font-family: var(--font-family);
font-size: medium;

View file

@ -3,7 +3,7 @@ import json
import logging
import os
from collections import defaultdict
from typing import Callable, Dict, Optional, Tuple, Union
from typing import Callable, Dict, List, Optional, Tuple, Union
import aiohttp
import requests
@ -43,8 +43,13 @@ MAX_WEBPAGES_TO_READ = 1
async def search_online(
query: str, conversation_history: dict, location: LocationData, send_status_func: Optional[Callable] = None
query: str,
conversation_history: dict,
location: LocationData,
send_status_func: Optional[Callable] = None,
custom_filters: List[str] = [],
):
query += " ".join(custom_filters)
if not online_search_enabled():
logger.warn("SERPER_DEV_API_KEY is not set")
return {}

View file

@ -515,15 +515,6 @@ async def websocket_endpoint(
await send_status_update(f"**👀 Understanding Query**: {q}")
if conversation_commands == [ConversationCommand.Help]:
conversation_config = await ConversationAdapters.aget_user_conversation_config(user)
if conversation_config == None:
conversation_config = await ConversationAdapters.aget_default_conversation_config()
model_type = conversation_config.model_type
formatted_help = help_message.format(model=model_type, version=state.khoj_version, device=get_device())
await send_complete_llm_response(formatted_help)
continue
meta_log = conversation.conversation_log
is_automated_task = conversation_commands == [ConversationCommand.AutomatedTask]
@ -541,6 +532,20 @@ async def websocket_endpoint(
await conversation_command_rate_limiter.update_and_check_if_valid(websocket, cmd)
q = q.replace(f"/{cmd.value}", "").strip()
custom_filters = []
if conversation_commands == [ConversationCommand.Help]:
if not q:
conversation_config = await ConversationAdapters.aget_user_conversation_config(user)
if conversation_config == None:
conversation_config = await ConversationAdapters.aget_default_conversation_config()
model_type = conversation_config.model_type
formatted_help = help_message.format(model=model_type, version=state.khoj_version, device=get_device())
await send_complete_llm_response(formatted_help)
continue
# Adding specification to search online specifically on khoj.dev pages.
custom_filters.append("site:khoj.dev")
conversation_commands.append(ConversationCommand.Online)
if ConversationCommand.Automation in conversation_commands:
try:
automation, crontime, query_to_run, subject = await create_automation(
@ -607,7 +612,9 @@ async def websocket_endpoint(
conversation_commands.append(ConversationCommand.Webpage)
else:
try:
online_results = await search_online(defiltered_query, meta_log, location, send_status_update)
online_results = await search_online(
defiltered_query, meta_log, location, send_status_update, custom_filters
)
except ValueError as e:
logger.warning(f"Error searching online: {e}. Attempting to respond without online results")
await send_complete_llm_response(
@ -755,13 +762,19 @@ async def chat(
await is_ready_to_chat(user)
conversation_commands = [get_conversation_command(query=q, any_references=True)]
_custom_filters = []
if conversation_commands == [ConversationCommand.Help]:
conversation_config = await ConversationAdapters.aget_user_conversation_config(user)
if conversation_config == None:
conversation_config = await ConversationAdapters.aget_default_conversation_config()
model_type = conversation_config.model_type
formatted_help = help_message.format(model=model_type, version=state.khoj_version, device=get_device())
return StreamingResponse(iter([formatted_help]), media_type="text/event-stream", status_code=200)
help_str = "/" + ConversationCommand.Help
if q.strip() == help_str:
conversation_config = await ConversationAdapters.aget_user_conversation_config(user)
if conversation_config == None:
conversation_config = await ConversationAdapters.aget_default_conversation_config()
model_type = conversation_config.model_type
formatted_help = help_message.format(model=model_type, version=state.khoj_version, device=get_device())
return StreamingResponse(iter([formatted_help]), media_type="text/event-stream", status_code=200)
# Adding specification to search online specifically on khoj.dev pages.
_custom_filters.append("site:khoj.dev")
conversation_commands.append(ConversationCommand.Online)
conversation = await ConversationAdapters.aget_conversation_by_user(
user, request.user.client_app, conversation_id, title
@ -856,7 +869,9 @@ async def chat(
conversation_commands.append(ConversationCommand.Webpage)
else:
try:
online_results = await search_online(defiltered_query, meta_log, location)
online_results = await search_online(
defiltered_query, meta_log, location, custom_filters=_custom_filters
)
except ValueError as e:
logger.warning(f"Error searching online: {e}. Attempting to respond without online results")

View file

@ -316,7 +316,7 @@ command_descriptions = {
ConversationCommand.Webpage: "Get information from webpage links provided by you.",
ConversationCommand.Image: "Generate images by describing your imagination in words.",
ConversationCommand.Automation: "Automatically run your query at a specified time or interval.",
ConversationCommand.Help: "Display a help message with all available commands and other metadata.",
ConversationCommand.Help: "Get help with how to use or setup Khoj from the documentation",
}
tool_descriptions_for_llm = {