feat: add turnId handling to chat messages and history

This commit is contained in:
Sam Ho
2025-01-16 00:44:16 +00:00
parent fc6fab4cce
commit f8f159efac

View File

@@ -31,6 +31,7 @@ interface ChatMessageState {
rawResponse: string; rawResponse: string;
rawQuery: string; rawQuery: string;
isVoice: boolean; isVoice: boolean;
turnId: string;
} }
interface Location { interface Location {
@@ -45,6 +46,7 @@ interface RenderMessageOptions {
chatBodyEl: Element; chatBodyEl: Element;
message: string; message: string;
sender: string; sender: string;
turnId?: string;
dt?: Date; dt?: Date;
raw?: boolean; raw?: boolean;
willReplace?: boolean; willReplace?: boolean;
@@ -490,6 +492,7 @@ export class KhojChatView extends KhojPaneView {
chatEl: Element, chatEl: Element,
message: string, message: string,
sender: string, sender: string,
turnId: string,
context?: string[], context?: string[],
onlineContext?: object, onlineContext?: object,
dt?: Date, dt?: Date,
@@ -497,7 +500,7 @@ export class KhojChatView extends KhojPaneView {
inferredQueries?: string[], inferredQueries?: string[],
conversationId?: string, conversationId?: string,
images?: string[], images?: string[],
excalidrawDiagram?: string excalidrawDiagram?: string,
) { ) {
if (!message) return; if (!message) return;
@@ -512,14 +515,16 @@ export class KhojChatView extends KhojPaneView {
chatBodyEl: chatEl, chatBodyEl: chatEl,
message: imageMarkdown, message: imageMarkdown,
sender, sender,
dt dt,
turnId
}); });
} else { } else {
chatMessageEl = this.renderMessage({ chatMessageEl = this.renderMessage({
chatBodyEl: chatEl, chatBodyEl: chatEl,
message, message,
sender, sender,
dt dt,
turnId
}); });
} }
@@ -570,7 +575,7 @@ export class KhojChatView extends KhojPaneView {
return imageMarkdown; return imageMarkdown;
} }
renderMessage({ chatBodyEl, message, sender, dt, raw = false, willReplace = true, isSystemMessage = false }: RenderMessageOptions): Element { renderMessage({ chatBodyEl, message, sender, dt, turnId, raw = false, willReplace = true, isSystemMessage = false }: RenderMessageOptions): Element {
let message_time = this.formatDate(dt ?? new Date()); let message_time = this.formatDate(dt ?? new Date());
// Append message to conversation history HTML element. // Append message to conversation history HTML element.
@@ -578,7 +583,8 @@ export class KhojChatView extends KhojPaneView {
let chatMessageEl = chatBodyEl.createDiv({ let chatMessageEl = chatBodyEl.createDiv({
attr: { attr: {
"data-meta": message_time, "data-meta": message_time,
class: `khoj-chat-message ${sender}` class: `khoj-chat-message ${sender}`,
...(turnId && { "data-turnId": turnId })
}, },
}) })
let chatMessageBodyEl = chatMessageEl.createDiv(); let chatMessageBodyEl = chatMessageEl.createDiv();
@@ -946,6 +952,7 @@ export class KhojChatView extends KhojPaneView {
chatBodyEl, chatBodyEl,
chatLog.message, chatLog.message,
chatLog.by, chatLog.by,
chatLog.turnId,
chatLog.context, chatLog.context,
chatLog.onlineContext, chatLog.onlineContext,
new Date(chatLog.created), new Date(chatLog.created),
@@ -1025,7 +1032,7 @@ export class KhojChatView extends KhojPaneView {
this.textToSpeech(this.chatMessageState.rawResponse); this.textToSpeech(this.chatMessageState.rawResponse);
// Append any references after all the data has been streamed // Append any references after all the data has been streamed
this.finalizeChatBodyResponse(this.chatMessageState.references, this.chatMessageState.newResponseTextEl); this.finalizeChatBodyResponse(this.chatMessageState.references, this.chatMessageState.newResponseTextEl, this.chatMessageState.turnId);
const liveQuery = this.chatMessageState.rawQuery; const liveQuery = this.chatMessageState.rawQuery;
// Reset variables // Reset variables
@@ -1038,6 +1045,7 @@ export class KhojChatView extends KhojPaneView {
rawQuery: liveQuery, rawQuery: liveQuery,
isVoice: false, isVoice: false,
generatedAssets: "", generatedAssets: "",
turnId: "",
}; };
} else if (chunk.type === "references") { } else if (chunk.type === "references") {
this.chatMessageState.references = { "notes": chunk.data.context, "online": chunk.data.onlineContext }; this.chatMessageState.references = { "notes": chunk.data.context, "online": chunk.data.onlineContext };
@@ -1059,6 +1067,12 @@ export class KhojChatView extends KhojPaneView {
this.chatMessageState.rawResponse += chunkData; this.chatMessageState.rawResponse += chunkData;
this.handleStreamResponse(this.chatMessageState.newResponseTextEl, this.chatMessageState.rawResponse + this.chatMessageState.generatedAssets, this.chatMessageState.loadingEllipsis); this.handleStreamResponse(this.chatMessageState.newResponseTextEl, this.chatMessageState.rawResponse + this.chatMessageState.generatedAssets, this.chatMessageState.loadingEllipsis);
} }
} else if (chunk.type === "metadata") {
const { turnId } = chunk.data;
if (turnId) {
// Append turnId to chatMessageState
this.chatMessageState.turnId = turnId;
}
} }
} }
@@ -1164,6 +1178,7 @@ export class KhojChatView extends KhojPaneView {
rawResponse: "", rawResponse: "",
isVoice: isVoice, isVoice: isVoice,
generatedAssets: "", generatedAssets: "",
turnId: "",
}; };
let response = await fetch(chatUrl, { let response = await fetch(chatUrl, {
@@ -1466,10 +1481,15 @@ export class KhojChatView extends KhojPaneView {
return rawResponse; return rawResponse;
} }
finalizeChatBodyResponse(references: object, newResponseElement: HTMLElement | null) { finalizeChatBodyResponse(references: object, newResponseElement: HTMLElement | null, turnId: string) {
if (!!newResponseElement && references != null && Object.keys(references).length > 0) { if (!!newResponseElement && references != null && Object.keys(references).length > 0) {
newResponseElement.appendChild(this.createReferenceSection(references)); newResponseElement.appendChild(this.createReferenceSection(references));
} }
if (!!newResponseElement && turnId) {
// Set the turnId for the new response and the previous user message
newResponseElement.parentElement?.setAttribute("data-turnId", turnId);
newResponseElement.parentElement?.previousElementSibling?.setAttribute("data-turnId", turnId);
}
this.scrollChatToBottom(); this.scrollChatToBottom();
let chatInput = this.contentEl.getElementsByClassName("khoj-chat-input")[0]; let chatInput = this.contentEl.getElementsByClassName("khoj-chat-input")[0];
if (chatInput) chatInput.removeAttribute("disabled"); if (chatInput) chatInput.removeAttribute("disabled");
@@ -1544,8 +1564,8 @@ export class KhojChatView extends KhojPaneView {
const chatBodyEl = this.contentEl.getElementsByClassName("khoj-chat-body")[0] as HTMLElement; const chatBodyEl = this.contentEl.getElementsByClassName("khoj-chat-body")[0] as HTMLElement;
const conversationId = chatBodyEl.dataset.conversationId; const conversationId = chatBodyEl.dataset.conversationId;
// Get the turn_id from the message's data-meta attribute // Get the turnId from the message's data-turn attribute
const turnId = messageEl.getAttribute("data-meta"); const turnId = messageEl.getAttribute("data-turnId");
if (!turnId || !conversationId) return; if (!turnId || !conversationId) return;
try { try {