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
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() { function onChatInput() {
let chatInput = document.getElementById("chat-input"); let chatInput = document.getElementById("chat-input");
chatInput.value = chatInput.value.trimStart(); 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); const command = chatInput.value.split(" ")[0].substring(1);
for (let key in chatOptions) { for (let key in chatOptions) {
if (!!!command || key.startsWith(command)) { 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; 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 { .option:hover {
box-shadow: 0 0 11px #aaa; box-shadow: 0 0 11px #aaa;
} }
.helpoption:hover {
background-color: #d9d9d9;
}
#chat-input { #chat-input {
font-family: var(--font-family); font-family: var(--font-family);
font-size: medium; font-size: medium;

View File

@@ -3,7 +3,7 @@ import json
import logging import logging
import os import os
from collections import defaultdict from collections import defaultdict
from typing import Callable, Dict, Optional, Tuple, Union from typing import Callable, Dict, List, Optional, Tuple, Union
import aiohttp import aiohttp
import requests import requests
@@ -43,8 +43,13 @@ MAX_WEBPAGES_TO_READ = 1
async def search_online( 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(): if not online_search_enabled():
logger.warn("SERPER_DEV_API_KEY is not set") logger.warn("SERPER_DEV_API_KEY is not set")
return {} return {}

View File

@@ -515,15 +515,6 @@ async def websocket_endpoint(
await send_status_update(f"**👀 Understanding Query**: {q}") 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 meta_log = conversation.conversation_log
is_automated_task = conversation_commands == [ConversationCommand.AutomatedTask] 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) await conversation_command_rate_limiter.update_and_check_if_valid(websocket, cmd)
q = q.replace(f"/{cmd.value}", "").strip() 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: if ConversationCommand.Automation in conversation_commands:
try: try:
automation, crontime, query_to_run, subject = await create_automation( automation, crontime, query_to_run, subject = await create_automation(
@@ -607,7 +612,9 @@ async def websocket_endpoint(
conversation_commands.append(ConversationCommand.Webpage) conversation_commands.append(ConversationCommand.Webpage)
else: else:
try: 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: except ValueError as e:
logger.warning(f"Error searching online: {e}. Attempting to respond without online results") logger.warning(f"Error searching online: {e}. Attempting to respond without online results")
await send_complete_llm_response( await send_complete_llm_response(
@@ -755,13 +762,19 @@ async def chat(
await is_ready_to_chat(user) await is_ready_to_chat(user)
conversation_commands = [get_conversation_command(query=q, any_references=True)] conversation_commands = [get_conversation_command(query=q, any_references=True)]
_custom_filters = []
if conversation_commands == [ConversationCommand.Help]: if conversation_commands == [ConversationCommand.Help]:
conversation_config = await ConversationAdapters.aget_user_conversation_config(user) help_str = "/" + ConversationCommand.Help
if conversation_config == None: if q.strip() == help_str:
conversation_config = await ConversationAdapters.aget_default_conversation_config() conversation_config = await ConversationAdapters.aget_user_conversation_config(user)
model_type = conversation_config.model_type if conversation_config == None:
formatted_help = help_message.format(model=model_type, version=state.khoj_version, device=get_device()) conversation_config = await ConversationAdapters.aget_default_conversation_config()
return StreamingResponse(iter([formatted_help]), media_type="text/event-stream", status_code=200) 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( conversation = await ConversationAdapters.aget_conversation_by_user(
user, request.user.client_app, conversation_id, title user, request.user.client_app, conversation_id, title
@@ -856,7 +869,9 @@ async def chat(
conversation_commands.append(ConversationCommand.Webpage) conversation_commands.append(ConversationCommand.Webpage)
else: else:
try: 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: except ValueError as e:
logger.warning(f"Error searching online: {e}. Attempting to respond without online results") 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.Webpage: "Get information from webpage links provided by you.",
ConversationCommand.Image: "Generate images by describing your imagination in words.", ConversationCommand.Image: "Generate images by describing your imagination in words.",
ConversationCommand.Automation: "Automatically run your query at a specified time or interval.", 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 = { tool_descriptions_for_llm = {