commit
70fc095edd
@ -1,23 +1,41 @@
|
|||||||
|
import "katex/dist/katex.min.css"
|
||||||
|
|
||||||
import remarkGfm from "remark-gfm"
|
import remarkGfm from "remark-gfm"
|
||||||
import remarkMath from "remark-math"
|
import remarkMath from "remark-math"
|
||||||
import ReactMarkdown from "react-markdown"
|
import ReactMarkdown from "react-markdown"
|
||||||
|
import rehypeKatex from "rehype-katex"
|
||||||
|
|
||||||
import "property-information"
|
import "property-information"
|
||||||
import React from "react"
|
import React from "react"
|
||||||
import { CodeBlock } from "./CodeBlock"
|
import { CodeBlock } from "./CodeBlock"
|
||||||
|
export const preprocessLaTeX = (content: string) => {
|
||||||
|
// Replace block-level LaTeX delimiters \[ \] with $$ $$
|
||||||
|
|
||||||
export default function Markdown({
|
const blockProcessedContent = content.replace(
|
||||||
|
/\\\[(.*?)\\\]/gs,
|
||||||
|
(_, equation) => `$$${equation}$$`
|
||||||
|
)
|
||||||
|
// Replace inline LaTeX delimiters \( \) with $ $
|
||||||
|
const inlineProcessedContent = blockProcessedContent.replace(
|
||||||
|
/\\\((.*?)\\\)/gs,
|
||||||
|
(_, equation) => `$${equation}$`
|
||||||
|
)
|
||||||
|
return inlineProcessedContent
|
||||||
|
}
|
||||||
|
function Markdown({
|
||||||
message,
|
message,
|
||||||
className = "prose break-words dark:prose-invert prose-p:leading-relaxed prose-pre:p-0 dark:prose-dark"
|
className = "prose break-words dark:prose-invert prose-p:leading-relaxed prose-pre:p-0 dark:prose-dark"
|
||||||
}: {
|
}: {
|
||||||
message: string
|
message: string
|
||||||
className?: string
|
className?: string
|
||||||
}) {
|
}) {
|
||||||
|
message = preprocessLaTeX(message)
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
className={className}
|
className={className}
|
||||||
remarkPlugins={[remarkGfm, remarkMath]}
|
remarkPlugins={[remarkGfm, remarkMath]}
|
||||||
|
rehypePlugins={[rehypeKatex]}
|
||||||
components={{
|
components={{
|
||||||
code({ node, inline, className, children, ...props }) {
|
code({ node, inline, className, children, ...props }) {
|
||||||
const match = /language-(\w+)/.exec(className || "")
|
const match = /language-(\w+)/.exec(className || "")
|
||||||
@ -52,3 +70,5 @@ export default function Markdown({
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default Markdown
|
||||||
|
@ -4,20 +4,27 @@ import { BookIcon, ComputerIcon, ZapIcon } from "lucide-react"
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
import { getAllPrompts } from "@/db"
|
import { getAllPrompts } from "@/db"
|
||||||
import { useMessageOption } from "@/hooks/useMessageOption"
|
|
||||||
|
|
||||||
export const PromptSelect: React.FC = () => {
|
type Props = {
|
||||||
|
setSelectedSystemPrompt: (promptId: string | undefined) => void
|
||||||
|
setSelectedQuickPrompt: (prompt: string | undefined) => void
|
||||||
|
selectedSystemPrompt: string | undefined
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PromptSelect: React.FC<Props> = ({
|
||||||
|
setSelectedQuickPrompt,
|
||||||
|
setSelectedSystemPrompt,
|
||||||
|
selectedSystemPrompt,
|
||||||
|
className = "dark:text-gray-300"
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation("option")
|
const { t } = useTranslation("option")
|
||||||
const {
|
|
||||||
selectedSystemPrompt,
|
|
||||||
setSelectedQuickPrompt,
|
|
||||||
setSelectedSystemPrompt
|
|
||||||
} = useMessageOption()
|
|
||||||
|
|
||||||
const { data } = useQuery({
|
const { data } = useQuery({
|
||||||
queryKey: ["getAllPromptsForSelect"],
|
queryKey: ["getAllPromptsForSelect"],
|
||||||
queryFn: getAllPrompts
|
queryFn: getAllPrompts
|
||||||
})
|
})
|
||||||
|
|
||||||
const handlePromptChange = (value?: string) => {
|
const handlePromptChange = (value?: string) => {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
setSelectedSystemPrompt(undefined)
|
setSelectedSystemPrompt(undefined)
|
||||||
@ -79,7 +86,7 @@ export const PromptSelect: React.FC = () => {
|
|||||||
placement={"topLeft"}
|
placement={"topLeft"}
|
||||||
trigger={["click"]}>
|
trigger={["click"]}>
|
||||||
<Tooltip title={t("selectAPrompt")}>
|
<Tooltip title={t("selectAPrompt")}>
|
||||||
<button type="button" className="dark:text-gray-300">
|
<button type="button" className={className}>
|
||||||
<BookIcon className="h-5 w-5" />
|
<BookIcon className="h-5 w-5" />
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -45,7 +45,7 @@ export const Header: React.FC<Props> = ({
|
|||||||
setSelectedQuickPrompt,
|
setSelectedQuickPrompt,
|
||||||
setSelectedSystemPrompt,
|
setSelectedSystemPrompt,
|
||||||
messages,
|
messages,
|
||||||
streaming
|
streaming,
|
||||||
} = useMessageOption()
|
} = useMessageOption()
|
||||||
const {
|
const {
|
||||||
data: models,
|
data: models,
|
||||||
@ -182,7 +182,11 @@ export const Header: React.FC<Props> = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="lg:hidden">
|
<div className="lg:hidden">
|
||||||
<PromptSelect />
|
<PromptSelect
|
||||||
|
selectedSystemPrompt={selectedSystemPrompt}
|
||||||
|
setSelectedSystemPrompt={setSelectedSystemPrompt}
|
||||||
|
setSelectedQuickPrompt={setSelectedQuickPrompt}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<SelectedKnowledge />
|
<SelectedKnowledge />
|
||||||
</div>
|
</div>
|
||||||
|
@ -24,7 +24,6 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
|
|||||||
const { sendWhenEnter, setSendWhenEnter } = useWebUI()
|
const { sendWhenEnter, setSendWhenEnter } = useWebUI()
|
||||||
const [typing, setTyping] = React.useState<boolean>(false)
|
const [typing, setTyping] = React.useState<boolean>(false)
|
||||||
const { t } = useTranslation(["playground", "common"])
|
const { t } = useTranslation(["playground", "common"])
|
||||||
|
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
initialValues: {
|
initialValues: {
|
||||||
message: "",
|
message: "",
|
||||||
@ -37,7 +36,7 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
|
|||||||
resetTranscript,
|
resetTranscript,
|
||||||
start: startListening,
|
start: startListening,
|
||||||
stop: stopSpeechRecognition,
|
stop: stopSpeechRecognition,
|
||||||
supported: browserSupportsSpeechRecognition
|
supported: browserSupportsSpeechRecognition,
|
||||||
} = useSpeechRecognition()
|
} = useSpeechRecognition()
|
||||||
|
|
||||||
const stopListening = async () => {
|
const stopListening = async () => {
|
||||||
@ -118,12 +117,14 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
|
|||||||
onSubmit,
|
onSubmit,
|
||||||
selectedModel,
|
selectedModel,
|
||||||
chatMode,
|
chatMode,
|
||||||
speechToTextLanguage,
|
|
||||||
stopStreamingRequest,
|
stopStreamingRequest,
|
||||||
streaming,
|
streaming,
|
||||||
setChatMode,
|
setChatMode,
|
||||||
webSearch,
|
webSearch,
|
||||||
setWebSearch
|
setWebSearch,
|
||||||
|
selectedQuickPrompt,
|
||||||
|
setSelectedQuickPrompt,
|
||||||
|
speechToTextLanguage
|
||||||
} = useMessage()
|
} = useMessage()
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@ -139,6 +140,23 @@ export const SidepanelForm = ({ dropedFile }: Props) => {
|
|||||||
form.setFieldValue("message", transcript)
|
form.setFieldValue("message", transcript)
|
||||||
}
|
}
|
||||||
}, [transcript])
|
}, [transcript])
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (selectedQuickPrompt) {
|
||||||
|
const word = getVariable(selectedQuickPrompt)
|
||||||
|
form.setFieldValue("message", selectedQuickPrompt)
|
||||||
|
if (word) {
|
||||||
|
textareaRef.current?.focus()
|
||||||
|
const interval = setTimeout(() => {
|
||||||
|
textareaRef.current?.setSelectionRange(word.start, word.end)
|
||||||
|
setSelectedQuickPrompt(null)
|
||||||
|
}, 100)
|
||||||
|
return () => {
|
||||||
|
clearInterval(interval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [selectedQuickPrompt])
|
||||||
const { mutateAsync: sendMessage, isPending: isSending } = useMutation({
|
const { mutateAsync: sendMessage, isPending: isSending } = useMutation({
|
||||||
mutationFn: onSubmit,
|
mutationFn: onSubmit,
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
|
@ -7,13 +7,22 @@ import { useTranslation } from "react-i18next"
|
|||||||
import { CurrentChatModelSettings } from "@/components/Common/Settings/CurrentChatModelSettings"
|
import { CurrentChatModelSettings } from "@/components/Common/Settings/CurrentChatModelSettings"
|
||||||
import React from "react"
|
import React from "react"
|
||||||
import { useStorage } from "@plasmohq/storage/hook"
|
import { useStorage } from "@plasmohq/storage/hook"
|
||||||
|
import { PromptSelect } from "@/components/Common/PromptSelect"
|
||||||
export const SidepanelHeader = () => {
|
export const SidepanelHeader = () => {
|
||||||
const [hideCurrentChatModelSettings] = useStorage(
|
const [hideCurrentChatModelSettings] = useStorage(
|
||||||
"hideCurrentChatModelSettings",
|
"hideCurrentChatModelSettings",
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
const { clearChat, isEmbedding, messages, streaming } = useMessage()
|
const {
|
||||||
|
clearChat,
|
||||||
|
isEmbedding,
|
||||||
|
messages,
|
||||||
|
streaming,
|
||||||
|
selectedSystemPrompt,
|
||||||
|
setSelectedSystemPrompt,
|
||||||
|
setSelectedQuickPrompt
|
||||||
|
} = useMessage()
|
||||||
const { t } = useTranslation(["sidepanel", "common"])
|
const { t } = useTranslation(["sidepanel", "common"])
|
||||||
const [openModelSettings, setOpenModelSettings] = React.useState(false)
|
const [openModelSettings, setOpenModelSettings] = React.useState(false)
|
||||||
|
|
||||||
@ -44,11 +53,13 @@ export const SidepanelHeader = () => {
|
|||||||
<EraserIcon className="h-5 w-5 text-gray-500 dark:text-gray-400" />
|
<EraserIcon className="h-5 w-5 text-gray-500 dark:text-gray-400" />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{/* <Tooltip title={t("tooltip.history")}>
|
<PromptSelect
|
||||||
<Link to="/history">
|
selectedSystemPrompt={selectedSystemPrompt}
|
||||||
<HistoryIcon className="h-5 w-5 text-gray-500 dark:text-gray-400" />
|
setSelectedSystemPrompt={setSelectedSystemPrompt}
|
||||||
</Link>
|
setSelectedQuickPrompt={setSelectedQuickPrompt}
|
||||||
</Tooltip> */}
|
className="text-gray-500 dark:text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
|
||||||
|
/>
|
||||||
|
|
||||||
{!hideCurrentChatModelSettings && (
|
{!hideCurrentChatModelSettings && (
|
||||||
<Tooltip title={t("common:currentChatModelSettings")}>
|
<Tooltip title={t("common:currentChatModelSettings")}>
|
||||||
<button
|
<button
|
||||||
|
@ -52,5 +52,6 @@ export default defineContentScript({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
allFrames: true,
|
allFrames: true,
|
||||||
matches: ["*://ollama.com/library/*"]
|
matches: ["*://ollama.com/*"],
|
||||||
|
|
||||||
})
|
})
|
@ -17,6 +17,7 @@ import { ChatHistory } from "@/store/option"
|
|||||||
import {
|
import {
|
||||||
deleteChatForEdit,
|
deleteChatForEdit,
|
||||||
generateID,
|
generateID,
|
||||||
|
getPromptById,
|
||||||
removeMessageUsingHistoryId,
|
removeMessageUsingHistoryId,
|
||||||
updateMessageByIndex
|
updateMessageByIndex
|
||||||
} from "@/db"
|
} from "@/db"
|
||||||
@ -75,9 +76,18 @@ export const useMessage = () => {
|
|||||||
setIsEmbedding,
|
setIsEmbedding,
|
||||||
isEmbedding,
|
isEmbedding,
|
||||||
currentURL,
|
currentURL,
|
||||||
setCurrentURL
|
setCurrentURL,
|
||||||
|
selectedQuickPrompt,
|
||||||
|
setSelectedQuickPrompt,
|
||||||
|
selectedSystemPrompt,
|
||||||
|
setSelectedSystemPrompt
|
||||||
} = useStoreMessage()
|
} = useStoreMessage()
|
||||||
|
|
||||||
|
const [speechToTextLanguage, setSpeechToTextLanguage] = useStorage(
|
||||||
|
"speechToTextLanguage",
|
||||||
|
"en-US"
|
||||||
|
)
|
||||||
|
|
||||||
const [keepTrackOfEmbedding, setKeepTrackOfEmbedding] = React.useState<{
|
const [keepTrackOfEmbedding, setKeepTrackOfEmbedding] = React.useState<{
|
||||||
[key: string]: MemoryVectorStore
|
[key: string]: MemoryVectorStore
|
||||||
}>({})
|
}>({})
|
||||||
@ -488,6 +498,7 @@ export const useMessage = () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const prompt = await systemPromptForNonRag()
|
const prompt = await systemPromptForNonRag()
|
||||||
|
const selectedPrompt = await getPromptById(selectedSystemPrompt)
|
||||||
|
|
||||||
let humanMessage = new HumanMessage({
|
let humanMessage = new HumanMessage({
|
||||||
content: [
|
content: [
|
||||||
@ -514,7 +525,7 @@ export const useMessage = () => {
|
|||||||
|
|
||||||
const applicationChatHistory = generateHistory(history)
|
const applicationChatHistory = generateHistory(history)
|
||||||
|
|
||||||
if (prompt) {
|
if (prompt && !selectedPrompt) {
|
||||||
applicationChatHistory.unshift(
|
applicationChatHistory.unshift(
|
||||||
new SystemMessage({
|
new SystemMessage({
|
||||||
content: [
|
content: [
|
||||||
@ -526,6 +537,18 @@ export const useMessage = () => {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if (selectedPrompt) {
|
||||||
|
applicationChatHistory.unshift(
|
||||||
|
new SystemMessage({
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
text: selectedPrompt.content,
|
||||||
|
type: "text"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const chunks = await ollama.stream(
|
const chunks = await ollama.stream(
|
||||||
[...applicationChatHistory, humanMessage],
|
[...applicationChatHistory, humanMessage],
|
||||||
@ -1231,6 +1254,12 @@ export const useMessage = () => {
|
|||||||
regenerateLastMessage,
|
regenerateLastMessage,
|
||||||
webSearch,
|
webSearch,
|
||||||
setWebSearch,
|
setWebSearch,
|
||||||
isSearchingInternet
|
isSearchingInternet,
|
||||||
|
selectedQuickPrompt,
|
||||||
|
setSelectedQuickPrompt,
|
||||||
|
selectedSystemPrompt,
|
||||||
|
setSelectedSystemPrompt,
|
||||||
|
speechToTextLanguage,
|
||||||
|
setSpeechToTextLanguage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,8 +55,6 @@ export const useMessageOption = () => {
|
|||||||
setIsProcessing,
|
setIsProcessing,
|
||||||
chatMode,
|
chatMode,
|
||||||
setChatMode,
|
setChatMode,
|
||||||
speechToTextLanguage,
|
|
||||||
setSpeechToTextLanguage,
|
|
||||||
webSearch,
|
webSearch,
|
||||||
setWebSearch,
|
setWebSearch,
|
||||||
isSearchingInternet,
|
isSearchingInternet,
|
||||||
@ -70,7 +68,10 @@ export const useMessageOption = () => {
|
|||||||
} = useStoreMessageOption()
|
} = useStoreMessageOption()
|
||||||
const currentChatModelSettings = useStoreChatModelSettings()
|
const currentChatModelSettings = useStoreChatModelSettings()
|
||||||
const [selectedModel, setSelectedModel] = useStorage("selectedModel")
|
const [selectedModel, setSelectedModel] = useStorage("selectedModel")
|
||||||
|
const [ speechToTextLanguage, setSpeechToTextLanguage ] = useStorage(
|
||||||
|
"speechToTextLanguage",
|
||||||
|
"en-US"
|
||||||
|
)
|
||||||
const { ttsEnabled } = useWebUI()
|
const { ttsEnabled } = useWebUI()
|
||||||
|
|
||||||
const { t } = useTranslation("option")
|
const { t } = useTranslation("option")
|
||||||
@ -411,8 +412,6 @@ export const useMessageOption = () => {
|
|||||||
const prompt = await systemPromptForNonRagOption()
|
const prompt = await systemPromptForNonRagOption()
|
||||||
const selectedPrompt = await getPromptById(selectedSystemPrompt)
|
const selectedPrompt = await getPromptById(selectedSystemPrompt)
|
||||||
|
|
||||||
// message = message.trim().replaceAll("\n", " ")
|
|
||||||
|
|
||||||
let humanMessage = new HumanMessage({
|
let humanMessage = new HumanMessage({
|
||||||
content: [
|
content: [
|
||||||
{
|
{
|
||||||
|
@ -1,35 +1,42 @@
|
|||||||
import { useRef, useEffect, useState } from 'react';
|
import { useRef, useEffect, useState } from "react"
|
||||||
|
|
||||||
export const useSmartScroll = (messages: any[], streaming: boolean) => {
|
export const useSmartScroll = (messages: any[], streaming: boolean) => {
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null)
|
||||||
const [isAtBottom, setIsAtBottom] = useState(true);
|
const [isAtBottom, setIsAtBottom] = useState(true)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const container = containerRef.current;
|
const container = containerRef.current
|
||||||
if (!container) return;
|
if (!container) return
|
||||||
|
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
const { scrollTop, scrollHeight, clientHeight } = container;
|
const { scrollTop, scrollHeight, clientHeight } = container
|
||||||
setIsAtBottom(scrollHeight - scrollTop - clientHeight < 50);
|
setIsAtBottom(scrollHeight - scrollTop - clientHeight < 50)
|
||||||
};
|
}
|
||||||
|
|
||||||
container.addEventListener('scroll', handleScroll);
|
container.addEventListener("scroll", handleScroll)
|
||||||
return () => container.removeEventListener('scroll', handleScroll);
|
return () => container.removeEventListener("scroll", handleScroll)
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (messages.length === 0) {
|
||||||
|
setIsAtBottom(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (isAtBottom && containerRef.current) {
|
if (isAtBottom && containerRef.current) {
|
||||||
const scrollOptions: ScrollIntoViewOptions = streaming
|
const scrollOptions: ScrollIntoViewOptions = streaming
|
||||||
? { behavior: 'smooth', block: 'end' }
|
? { behavior: "smooth", block: "end" }
|
||||||
: { behavior: 'auto', block: 'end' };
|
: { behavior: "auto", block: "end" }
|
||||||
containerRef.current.lastElementChild?.scrollIntoView(scrollOptions);
|
containerRef.current.lastElementChild?.scrollIntoView(scrollOptions)
|
||||||
}
|
}
|
||||||
}, [messages, streaming, isAtBottom]);
|
}, [messages, streaming, isAtBottom])
|
||||||
|
|
||||||
const scrollToBottom = () => {
|
const scrollToBottom = () => {
|
||||||
containerRef.current?.lastElementChild?.scrollIntoView({ behavior: 'smooth', block: 'end' });
|
containerRef.current?.lastElementChild?.scrollIntoView({
|
||||||
};
|
behavior: "smooth",
|
||||||
|
block: "end"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return { containerRef, isAtBottom, scrollToBottom }
|
||||||
return { containerRef, isAtBottom, scrollToBottom };
|
}
|
||||||
};
|
|
@ -329,13 +329,15 @@ export const saveForRag = async (
|
|||||||
chunkSize: number,
|
chunkSize: number,
|
||||||
overlap: number,
|
overlap: number,
|
||||||
totalFilePerKB: number,
|
totalFilePerKB: number,
|
||||||
noOfRetrievedDocs: number
|
noOfRetrievedDocs?: number
|
||||||
) => {
|
) => {
|
||||||
await setDefaultEmbeddingModelForRag(model)
|
await setDefaultEmbeddingModelForRag(model)
|
||||||
await setDefaultEmbeddingChunkSize(chunkSize)
|
await setDefaultEmbeddingChunkSize(chunkSize)
|
||||||
await setDefaultEmbeddingChunkOverlap(overlap)
|
await setDefaultEmbeddingChunkOverlap(overlap)
|
||||||
await setTotalFilePerKB(totalFilePerKB)
|
await setTotalFilePerKB(totalFilePerKB)
|
||||||
await setNoOfRetrievedDocs(noOfRetrievedDocs)
|
if(noOfRetrievedDocs) {
|
||||||
|
await setNoOfRetrievedDocs(noOfRetrievedDocs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getWebSearchPrompt = async () => {
|
export const getWebSearchPrompt = async () => {
|
||||||
|
@ -40,6 +40,11 @@ type State = {
|
|||||||
setSpeechToTextLanguage: (speechToTextLanguage: string) => void
|
setSpeechToTextLanguage: (speechToTextLanguage: string) => void
|
||||||
currentURL: string
|
currentURL: string
|
||||||
setCurrentURL: (currentURL: string) => void
|
setCurrentURL: (currentURL: string) => void
|
||||||
|
selectedSystemPrompt: string | null
|
||||||
|
setSelectedSystemPrompt: (selectedSystemPrompt: string) => void
|
||||||
|
|
||||||
|
selectedQuickPrompt: string | null
|
||||||
|
setSelectedQuickPrompt: (selectedQuickPrompt: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useStoreMessage = create<State>((set) => ({
|
export const useStoreMessage = create<State>((set) => ({
|
||||||
@ -68,5 +73,11 @@ export const useStoreMessage = create<State>((set) => ({
|
|||||||
setSpeechToTextLanguage: (speechToTextLanguage) =>
|
setSpeechToTextLanguage: (speechToTextLanguage) =>
|
||||||
set({ speechToTextLanguage }),
|
set({ speechToTextLanguage }),
|
||||||
currentURL: "",
|
currentURL: "",
|
||||||
setCurrentURL: (currentURL) => set({ currentURL })
|
setCurrentURL: (currentURL) => set({ currentURL }),
|
||||||
|
|
||||||
|
selectedSystemPrompt: null,
|
||||||
|
setSelectedSystemPrompt: (selectedSystemPrompt) =>
|
||||||
|
set({ selectedSystemPrompt }),
|
||||||
|
selectedQuickPrompt: null,
|
||||||
|
setSelectedQuickPrompt: (selectedQuickPrompt) => set({ selectedQuickPrompt })
|
||||||
}))
|
}))
|
||||||
|
@ -62,6 +62,9 @@ type State = {
|
|||||||
|
|
||||||
selectedKnowledge: Knowledge | null
|
selectedKnowledge: Knowledge | null
|
||||||
setSelectedKnowledge: (selectedKnowledge: Knowledge) => void
|
setSelectedKnowledge: (selectedKnowledge: Knowledge) => void
|
||||||
|
|
||||||
|
setSpeechToTextLanguage: (language: string) => void
|
||||||
|
speechToTextLanguage: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useStoreMessageOption = create<State>((set) => ({
|
export const useStoreMessageOption = create<State>((set) => ({
|
||||||
|
@ -50,7 +50,7 @@ export default defineConfig({
|
|||||||
outDir: "build",
|
outDir: "build",
|
||||||
|
|
||||||
manifest: {
|
manifest: {
|
||||||
version: "1.2.2",
|
version: "1.2.3",
|
||||||
name:
|
name:
|
||||||
process.env.TARGET === "firefox"
|
process.env.TARGET === "firefox"
|
||||||
? "Page Assist - A Web UI for Local AI Models"
|
? "Page Assist - A Web UI for Local AI Models"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user