From 094615498c9cf170bc7327c3502afa621141872f Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Sun, 25 Feb 2024 21:17:27 +0530 Subject: [PATCH] Add @mantine/hooks dependency and update PlaygroundChat component --- package.json | 1 + src/components/Common/Markdown.tsx | 3 +- src/components/Common/Playground/Message.tsx | 15 +++++++ .../Common/Playground/WebSearch.tsx | 13 ++---- .../Option/Playground/Playground.tsx | 7 +++- .../Option/Playground/PlaygroundChat.tsx | 1 + src/hooks/useMessageOption.tsx | 42 ++++++++++++++++--- src/libs/db.ts | 5 ++- src/loader/html.ts | 2 +- src/services/ollama.ts | 13 ++++++ src/store/web.tsx | 15 ------- src/web/web.ts | 17 +++++++- yarn.lock | 5 +++ 13 files changed, 99 insertions(+), 40 deletions(-) delete mode 100644 src/store/web.tsx diff --git a/package.json b/package.json index 714c54d..00dc109 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@langchain/community": "^0.0.21", "@langchain/core": "^0.1.22", "@mantine/form": "^7.5.0", + "@mantine/hooks": "^7.5.3", "@plasmohq/storage": "^1.9.0", "@tailwindcss/forms": "^0.5.7", "@tailwindcss/typography": "^0.5.10", diff --git a/src/components/Common/Markdown.tsx b/src/components/Common/Markdown.tsx index 2a0cac5..f3f374f 100644 --- a/src/components/Common/Markdown.tsx +++ b/src/components/Common/Markdown.tsx @@ -7,8 +7,7 @@ import ReactMarkdown from "react-markdown" import "property-information" import React from "react" import { Tooltip } from "antd" -import { ClipboardIcon } from "~icons/ClipboardIcon" -import { CheckIcon } from "~icons/CheckIcon" +import { CheckIcon, ClipboardIcon } from "lucide-react" export default function Markdown({ message }: { message: string }) { const [isBtnPressed, setIsBtnPressed] = React.useState(false) diff --git a/src/components/Common/Playground/Message.tsx b/src/components/Common/Playground/Message.tsx index 5bb3404..26b9833 100644 --- a/src/components/Common/Playground/Message.tsx +++ b/src/components/Common/Playground/Message.tsx @@ -18,6 +18,7 @@ type Props = { isProcessing: boolean webSearch?: {} isSearchingInternet?: boolean + sources?: any[] } export const PlaygroundMessage = (props: Props) => { @@ -72,6 +73,20 @@ export const PlaygroundMessage = (props: Props) => { ))} )} + + {props.isBot && ( +
+ {props?.sources?.map((source, index) => ( + + {source.name} + + ))} +
+ )} {props.isBot && !props.isProcessing && (
{!props.hideCopy && ( diff --git a/src/components/Common/Playground/WebSearch.tsx b/src/components/Common/Playground/WebSearch.tsx index b4c3180..ca304db 100644 --- a/src/components/Common/Playground/WebSearch.tsx +++ b/src/components/Common/Playground/WebSearch.tsx @@ -1,19 +1,12 @@ -import { useWebSearch } from "~store/web" -import { - Globe, - MousePointer, - Boxes -} from "lucide-react" - +import { Globe } from "lucide-react" export const WebSearch = () => { - const { state, text } = useWebSearch() return (
- +
-
{text}
+
Searching the web
) } diff --git a/src/components/Option/Playground/Playground.tsx b/src/components/Option/Playground/Playground.tsx index 30e642b..fd59544 100644 --- a/src/components/Option/Playground/Playground.tsx +++ b/src/components/Option/Playground/Playground.tsx @@ -5,6 +5,7 @@ import { PlaygroundChat } from "./PlaygroundChat" export const Playground = () => { const drop = React.useRef(null) const [dropedFile, setDropedFile] = React.useState() + const [dropState, setDropState] = React.useState< "idle" | "dragging" | "error" >("idle") @@ -70,14 +71,16 @@ export const Playground = () => { className={`${ dropState === "dragging" ? "bg-gray-100 dark:bg-gray-800 z-10" : "" } min-h-screen`}> - +
- +
diff --git a/src/components/Option/Playground/PlaygroundChat.tsx b/src/components/Option/Playground/PlaygroundChat.tsx index af56241..ac0f5b0 100644 --- a/src/components/Option/Playground/PlaygroundChat.tsx +++ b/src/components/Option/Playground/PlaygroundChat.tsx @@ -31,6 +31,7 @@ export const PlaygroundChat = () => { onRengerate={regenerateLastMessage} isProcessing={streaming} isSearchingInternet={isSearchingInternet} + sources={message.sources} /> ))} {messages.length > 0 && ( diff --git a/src/hooks/useMessageOption.tsx b/src/hooks/useMessageOption.tsx index 037f869..9e804e5 100644 --- a/src/hooks/useMessageOption.tsx +++ b/src/hooks/useMessageOption.tsx @@ -1,6 +1,10 @@ import React from "react" import { cleanUrl } from "~libs/clean-url" -import { getOllamaURL, systemPromptForNonRagOption } from "~services/ollama" +import { + geWebSearchFollowUpPrompt, + getOllamaURL, + systemPromptForNonRagOption +} from "~services/ollama" import { type ChatHistory, type Message } from "~store/option" import { ChatOllama } from "@langchain/community/chat_models/ollama" import { @@ -101,7 +105,6 @@ export const useMessageOption = () => { setIsSearchingInternet } = useStoreMessageOption() - const navigate = useNavigate() const abortControllerRef = React.useRef(null) @@ -158,7 +161,30 @@ export const useMessageOption = () => { try { setIsSearchingInternet(true) - const prompt = await getSystemPromptForWeb(message) + + let query = message + + if (newMessage.length > 2) { + let questionPrompt = await geWebSearchFollowUpPrompt() + const lastTenMessages = newMessage.slice(-10) + lastTenMessages.pop() + const chat_history = lastTenMessages + .map((message) => { + return `${message.isBot ? "Assistant: " : "Human: "}${message.message}` + }) + .join("\n") + const promptForQuestion = questionPrompt + .replaceAll("{chat_history}", chat_history) + .replaceAll("{question}", message) + const questionOllama = new ChatOllama({ + model: selectedModel, + baseUrl: cleanUrl(url) + }) + const response = await questionOllama.invoke(promptForQuestion) + query = response.content.toString() + } + + const { prompt, source } = await getSystemPromptForWeb(query) setIsSearchingInternet(false) message = message.trim().replaceAll("\n", " ") @@ -228,6 +254,8 @@ export const useMessageOption = () => { appendingIndex ].message.slice(0, -1) + newMessage[appendingIndex].sources = source + if (!isRegenerate) { setHistory([ ...history, @@ -260,7 +288,8 @@ export const useMessageOption = () => { selectedModel, "assistant", newMessage[appendingIndex].message, - [] + [], + source ) } else { const newHistoryId = await saveHistory(message) @@ -272,7 +301,8 @@ export const useMessageOption = () => { selectedModel, "assistant", newMessage[appendingIndex].message, - [] + [], + source ) setHistoryId(newHistoryId.id) } @@ -615,6 +645,6 @@ export const useMessageOption = () => { regenerateLastMessage, webSearch, setWebSearch, - isSearchingInternet, + isSearchingInternet } } diff --git a/src/libs/db.ts b/src/libs/db.ts index 1a9c724..ff61f26 100644 --- a/src/libs/db.ts +++ b/src/libs/db.ts @@ -125,11 +125,12 @@ export const saveMessage = async ( name: string, role: string, content: string, - images: string[] + images: string[], + source?: any[] ) => { const id = generateID() const createdAt = Date.now() - const message = { id, history_id, name, role, content, images, createdAt } + const message = { id, history_id, name, role, content, images, createdAt, sources: source } const db = new PageAssitDatabase() await db.addMessage(message) return message diff --git a/src/loader/html.ts b/src/loader/html.ts index f379c67..94206f4 100644 --- a/src/loader/html.ts +++ b/src/loader/html.ts @@ -41,7 +41,7 @@ export class PageAssistHtmlLoader ] }) const text = htmlCompiler(html) - const metadata = { source: this.url } + const metadata = { url: this.url } return [new Document({ pageContent: text, metadata })] } } diff --git a/src/services/ollama.ts b/src/services/ollama.ts index 4db0f53..88f8a4d 100644 --- a/src/services/ollama.ts +++ b/src/services/ollama.ts @@ -266,4 +266,17 @@ export const getWebSearchPrompt = async () => { export const setWebSearchPrompt = async (prompt: string) => { await storage.set("webSearchPrompt", prompt) +} + +export const geWebSearchFollowUpPrompt = async () => { + const prompt = await storage.get("webSearchFollowUpPrompt") + if (!prompt || prompt.length === 0) { + return DEFAULT_RAG_QUESTION_PROMPT; + } + return prompt +} + + +export const setWebSearchFollowUpPrompt = async (prompt: string) => { + await storage.set("webSearchFollowUpPrompt", prompt) } \ No newline at end of file diff --git a/src/store/web.tsx b/src/store/web.tsx deleted file mode 100644 index 9474700..0000000 --- a/src/store/web.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { create } from "zustand" - -type State = { - state: "searching" | "clicked" | "embeddings" | "done" - text: string - setText: (text: string) => void - setState: (state: "searching" | "clicked" | "embeddings" | "done") => void -} - -export const useWebSearch = create((set) => ({ - state: "searching", - text: "Searching Google", - setText: (text) => set({ text }), - setState: (state) => set({ state }) -})) diff --git a/src/web/web.ts b/src/web/web.ts index 1ed5f49..be1eef1 100644 --- a/src/web/web.ts +++ b/src/web/web.ts @@ -13,8 +13,21 @@ export const getSystemPromptForWeb = async (query: string) => { const prompt = system.replace("{current_date_time}", current_date_time).replace("{search_results}", search_results) - return prompt + return { + prompt, + source: search.map((result) => { + return { + url: result.url, + name: new URL(result.url).hostname, + type: "url", + } + }) + } } catch (e) { - return '' + console.error(e) + return { + prompt: "", + source: [], + } } } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 1dc6031..a202d5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -681,6 +681,11 @@ fast-deep-equal "^3.1.3" klona "^2.0.6" +"@mantine/hooks@^7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@mantine/hooks/-/hooks-7.5.3.tgz#34168712075ee40ff7353c840420d4568b0dd54e" + integrity sha512-mFI448mAs12v8FrgSVhytqlhTVrEjIfd/PqPEfwJu5YcZIq4YZdqpzJIUbANnRrFSvmoQpDb1PssdKx7Ds35hw== + "@mischnic/json-sourcemap@0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz#38af657be4108140a548638267d02a2ea3336507"