mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-11-19 04:30:10 +01:00
add codeblock support for prompt replies and historical messages (#55)
* add codeblock support for prompt replies and historical messages add markdown-it * Fix spacing for HTML rendering
This commit is contained in:
parent
bd32f97a21
commit
2403806949
7662
frontend/package-lock.json
generated
Normal file
7662
frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,7 @@
|
|||||||
"@metamask/jazzicon": "^2.0.0",
|
"@metamask/jazzicon": "^2.0.0",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"he": "^1.2.0",
|
"he": "^1.2.0",
|
||||||
|
"markdown-it": "^13.0.1",
|
||||||
"pluralize": "^8.0.0",
|
"pluralize": "^8.0.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-device-detect": "^2.2.2",
|
"react-device-detect": "^2.2.2",
|
||||||
|
@ -119,9 +119,7 @@ export default function ManageWorkspace({ hideModal = noop, workspace }) {
|
|||||||
setSelectFiles([...new Set(updatedDocs)]);
|
setSelectFiles([...new Set(updatedDocs)]);
|
||||||
} else {
|
} else {
|
||||||
var newDocs = [];
|
var newDocs = [];
|
||||||
var parentDirs = directories.items.find(
|
var parentDirs = directories.items.find((item) => item.name === parent);
|
||||||
(item) => item.name === parent
|
|
||||||
)
|
|
||||||
if (isFolder && parentDirs) {
|
if (isFolder && parentDirs) {
|
||||||
const folderItems = parentDirs.items;
|
const folderItems = parentDirs.items;
|
||||||
newDocs = folderItems.map((item) => parent + "/" + item.name);
|
newDocs = folderItems.map((item) => parent + "/" + item.name);
|
||||||
|
@ -3,6 +3,7 @@ import { AlertTriangle } from "react-feather";
|
|||||||
import Jazzicon from "../../../../UserIcon";
|
import Jazzicon from "../../../../UserIcon";
|
||||||
import { v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
import { decode as HTMLDecode } from "he";
|
import { decode as HTMLDecode } from "he";
|
||||||
|
import renderMarkdown from "../../../../../utils/chat/markdown";
|
||||||
|
|
||||||
function HistoricalMessage({
|
function HistoricalMessage({
|
||||||
message,
|
message,
|
||||||
@ -52,9 +53,10 @@ function HistoricalMessage({
|
|||||||
<div ref={replyRef} className="flex justify-start items-end mb-4">
|
<div ref={replyRef} className="flex justify-start items-end mb-4">
|
||||||
<Jazzicon size={30} user={{ uid: workspace.slug }} />
|
<Jazzicon size={30} user={{ uid: workspace.slug }} />
|
||||||
<div className="ml-2 py-3 px-4 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-t-2xl rounded-br-2xl rounded-bl-sm">
|
<div className="ml-2 py-3 px-4 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-t-2xl rounded-br-2xl rounded-bl-sm">
|
||||||
<span className="whitespace-pre-line text-slate-800 dark:text-slate-200 font-semibold">
|
<span
|
||||||
{message}
|
className="whitespace-pre-line text-slate-800 dark:text-slate-200 font-semibold flex flex-col gap-y-1"
|
||||||
</span>
|
dangerouslySetInnerHTML={{ __html: renderMarkdown(message) }}
|
||||||
|
/>
|
||||||
<Citations sources={sources} />
|
<Citations sources={sources} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { memo, useEffect, useRef, useState } from "react";
|
import { memo, useEffect, useRef, useState } from "react";
|
||||||
import { AlertTriangle } from "react-feather";
|
import { AlertTriangle } from "react-feather";
|
||||||
import Jazzicon from "../../../../UserIcon";
|
import Jazzicon from "../../../../UserIcon";
|
||||||
import { decode as HTMLDecode } from "he";
|
|
||||||
import { v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
|
import { decode as HTMLDecode } from "he";
|
||||||
|
import renderMarkdown from "../../../../../utils/chat/markdown";
|
||||||
|
|
||||||
function PromptReply({
|
function PromptReply({
|
||||||
uuid,
|
uuid,
|
||||||
@ -54,14 +55,14 @@ function PromptReply({
|
|||||||
<div
|
<div
|
||||||
key={uuid}
|
key={uuid}
|
||||||
ref={replyRef}
|
ref={replyRef}
|
||||||
className="chat__message mb-4 flex justify-start items-end"
|
className="mb-4 flex justify-start items-end"
|
||||||
>
|
>
|
||||||
<Jazzicon size={30} user={{ uid: workspace.slug }} />
|
<Jazzicon size={30} user={{ uid: workspace.slug }} />
|
||||||
<div className="ml-2 py-3 px-4 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-t-2xl rounded-br-2xl rounded-bl-sm">
|
<div className="ml-2 py-3 px-4 max-w-[75%] bg-orange-100 dark:bg-stone-700 rounded-t-2xl rounded-br-2xl rounded-bl-sm">
|
||||||
<p className="text-[15px] whitespace-pre-line break-words text-slate-800 dark:text-slate-200 font-semibold">
|
<span
|
||||||
{reply}
|
className="whitespace-pre-line text-slate-800 dark:text-slate-200 font-semibold flex flex-col gap-y-1"
|
||||||
{!closed && <i className="not-italic blink">|</i>}
|
dangerouslySetInnerHTML={{ __html: renderMarkdown(reply) }}
|
||||||
</p>
|
/>
|
||||||
<Citations sources={sources} />
|
<Citations sources={sources} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
36
frontend/src/utils/chat/markdown.js
Normal file
36
frontend/src/utils/chat/markdown.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { encode as HTMLEncode } from "he";
|
||||||
|
import markdownIt from "markdown-it";
|
||||||
|
const markdown = markdownIt({
|
||||||
|
html: true,
|
||||||
|
typographer: true,
|
||||||
|
highlight: function (str) {
|
||||||
|
return `<div class="whitespace-pre-line w-fit rounded-lg bg-black-900 px-4 pt-10 pb-4 relative font-mono font-normal text-sm text-slate-200"><div class="w-full flex items-center absolute top-0 left-0 text-slate-200 bg-stone-800 px-4 py-2 text-xs font-sans justify-between rounded-t-md"><button onclick='window.copySnippet();' class="flex ml-auto gap-2"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg>Copy code</button></div><pre class='markdown'>${HTMLEncode(
|
||||||
|
str
|
||||||
|
)}<pre></div>`;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
window.copySnippet = function () {
|
||||||
|
if (!event?.target) return false;
|
||||||
|
|
||||||
|
const target = event?.target;
|
||||||
|
const markdown =
|
||||||
|
target.parentElement?.parentElement?.querySelector(".markdown")?.innerText;
|
||||||
|
if (!markdown) return false;
|
||||||
|
|
||||||
|
window.navigator.clipboard.writeText(markdown);
|
||||||
|
target.classList.add("text-green-500");
|
||||||
|
const originalText = target.innerHTML;
|
||||||
|
target.innerText = "Copied!";
|
||||||
|
target.setAttribute("disabled", true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
target.classList.remove("text-green-500");
|
||||||
|
target.innerHTML = originalText;
|
||||||
|
target.removeAttribute("disabled");
|
||||||
|
}, 5000);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function renderMarkdown(text) {
|
||||||
|
return markdown.render(text);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -61,11 +61,13 @@ apiRouter.post("/v/:command", async (request, response) => {
|
|||||||
app.use("/api", apiRouter);
|
app.use("/api", apiRouter);
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== "development") {
|
if (process.env.NODE_ENV !== "development") {
|
||||||
app.use(express.static(path.resolve(__dirname, 'public'), {extensions: ["js"]}));
|
app.use(
|
||||||
|
express.static(path.resolve(__dirname, "public"), { extensions: ["js"] })
|
||||||
|
);
|
||||||
|
|
||||||
app.use("/", function (_, response) {
|
app.use("/", function (_, response) {
|
||||||
response.sendFile(path.join(__dirname, "public", "index.html"));
|
response.sendFile(path.join(__dirname, "public", "index.html"));
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
app.all("*", function (_, response) {
|
app.all("*", function (_, response) {
|
||||||
|
@ -26,7 +26,8 @@ function curateLanceSources(sources = []) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const LanceDb = {
|
const LanceDb = {
|
||||||
uri: `${!!process.env.STORAGE_DIR ? `${process.env.STORAGE_DIR}/` : "./storage/"
|
uri: `${
|
||||||
|
!!process.env.STORAGE_DIR ? `${process.env.STORAGE_DIR}/` : "./storage/"
|
||||||
}lancedb`,
|
}lancedb`,
|
||||||
name: "LanceDb",
|
name: "LanceDb",
|
||||||
connect: async function () {
|
connect: async function () {
|
||||||
|
Loading…
Reference in New Issue
Block a user