From d8386c6e58dd6f117a7a058a17175acccc48dfdc Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Wed, 17 Jul 2024 16:34:55 +0200 Subject: [PATCH] Fix incorrect path --- on-device-ai/chat.js | 2 +- on-device-ai/dist/chat.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/on-device-ai/chat.js b/on-device-ai/chat.js index dce5a7d..7e2b135 100644 --- a/on-device-ai/chat.js +++ b/on-device-ai/chat.js @@ -1,4 +1,4 @@ -import { Init, Query, Abort } from "./main.js"; +import { Init, Query, Abort } from "./model.js"; import { marked } from "marked"; const preCannedQueries = { diff --git a/on-device-ai/dist/chat.js b/on-device-ai/dist/chat.js index b60a7ab..6fdaf63 100644 --- a/on-device-ai/dist/chat.js +++ b/on-device-ai/dist/chat.js @@ -194,7 +194,7 @@ eval("/* (ignored) */\n\n//# sourceURL=webpack://localchat/url_(ignored)?"); \*****************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _model_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./model.js */ \"./model.js\");\n/* harmony import */ var marked__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! marked */ \"./node_modules/marked/lib/marked.esm.js\");\n\r\n\r\n\r\nconst clipboardIcon = `\r\n\r\n\r\n`;\r\n\r\nmarked__WEBPACK_IMPORTED_MODULE_1__.marked.use({ mangle: false, headerIds: false });\r\n\r\nconst sendButton = document.getElementById(\"send-button\");\r\nconst scrollWrapper = document.getElementById(\"scroll-wrapper\");\r\nconst userInput = document.getElementById(\"user-input\");\r\nconst status = document.getElementById(\"status\");\r\nconst chatContainer = document.getElementById(\"chat-container\");\r\nconst chatHistory = document.getElementById(\"chat-history\");\r\n\r\nlet context = undefined;\r\nlet isResponding = false;\r\n\r\n//\r\n// auto scroll the content area until a user scrolls up\r\n//\r\nlet isAutoScrollOn = true;\r\nlet lastKnownScrollPosition = 0;\r\nlet ticking = false;\r\n\r\nconst autoScroller = new ResizeObserver(() => {\r\n if (isAutoScrollOn) {\r\n scrollWrapper.scrollIntoView({ behavior: \"smooth\", block: \"end\" });\r\n }\r\n});\r\n\r\ndocument.addEventListener(\"scroll\", () => {\r\n if (!ticking && isAutoScrollOn && window.scrollY < lastKnownScrollPosition) {\r\n window.requestAnimationFrame(() => {\r\n isAutoScrollOn = false;\r\n ticking = false;\r\n });\r\n ticking = true;\r\n } else if (\r\n !ticking &&\r\n !isAutoScrollOn &&\r\n window.scrollY > lastKnownScrollPosition &&\r\n window.scrollY >=\r\n document.documentElement.scrollHeight - window.innerHeight - 30\r\n ) {\r\n window.requestAnimationFrame(() => {\r\n isAutoScrollOn = true;\r\n ticking = false;\r\n });\r\n ticking = true;\r\n }\r\n lastKnownScrollPosition = window.scrollY;\r\n});\r\n\r\n//\r\n// make response available for copying to clipboard\r\n//\r\nfunction copyTextToClipboard(responseDiv) {\r\n let elem = responseDiv;\r\n const copyButton = document.createElement(\"button\");\r\n copyButton.className = \"btn btn-secondary copy-button\";\r\n copyButton.innerHTML = clipboardIcon;\r\n elem = copyButton;\r\n elem.onclick = () => {\r\n navigator.clipboard.writeText(responseDiv.innerText);\r\n };\r\n responseDiv.appendChild(elem);\r\n}\r\n\r\nasync function submitRequest(isContinuation) {\r\n if (isResponding) {\r\n (0,_model_js__WEBPACK_IMPORTED_MODULE_0__.Abort)();\r\n isResponding = false;\r\n return;\r\n }\r\n\r\n chatContainer.style.display = \"block\";\r\n\r\n let input = userInput.value;\r\n if (!isContinuation) {\r\n chatHistory.context = \"\";\r\n while (chatHistory.firstChild) {\r\n chatHistory.firstChild.remove();\r\n }\r\n }\r\n\r\n if (context === undefined) {\r\n context = \"\";\r\n }\r\n\r\n // append to chat history\r\n const userMessageDiv = document.createElement(\"div\");\r\n userMessageDiv.className = \"mb-2 user-message\";\r\n userMessageDiv.innerText = input;\r\n chatHistory.appendChild(userMessageDiv);\r\n\r\n // container for llm response\r\n const responseDiv = document.createElement(\"div\");\r\n responseDiv.className = \"response-message mb-2 text-start\";\r\n responseDiv.style.minHeight = \"3em\";\r\n\r\n const spinner = document.createElement(\"div\");\r\n spinner.className = \"spinner-border text-light\";\r\n spinner.setAttribute(\"role\", \"status\");\r\n responseDiv.appendChild(spinner);\r\n chatHistory.appendChild(responseDiv);\r\n\r\n // toggle button to stop text generation\r\n sendButton.innerHTML = \"Stop\";\r\n\r\n // change autoScroller to keep track of our new responseDiv\r\n autoScroller.observe(responseDiv);\r\n\r\n if (isContinuation) {\r\n input = context + \" \" + input;\r\n } else {\r\n input = `<|system|>\\nYou are a friendly assistant.<|end|>\\n<|user|>\\n${input}<|end|>\\n<|assistant|>\\n`;\r\n }\r\n\r\n isResponding = true;\r\n (0,_model_js__WEBPACK_IMPORTED_MODULE_0__.Query)(input, (word) => {\r\n console.log(word);\r\n responseDiv.innerHTML = marked__WEBPACK_IMPORTED_MODULE_1__.marked.parse(word);\r\n })\r\n .then(() => {\r\n context = responseDiv.textContent;\r\n copyTextToClipboard(responseDiv, true);\r\n sendButton.innerHTML = \"Send\";\r\n spinner.remove();\r\n isResponding = false;\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n sendButton.innerHTML = \"Send\";\r\n spinner.remove();\r\n });\r\n\r\n // Clear user input\r\n userInput.value = \"\";\r\n}\r\n\r\n// Wait for the page to load.\r\nwindow.onload = async () => {\r\n // Initialize the model.\r\n await (0,_model_js__WEBPACK_IMPORTED_MODULE_0__.Init)();\r\n\r\n // Once ready, hide the debug status messages.\r\n status.style.display = \"none\";\r\n\r\n // Focus the input field.\r\n userInput.focus();\r\n\r\n // And start listening to events in the input field and button.\r\n sendButton.addEventListener(\"click\", submitRequest);\r\n userInput.addEventListener(\"keydown\", (e) => {\r\n if (e.key !== \"Enter\") {\r\n return;\r\n }\r\n\r\n e.preventDefault();\r\n \r\n const hasCtrlKey = e.ctrlKey;\r\n const hasConversationStarted = context !== undefined;\r\n submitRequest(!hasCtrlKey && hasConversationStarted);\r\n });\r\n};\r\n\n\n//# sourceURL=webpack://localchat/./chat.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _model_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./model.js */ \"./model.js\");\n/* harmony import */ var marked__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! marked */ \"./node_modules/marked/lib/marked.esm.js\");\n\r\n\r\n\r\nconst preCannedQueries = {\r\n 1: \"Tell me about the lighthouse of Alexandria.\",\r\n 2: \"Did the lighthouse of Alexandria existed at the same time the library of Alexandria existed?\",\r\n 3: \"How did the Pharos lighthouse impact ancient maritime trade?\",\r\n 4: \"Tell me about Constantinople.\",\r\n};\r\n\r\nconst clipboardIcon = `\r\n\r\n\r\n`;\r\n\r\nmarked__WEBPACK_IMPORTED_MODULE_1__.marked.use({ mangle: false, headerIds: false });\r\n\r\nconst sendButton = document.getElementById(\"send-button\");\r\nconst scrollWrapper = document.getElementById(\"scroll-wrapper\");\r\n\r\n//\r\n// auto scroll the content area until a user scrolls up\r\n//\r\nlet isAutoScrollOn = true;\r\nlet lastKnownScrollPosition = 0;\r\nlet ticking = false;\r\n\r\nconst autoScroller = new ResizeObserver(() => {\r\n if (isAutoScrollOn) {\r\n scrollWrapper.scrollIntoView({ behavior: \"smooth\", block: \"end\" });\r\n }\r\n});\r\n\r\ndocument.addEventListener(\"scroll\", () => {\r\n if (!ticking && isAutoScrollOn && window.scrollY < lastKnownScrollPosition) {\r\n window.requestAnimationFrame(() => {\r\n isAutoScrollOn = false;\r\n ticking = false;\r\n });\r\n ticking = true;\r\n } else if (\r\n !ticking &&\r\n !isAutoScrollOn &&\r\n window.scrollY > lastKnownScrollPosition &&\r\n window.scrollY >=\r\n document.documentElement.scrollHeight - window.innerHeight - 30\r\n ) {\r\n window.requestAnimationFrame(() => {\r\n isAutoScrollOn = true;\r\n ticking = false;\r\n });\r\n ticking = true;\r\n }\r\n lastKnownScrollPosition = window.scrollY;\r\n});\r\n\r\n//\r\n// make response available for copying to clipboard\r\n//\r\nfunction copyTextToClipboard(responseDiv) {\r\n let elem = responseDiv;\r\n const copyButton = document.createElement(\"button\");\r\n copyButton.className = \"btn btn-secondary copy-button\";\r\n copyButton.innerHTML = clipboardIcon;\r\n elem = copyButton;\r\n elem.onclick = () => {\r\n navigator.clipboard.writeText(responseDiv.innerText);\r\n };\r\n responseDiv.appendChild(elem);\r\n}\r\n\r\n//\r\n// user hits send, enter or ctl enter\r\n//\r\nasync function submitRequest(e) {\r\n if (sendButton.innerHTML == \"Stop\") {\r\n (0,_model_js__WEBPACK_IMPORTED_MODULE_0__.Abort)();\r\n return;\r\n }\r\n\r\n // enter clears the chat history, ctl enter will continue the conversation\r\n const continuation = e.ctrlKey && e.key === \"Enter\";\r\n\r\n document.getElementById(\"chat-container\").style.display = \"block\";\r\n\r\n let input = document.getElementById(\"user-input\").value;\r\n if (input.length == 0) {\r\n document.getElementById(\"chat-history\").context = \"\";\r\n let chatHistory = document.getElementById(\"chat-history\");\r\n while (chatHistory.firstChild) {\r\n chatHistory.firstChild.remove();\r\n }\r\n return;\r\n }\r\n let context = document.getElementById(\"chat-history\").context;\r\n if (context === undefined) {\r\n context = \"\";\r\n }\r\n\r\n // append to chat history\r\n let chatHistory = document.getElementById(\"chat-history\");\r\n let userMessageDiv = document.createElement(\"div\");\r\n userMessageDiv.className = \"mb-2 user-message\";\r\n userMessageDiv.innerText = input;\r\n chatHistory.appendChild(userMessageDiv);\r\n\r\n // container for llm response\r\n let responseDiv = document.createElement(\"div\");\r\n responseDiv.className = \"response-message mb-2 text-start\";\r\n responseDiv.style.minHeight = \"3em\";\r\n let spinner = document.createElement(\"div\");\r\n spinner.className = \"spinner-border text-light\";\r\n spinner.setAttribute(\"role\", \"status\");\r\n responseDiv.appendChild(spinner);\r\n chatHistory.appendChild(responseDiv);\r\n\r\n // toggle button to stop text generation\r\n sendButton.innerHTML = \"Stop\";\r\n\r\n // change autoScroller to keep track of our new responseDiv\r\n autoScroller.observe(responseDiv);\r\n\r\n if (continuation) {\r\n input = context + \" \" + input;\r\n } else {\r\n input = `<|system|>\\nYou are a friendly assistant.<|end|>\\n<|user|>\\n${input}<|end|>\\n<|assistant|>\\n`;\r\n }\r\n\r\n (0,_model_js__WEBPACK_IMPORTED_MODULE_0__.Query)(input, (word) => {\r\n responseDiv.innerHTML = marked__WEBPACK_IMPORTED_MODULE_1__.marked.parse(word);\r\n })\r\n .then(() => {\r\n chatHistory.context = responseDiv.innerHTML;\r\n copyTextToClipboard(responseDiv, true);\r\n sendButton.innerHTML = \"Send\";\r\n spinner.remove();\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n sendButton.innerHTML = \"Send\";\r\n spinner.remove();\r\n });\r\n\r\n // Clear user input\r\n document.getElementById(\"user-input\").value = \"\";\r\n}\r\n\r\n//\r\n// event listener for Ctrl+Enter or Enter\r\n//\r\ndocument.getElementById(\"user-input\").addEventListener(\"keydown\", function (e) {\r\n if (e.ctrlKey) {\r\n if (e.key === \"Enter\") {\r\n submitRequest(e);\r\n } else {\r\n const query = preCannedQueries[e.key];\r\n if (query) {\r\n document.getElementById(\"user-input\").value = query;\r\n submitRequest(e);\r\n }\r\n }\r\n } else if (e.key === \"Enter\") {\r\n e.preventDefault();\r\n submitRequest(e);\r\n }\r\n});\r\n\r\nwindow.onload = () => {\r\n (0,_model_js__WEBPACK_IMPORTED_MODULE_0__.Init)(true).then(() => {\r\n // adjustPadding();\r\n sendButton.addEventListener(\"click\", submitRequest);\r\n const userInput = document.getElementById(\"user-input\");\r\n document.getElementById(\"status\").style.display = \"none\";\r\n userInput.focus();\r\n });\r\n};\r\n\n\n//# sourceURL=webpack://localchat/./chat.js?"); /***/ }),