From 3096544cf20fb37cc5838433471850ea18e293b2 Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Wed, 22 Nov 2023 03:13:53 -0800 Subject: [PATCH 1/4] Create API endpoint to clear user's chat history --- src/khoj/database/adapters/__init__.py | 4 ++++ src/khoj/routers/api.py | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/khoj/database/adapters/__init__.py b/src/khoj/database/adapters/__init__.py index ea0c0a85..9b820ea9 100644 --- a/src/khoj/database/adapters/__init__.py +++ b/src/khoj/database/adapters/__init__.py @@ -232,6 +232,10 @@ class ConversationAdapters: return await conversation.afirst() return await Conversation.objects.acreate(user=user) + @staticmethod + async def adelete_conversation_by_user(user: KhojUser): + return await Conversation.objects.filter(user=user).adelete() + @staticmethod def has_any_conversation_config(user: KhojUser): return ChatModelOptions.objects.filter(user=user).exists() diff --git a/src/khoj/routers/api.py b/src/khoj/routers/api.py index f2e5c966..66ec75d5 100644 --- a/src/khoj/routers/api.py +++ b/src/khoj/routers/api.py @@ -534,6 +534,27 @@ def chat_history( return {"status": "ok", "response": meta_log.get("chat", [])} +@api.delete("/chat/history") +@requires(["authenticated"]) +async def clear_chat_history( + request: Request, + common: CommonQueryParams, +): + user = request.user.object + + # Clear Conversation History + await ConversationAdapters.adelete_conversation_by_user(user) + + update_telemetry_state( + request=request, + telemetry_type="api", + api="clear_chat_history", + **common.__dict__, + ) + + return {"status": "ok", "message": "Conversation history cleared"} + + @api.get("/chat/options", response_class=Response) @requires(["authenticated"]) async def chat_options( From d5a4830761f2c68ebb5473271b7aa830c48abeea Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Wed, 22 Nov 2023 03:18:29 -0800 Subject: [PATCH 2/4] Clear Conversation History from the Desktop Client --- .../desktop/assets/icons/trash-solid.svg | 1 + src/interface/desktop/chat.html | 63 +++++++++++++++++-- 2 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 src/interface/desktop/assets/icons/trash-solid.svg diff --git a/src/interface/desktop/assets/icons/trash-solid.svg b/src/interface/desktop/assets/icons/trash-solid.svg new file mode 100644 index 00000000..768d80f8 --- /dev/null +++ b/src/interface/desktop/assets/icons/trash-solid.svg @@ -0,0 +1 @@ + diff --git a/src/interface/desktop/chat.html b/src/interface/desktop/chat.html index 4997ef99..8b77fe22 100644 --- a/src/interface/desktop/chat.html +++ b/src/interface/desktop/chat.html @@ -377,6 +377,32 @@ chat(); } } + + async function clearConversationHistory() { + let chatInput = document.getElementById("chat-input"); + let originalPlaceholder = chatInput.placeholder; + let chatBody = document.getElementById("chat-body"); + + const hostURL = await window.hostURLAPI.getURL(); + const khojToken = await window.tokenAPI.getToken(); + const headers = { 'Authorization': `Bearer ${khojToken}` }; + + fetch(`${hostURL}/api/chat/history?client=desktop`, { method: "DELETE", headers }) + .then(response => response.ok ? response.json() : Promise.reject(response)) + .then(data => { + chatBody.innerHTML = ""; + loadChat(); + chatInput.placeholder = "Cleared conversation history"; + }) + .catch(err => { + chatInput.placeholder = "Failed to clear conversation history"; + }) + .finally(() => { + setTimeout(() => { + chatInput.placeholder = originalPlaceholder; + }, 2000); + }); + }
@@ -400,7 +426,12 @@ @@ -514,15 +545,17 @@ #chat-footer { padding: 0; + margin: 8px; display: grid; grid-template-columns: minmax(70px, 100%); grid-column-gap: 10px; grid-row-gap: 10px; } - #chat-footer > * { - padding: 15px; - border-radius: 5px; - border: 1px solid #475569; + #input-row { + display: grid; + grid-template-columns: auto 32px; + grid-column-gap: 10px; + grid-row-gap: 10px; background: #f9fafc } .option:hover { @@ -543,6 +576,26 @@ #chat-input:focus { outline: none !important; } + .input-row-button { + background: var(--background-color); + border: none; + border-radius: 5px; + padding: 5px; + font-size: 14px; + font-weight: 300; + line-height: 1.5em; + cursor: pointer; + transition: background 0.3s ease-in-out; + } + .input-row-button:hover { + background: var(--primary-hover); + } + .input-row-button:active { + background: var(--primary-active); + } + .input-row-button-img { + width: 24px; + } .option-enabled { box-shadow: 0 0 12px rgb(119, 156, 46); From fd60db766e917a70d6248f06f6d7c1f18ca99f11 Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Wed, 22 Nov 2023 03:20:12 -0800 Subject: [PATCH 3/4] Clear Conversation History from the Web Client --- src/khoj/interface/web/chat.html | 63 +++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/src/khoj/interface/web/chat.html b/src/khoj/interface/web/chat.html index 1c661a92..d1b85cd3 100644 --- a/src/khoj/interface/web/chat.html +++ b/src/khoj/interface/web/chat.html @@ -322,7 +322,9 @@ To get started, just start typing below. You can also type / to see a list of co document.getElementById("chat-body").scrollTop = document.getElementById("chat-body").scrollHeight; } - window.onload = function () { + window.onload = loadChat; + + function loadChat() { fetch('/api/chat/history?client=web') .then(response => response.json()) .then(data => { @@ -369,6 +371,28 @@ To get started, just start typing below. You can also type / to see a list of co chat(); } } + + function clearConversationHistory() { + let chatInput = document.getElementById("chat-input"); + let originalPlaceholder = chatInput.placeholder; + let chatBody = document.getElementById("chat-body"); + + fetch(`/api/chat/history?client=web`, { method: "DELETE" }) + .then(response => response.ok ? response.json() : Promise.reject(response)) + .then(data => { + chatBody.innerHTML = ""; + loadChat(); + chatInput.placeholder = "Cleared conversation history"; + }) + .catch(err => { + chatInput.placeholder = "Failed to clear conversation history"; + }) + .finally(() => { + setTimeout(() => { + chatInput.placeholder = originalPlaceholder; + }, 2000); + }); + }
@@ -384,7 +408,12 @@ To get started, just start typing below. You can also type / to see a list of co