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.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"