diff --git a/src/interface/desktop/chat.html b/src/interface/desktop/chat.html
index 73e88159..68ef9513 100644
--- a/src/interface/desktop/chat.html
+++ b/src/interface/desktop/chat.html
@@ -219,98 +219,44 @@
}
function renderMessageWithReference(message, by, context=null, dt=null, onlineContext=null, intentType=null, inferredQueries=null) {
+ let chatEl;
+ if (intentType?.includes("text-to-image")) {
+ let imageMarkdown = generateImageMarkdown(message, intentType, inferredQueries);
+ chatEl = renderMessage(imageMarkdown, by, dt, null, false, "return");
+ } else {
+ chatEl = renderMessage(message, by, dt, null, false, "return");
+ }
+
// If no document or online context is provided, render the message as is
- if ((context == null || context.length == 0) && (onlineContext == null || (onlineContext && Object.keys(onlineContext).length == 0))) {
- if (intentType?.includes("text-to-image")) {
- let imageMarkdown;
- if (intentType === "text-to-image") {
- imageMarkdown = ``;
- } else if (intentType === "text-to-image2") {
- imageMarkdown = ``;
- } else if (intentType === "text-to-image-v3") {
- imageMarkdown = ``;
- }
-
- const inferredQuery = inferredQueries?.[0];
- if (inferredQuery) {
- imageMarkdown += `\n\n**Inferred Query**:\n\n${inferredQuery}`;
- }
- return renderMessage(imageMarkdown, by, dt, null, false, "return");
- }
-
- return renderMessage(message, by, dt, null, false, "return");
- }
-
- if (context == null && onlineContext == null) {
- return renderMessage(message, by, dt, null, false, "return");
- }
-
- if ((context && context.length == 0) && (onlineContext == null || (onlineContext && Object.keys(onlineContext).length == 0))) {
- return renderMessage(message, by, dt, null, false, "return");
+ if ((context == null || context?.length == 0)
+ && (onlineContext == null || (onlineContext && Object.keys(onlineContext).length == 0))) {
+ return chatEl;
}
// If document or online context is provided, render the message with its references
- let references = document.createElement('div');
+ let references = {};
+ if (!!context) references["notes"] = context;
+ if (!!onlineContext) references["online"] = onlineContext;
+ let chatMessageEl = chatEl.getElementsByClassName("chat-message-text")[0];
+ chatMessageEl.appendChild(createReferenceSection(references));
- let referenceExpandButton = document.createElement('button');
- referenceExpandButton.classList.add("reference-expand-button");
- let numReferences = 0;
+ return chatEl;
+ }
- if (context) {
- numReferences += context.length;
+ function generateImageMarkdown(message, intentType, inferredQueries=null) {
+ let imageMarkdown;
+ if (intentType === "text-to-image") {
+ imageMarkdown = ``;
+ } else if (intentType === "text-to-image2") {
+ imageMarkdown = ``;
+ } else if (intentType === "text-to-image-v3") {
+ imageMarkdown = ``;
}
-
- references.appendChild(referenceExpandButton);
-
- let referenceSection = document.createElement('div');
- referenceSection.classList.add("reference-section");
- referenceSection.classList.add("collapsed");
-
- referenceExpandButton.addEventListener('click', function() {
- if (referenceSection.classList.contains("collapsed")) {
- referenceSection.classList.remove("collapsed");
- referenceSection.classList.add("expanded");
- } else {
- referenceSection.classList.add("collapsed");
- referenceSection.classList.remove("expanded");
- }
- });
-
- references.classList.add("references");
- if (context) {
- for (let index in context) {
- let reference = context[index];
- let polishedReference = generateReference(reference, index);
- referenceSection.appendChild(polishedReference);
- }
+ const inferredQuery = inferredQueries?.[0];
+ if (inferredQuery) {
+ imageMarkdown += `\n\n**Inferred Query**:\n\n${inferredQuery}`;
}
-
- if (onlineContext) {
- numReferences += processOnlineReferences(referenceSection, onlineContext);
- }
-
- let expandButtonText = numReferences == 1 ? "1 reference" : `${numReferences} references`;
- referenceExpandButton.innerHTML = expandButtonText;
-
- references.appendChild(referenceSection);
-
- if (intentType?.includes("text-to-image")) {
- let imageMarkdown;
- if (intentType === "text-to-image") {
- imageMarkdown = ``;
- } else if (intentType === "text-to-image2") {
- imageMarkdown = ``;
- } else if (intentType === "text-to-image-v3") {
- imageMarkdown = ``;
- }
- const inferredQuery = inferredQueries?.[0];
- if (inferredQuery) {
- imageMarkdown += `\n\n**Inferred Query**:\n\n${inferredQuery}`;
- }
- return renderMessage(imageMarkdown, by, dt, references, false, "return");
- }
-
- return renderMessage(message, by, dt, references, false, "return");
+ return imageMarkdown;
}
function formatHTMLMessage(message, raw=false, willReplace=true) {
diff --git a/src/interface/obsidian/src/chat_view.ts b/src/interface/obsidian/src/chat_view.ts
index 4350a608..97149b98 100644
--- a/src/interface/obsidian/src/chat_view.ts
+++ b/src/interface/obsidian/src/chat_view.ts
@@ -172,36 +172,36 @@ export class KhojChatView extends KhojPaneView {
let onlineReference = onlineContext[subquery];
if (onlineReference.organic && onlineReference.organic.length > 0) {
numOnlineReferences += onlineReference.organic.length;
- for (let index in onlineReference.organic) {
- let reference = onlineReference.organic[index];
- let polishedReference = this.generateOnlineReference(referenceSection, reference, index);
+ for (let key in onlineReference.organic) {
+ let reference = onlineReference.organic[key];
+ let polishedReference = this.generateOnlineReference(referenceSection, reference, key);
referenceSection.appendChild(polishedReference);
}
}
if (onlineReference.knowledgeGraph && onlineReference.knowledgeGraph.length > 0) {
numOnlineReferences += onlineReference.knowledgeGraph.length;
- for (let index in onlineReference.knowledgeGraph) {
- let reference = onlineReference.knowledgeGraph[index];
- let polishedReference = this.generateOnlineReference(referenceSection, reference, index);
+ for (let key in onlineReference.knowledgeGraph) {
+ let reference = onlineReference.knowledgeGraph[key];
+ let polishedReference = this.generateOnlineReference(referenceSection, reference, key);
referenceSection.appendChild(polishedReference);
}
}
if (onlineReference.peopleAlsoAsk && onlineReference.peopleAlsoAsk.length > 0) {
numOnlineReferences += onlineReference.peopleAlsoAsk.length;
- for (let index in onlineReference.peopleAlsoAsk) {
- let reference = onlineReference.peopleAlsoAsk[index];
- let polishedReference = this.generateOnlineReference(referenceSection, reference, index);
+ for (let key in onlineReference.peopleAlsoAsk) {
+ let reference = onlineReference.peopleAlsoAsk[key];
+ let polishedReference = this.generateOnlineReference(referenceSection, reference, key);
referenceSection.appendChild(polishedReference);
}
}
if (onlineReference.webpages && onlineReference.webpages.length > 0) {
numOnlineReferences += onlineReference.webpages.length;
- for (let index in onlineReference.webpages) {
- let reference = onlineReference.webpages[index];
- let polishedReference = this.generateOnlineReference(referenceSection, reference, index);
+ for (let key in onlineReference.webpages) {
+ let reference = onlineReference.webpages[key];
+ let polishedReference = this.generateOnlineReference(referenceSection, reference, key);
referenceSection.appendChild(polishedReference);
}
}
@@ -215,14 +215,10 @@ export class KhojChatView extends KhojPaneView {
let title = reference.title || reference.link;
let link = reference.link;
let snippet = reference.snippet;
- let question = reference.question;
- if (question) {
- question = `Question: ${question}
`;
- } else {
- question = "";
- }
+ let question = reference.question ? `Question: ${reference.question}
` : "";
- let linkElement = messageEl.createEl('a');
+ let referenceButton = messageEl.createEl('button');
+ let linkElement = referenceButton.createEl('a');
linkElement.setAttribute('href', link);
linkElement.setAttribute('target', '_blank');
linkElement.setAttribute('rel', 'noopener noreferrer');
@@ -230,8 +226,6 @@ export class KhojChatView extends KhojPaneView {
linkElement.setAttribute('title', title);
linkElement.textContent = title;
- let referenceButton = messageEl.createEl('button');
- referenceButton.innerHTML = linkElement.outerHTML;
referenceButton.id = `ref-${index}`;
referenceButton.classList.add("reference-button");
referenceButton.classList.add("collapsed");
@@ -325,68 +319,53 @@ export class KhojChatView extends KhojPaneView {
return chat_message_body_text_el;
}
- renderMessageWithReferences(chatEl: Element, message: string, sender: string, context?: string[], dt?: Date, intentType?: string, inferredQueries?: string) {
- if (!message) {
- return;
- } else if (intentType?.includes("text-to-image")) {
- let imageMarkdown = "";
- if (intentType === "text-to-image") {
- imageMarkdown = ``;
- } else if (intentType === "text-to-image2") {
- imageMarkdown = ``;
- } else if (intentType === "text-to-image-v3") {
- imageMarkdown = ``;
- }
- if (inferredQueries) {
- imageMarkdown += "\n\n**Inferred Query**:";
- for (let inferredQuery of inferredQueries) {
- imageMarkdown += `\n\n${inferredQuery}`;
- }
- }
- this.renderMessage(chatEl, imageMarkdown, sender, dt);
- return;
- } else if (!context) {
- this.renderMessage(chatEl, message, sender, dt);
- return;
- } else if (!!context && context?.length === 0) {
- this.renderMessage(chatEl, message, sender, dt);
- return;
- }
- let chatMessageEl = this.renderMessage(chatEl, message, sender, dt);
- let chatMessageBodyEl = chatMessageEl.getElementsByClassName("khoj-chat-message-text")[0]
- let references = chatMessageBodyEl.createDiv();
+ renderMessageWithReferences(
+ chatEl: Element,
+ message: string,
+ sender: string,
+ context?: string[],
+ dt?: Date,
+ intentType?: string,
+ inferredQueries?: string[],
+ ) {
+ if (!message) return;
- let referenceExpandButton = references.createEl('button');
- referenceExpandButton.classList.add("reference-expand-button");
- let numReferences = 0;
-
- if (context) {
- numReferences += context.length;
+ let chatMessageEl;
+ if (intentType?.includes("text-to-image")) {
+ let imageMarkdown = this.generateImageMarkdown(message, intentType, inferredQueries);
+ chatMessageEl = this.renderMessage(chatEl, imageMarkdown, sender, dt);
+ } else {
+ chatMessageEl = this.renderMessage(chatEl, message, sender, dt);
}
- let referenceSection = references.createEl('div');
- referenceSection.classList.add("reference-section");
- referenceSection.classList.add("collapsed");
-
- referenceExpandButton.addEventListener('click', function() {
- if (referenceSection.classList.contains("collapsed")) {
- referenceSection.classList.remove("collapsed");
- referenceSection.classList.add("expanded");
- } else {
- referenceSection.classList.add("collapsed");
- referenceSection.classList.remove("expanded");
- }
- });
-
- references.classList.add("references");
- if (context) {
- context.map((reference, index) => {
- this.generateReference(referenceSection, reference, index + 1);
- });
+ // If no document or online context is provided, skip rendering the reference section
+ if (context == null || context.length == 0) {
+ return;
}
- let expandButtonText = numReferences == 1 ? "1 reference" : `${numReferences} references`;
- referenceExpandButton.innerHTML = expandButtonText;
+ // If document or online context is provided, render the message with its references
+ let references: any = {};
+ if (!!context) references["notes"] = context;
+ let chatMessageBodyEl = chatMessageEl.getElementsByClassName("khoj-chat-message-text")[0];
+ chatMessageBodyEl.appendChild(this.createReferenceSection(references));
+ }
+
+ generateImageMarkdown(message: string, intentType: string, inferredQueries?: string[]) {
+ let imageMarkdown = "";
+ if (intentType === "text-to-image") {
+ imageMarkdown = ``;
+ } else if (intentType === "text-to-image2") {
+ imageMarkdown = ``;
+ } else if (intentType === "text-to-image-v3") {
+ imageMarkdown = ``;
+ }
+ if (inferredQueries) {
+ imageMarkdown += "\n\n**Inferred Query**:";
+ for (let inferredQuery of inferredQueries) {
+ imageMarkdown += `\n\n${inferredQuery}`;
+ }
+ }
+ return imageMarkdown;
}
renderMessage(chatEl: Element, message: string, sender: string, dt?: Date, raw: boolean=false, willReplace: boolean=true): Element {
@@ -423,7 +402,7 @@ export class KhojChatView extends KhojPaneView {
// Add button to paste into current buffer
let pasteToFile = chatMessageEl.createEl('button');
pasteToFile.classList.add("copy-button");
- pasteToFile.title = "Paste Message to File";
+ pasteToFile.title = "Paste Message to Current File";
setIcon(pasteToFile, "clipboard-paste");
pasteToFile.addEventListener('click', (event) => { pasteTextAtCursor(createCopyParentText(message, 'clipboard-paste')(event)); });
chat_message_body_text_el.append(pasteToFile);
@@ -435,7 +414,7 @@ export class KhojChatView extends KhojPaneView {
// Scroll to bottom after inserting chat messages
this.scrollChatToBottom();
- return chatMessageEl
+ return chatMessageEl;
}
createKhojResponseDiv(dt?: Date): HTMLDivElement {
@@ -548,41 +527,8 @@ export class KhojChatView extends KhojPaneView {
await this.renderIncrementalMessage(responseElement, additionalResponse);
const rawReferenceAsJson = JSON.parse(rawReference);
- let references = responseElement.createDiv();
- references.classList.add("references");
-
- let referenceExpandButton = references.createEl('button');
- referenceExpandButton.classList.add("reference-expand-button");
-
- let referenceSection = references.createDiv();
- referenceSection.classList.add("reference-section");
- referenceSection.classList.add("collapsed");
-
- let numReferences = 0;
-
- // If rawReferenceAsJson is a list, then count the length
- if (Array.isArray(rawReferenceAsJson)) {
- numReferences = rawReferenceAsJson.length;
-
- rawReferenceAsJson.forEach((reference, index) => {
- this.generateReference(referenceSection, reference, index);
- });
- }
- references.appendChild(referenceExpandButton);
-
- referenceExpandButton.addEventListener('click', function() {
- if (referenceSection.classList.contains("collapsed")) {
- referenceSection.classList.remove("collapsed");
- referenceSection.classList.add("expanded");
- } else {
- referenceSection.classList.add("collapsed");
- referenceSection.classList.remove("expanded");
- }
- });
-
- let expandButtonText = numReferences == 1 ? "1 reference" : `${numReferences} references`;
- referenceExpandButton.innerHTML = expandButtonText;
- references.appendChild(referenceSection);
+ let references = this.extractReferences(rawReferenceAsJson);
+ responseElement.appendChild(this.createReferenceSection(references));
} else {
// Render incremental chat response
await this.renderIncrementalMessage(responseElement, responseText);
@@ -898,18 +844,15 @@ export class KhojChatView extends KhojPaneView {
handleCompiledReferences(rawResponseElement: HTMLElement | null, chunk: string, references: any, rawResponse: string) {
if (!rawResponseElement || !chunk) return { rawResponse, references };
- const additionalResponse = chunk.split("### compiled references:")[0];
+
+ const [additionalResponse, rawReference] = chunk.split("### compiled references:", 2);
rawResponse += additionalResponse;
rawResponseElement.innerHTML = "";
rawResponseElement.appendChild(this.formatHTMLMessage(rawResponse));
- const rawReference = chunk.split("### compiled references:")[1];
const rawReferenceAsJson = JSON.parse(rawReference);
- if (rawReferenceAsJson instanceof Array) {
- references["notes"] = rawReferenceAsJson;
- } else if (typeof rawReferenceAsJson === "object" && rawReferenceAsJson !== null) {
- references["online"] = rawReferenceAsJson;
- }
+ references = this.extractReferences(rawReferenceAsJson);
+
return { rawResponse, references };
}
@@ -929,14 +872,9 @@ export class KhojChatView extends KhojPaneView {
rawResponse += `\n\n**Inferred Query**:\n\n${inferredQuery}`;
}
}
- let references: any = {};
+ let references = {};
if (imageJson.context && imageJson.context.length > 0) {
- const rawReferenceAsJson = imageJson.context;
- if (rawReferenceAsJson instanceof Array) {
- references["notes"] = rawReferenceAsJson;
- } else if (typeof rawReferenceAsJson === "object" && rawReferenceAsJson !== null) {
- references["online"] = rawReferenceAsJson;
- }
+ references = this.extractReferences(imageJson.context);
}
if (imageJson.detail) {
// If response has detail field, response is an error message.
@@ -945,6 +883,14 @@ export class KhojChatView extends KhojPaneView {
return { rawResponse, references };
}
+ extractReferences(rawReferenceAsJson: any): object {
+ let references: any = {};
+ if (rawReferenceAsJson instanceof Array) {
+ references["notes"] = rawReferenceAsJson;
+ }
+ return references;
+ }
+
addMessageToChatBody(rawResponse: string, newResponseElement: HTMLElement | null, references: any) {
if (!newResponseElement) return;
newResponseElement.innerHTML = "";
@@ -1146,7 +1092,6 @@ export class KhojChatView extends KhojPaneView {
// Temporary status message to indicate that Khoj is thinking
let loadingEllipsis = this.createLoadingEllipse();
-
newResponseTextEl.appendChild(loadingEllipsis);
chatBody.scrollTop = chatBody.scrollHeight;
diff --git a/src/khoj/interface/web/chat.html b/src/khoj/interface/web/chat.html
index 95b5e19e..f8f43770 100644
--- a/src/khoj/interface/web/chat.html
+++ b/src/khoj/interface/web/chat.html
@@ -260,93 +260,44 @@ To get started, just start typing below. You can also type / to see a list of co
}
function renderMessageWithReference(message, by, context=null, dt=null, onlineContext=null, intentType=null, inferredQueries=null) {
- // If no document or online context is provided, render the message as is
- if ((context == null || context.length == 0) && (onlineContext == null || (onlineContext && Object.keys(onlineContext).length == 0))) {
- if (intentType?.includes("text-to-image")) {
- let imageMarkdown;
- if (intentType === "text-to-image") {
- imageMarkdown = ``;
- } else if (intentType === "text-to-image2") {
- imageMarkdown = ``;
- } else if (intentType === "text-to-image-v3") {
- imageMarkdown = ``;
- }
- const inferredQuery = inferredQueries?.[0];
- if (inferredQuery) {
- imageMarkdown += `\n\n**Inferred Query**:\n\n${inferredQuery}`;
- }
- return renderMessage(imageMarkdown, by, dt, null, false, "return");
- }
-
- return renderMessage(message, by, dt, null, false, "return");
+ let chatEl;
+ if (intentType?.includes("text-to-image")) {
+ let imageMarkdown = generateImageMarkdown(message, intentType, inferredQueries);
+ chatEl = renderMessage(imageMarkdown, by, dt, null, false, "return");
+ } else {
+ chatEl = renderMessage(message, by, dt, null, false, "return");
}
- if ((context && context.length == 0) && (onlineContext == null || (onlineContext && Object.keys(onlineContext).length == 0))) {
- return renderMessage(message, by, dt, null, false, "return");
+ // If no document or online context is provided, render the message as is
+ if ((context == null || context?.length == 0)
+ && (onlineContext == null || (onlineContext && Object.keys(onlineContext).length == 0))) {
+ return chatEl;
}
// If document or online context is provided, render the message with its references
- let references = document.createElement('div');
+ let references = {};
+ if (!!context) references["notes"] = context;
+ if (!!onlineContext) references["online"] = onlineContext;
+ let chatMessageEl = chatEl.getElementsByClassName("chat-message-text")[0];
+ chatMessageEl.appendChild(createReferenceSection(references));
- let referenceExpandButton = document.createElement('button');
- referenceExpandButton.classList.add("reference-expand-button");
- let numReferences = 0;
+ return chatEl;
+ }
- if (context) {
- numReferences += context.length;
+ function generateImageMarkdown(message, intentType, inferredQueries=null) {
+ let imageMarkdown;
+ if (intentType === "text-to-image") {
+ imageMarkdown = ``;
+ } else if (intentType === "text-to-image2") {
+ imageMarkdown = ``;
+ } else if (intentType === "text-to-image-v3") {
+ imageMarkdown = ``;
}
-
- references.appendChild(referenceExpandButton);
-
- let referenceSection = document.createElement('div');
- referenceSection.classList.add("reference-section");
- referenceSection.classList.add("collapsed");
-
- referenceExpandButton.addEventListener('click', function() {
- if (referenceSection.classList.contains("collapsed")) {
- referenceSection.classList.remove("collapsed");
- referenceSection.classList.add("expanded");
- } else {
- referenceSection.classList.add("collapsed");
- referenceSection.classList.remove("expanded");
- }
- });
-
- references.classList.add("references");
- if (context) {
- for (let index in context) {
- let reference = context[index];
- let polishedReference = generateReference(reference, index);
- referenceSection.appendChild(polishedReference);
- }
+ const inferredQuery = inferredQueries?.[0];
+ if (inferredQuery) {
+ imageMarkdown += `\n\n**Inferred Query**:\n\n${inferredQuery}`;
}
-
- if (onlineContext) {
- numReferences += processOnlineReferences(referenceSection, onlineContext);
- }
-
- let expandButtonText = numReferences == 1 ? "1 reference" : `${numReferences} references`;
- referenceExpandButton.innerHTML = expandButtonText;
-
- references.appendChild(referenceSection);
-
- if (intentType?.includes("text-to-image")) {
- let imageMarkdown;
- if (intentType === "text-to-image") {
- imageMarkdown = ``;
- } else if (intentType === "text-to-image2") {
- imageMarkdown = ``;
- } else if (intentType === "text-to-image-v3") {
- imageMarkdown = ``;
- }
- const inferredQuery = inferredQueries?.[0];
- if (inferredQuery) {
- imageMarkdown += `\n\n**Inferred Query**:\n\n${inferredQuery}`;
- }
- return renderMessage(imageMarkdown, by, dt, references, false, "return");
- }
-
- return renderMessage(message, by, dt, references, false, "return");
+ return imageMarkdown;
}
function formatHTMLMessage(message, raw=false, willReplace=true) {