From 218946edda7a4757aa23d330b6a6c69c167e7723 Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Wed, 23 Oct 2024 02:56:03 -0700 Subject: [PATCH 1/2] Fix copying message with user images on web app Adding div elements to message to render degraded text copied to clipboard for messages with user uploaded images. This change fixes that by separating message to render from message for clipboard. It ensures differently formatted forms of the user images are added to the two to allow proper rendering while still having decently formatted text copied to clipboard --- .../components/chatMessage/chatMessage.tsx | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/interface/web/app/components/chatMessage/chatMessage.tsx b/src/interface/web/app/components/chatMessage/chatMessage.tsx index 77eaf64a..192f3097 100644 --- a/src/interface/web/app/components/chatMessage/chatMessage.tsx +++ b/src/interface/web/app/components/chatMessage/chatMessage.tsx @@ -327,6 +327,7 @@ const ChatMessage = forwardRef((props, ref) => }, [messageRef.current]); useEffect(() => { + // Prepare initial message for rendering let message = props.chatMessage.message; if (props.chatMessage.intent && props.chatMessage.intent.type == "excalidraw") { @@ -341,29 +342,15 @@ const ChatMessage = forwardRef((props, ref) => .replace(/\\\[/g, "LEFTBRACKET") .replace(/\\\]/g, "RIGHTBRACKET"); - if (props.chatMessage.images && props.chatMessage.images.length > 0) { - const imagesInMd = props.chatMessage.images - .map((image, index) => { - const decodedImage = image.startsWith("data%3Aimage") - ? decodeURIComponent(image) - : image; - const sanitizedImage = DOMPurify.sanitize(decodedImage); - return `
uploaded image ${index + 1}
`; - }) - .join(""); - message = `
${imagesInMd}
${message}`; - } - const intentTypeHandlers = { "text-to-image": (msg: string) => `![generated image](data:image/png;base64,${msg})`, "text-to-image2": (msg: string) => `![generated image](${msg})`, "text-to-image-v3": (msg: string) => `![generated image](data:image/webp;base64,${msg})`, - excalidraw: (msg: string) => { - return msg; - }, + excalidraw: (msg: string) => msg, }; + // Handle intent-specific rendering if (props.chatMessage.intent) { const { type, "inferred-queries": inferredQueries } = props.chatMessage.intent; @@ -376,11 +363,36 @@ const ChatMessage = forwardRef((props, ref) => message += `\n\n${inferredQueries[0]}`; } } + // Handle user attached images rendering + let messageForClipboard = message; + let messageToRender = message; + if (props.chatMessage.images && props.chatMessage.images.length > 0) { + const sanitizedImages = props.chatMessage.images.map((image) => { + const decodedImage = image.startsWith("data%3Aimage") + ? decodeURIComponent(image) + : image; + return DOMPurify.sanitize(decodedImage); + }); + const imagesInMd = sanitizedImages + .map((sanitizedImage, index) => { + return `![uploaded image ${index + 1}](${sanitizedImage})`; + }) + .join("\n"); + const imagesInHtml = sanitizedImages + .map((sanitizedImage, index) => { + return `
uploaded image ${index + 1}
`; + }) + .join(""); + const userImagesInHtml = `
${imagesInHtml}
`; + messageForClipboard = `${imagesInMd}\n\n${messageForClipboard}`; + messageToRender = `${userImagesInHtml}${messageToRender}`; + } - setTextRendered(message); + // Set the message text + setTextRendered(messageForClipboard); // Render the markdown - let markdownRendered = md.render(message); + let markdownRendered = md.render(messageToRender); // Replace placeholders with LaTeX delimiters markdownRendered = markdownRendered From 9f2c02d9f7db096f7a9b4a193300310e3000f241 Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Wed, 23 Oct 2024 03:43:57 -0700 Subject: [PATCH 2/2] Chat with the default agent by default from web app home Had temporarily updated the default selected agent to last used. Revert for now as 1. The previous logic was buggy. It didn't select the default agent even when the last used agent was the default agent. Which would require more work. 2. It maybe too early anyway to set the default agent to last used. --- src/interface/web/app/page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interface/web/app/page.tsx b/src/interface/web/app/page.tsx index 5c593401..b570e86c 100644 --- a/src/interface/web/app/page.tsx +++ b/src/interface/web/app/page.tsx @@ -132,8 +132,8 @@ function ChatBodyData(props: ChatBodyDataProps) { useEffect(() => { const agents = (agentsData || []).filter((agent) => agent !== null && agent !== undefined); setAgents(agents); - // set the selected agent to the most recently used agent, first agent is always khoj - setSelectedAgent(agents.length > 1 ? agents[1].slug : "khoj"); + // set the first agent, which is always the default agent, as the default for chat + setSelectedAgent(agents.length > 1 ? agents[0].slug : "khoj"); // generate colored icons for the available agents const agentIcons = agents.map((agent) => getIconFromIconName(agent.icon, agent.color)!);