Add deleteChatHistory method to PageAssitDatabase class and systemPromptForNonRagOption functions to ollama service
This commit is contained in:
parent
c1efb2d5cb
commit
b54527cab5
38
package.json
38
package.json
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "pageassist",
|
||||
"displayName": "Page Assist - AI Powered Browser Assistant",
|
||||
"version": "0.0.1",
|
||||
"description": "Use your local AI models to assist you in your daily browsing.",
|
||||
"displayName": "Page Assist - Browse the Internet with Your Local AI Models",
|
||||
"version": "1.0.0",
|
||||
"description": "Page Assist is a browser extension that allows you to browse the internet with your local AI models. It is a privacy-focused and open-source project.",
|
||||
"author": "n4ze3m",
|
||||
"scripts": {
|
||||
"dev": "plasmo dev",
|
||||
@ -55,32 +55,30 @@
|
||||
},
|
||||
"manifest": {
|
||||
"host_permissions": [
|
||||
"https://*/*",
|
||||
"http://*/*",
|
||||
"http://*:11434/api/tags",
|
||||
"http://*:11434/api/chat",
|
||||
"https://*:11434/api/tags",
|
||||
"https://*:11434/api/chat"
|
||||
"https://*/*"
|
||||
],
|
||||
"web_accessible_resources": [
|
||||
{
|
||||
"resources": [
|
||||
"popup.html"
|
||||
],
|
||||
"matches": [
|
||||
"https://*/*",
|
||||
"http://*/*"
|
||||
]
|
||||
"commands": {
|
||||
"_execute_action": {
|
||||
"suggested_key": {
|
||||
"default": "Ctrl+Shift+L"
|
||||
}
|
||||
],
|
||||
},
|
||||
"execute_side_panel": {
|
||||
"description": "Open the side panel",
|
||||
"suggested_key": {
|
||||
"default": "Ctrl+Shift+P"
|
||||
}
|
||||
}
|
||||
},
|
||||
"permissions": [
|
||||
"storage",
|
||||
"activeTab",
|
||||
"scripting",
|
||||
"declarativeNetRequest",
|
||||
"declarativeNetRequestFeedback",
|
||||
"action",
|
||||
"unlimitedStorage"
|
||||
"unlimitedStorage",
|
||||
"contextMenus"
|
||||
]
|
||||
}
|
||||
}
|
@ -12,5 +12,37 @@ chrome.runtime.onMessage.addListener(async (message) => {
|
||||
})
|
||||
|
||||
chrome.action.onClicked.addListener((tab) => {
|
||||
chrome.tabs.create({url: chrome.runtime.getURL("options.html")});
|
||||
});
|
||||
chrome.tabs.create({ url: chrome.runtime.getURL("options.html") })
|
||||
})
|
||||
|
||||
chrome.commands.onCommand.addListener((command) => {
|
||||
switch (command) {
|
||||
case "execute_side_panel":
|
||||
chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => {
|
||||
const tab = tabs[0]
|
||||
await chrome.sidePanel.open({
|
||||
tabId: tab.id
|
||||
})
|
||||
})
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
chrome.contextMenus.create({
|
||||
id: "open-side-panel-pa",
|
||||
title: "Open Side Panel to Chat",
|
||||
contexts: ["all"]
|
||||
})
|
||||
|
||||
chrome.contextMenus.onClicked.addListener((info, tab) => {
|
||||
if (info.menuItemId === "open-side-panel-pa") {
|
||||
chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => {
|
||||
const tab = tabs[0]
|
||||
await chrome.sidePanel.open({
|
||||
tabId: tab.id
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -15,11 +15,13 @@ import logoImage from "data-base64:~assets/icon.png"
|
||||
|
||||
import { Link, useParams, useLocation, useNavigate } from "react-router-dom"
|
||||
import { Sidebar } from "./Sidebar"
|
||||
import { Drawer, Layout, Select } from "antd"
|
||||
import { Drawer, Layout, Modal, Select } from "antd"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { fetchModels } from "~services/ollama"
|
||||
import { useMessageOption } from "~hooks/useMessageOption"
|
||||
import { PanelLeftIcon, Settings2 } from "lucide-react"
|
||||
import { Settings } from "./Settings"
|
||||
import { useDarkMode } from "~hooks/useDarkmode"
|
||||
|
||||
const navigation = [
|
||||
{ name: "Embed", href: "/bot/:id", icon: TagIcon },
|
||||
@ -51,8 +53,7 @@ export default function OptionLayout({
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false)
|
||||
const params = useParams<{ id: string }>()
|
||||
const location = useLocation()
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const {
|
||||
data: models,
|
||||
@ -66,9 +67,10 @@ export default function OptionLayout({
|
||||
|
||||
const { selectedModel, setSelectedModel } = useMessageOption()
|
||||
|
||||
|
||||
return (
|
||||
<Layout className="bg-white dark:bg-[#171717] md:flex">
|
||||
<div className="flex items-center p-3 fixed flex-row justify-between border-b border-gray-200 dark:border-gray-800 bg-white dark:bg-[#171717] w-full z-10">
|
||||
<div className="flex items-center p-3 fixed flex-row justify-between border-b border-gray-200 dark:border-gray-600 bg-white dark:bg-[#171717] w-full z-10">
|
||||
<div className="flex items-center flex-row gap-3">
|
||||
<div>
|
||||
<button
|
||||
@ -92,7 +94,12 @@ export default function OptionLayout({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button className="text-gray-500 dark:text-gray-400">
|
||||
<button>
|
||||
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setOpen(true)}
|
||||
className="text-gray-500 dark:text-gray-400">
|
||||
<CogIcon className="w-6 h-6" />
|
||||
</button>
|
||||
</div>
|
||||
@ -104,10 +111,19 @@ export default function OptionLayout({
|
||||
placement="left"
|
||||
closeIcon={null}
|
||||
onClose={() => setSidebarOpen(false)}
|
||||
open={sidebarOpen}
|
||||
>
|
||||
open={sidebarOpen}>
|
||||
<Sidebar />
|
||||
</Drawer>
|
||||
|
||||
<Modal
|
||||
open={open}
|
||||
width={800}
|
||||
title={"Settings"}
|
||||
onOk={() => setOpen(false)}
|
||||
footer={null}
|
||||
onCancel={() => setOpen(false)}>
|
||||
<Settings setClose={() => setOpen(false)} />
|
||||
</Modal>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import React from "react"
|
||||
import { useMessage } from "~hooks/useMessage"
|
||||
import { useMessageOption } from "~hooks/useMessageOption"
|
||||
import { PlaygroundMessage } from "./PlaygroundMessage"
|
||||
import { PlaygroundEmpty } from "./PlaygroundEmpty"
|
||||
|
||||
export const PlaygroundChat = () => {
|
||||
const { messages } = useMessageOption()
|
||||
@ -13,7 +14,11 @@ export const PlaygroundChat = () => {
|
||||
})
|
||||
return (
|
||||
<div className="grow flex flex-col md:translate-x-0 transition-transform duration-300 ease-in-out">
|
||||
{/* {messages.length === 0 && <div>no message</div>} */}
|
||||
{messages.length === 0 && (
|
||||
<div className="mt-32">
|
||||
<PlaygroundEmpty />
|
||||
</div>
|
||||
)}
|
||||
{messages.length > 0 && <div className="w-full h-14 flex-shrink-0"></div>}
|
||||
{messages.map((message, index) => (
|
||||
<PlaygroundMessage
|
||||
|
86
src/components/Option/Playground/PlaygroundEmpty.tsx
Normal file
86
src/components/Option/Playground/PlaygroundEmpty.tsx
Normal file
@ -0,0 +1,86 @@
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { useEffect, useState } from "react"
|
||||
import { useMessage } from "~hooks/useMessage"
|
||||
import { useMessageOption } from "~hooks/useMessageOption"
|
||||
import {
|
||||
getOllamaURL,
|
||||
isOllamaRunning,
|
||||
setOllamaURL as saveOllamaURL
|
||||
} from "~services/ollama"
|
||||
|
||||
export const PlaygroundEmpty = () => {
|
||||
const [ollamaURL, setOllamaURL] = useState<string>("")
|
||||
const {
|
||||
data: ollamaInfo,
|
||||
status: ollamaStatus,
|
||||
refetch,
|
||||
isRefetching
|
||||
} = useQuery({
|
||||
queryKey: ["ollamaStatus"],
|
||||
queryFn: async () => {
|
||||
const ollamaURL = await getOllamaURL()
|
||||
const isOk = await isOllamaRunning()
|
||||
|
||||
return {
|
||||
isOk,
|
||||
ollamaURL
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (ollamaInfo?.ollamaURL) {
|
||||
setOllamaURL(ollamaInfo.ollamaURL)
|
||||
}
|
||||
}, [ollamaInfo])
|
||||
|
||||
return (
|
||||
<div className="mx-auto sm:max-w-xl px-4 mt-10">
|
||||
<div className="rounded-lg justify-center items-center flex flex-col border p-8 bg-white dark:bg-[#262626] shadow-sm dark:border-gray-600">
|
||||
{(ollamaStatus === "pending" || isRefetching) && (
|
||||
<div className="inline-flex items-center space-x-2">
|
||||
<div className="w-3 h-3 bg-blue-500 rounded-full animate-bounce"></div>
|
||||
<p className="dark:text-gray-400 text-gray-900">
|
||||
Searching for Your Ollama 🦙
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{!isRefetching && ollamaStatus === "success" ? (
|
||||
ollamaInfo.isOk ? (
|
||||
<div className="inline-flex items-center space-x-2">
|
||||
<div className="w-3 h-3 bg-green-500 rounded-full"></div>
|
||||
<p className="dark:text-gray-400 text-gray-900">
|
||||
Ollama is running 🦙
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col space-y-2 justify-center items-center">
|
||||
<div className="inline-flex space-x-2">
|
||||
<div className="w-3 h-3 bg-red-500 rounded-full"></div>
|
||||
<p className="dark:text-gray-400 text-gray-900">
|
||||
Unable to connect to Ollama 🦙
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<input
|
||||
className="bg-gray-100 dark:bg-[#262626] dark:text-gray-100 rounded-md px-4 py-2 mt-2 w-full"
|
||||
type="url"
|
||||
value={ollamaURL}
|
||||
onChange={(e) => setOllamaURL(e.target.value)}
|
||||
/>
|
||||
|
||||
<button
|
||||
onClick={() => {
|
||||
saveOllamaURL(ollamaURL)
|
||||
refetch()
|
||||
}}
|
||||
className="bg-pink-500 mt-4 hover:bg-pink-600 text-white px-4 py-2 rounded-md dark:bg-pink-600 dark:hover:bg-pink-700">
|
||||
Retry
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -66,7 +66,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="p-3 md:p-6 md:bg-white dark:bg-black border rounded-t-xl border-black/10 dark:border-gray-800">
|
||||
<div className="p-3 md:p-6 md:bg-white dark:bg-[#262626] border rounded-t-xl border-black/10 dark:border-gray-600">
|
||||
<div className="flex-grow space-y-6 ">
|
||||
<div
|
||||
className={`h-full rounded-md shadow relative ${
|
||||
@ -82,7 +82,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
|
||||
onClick={() => {
|
||||
form.setFieldValue("image", "")
|
||||
}}
|
||||
className="absolute top-2 right-2 bg-white dark:bg-black p-1 rounded-full hover:bg-gray-100 dark:hover:bg-gray-600 text-black dark:text-gray-100">
|
||||
className="absolute top-2 right-2 bg-white dark:bg-[#262626] p-1 rounded-full hover:bg-gray-100 dark:hover:bg-gray-600 text-black dark:text-gray-100">
|
||||
<XMarkIcon className="h-5 w-5" />
|
||||
</button>
|
||||
</div>
|
||||
@ -109,7 +109,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
|
||||
})
|
||||
})}
|
||||
className="shrink-0 flex-grow flex items-center ">
|
||||
<div className="flex items-center p-2 rounded-2xl border bg-gray-100 w-full dark:bg-black dark:border-gray-800">
|
||||
<div className="flex items-center p-2 rounded-2xl border bg-gray-100 w-full dark:bg-[#262626] dark:border-gray-600">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
@ -162,7 +162,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
|
||||
/>
|
||||
<button
|
||||
disabled={isSending || form.values.message.length === 0}
|
||||
className="ml-2 flex items-center justify-center w-10 h-10 text-white bg-black rounded-xl disabled:opacity-50">
|
||||
className="ml-2 flex items-center justify-center w-10 h-10 text-white bg-[#262626] rounded-xl disabled:opacity-50">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
|
39
src/components/Option/Settings.tsx
Normal file
39
src/components/Option/Settings.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import { Tabs } from "antd"
|
||||
import { SettingsOllama } from "./Settings/ollama"
|
||||
import { SettingPrompt } from "./Settings/prompt"
|
||||
import { SettingOther } from "./Settings/other"
|
||||
|
||||
type Props = {
|
||||
setClose: (close: boolean) => void
|
||||
}
|
||||
|
||||
export const Settings = ({ setClose }: Props) => {
|
||||
return (
|
||||
<div className="my-6">
|
||||
<Tabs
|
||||
tabPosition="left"
|
||||
defaultActiveKey="1"
|
||||
items={[
|
||||
{
|
||||
id: "1",
|
||||
key: "1",
|
||||
label: "Prompt",
|
||||
children: <SettingPrompt />
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
key: "2",
|
||||
label: "Ollama",
|
||||
children: <SettingsOllama />
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
key: "3",
|
||||
label: "Other",
|
||||
children: <SettingOther />
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
55
src/components/Option/Settings/ollama.tsx
Normal file
55
src/components/Option/Settings/ollama.tsx
Normal file
@ -0,0 +1,55 @@
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { useEffect, useState } from "react"
|
||||
import { SaveButton } from "~components/Common/SaveButton"
|
||||
import { getOllamaURL, setOllamaURL as saveOllamaURL } from "~services/ollama"
|
||||
|
||||
export const SettingsOllama = () => {
|
||||
const [ollamaURL, setOllamaURL] = useState<string>("")
|
||||
const { data: ollamaInfo } = useQuery({
|
||||
queryKey: ["fetchOllamURL"],
|
||||
queryFn: async () => {
|
||||
const ollamaURL = await getOllamaURL()
|
||||
|
||||
return {
|
||||
ollamaURL
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (ollamaInfo?.ollamaURL) {
|
||||
setOllamaURL(ollamaInfo.ollamaURL)
|
||||
}
|
||||
}, [ollamaInfo])
|
||||
|
||||
return (
|
||||
<div className="">
|
||||
<div>
|
||||
<label
|
||||
htmlFor="ollamaURL"
|
||||
className="text-sm font-medium dark:text-gray-200">
|
||||
Ollama URL
|
||||
</label>
|
||||
<input
|
||||
type="url"
|
||||
id="ollamaURL"
|
||||
value={ollamaURL}
|
||||
onChange={(e) => {
|
||||
setOllamaURL(e.target.value)
|
||||
}}
|
||||
placeholder="Your Ollama URL"
|
||||
className="w-full p-2 border border-gray-300 rounded-md dark:bg-[#262626] dark:text-gray-100"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-end">
|
||||
<SaveButton
|
||||
onClick={() => {
|
||||
saveOllamaURL(ollamaURL)
|
||||
}}
|
||||
className="mt-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
52
src/components/Option/Settings/other.tsx
Normal file
52
src/components/Option/Settings/other.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
import { useQueryClient } from "@tanstack/react-query"
|
||||
import { useDarkMode } from "~hooks/useDarkmode"
|
||||
import { useMessageOption } from "~hooks/useMessageOption"
|
||||
import { PageAssitDatabase } from "~libs/db"
|
||||
|
||||
export const SettingOther = () => {
|
||||
const { clearChat } = useMessageOption()
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
const { mode, toggleDarkMode } = useDarkMode()
|
||||
|
||||
return (
|
||||
<div className="flex flex-col space-y-4">
|
||||
<div className="flex flex-row justify-between">
|
||||
<span className="text-gray-500 dark:text-gray-400 text-lg">
|
||||
Change Theme
|
||||
</span>
|
||||
|
||||
<button
|
||||
onClick={toggleDarkMode}
|
||||
className="bg-blue-500 dark:bg-blue-600 text-white dark:text-gray-200 px-4 py-2 rounded-md">
|
||||
{mode === "dark" ? "Light" : "Dark"}
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex flex-row justify-between">
|
||||
<span className="text-gray-500 dark:text-gray-400 text-lg">
|
||||
Delete Chat History
|
||||
</span>
|
||||
|
||||
<button
|
||||
onClick={async () => {
|
||||
const confirm = window.confirm(
|
||||
"Are you sure you want to delete your chat history? This action cannot be undone."
|
||||
)
|
||||
|
||||
if (confirm) {
|
||||
const db = new PageAssitDatabase()
|
||||
await db.deleteChatHistory()
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ["fetchChatHistory"]
|
||||
})
|
||||
clearChat()
|
||||
}
|
||||
}}
|
||||
className="bg-red-500 dark:bg-red-600 text-white dark:text-gray-200 px-4 py-2 rounded-md">
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
56
src/components/Option/Settings/prompt.tsx
Normal file
56
src/components/Option/Settings/prompt.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { useEffect, useState } from "react"
|
||||
import { SaveButton } from "~components/Common/SaveButton"
|
||||
import {
|
||||
setSystemPromptForNonRagOption,
|
||||
systemPromptForNonRagOption
|
||||
} from "~services/ollama"
|
||||
|
||||
export const SettingPrompt = () => {
|
||||
const [ollamaPrompt, setOllamaPrompt] = useState<string>("")
|
||||
const { data: ollamaInfo } = useQuery({
|
||||
queryKey: ["fetchOllaPrompt"],
|
||||
queryFn: async () => {
|
||||
const prompt = await systemPromptForNonRagOption()
|
||||
|
||||
return {
|
||||
prompt
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (ollamaInfo?.prompt) {
|
||||
setOllamaPrompt(ollamaInfo.prompt)
|
||||
}
|
||||
}, [ollamaInfo])
|
||||
|
||||
return (
|
||||
<div className="">
|
||||
<div>
|
||||
<label htmlFor="ollamaPrompt" className="text-sm font-medium dark:text-gray-200">
|
||||
System Prompt
|
||||
</label>
|
||||
<textarea
|
||||
value={ollamaPrompt}
|
||||
rows={5}
|
||||
id="ollamaPrompt"
|
||||
placeholder="Your System Prompt"
|
||||
onChange={(e) => {
|
||||
setOllamaPrompt(e.target.value)
|
||||
}}
|
||||
className="w-full p-2 border border-gray-300 rounded-md dark:bg-[#262626] dark:text-gray-100"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<SaveButton
|
||||
onClick={() => {
|
||||
setSystemPromptForNonRagOption(ollamaPrompt)
|
||||
}}
|
||||
className="mt-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
export {}
|
||||
import { Storage } from "@plasmohq/storage"
|
||||
|
||||
const storage = new Storage()
|
||||
|
||||
const sidePanelController = async () => {
|
||||
const sidepanelCommand = await storage.get("sidepanel-command")
|
||||
const command = sidepanelCommand || "Ctrl+0"
|
||||
|
||||
document.addEventListener("keydown", (event) => {
|
||||
let pressedKey = ""
|
||||
if (event.ctrlKey) {
|
||||
pressedKey += "Ctrl+"
|
||||
}
|
||||
|
||||
if (event.shiftKey) {
|
||||
pressedKey += "Shift+"
|
||||
}
|
||||
|
||||
pressedKey += event.key
|
||||
|
||||
if (pressedKey === command) {
|
||||
chrome.runtime.sendMessage({ type: "sidepanel" })
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
sidePanelController()
|
@ -1,6 +1,6 @@
|
||||
import React from "react"
|
||||
import { cleanUrl } from "~libs/clean-url"
|
||||
import { getOllamaURL, systemPromptForNonRag } from "~services/ollama"
|
||||
import { getOllamaURL, systemPromptForNonRagOption } from "~services/ollama"
|
||||
import { type ChatHistory, type Message } from "~store/option"
|
||||
import { ChatOllama } from "@langchain/community/chat_models/ollama"
|
||||
import {
|
||||
@ -139,7 +139,7 @@ export const useMessageOption = () => {
|
||||
setMessages(newMessage)
|
||||
|
||||
try {
|
||||
const prompt = await systemPromptForNonRag()
|
||||
const prompt = await systemPromptForNonRagOption()
|
||||
|
||||
message = message.trim().replaceAll("\n", " ")
|
||||
|
||||
|
@ -79,6 +79,14 @@ export class PageAssitDatabase {
|
||||
async clear() {
|
||||
this.db.clear()
|
||||
}
|
||||
|
||||
async deleteChatHistory() {
|
||||
const chatHistories = await this.getChatHistories()
|
||||
for (const history of chatHistories) {
|
||||
this.db.remove(history.id)
|
||||
}
|
||||
this.db.remove("chatHistories")
|
||||
}
|
||||
}
|
||||
|
||||
const generateID = () => {
|
||||
|
@ -121,3 +121,12 @@ export const setPromptForRag = async (
|
||||
await storage.set("systemPromptForRag", prompt)
|
||||
await storage.set("questionPromptForRag", questionPrompt)
|
||||
}
|
||||
|
||||
export const systemPromptForNonRagOption = async () => {
|
||||
const prompt = await storage.get("systemPromptForNonRagOption")
|
||||
return prompt
|
||||
}
|
||||
|
||||
export const setSystemPromptForNonRagOption = async (prompt: string) => {
|
||||
await storage.set("systemPromptForNonRagOption", prompt)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user