mirror of
https://github.com/khoaliber/khoj.git
synced 2026-03-09 05:39:12 +00:00
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:
@@ -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;
|
||||||
|
|||||||
@@ -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 {}
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|
||||||
|
|||||||
@@ -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 = {
|
||||||
|
|||||||
Reference in New Issue
Block a user