Add localization for manage search feature
This commit is contained in:
parent
12558c39d1
commit
ea56a2ffa2
@ -203,5 +203,9 @@
|
|||||||
"webSearchFollowUpPromptPlaceholder": "Your Web Search Follow Up Prompt"
|
"webSearchFollowUpPromptPlaceholder": "Your Web Search Follow Up Prompt"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"manageSearch": {
|
||||||
|
"title": "Manage Web Search",
|
||||||
|
"heading": "Configure Web Search"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -203,5 +203,9 @@
|
|||||||
"webSearchFollowUpPromptPlaceholder": "Web検索フォローアッププロンプト"
|
"webSearchFollowUpPromptPlaceholder": "Web検索フォローアッププロンプト"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"manageSearch": {
|
||||||
|
"title": "Web検索の管理",
|
||||||
|
"heading": "Web検索を設定する"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -203,5 +203,9 @@
|
|||||||
"webSearchFollowUpPromptPlaceholder": "നിങ്ങളുടെ വെബ് തിരയല് തുടര്പ്രോംപ്റ്റ്"
|
"webSearchFollowUpPromptPlaceholder": "നിങ്ങളുടെ വെബ് തിരയല് തുടര്പ്രോംപ്റ്റ്"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"manageSearch": {
|
||||||
|
"heading": "Web തിരയൽ സജ്ജമാക്കുക",
|
||||||
|
"title": "Web തിരയൽ നിയന്ത്രിക്കുക"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -204,5 +204,9 @@
|
|||||||
"webSearchFollowUpPromptPlaceholder": "您的网页搜索追问提示词"
|
"webSearchFollowUpPromptPlaceholder": "您的网页搜索追问提示词"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"manageSearch": {
|
||||||
|
"heading": "配置网络搜索",
|
||||||
|
"title": "管理网络搜索"
|
||||||
}
|
}
|
||||||
}
|
}
|
27
src/components/Common/PageAssistProvider.tsx
Normal file
27
src/components/Common/PageAssistProvider.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { PageAssistContext } from "@/context"
|
||||||
|
import { Message } from "@/types/message"
|
||||||
|
import React from "react"
|
||||||
|
|
||||||
|
export const PageAssistProvider = ({
|
||||||
|
children
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode
|
||||||
|
}) => {
|
||||||
|
const [messages, setMessages] = React.useState<Message[]>([])
|
||||||
|
const [controller, setController] = React.useState<AbortController | null>(
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageAssistContext.Provider
|
||||||
|
value={{
|
||||||
|
messages,
|
||||||
|
setMessages,
|
||||||
|
|
||||||
|
controller,
|
||||||
|
setController
|
||||||
|
}}>
|
||||||
|
{children}
|
||||||
|
</PageAssistContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
@ -1,9 +1,4 @@
|
|||||||
import {
|
import { Book, BrainCircuit, Orbit, Share } from "lucide-react"
|
||||||
Book,
|
|
||||||
BrainCircuit,
|
|
||||||
Orbit,
|
|
||||||
Share
|
|
||||||
} from "lucide-react"
|
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
import { Link, useLocation } from "react-router-dom"
|
import { Link, useLocation } from "react-router-dom"
|
||||||
import { OllamaIcon } from "../Icons/Ollama"
|
import { OllamaIcon } from "../Icons/Ollama"
|
||||||
|
26
src/context/index.tsx
Normal file
26
src/context/index.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { Message } from "@/types/message"
|
||||||
|
import React, { Dispatch, SetStateAction, createContext } from "react"
|
||||||
|
|
||||||
|
interface PageAssistContext {
|
||||||
|
messages: Message[]
|
||||||
|
setMessages: Dispatch<SetStateAction<Message[]>>
|
||||||
|
|
||||||
|
controller: AbortController | null
|
||||||
|
setController: Dispatch<SetStateAction<AbortController>>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PageAssistContext = createContext<PageAssistContext>({
|
||||||
|
messages: [],
|
||||||
|
setMessages: () => {},
|
||||||
|
|
||||||
|
controller: null,
|
||||||
|
setController: () => {}
|
||||||
|
})
|
||||||
|
|
||||||
|
export const usePageAssist = () => {
|
||||||
|
const context = React.useContext(PageAssistContext)
|
||||||
|
if (!context) {
|
||||||
|
throw new Error("usePageAssist must be used within a PageAssistContext")
|
||||||
|
}
|
||||||
|
return context
|
||||||
|
}
|
@ -1,7 +1,5 @@
|
|||||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
||||||
import { MemoryRouter } from "react-router-dom"
|
import { MemoryRouter } from "react-router-dom"
|
||||||
import { ToastContainer } from "react-toastify"
|
|
||||||
import "react-toastify/dist/ReactToastify.css"
|
|
||||||
const queryClient = new QueryClient()
|
const queryClient = new QueryClient()
|
||||||
import { ConfigProvider, Empty, theme } from "antd"
|
import { ConfigProvider, Empty, theme } from "antd"
|
||||||
import { StyleProvider } from "@ant-design/cssinjs"
|
import { StyleProvider } from "@ant-design/cssinjs"
|
||||||
@ -9,6 +7,7 @@ import { useDarkMode } from "~/hooks/useDarkmode"
|
|||||||
import { OptionRouting } from "~/routes"
|
import { OptionRouting } from "~/routes"
|
||||||
import "~/i18n"
|
import "~/i18n"
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
|
import { PageAssistProvider } from "@/components/Common/PageAssistProvider"
|
||||||
|
|
||||||
function IndexOption() {
|
function IndexOption() {
|
||||||
const { mode } = useDarkMode()
|
const { mode } = useDarkMode()
|
||||||
@ -27,12 +26,12 @@ function IndexOption() {
|
|||||||
}}
|
}}
|
||||||
description={t("common:noData")}
|
description={t("common:noData")}
|
||||||
/>
|
/>
|
||||||
)}
|
)}>
|
||||||
>
|
|
||||||
<StyleProvider hashPriority="high">
|
<StyleProvider hashPriority="high">
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<OptionRouting />
|
<PageAssistProvider>
|
||||||
<ToastContainer />
|
<OptionRouting />
|
||||||
|
</PageAssistProvider>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
</StyleProvider>
|
</StyleProvider>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
||||||
import { MemoryRouter } from "react-router-dom"
|
import { MemoryRouter } from "react-router-dom"
|
||||||
import { SidepanelRouting } from "~/routes"
|
import { SidepanelRouting } from "~/routes"
|
||||||
import { ToastContainer } from "react-toastify"
|
|
||||||
import "react-toastify/dist/ReactToastify.css"
|
|
||||||
const queryClient = new QueryClient()
|
const queryClient = new QueryClient()
|
||||||
import { ConfigProvider, Empty, theme } from "antd"
|
import { ConfigProvider, Empty, theme } from "antd"
|
||||||
import { StyleProvider } from "@ant-design/cssinjs"
|
import { StyleProvider } from "@ant-design/cssinjs"
|
||||||
import { useDarkMode } from "~/hooks/useDarkmode"
|
import { useDarkMode } from "~/hooks/useDarkmode"
|
||||||
import "~/i18n"
|
import "~/i18n"
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
|
import { PageAssistProvider } from "@/components/Common/PageAssistProvider"
|
||||||
|
|
||||||
function IndexSidepanel() {
|
function IndexSidepanel() {
|
||||||
const { mode } = useDarkMode()
|
const { mode } = useDarkMode()
|
||||||
@ -28,12 +27,12 @@ function IndexSidepanel() {
|
|||||||
}}
|
}}
|
||||||
description={t("common:noData")}
|
description={t("common:noData")}
|
||||||
/>
|
/>
|
||||||
)}
|
)}>
|
||||||
>
|
|
||||||
<StyleProvider hashPriority="high">
|
<StyleProvider hashPriority="high">
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<SidepanelRouting />
|
<PageAssistProvider>
|
||||||
<ToastContainer />
|
<SidepanelRouting />
|
||||||
|
</PageAssistProvider>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
</StyleProvider>
|
</StyleProvider>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
|
160
src/hooks/chat-helper/index.ts
Normal file
160
src/hooks/chat-helper/index.ts
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
import { saveHistory, saveMessage } from "@/libs/db"
|
||||||
|
import { ChatHistory } from "@/store/option"
|
||||||
|
|
||||||
|
export const saveMessageOnError = async ({
|
||||||
|
e,
|
||||||
|
history,
|
||||||
|
setHistory,
|
||||||
|
image,
|
||||||
|
userMessage,
|
||||||
|
botMessage,
|
||||||
|
historyId,
|
||||||
|
selectedModel,
|
||||||
|
setHistoryId,
|
||||||
|
isRegenerating
|
||||||
|
}: {
|
||||||
|
e: any
|
||||||
|
setHistory: (history: ChatHistory) => void
|
||||||
|
history: ChatHistory
|
||||||
|
userMessage: string
|
||||||
|
image: string
|
||||||
|
botMessage: string
|
||||||
|
historyId: string | null
|
||||||
|
selectedModel: string
|
||||||
|
setHistoryId: (historyId: string) => void
|
||||||
|
isRegenerating: boolean
|
||||||
|
}) => {
|
||||||
|
if (
|
||||||
|
e?.name === "AbortError" ||
|
||||||
|
e?.message === "AbortError" ||
|
||||||
|
e?.name?.includes("AbortError") ||
|
||||||
|
e?.message?.includes("AbortError")
|
||||||
|
) {
|
||||||
|
setHistory([
|
||||||
|
...history,
|
||||||
|
{
|
||||||
|
role: "user",
|
||||||
|
content: userMessage,
|
||||||
|
image
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "assistant",
|
||||||
|
content: botMessage
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
if (historyId) {
|
||||||
|
if (!isRegenerating) {
|
||||||
|
await saveMessage(
|
||||||
|
historyId,
|
||||||
|
selectedModel,
|
||||||
|
"user",
|
||||||
|
userMessage,
|
||||||
|
[image],
|
||||||
|
[],
|
||||||
|
1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
await saveMessage(
|
||||||
|
historyId,
|
||||||
|
selectedModel,
|
||||||
|
"assistant",
|
||||||
|
botMessage,
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
2
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
const newHistoryId = await saveHistory(userMessage)
|
||||||
|
if (!isRegenerating) {
|
||||||
|
await saveMessage(
|
||||||
|
newHistoryId.id,
|
||||||
|
selectedModel,
|
||||||
|
"user",
|
||||||
|
userMessage,
|
||||||
|
[image],
|
||||||
|
[],
|
||||||
|
1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
await saveMessage(
|
||||||
|
newHistoryId.id,
|
||||||
|
selectedModel,
|
||||||
|
"assistant",
|
||||||
|
botMessage,
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
2
|
||||||
|
)
|
||||||
|
setHistoryId(newHistoryId.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
export const saveMessageOnSuccess = async ({
|
||||||
|
historyId,
|
||||||
|
setHistoryId,
|
||||||
|
isRegenerate,
|
||||||
|
selectedModel,
|
||||||
|
message,
|
||||||
|
image,
|
||||||
|
fullText,
|
||||||
|
source
|
||||||
|
}: {
|
||||||
|
historyId: string | null
|
||||||
|
setHistoryId: (historyId: string) => void
|
||||||
|
isRegenerate: boolean
|
||||||
|
selectedModel: string | null
|
||||||
|
message: string
|
||||||
|
image: string
|
||||||
|
fullText: string
|
||||||
|
source: any[]
|
||||||
|
}) => {
|
||||||
|
if (historyId) {
|
||||||
|
if (!isRegenerate) {
|
||||||
|
await saveMessage(
|
||||||
|
historyId,
|
||||||
|
selectedModel,
|
||||||
|
"user",
|
||||||
|
message,
|
||||||
|
[image],
|
||||||
|
[],
|
||||||
|
1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
await saveMessage(
|
||||||
|
historyId,
|
||||||
|
selectedModel!,
|
||||||
|
"assistant",
|
||||||
|
fullText,
|
||||||
|
[],
|
||||||
|
source,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
const newHistoryId = await saveHistory(message)
|
||||||
|
await saveMessage(
|
||||||
|
newHistoryId.id,
|
||||||
|
selectedModel,
|
||||||
|
"user",
|
||||||
|
message,
|
||||||
|
[image],
|
||||||
|
[],
|
||||||
|
1
|
||||||
|
)
|
||||||
|
await saveMessage(
|
||||||
|
newHistoryId.id,
|
||||||
|
selectedModel!,
|
||||||
|
"assistant",
|
||||||
|
fullText,
|
||||||
|
[],
|
||||||
|
source,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
setHistoryId(newHistoryId.id)
|
||||||
|
}
|
||||||
|
}
|
@ -11,10 +11,9 @@ import { HumanMessage, SystemMessage } from "@langchain/core/messages"
|
|||||||
import { useStoreMessageOption } from "~/store/option"
|
import { useStoreMessageOption } from "~/store/option"
|
||||||
import {
|
import {
|
||||||
deleteChatForEdit,
|
deleteChatForEdit,
|
||||||
|
generateID,
|
||||||
getPromptById,
|
getPromptById,
|
||||||
removeMessageUsingHistoryId,
|
removeMessageUsingHistoryId,
|
||||||
saveHistory,
|
|
||||||
saveMessage,
|
|
||||||
updateMessageByIndex
|
updateMessageByIndex
|
||||||
} from "~/libs/db"
|
} from "~/libs/db"
|
||||||
import { useNavigate } from "react-router-dom"
|
import { useNavigate } from "react-router-dom"
|
||||||
@ -22,13 +21,19 @@ import { notification } from "antd"
|
|||||||
import { getSystemPromptForWeb } from "~/web/web"
|
import { getSystemPromptForWeb } from "~/web/web"
|
||||||
import { generateHistory } from "@/utils/generate-history"
|
import { generateHistory } from "@/utils/generate-history"
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
|
import { saveMessageOnError, saveMessageOnSuccess } from "./chat-helper"
|
||||||
|
import { usePageAssist } from "@/context"
|
||||||
|
|
||||||
export const useMessageOption = () => {
|
export const useMessageOption = () => {
|
||||||
const {
|
const {
|
||||||
history,
|
controller: abortController,
|
||||||
|
setController: setAbortController,
|
||||||
messages,
|
messages,
|
||||||
|
setMessages
|
||||||
|
} = usePageAssist()
|
||||||
|
const {
|
||||||
|
history,
|
||||||
setHistory,
|
setHistory,
|
||||||
setMessages,
|
|
||||||
setStreaming,
|
setStreaming,
|
||||||
streaming,
|
streaming,
|
||||||
setIsFirstMessage,
|
setIsFirstMessage,
|
||||||
@ -59,8 +64,6 @@ export const useMessageOption = () => {
|
|||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const textareaRef = React.useRef<HTMLTextAreaElement>(null)
|
const textareaRef = React.useRef<HTMLTextAreaElement>(null)
|
||||||
|
|
||||||
const abortControllerRef = React.useRef<AbortController | null>(null)
|
|
||||||
|
|
||||||
const clearChat = () => {
|
const clearChat = () => {
|
||||||
navigate("/")
|
navigate("/")
|
||||||
setMessages([])
|
setMessages([])
|
||||||
@ -78,14 +81,14 @@ export const useMessageOption = () => {
|
|||||||
image: string,
|
image: string,
|
||||||
isRegenerate: boolean,
|
isRegenerate: boolean,
|
||||||
messages: Message[],
|
messages: Message[],
|
||||||
history: ChatHistory
|
history: ChatHistory,
|
||||||
|
signal: AbortSignal
|
||||||
) => {
|
) => {
|
||||||
const url = await getOllamaURL()
|
const url = await getOllamaURL()
|
||||||
|
|
||||||
if (image.length > 0) {
|
if (image.length > 0) {
|
||||||
image = `data:image/jpeg;base64,${image.split(",")[1]}`
|
image = `data:image/jpeg;base64,${image.split(",")[1]}`
|
||||||
}
|
}
|
||||||
abortControllerRef.current = new AbortController()
|
|
||||||
|
|
||||||
const ollama = new ChatOllama({
|
const ollama = new ChatOllama({
|
||||||
model: selectedModel!,
|
model: selectedModel!,
|
||||||
@ -93,6 +96,8 @@ export const useMessageOption = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
let newMessage: Message[] = []
|
let newMessage: Message[] = []
|
||||||
|
let generateMessageId = generateID()
|
||||||
|
|
||||||
if (!isRegenerate) {
|
if (!isRegenerate) {
|
||||||
newMessage = [
|
newMessage = [
|
||||||
...messages,
|
...messages,
|
||||||
@ -107,7 +112,8 @@ export const useMessageOption = () => {
|
|||||||
isBot: true,
|
isBot: true,
|
||||||
name: selectedModel,
|
name: selectedModel,
|
||||||
message: "▋",
|
message: "▋",
|
||||||
sources: []
|
sources: [],
|
||||||
|
id: generateMessageId
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
@ -117,12 +123,14 @@ export const useMessageOption = () => {
|
|||||||
isBot: true,
|
isBot: true,
|
||||||
name: selectedModel,
|
name: selectedModel,
|
||||||
message: "▋",
|
message: "▋",
|
||||||
sources: []
|
sources: [],
|
||||||
|
id: generateMessageId
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
setMessages(newMessage)
|
setMessages(newMessage)
|
||||||
const appendingIndex = newMessage.length - 1
|
let fullText = ""
|
||||||
|
let contentToSave = ""
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setIsSearchingInternet(true)
|
setIsSearchingInternet(true)
|
||||||
@ -195,138 +203,93 @@ export const useMessageOption = () => {
|
|||||||
const chunks = await ollama.stream(
|
const chunks = await ollama.stream(
|
||||||
[...applicationChatHistory, humanMessage],
|
[...applicationChatHistory, humanMessage],
|
||||||
{
|
{
|
||||||
signal: abortControllerRef.current.signal
|
signal: signal
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let count = 0
|
let count = 0
|
||||||
for await (const chunk of chunks) {
|
for await (const chunk of chunks) {
|
||||||
|
contentToSave += chunk.content
|
||||||
|
fullText += chunk.content
|
||||||
if (count === 0) {
|
if (count === 0) {
|
||||||
setIsProcessing(true)
|
setIsProcessing(true)
|
||||||
newMessage[appendingIndex].message = chunk.content + "▋"
|
|
||||||
setMessages(newMessage)
|
|
||||||
} else {
|
|
||||||
newMessage[appendingIndex].message =
|
|
||||||
newMessage[appendingIndex].message.slice(0, -1) +
|
|
||||||
chunk.content +
|
|
||||||
"▋"
|
|
||||||
setMessages(newMessage)
|
|
||||||
}
|
}
|
||||||
|
setMessages((prev) => {
|
||||||
|
return prev.map((message) => {
|
||||||
|
if (message.id === generateMessageId) {
|
||||||
|
return {
|
||||||
|
...message,
|
||||||
|
message: fullText.slice(0, -1) + "▋"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return message
|
||||||
|
})
|
||||||
|
})
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
|
// update the message with the full text
|
||||||
newMessage[appendingIndex].message = newMessage[
|
setMessages((prev) => {
|
||||||
appendingIndex
|
return prev.map((message) => {
|
||||||
].message.slice(0, -1)
|
if (message.id === generateMessageId) {
|
||||||
|
return {
|
||||||
newMessage[appendingIndex].sources = source
|
...message,
|
||||||
|
message: fullText,
|
||||||
if (!isRegenerate) {
|
sources: source
|
||||||
setHistory([
|
}
|
||||||
...history,
|
|
||||||
{
|
|
||||||
role: "user",
|
|
||||||
content: message,
|
|
||||||
image
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: "assistant",
|
|
||||||
content: newMessage[appendingIndex].message
|
|
||||||
}
|
}
|
||||||
])
|
return message
|
||||||
} else {
|
})
|
||||||
setHistory([
|
})
|
||||||
...history,
|
|
||||||
{
|
|
||||||
role: "assistant",
|
|
||||||
content: newMessage[appendingIndex].message
|
|
||||||
}
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
if (historyId) {
|
setHistory([
|
||||||
if (!isRegenerate) {
|
...history,
|
||||||
await saveMessage(historyId, selectedModel!, "user", message, [image])
|
{
|
||||||
}
|
role: "user",
|
||||||
await saveMessage(
|
content: message,
|
||||||
historyId,
|
|
||||||
selectedModel!,
|
|
||||||
"assistant",
|
|
||||||
newMessage[appendingIndex].message,
|
|
||||||
[],
|
|
||||||
source
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
const newHistoryId = await saveHistory(message)
|
|
||||||
await saveMessage(newHistoryId.id, selectedModel!, "user", message, [
|
|
||||||
image
|
image
|
||||||
])
|
},
|
||||||
await saveMessage(
|
{
|
||||||
newHistoryId.id,
|
role: "assistant",
|
||||||
selectedModel!,
|
content: fullText
|
||||||
"assistant",
|
}
|
||||||
newMessage[appendingIndex].message,
|
])
|
||||||
[],
|
|
||||||
source
|
await saveMessageOnSuccess({
|
||||||
)
|
historyId,
|
||||||
setHistoryId(newHistoryId.id)
|
setHistoryId,
|
||||||
}
|
isRegenerate,
|
||||||
|
selectedModel: selectedModel,
|
||||||
|
message,
|
||||||
|
image,
|
||||||
|
fullText,
|
||||||
|
source
|
||||||
|
})
|
||||||
|
|
||||||
setIsProcessing(false)
|
setIsProcessing(false)
|
||||||
setStreaming(false)
|
setStreaming(false)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
//@ts-ignore
|
const errorSave = await saveMessageOnError({
|
||||||
if (e?.name === "AbortError") {
|
e,
|
||||||
newMessage[appendingIndex].message = newMessage[
|
botMessage: fullText,
|
||||||
appendingIndex
|
history,
|
||||||
].message.slice(0, -1)
|
historyId,
|
||||||
|
image,
|
||||||
|
selectedModel,
|
||||||
|
setHistory,
|
||||||
|
setHistoryId,
|
||||||
|
userMessage: message,
|
||||||
|
isRegenerating: isRegenerate
|
||||||
|
})
|
||||||
|
|
||||||
setHistory([
|
if (!errorSave) {
|
||||||
...history,
|
|
||||||
{
|
|
||||||
role: "user",
|
|
||||||
content: message,
|
|
||||||
image
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: "assistant",
|
|
||||||
content: newMessage[appendingIndex].message
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
if (historyId) {
|
|
||||||
await saveMessage(historyId, selectedModel!, "user", message, [image])
|
|
||||||
await saveMessage(
|
|
||||||
historyId,
|
|
||||||
selectedModel!,
|
|
||||||
"assistant",
|
|
||||||
newMessage[appendingIndex].message,
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
const newHistoryId = await saveHistory(message)
|
|
||||||
await saveMessage(newHistoryId.id, selectedModel!, "user", message, [
|
|
||||||
image
|
|
||||||
])
|
|
||||||
await saveMessage(
|
|
||||||
newHistoryId.id,
|
|
||||||
selectedModel!,
|
|
||||||
"assistant",
|
|
||||||
newMessage[appendingIndex].message,
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
setHistoryId(newHistoryId.id)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//@ts-ignore
|
|
||||||
notification.error({
|
notification.error({
|
||||||
message: t("error"),
|
message: t("error"),
|
||||||
description: e?.message || t("somethingWentWrong")
|
description: e?.message || t("somethingWentWrong")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsProcessing(false)
|
setIsProcessing(false)
|
||||||
setStreaming(false)
|
setStreaming(false)
|
||||||
|
} finally {
|
||||||
|
setAbortController(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,14 +298,14 @@ export const useMessageOption = () => {
|
|||||||
image: string,
|
image: string,
|
||||||
isRegenerate: boolean,
|
isRegenerate: boolean,
|
||||||
messages: Message[],
|
messages: Message[],
|
||||||
history: ChatHistory
|
history: ChatHistory,
|
||||||
|
signal: AbortSignal
|
||||||
) => {
|
) => {
|
||||||
const url = await getOllamaURL()
|
const url = await getOllamaURL()
|
||||||
|
|
||||||
if (image.length > 0) {
|
if (image.length > 0) {
|
||||||
image = `data:image/jpeg;base64,${image.split(",")[1]}`
|
image = `data:image/jpeg;base64,${image.split(",")[1]}`
|
||||||
}
|
}
|
||||||
abortControllerRef.current = new AbortController()
|
|
||||||
|
|
||||||
const ollama = new ChatOllama({
|
const ollama = new ChatOllama({
|
||||||
model: selectedModel!,
|
model: selectedModel!,
|
||||||
@ -350,6 +313,8 @@ export const useMessageOption = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
let newMessage: Message[] = []
|
let newMessage: Message[] = []
|
||||||
|
let generateMessageId = generateID()
|
||||||
|
|
||||||
if (!isRegenerate) {
|
if (!isRegenerate) {
|
||||||
newMessage = [
|
newMessage = [
|
||||||
...messages,
|
...messages,
|
||||||
@ -364,7 +329,8 @@ export const useMessageOption = () => {
|
|||||||
isBot: true,
|
isBot: true,
|
||||||
name: selectedModel,
|
name: selectedModel,
|
||||||
message: "▋",
|
message: "▋",
|
||||||
sources: []
|
sources: [],
|
||||||
|
id: generateMessageId
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
@ -374,12 +340,14 @@ export const useMessageOption = () => {
|
|||||||
isBot: true,
|
isBot: true,
|
||||||
name: selectedModel,
|
name: selectedModel,
|
||||||
message: "▋",
|
message: "▋",
|
||||||
sources: []
|
sources: [],
|
||||||
|
id: generateMessageId
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
setMessages(newMessage)
|
setMessages(newMessage)
|
||||||
const appendingIndex = newMessage.length - 1
|
let fullText = ""
|
||||||
|
let contentToSave = ""
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const prompt = await systemPromptForNonRagOption()
|
const prompt = await systemPromptForNonRagOption()
|
||||||
@ -441,132 +409,94 @@ export const useMessageOption = () => {
|
|||||||
const chunks = await ollama.stream(
|
const chunks = await ollama.stream(
|
||||||
[...applicationChatHistory, humanMessage],
|
[...applicationChatHistory, humanMessage],
|
||||||
{
|
{
|
||||||
signal: abortControllerRef.current.signal
|
signal: signal
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let count = 0
|
let count = 0
|
||||||
for await (const chunk of chunks) {
|
for await (const chunk of chunks) {
|
||||||
|
contentToSave += chunk.content
|
||||||
|
fullText += chunk.content
|
||||||
if (count === 0) {
|
if (count === 0) {
|
||||||
setIsProcessing(true)
|
setIsProcessing(true)
|
||||||
newMessage[appendingIndex].message = chunk.content + "▋"
|
|
||||||
setMessages(newMessage)
|
|
||||||
} else {
|
|
||||||
newMessage[appendingIndex].message =
|
|
||||||
newMessage[appendingIndex].message.slice(0, -1) +
|
|
||||||
chunk.content +
|
|
||||||
"▋"
|
|
||||||
setMessages(newMessage)
|
|
||||||
}
|
}
|
||||||
|
setMessages((prev) => {
|
||||||
|
return prev.map((message) => {
|
||||||
|
if (message.id === generateMessageId) {
|
||||||
|
return {
|
||||||
|
...message,
|
||||||
|
message: fullText.slice(0, -1) + "▋"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return message
|
||||||
|
})
|
||||||
|
})
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
|
|
||||||
newMessage[appendingIndex].message = newMessage[
|
setMessages((prev) => {
|
||||||
appendingIndex
|
return prev.map((message) => {
|
||||||
].message.slice(0, -1)
|
if (message.id === generateMessageId) {
|
||||||
|
return {
|
||||||
if (!isRegenerate) {
|
...message,
|
||||||
setHistory([
|
message: fullText.slice(0, -1)
|
||||||
...history,
|
}
|
||||||
{
|
|
||||||
role: "user",
|
|
||||||
content: message,
|
|
||||||
image
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: "assistant",
|
|
||||||
content: newMessage[appendingIndex].message
|
|
||||||
}
|
}
|
||||||
])
|
return message
|
||||||
} else {
|
})
|
||||||
setHistory([
|
})
|
||||||
...history,
|
|
||||||
{
|
|
||||||
role: "assistant",
|
|
||||||
content: newMessage[appendingIndex].message
|
|
||||||
}
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
if (historyId) {
|
setHistory([
|
||||||
if (!isRegenerate) {
|
...history,
|
||||||
await saveMessage(historyId, selectedModel, "user", message, [image])
|
{
|
||||||
}
|
role: "user",
|
||||||
await saveMessage(
|
content: message,
|
||||||
historyId,
|
|
||||||
selectedModel,
|
|
||||||
"assistant",
|
|
||||||
newMessage[appendingIndex].message,
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
const newHistoryId = await saveHistory(message)
|
|
||||||
await saveMessage(newHistoryId.id, selectedModel, "user", message, [
|
|
||||||
image
|
image
|
||||||
])
|
},
|
||||||
await saveMessage(
|
{
|
||||||
newHistoryId.id,
|
role: "assistant",
|
||||||
selectedModel,
|
content: fullText
|
||||||
"assistant",
|
}
|
||||||
newMessage[appendingIndex].message,
|
])
|
||||||
[]
|
|
||||||
)
|
await saveMessageOnSuccess({
|
||||||
setHistoryId(newHistoryId.id)
|
historyId,
|
||||||
}
|
setHistoryId,
|
||||||
|
isRegenerate,
|
||||||
|
selectedModel: selectedModel,
|
||||||
|
message,
|
||||||
|
image,
|
||||||
|
fullText,
|
||||||
|
source: []
|
||||||
|
})
|
||||||
|
|
||||||
setIsProcessing(false)
|
setIsProcessing(false)
|
||||||
setStreaming(false)
|
setStreaming(false)
|
||||||
|
setIsProcessing(false)
|
||||||
|
setStreaming(false)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e?.name === "AbortError") {
|
const errorSave = await saveMessageOnError({
|
||||||
newMessage[appendingIndex].message = newMessage[
|
e,
|
||||||
appendingIndex
|
botMessage: fullText,
|
||||||
].message.slice(0, -1)
|
history,
|
||||||
|
historyId,
|
||||||
|
image,
|
||||||
|
selectedModel,
|
||||||
|
setHistory,
|
||||||
|
setHistoryId,
|
||||||
|
userMessage: message,
|
||||||
|
isRegenerating: isRegenerate
|
||||||
|
})
|
||||||
|
|
||||||
setHistory([
|
if (!errorSave) {
|
||||||
...history,
|
|
||||||
{
|
|
||||||
role: "user",
|
|
||||||
content: message,
|
|
||||||
image
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: "assistant",
|
|
||||||
content: newMessage[appendingIndex].message
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
if (historyId) {
|
|
||||||
await saveMessage(historyId, selectedModel, "user", message, [image])
|
|
||||||
await saveMessage(
|
|
||||||
historyId,
|
|
||||||
selectedModel,
|
|
||||||
"assistant",
|
|
||||||
newMessage[appendingIndex].message,
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
const newHistoryId = await saveHistory(message)
|
|
||||||
await saveMessage(newHistoryId.id, selectedModel, "user", message, [
|
|
||||||
image
|
|
||||||
])
|
|
||||||
await saveMessage(
|
|
||||||
newHistoryId.id,
|
|
||||||
selectedModel,
|
|
||||||
"assistant",
|
|
||||||
newMessage[appendingIndex].message,
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
setHistoryId(newHistoryId.id)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
notification.error({
|
notification.error({
|
||||||
message: t("error"),
|
message: t("error"),
|
||||||
description: e?.message || t("somethingWentWrong")
|
description: e?.message || t("somethingWentWrong")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsProcessing(false)
|
setIsProcessing(false)
|
||||||
setStreaming(false)
|
setStreaming(false)
|
||||||
|
} finally {
|
||||||
|
setAbortController(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,22 +505,34 @@ export const useMessageOption = () => {
|
|||||||
image,
|
image,
|
||||||
isRegenerate = false,
|
isRegenerate = false,
|
||||||
messages: chatHistory,
|
messages: chatHistory,
|
||||||
memory
|
memory,
|
||||||
|
controller
|
||||||
}: {
|
}: {
|
||||||
message: string
|
message: string
|
||||||
image: string
|
image: string
|
||||||
isRegenerate?: boolean
|
isRegenerate?: boolean
|
||||||
messages?: Message[]
|
messages?: Message[]
|
||||||
memory?: ChatHistory
|
memory?: ChatHistory
|
||||||
|
controller?: AbortController
|
||||||
}) => {
|
}) => {
|
||||||
setStreaming(true)
|
setStreaming(true)
|
||||||
|
let signal: AbortSignal
|
||||||
|
if (!controller) {
|
||||||
|
const newController = new AbortController()
|
||||||
|
signal = newController.signal
|
||||||
|
setAbortController(newController)
|
||||||
|
} else {
|
||||||
|
setAbortController(controller)
|
||||||
|
signal = controller.signal
|
||||||
|
}
|
||||||
if (webSearch) {
|
if (webSearch) {
|
||||||
await searchChatMode(
|
await searchChatMode(
|
||||||
message,
|
message,
|
||||||
image,
|
image,
|
||||||
isRegenerate,
|
isRegenerate,
|
||||||
chatHistory || messages,
|
chatHistory || messages,
|
||||||
memory || history
|
memory || history,
|
||||||
|
signal
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
await normalChatMode(
|
await normalChatMode(
|
||||||
@ -598,7 +540,8 @@ export const useMessageOption = () => {
|
|||||||
image,
|
image,
|
||||||
isRegenerate,
|
isRegenerate,
|
||||||
chatHistory || messages,
|
chatHistory || messages,
|
||||||
memory || history
|
memory || history,
|
||||||
|
signal
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -611,28 +554,29 @@ export const useMessageOption = () => {
|
|||||||
}
|
}
|
||||||
if (history.length > 0) {
|
if (history.length > 0) {
|
||||||
const lastMessage = history[history.length - 2]
|
const lastMessage = history[history.length - 2]
|
||||||
let newHistory = history
|
let newHistory = history.slice(0, -2)
|
||||||
let mewMessages = messages
|
let mewMessages = messages
|
||||||
newHistory.pop()
|
|
||||||
mewMessages.pop()
|
mewMessages.pop()
|
||||||
setHistory(newHistory)
|
setHistory(newHistory)
|
||||||
setMessages(mewMessages)
|
setMessages(mewMessages)
|
||||||
await removeMessageUsingHistoryId(historyId)
|
await removeMessageUsingHistoryId(historyId)
|
||||||
if (lastMessage.role === "user") {
|
if (lastMessage.role === "user") {
|
||||||
|
const newController = new AbortController()
|
||||||
await onSubmit({
|
await onSubmit({
|
||||||
message: lastMessage.content,
|
message: lastMessage.content,
|
||||||
image: lastMessage.image || "",
|
image: lastMessage.image || "",
|
||||||
isRegenerate: true,
|
isRegenerate: true,
|
||||||
memory: newHistory
|
memory: newHistory,
|
||||||
|
controller: newController
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const stopStreamingRequest = () => {
|
const stopStreamingRequest = () => {
|
||||||
if (abortControllerRef.current) {
|
if (abortController) {
|
||||||
abortControllerRef.current.abort()
|
abortController.abort()
|
||||||
abortControllerRef.current = null
|
setAbortController(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,7 +597,6 @@ export const useMessageOption = () => {
|
|||||||
message: string,
|
message: string,
|
||||||
isHuman: boolean
|
isHuman: boolean
|
||||||
) => {
|
) => {
|
||||||
// update message and history by index
|
|
||||||
let newMessages = messages
|
let newMessages = messages
|
||||||
let newHistory = history
|
let newHistory = history
|
||||||
|
|
||||||
@ -665,20 +608,21 @@ export const useMessageOption = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const currentHumanMessage = newMessages[index]
|
const currentHumanMessage = newMessages[index]
|
||||||
newMessages[index].message = message
|
|
||||||
newHistory[index].content = message
|
|
||||||
const previousMessages = newMessages.slice(0, index + 1)
|
const previousMessages = newMessages.slice(0, index + 1)
|
||||||
setMessages(previousMessages)
|
setMessages(previousMessages)
|
||||||
const previousHistory = newHistory.slice(0, index + 1)
|
const previousHistory = newHistory.slice(0, index)
|
||||||
setHistory(previousHistory)
|
setHistory(previousHistory)
|
||||||
await updateMessageByIndex(historyId, index, message)
|
await updateMessageByIndex(historyId, index, message)
|
||||||
await deleteChatForEdit(historyId, index)
|
await deleteChatForEdit(historyId, index)
|
||||||
|
const abortController = new AbortController()
|
||||||
await onSubmit({
|
await onSubmit({
|
||||||
message: message,
|
message: message,
|
||||||
image: currentHumanMessage.images[0] || "",
|
image: currentHumanMessage.images[0] || "",
|
||||||
isRegenerate: true,
|
isRegenerate: true,
|
||||||
messages: previousMessages,
|
messages: previousMessages,
|
||||||
memory: previousHistory
|
memory: previousHistory,
|
||||||
|
controller: abortController
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
newMessages[index].message = message
|
newMessages[index].message = message
|
||||||
|
@ -31,7 +31,6 @@ type Message = {
|
|||||||
createdAt: number
|
createdAt: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type Webshare = {
|
type Webshare = {
|
||||||
id: string
|
id: string
|
||||||
title: string
|
title: string
|
||||||
@ -41,7 +40,6 @@ type Webshare = {
|
|||||||
createdAt: number
|
createdAt: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type Prompt = {
|
type Prompt = {
|
||||||
id: string
|
id: string
|
||||||
title: string
|
title: string
|
||||||
@ -125,7 +123,6 @@ export class PageAssitDatabase {
|
|||||||
await this.db.remove(history_id)
|
await this.db.remove(history_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async getAllPrompts(): Promise<Prompts> {
|
async getAllPrompts(): Promise<Prompts> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.db.get("prompts", (result) => {
|
this.db.get("prompts", (result) => {
|
||||||
@ -146,7 +143,12 @@ export class PageAssitDatabase {
|
|||||||
this.db.set({ prompts: newPrompts })
|
this.db.set({ prompts: newPrompts })
|
||||||
}
|
}
|
||||||
|
|
||||||
async updatePrompt(id: string, title: string, content: string, is_system: boolean) {
|
async updatePrompt(
|
||||||
|
id: string,
|
||||||
|
title: string,
|
||||||
|
content: string,
|
||||||
|
is_system: boolean
|
||||||
|
) {
|
||||||
const prompts = await this.getAllPrompts()
|
const prompts = await this.getAllPrompts()
|
||||||
const newPrompts = prompts.map((prompt) => {
|
const newPrompts = prompts.map((prompt) => {
|
||||||
if (prompt.id === id) {
|
if (prompt.id === id) {
|
||||||
@ -164,7 +166,6 @@ export class PageAssitDatabase {
|
|||||||
return prompts.find((prompt) => prompt.id === id)
|
return prompts.find((prompt) => prompt.id === id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async getWebshare(id: string) {
|
async getWebshare(id: string) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.db.get(id, (result) => {
|
this.db.get(id, (result) => {
|
||||||
@ -173,7 +174,6 @@ export class PageAssitDatabase {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async getAllWebshares(): Promise<Webshare[]> {
|
async getAllWebshares(): Promise<Webshare[]> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.db.get("webshares", (result) => {
|
this.db.get("webshares", (result) => {
|
||||||
@ -207,8 +207,7 @@ export class PageAssitDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const generateID = () => {
|
||||||
const generateID = () => {
|
|
||||||
return "pa_xxxx-xxxx-xxx-xxxx".replace(/[x]/g, () => {
|
return "pa_xxxx-xxxx-xxx-xxxx".replace(/[x]/g, () => {
|
||||||
const r = Math.floor(Math.random() * 16)
|
const r = Math.floor(Math.random() * 16)
|
||||||
return r.toString(16)
|
return r.toString(16)
|
||||||
@ -230,11 +229,24 @@ export const saveMessage = async (
|
|||||||
role: string,
|
role: string,
|
||||||
content: string,
|
content: string,
|
||||||
images: string[],
|
images: string[],
|
||||||
source?: any[]
|
source?: any[],
|
||||||
|
time?: number
|
||||||
) => {
|
) => {
|
||||||
const id = generateID()
|
const id = generateID()
|
||||||
const createdAt = Date.now()
|
let createdAt = Date.now()
|
||||||
const message = { id, history_id, name, role, content, images, createdAt, sources: source }
|
if (time) {
|
||||||
|
createdAt += time
|
||||||
|
}
|
||||||
|
const message = {
|
||||||
|
id,
|
||||||
|
history_id,
|
||||||
|
name,
|
||||||
|
role,
|
||||||
|
content,
|
||||||
|
images,
|
||||||
|
createdAt,
|
||||||
|
sources: source
|
||||||
|
}
|
||||||
const db = new PageAssitDatabase()
|
const db = new PageAssitDatabase()
|
||||||
await db.addMessage(message)
|
await db.addMessage(message)
|
||||||
return message
|
return message
|
||||||
@ -292,19 +304,20 @@ export const removeMessageUsingHistoryId = async (history_id: string) => {
|
|||||||
await db.db.set({ [history_id]: chatHistory })
|
await db.db.set({ [history_id]: chatHistory })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const getAllPrompts = async () => {
|
export const getAllPrompts = async () => {
|
||||||
const db = new PageAssitDatabase()
|
const db = new PageAssitDatabase()
|
||||||
return await db.getAllPrompts()
|
return await db.getAllPrompts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const updateMessageByIndex = async (
|
||||||
export const updateMessageByIndex = async (history_id: string, index: number, message: string) => {
|
history_id: string,
|
||||||
|
index: number,
|
||||||
|
message: string
|
||||||
|
) => {
|
||||||
const db = new PageAssitDatabase()
|
const db = new PageAssitDatabase()
|
||||||
const chatHistory = (await db.getChatHistory(history_id)).reverse()
|
const chatHistory = (await db.getChatHistory(history_id)).reverse()
|
||||||
chatHistory[index].content = message
|
chatHistory[index].content = message
|
||||||
await db.db.set({ [history_id]: chatHistory.reverse() })
|
await db.db.set({ [history_id]: chatHistory.reverse() })
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deleteChatForEdit = async (history_id: string, index: number) => {
|
export const deleteChatForEdit = async (history_id: string, index: number) => {
|
||||||
@ -315,7 +328,15 @@ export const deleteChatForEdit = async (history_id: string, index: number) => {
|
|||||||
await db.db.set({ [history_id]: previousHistory.reverse() })
|
await db.db.set({ [history_id]: previousHistory.reverse() })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const savePrompt = async ({ content, title, is_system = false }: { title: string, content: string, is_system: boolean }) => {
|
export const savePrompt = async ({
|
||||||
|
content,
|
||||||
|
title,
|
||||||
|
is_system = false
|
||||||
|
}: {
|
||||||
|
title: string
|
||||||
|
content: string
|
||||||
|
is_system: boolean
|
||||||
|
}) => {
|
||||||
const db = new PageAssitDatabase()
|
const db = new PageAssitDatabase()
|
||||||
const id = generateID()
|
const id = generateID()
|
||||||
const createdAt = Date.now()
|
const createdAt = Date.now()
|
||||||
@ -324,21 +345,28 @@ export const savePrompt = async ({ content, title, is_system = false }: { title:
|
|||||||
return prompt
|
return prompt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const deletePromptById = async (id: string) => {
|
export const deletePromptById = async (id: string) => {
|
||||||
const db = new PageAssitDatabase()
|
const db = new PageAssitDatabase()
|
||||||
await db.deletePrompt(id)
|
await db.deletePrompt(id)
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const updatePrompt = async ({
|
||||||
export const updatePrompt = async ({ content, id, title, is_system }: { id: string, title: string, content: string, is_system: boolean }) => {
|
content,
|
||||||
|
id,
|
||||||
|
title,
|
||||||
|
is_system
|
||||||
|
}: {
|
||||||
|
id: string
|
||||||
|
title: string
|
||||||
|
content: string
|
||||||
|
is_system: boolean
|
||||||
|
}) => {
|
||||||
const db = new PageAssitDatabase()
|
const db = new PageAssitDatabase()
|
||||||
await db.updatePrompt(id, title, content, is_system)
|
await db.updatePrompt(id, title, content, is_system)
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const getPromptById = async (id: string) => {
|
export const getPromptById = async (id: string) => {
|
||||||
if (!id || id.trim() === "") return null
|
if (!id || id.trim() === "") return null
|
||||||
const db = new PageAssitDatabase()
|
const db = new PageAssitDatabase()
|
||||||
@ -354,10 +382,19 @@ export const deleteWebshare = async (id: string) => {
|
|||||||
const db = new PageAssitDatabase()
|
const db = new PageAssitDatabase()
|
||||||
await db.deleteWebshare(id)
|
await db.deleteWebshare(id)
|
||||||
return id
|
return id
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const saveWebshare = async ({ title, url, api_url, share_id }: { title: string, url: string, api_url: string, share_id: string }) => {
|
export const saveWebshare = async ({
|
||||||
|
title,
|
||||||
|
url,
|
||||||
|
api_url,
|
||||||
|
share_id
|
||||||
|
}: {
|
||||||
|
title: string
|
||||||
|
url: string
|
||||||
|
api_url: string
|
||||||
|
share_id: string
|
||||||
|
}) => {
|
||||||
const db = new PageAssitDatabase()
|
const db = new PageAssitDatabase()
|
||||||
const id = generateID()
|
const id = generateID()
|
||||||
const createdAt = Date.now()
|
const createdAt = Date.now()
|
||||||
@ -368,7 +405,7 @@ export const saveWebshare = async ({ title, url, api_url, share_id }: { title: s
|
|||||||
|
|
||||||
export const getUserId = async () => {
|
export const getUserId = async () => {
|
||||||
const db = new PageAssitDatabase()
|
const db = new PageAssitDatabase()
|
||||||
const id = await db.getUserID() as string
|
const id = (await db.getUserID()) as string
|
||||||
if (!id || id?.trim() === "") {
|
if (!id || id?.trim() === "") {
|
||||||
const user_id = "user_xxxx-xxxx-xxx-xxxx-xxxx".replace(/[x]/g, () => {
|
const user_id = "user_xxxx-xxxx-xxx-xxxx-xxxx".replace(/[x]/g, () => {
|
||||||
const r = Math.floor(Math.random() * 16)
|
const r = Math.floor(Math.random() * 16)
|
||||||
@ -378,4 +415,4 @@ export const getUserId = async () => {
|
|||||||
return user_id
|
return user_id
|
||||||
}
|
}
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ export type Message = {
|
|||||||
sources: any[]
|
sources: any[]
|
||||||
images?: string[]
|
images?: string[]
|
||||||
search?: WebSearch
|
search?: WebSearch
|
||||||
|
id?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ChatHistory = {
|
export type ChatHistory = {
|
||||||
|
18
src/types/message.ts
Normal file
18
src/types/message.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
type WebSearch = {
|
||||||
|
search_engine: string
|
||||||
|
search_url: string
|
||||||
|
search_query: string
|
||||||
|
search_results: {
|
||||||
|
title: string
|
||||||
|
link: string
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
export type Message = {
|
||||||
|
isBot: boolean
|
||||||
|
name: string
|
||||||
|
message: string
|
||||||
|
sources: any[]
|
||||||
|
images?: string[]
|
||||||
|
search?: WebSearch
|
||||||
|
id?: string
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user