diff --git a/src/components/Common/Playground/Data.tsx b/src/components/Common/Playground/Data.tsx
index 89269fb..7dae897 100644
--- a/src/components/Common/Playground/Data.tsx
+++ b/src/components/Common/Playground/Data.tsx
@@ -11,8 +11,7 @@ const defaultData: IodRegistryEntry[] = [
{
name: "固态电池固体电解质材料数据集",
doId: "CSTR:16666.11.nbsdc.9bjqrscd",
- description:
- "国家基础学科公共科学数据中心"
+ description: "国家基础学科公共科学数据中心"
},
{
name: "固体颗粒物与流体耦合",
@@ -98,31 +97,22 @@ type Props = {
className?: string
}
export const PlaygroundData: React.FC = ({ className }) => {
- const { messages, iodLoading, currentMessageId, iodSearch } =
- useMessageOption()
+ const { iodLoading } = useMessageOption()
- const { setShowPlayground, setDetailHeader, setDetailMain } =
- useIodPlaygroundContext()
+ const {
+ setShowPlayground,
+ setDetailHeader,
+ setDetailMain,
+ currentIodMessage
+ } = useIodPlaygroundContext()
const data = useMemo(() => {
- // 确保loading状态时数据大于3
- if (iodLoading) {
- return defaultData
- }
-
- if (messages.length && iodSearch) {
- const currentMessage = messages?.find(
- (message) => message.id === currentMessageId
- )
- return currentMessage?.iodSources.data.data ?? []
- }
-
- return defaultData
- }, [currentMessageId, messages, iodLoading, iodSearch])
+ return currentIodMessage ? currentIodMessage.data?.data ?? [] : defaultData
+ }, [currentIodMessage])
const title = useMemo(() => {
- return messages.length > 0 ? "推荐数据" : "热点数据"
- }, [messages])
+ return currentIodMessage ? "推荐数据" : "热点数据"
+ }, [currentIodMessage])
const showMore = () => {
setShowPlayground(false)
@@ -133,7 +123,7 @@ export const PlaygroundData: React.FC = ({ className }) => {
onClick={() => setShowPlayground(false)}
/>
)
- setDetailMain()
+ setDetailMain()
}
return (
@@ -142,7 +132,7 @@ export const PlaygroundData: React.FC = ({ className }) => {
{/* 数据导航 */}
{/* 数据列表 */}
-
+
)
diff --git a/src/components/Common/Playground/IodRelevant.tsx b/src/components/Common/Playground/IodRelevant.tsx
index 5b979b6..ca1e4f4 100644
--- a/src/components/Common/Playground/IodRelevant.tsx
+++ b/src/components/Common/Playground/IodRelevant.tsx
@@ -10,6 +10,7 @@ import { DatasetIcon } from "@/components/Icons/Dataset.tsx"
import { TechCompanyIcon } from "@/components/Icons/TechCompany.tsx"
import { ResearchInstitutesIcon } from "@/components/Icons/ResearchInstitutes.tsx"
import { NSDCIcon } from "@/components/Icons/NSDC.tsx"
+import { useIodPlaygroundContext } from "@/components/Option/Playground/PlaygroundIod.tsx"
const rotate = keyframes`
0% {
@@ -32,8 +33,8 @@ const breathe = keyframes`
}
`
-// 花瓣
-const CircleElement = styled.div<{ delay: number; playing: boolean }>`
+// 花瓣 /* ${(props) => (props.playing ? "running" : "paused")}; */
+const CircleElement = styled.div<{ delay: number }>`
position: absolute;
width: 300px;
height: 160px;
@@ -46,7 +47,7 @@ const CircleElement = styled.div<{ delay: number; playing: boolean }>`
${rotate} 6s linear infinite,
${breathe} 2s infinite alternate;
animation-delay: ${(props) => props.delay}s;
- animation-play-state: ${(props) => (props.playing ? "running" : "paused")};
+ animation-play-state: running;
animation-duration: 3s; /* 添加动画总持续时间 */
animation-fill-mode: forwards; /* 保持动画结束时的状态 */
`
@@ -221,24 +222,19 @@ type Props = {
className?: string
}
export const PlaygroundIodRelevant: React.FC = ({ className }) => {
- const { messages, iodLoading, currentMessageId, iodSearch } =
- useMessageOption()
+ const { iodLoading, iodSearch } = useMessageOption()
+
+ const { currentIodMessage } = useIodPlaygroundContext()
const showSearchData = useMemo(() => {
- return iodSearch && messages.length > 0 && !iodLoading
- }, [iodSearch, messages, iodLoading])
-
-
+ return currentIodMessage && !iodLoading
+ }, [currentIodMessage, iodLoading])
const data = useMemo(() => {
- const currentMessage = messages?.find(
- (message) => message.id === currentMessageId
- )
-
- const loading = (iodSearch && iodLoading)
- const text = loading ? '正' : '已'
- const text2 = loading ? '进行' : '完成'
- const text3 = loading ? '……' : ''
+ const loading = iodSearch && iodLoading
+ const text = loading ? "正" : "已"
+ const text2 = loading ? "进行" : "完成"
+ const text3 = loading ? "……" : ""
const duration = loading ? 2.5 : 0
return [
@@ -256,7 +252,12 @@ export const PlaygroundIodRelevant: React.FC = ({ className }) => {
高等院校的
-
+
万个
科学数据集中{text2}搜索{text3}
@@ -268,7 +269,7 @@ export const PlaygroundIodRelevant: React.FC = ({ className }) => {
{" "}
@@ -288,9 +289,14 @@ export const PlaygroundIodRelevant: React.FC = ({ className }) => {
万篇
- 学术论文、
+ 数据论文、
-
+
万个
数据项目中{text2}搜索{text3}
@@ -302,7 +308,7 @@ export const PlaygroundIodRelevant: React.FC = ({ className }) => {
{" "}
@@ -324,7 +330,13 @@ export const PlaygroundIodRelevant: React.FC = ({ className }) => {
高等院校和科研机构、
{" "}
- 万
+
+ 万
家科技型企业、
@@ -340,7 +352,7 @@ export const PlaygroundIodRelevant: React.FC = ({ className }) => {
{" "}
@@ -353,7 +365,7 @@ export const PlaygroundIodRelevant: React.FC = ({ className }) => {
)
}
]
- }, [messages, iodLoading])
+ }, [showSearchData, iodLoading])
return (
= ({ className }) => {
@@ -376,16 +388,14 @@ export const PlaygroundIodRelevant: React.FC = ({ className }) => {
- {messages.length > 0
- ? "科创数联网深度搜索"
- : "科创数联网连接资源"}
+ {currentIodMessage ? "科创数联网深度搜索" : "科创数联网连接资源"}
{/**/}
- {messages.length > 0
+ {currentIodMessage
? "下面是在科创数联网上进行深度搜索得到的相关数据、场景和团队"
: "下面是科创数联网连接的数据、场景和团队"}
@@ -393,7 +403,7 @@ export const PlaygroundIodRelevant: React.FC = ({ className }) => {
{/* Content */}
- {messages.length ? (
+ {currentIodMessage ? (
= ({ className }) => {
/>
)}
-
{item.title}
-
+
{item.description && (
-
+
{item.description}
-
+
)}
diff --git a/src/components/Common/Playground/Message.tsx b/src/components/Common/Playground/Message.tsx
index b857ecb..a2655a7 100644
--- a/src/components/Common/Playground/Message.tsx
+++ b/src/components/Common/Playground/Message.tsx
@@ -25,8 +25,10 @@ import { GenerationInfo } from "./GenerationInfo"
import { parseReasoning } from "@/libs/reasoning"
import { humanizeMilliseconds } from "@/utils/humanize-milliseconds"
import { AllIodRegistryEntry } from "@/types/iod.ts"
+import { PiNetwork } from "react-icons/pi"
type Props = {
+ id?: string
message: string
message_type?: string
hideCopy?: boolean
@@ -50,9 +52,11 @@ type Props = {
generationInfo?: any
isStreaming: boolean
reasoningTimeTaken?: number
+ iodSearch?: boolean
+ setCurrentMessageId: (id: string) => void
}
-export const PlaygroundMessage = (props: Props) => {
+export const PlaygroundMessage: React.FC = (props) => {
const [isBtnPressed, setIsBtnPressed] = React.useState(false)
const [editMode, setEditMode] = React.useState(false)
@@ -258,6 +262,18 @@ export const PlaygroundMessage = (props: Props) => {
)}
{props.isBot && (
<>
+ {/*数联网搜索*/}
+ {props.iodSearch && (
+
+
+
+ )}
+
{!props.hideCopy && (
+
)
},
{
key: 1,
label: (
- {
setIodSearch(false)
}}>
@@ -242,7 +242,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
关闭
快速直接回答
-
+
)
}
]
@@ -397,7 +397,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
className={`!px-[5px] flex items-center justify-center dark:text-gray-300 ${
chatMode === "rag" ? "hidden" : "block"
}`}>
-
+
)}
@@ -420,12 +420,12 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
}}
className={`flex items-center justify-center dark:text-gray-300 !px-[5px]`}>
{!isListening ? (
-
+
) : (
diff --git a/src/components/Option/Playground/PlaygroundIod.tsx b/src/components/Option/Playground/PlaygroundIod.tsx
index e6ab985..c16773c 100644
--- a/src/components/Option/Playground/PlaygroundIod.tsx
+++ b/src/components/Option/Playground/PlaygroundIod.tsx
@@ -9,7 +9,7 @@ import { PlaygroundTeam } from "@/components/Common/Playground/Team.tsx"
import { Card } from "antd"
import { CloseOutlined } from "@ant-design/icons"
import { useMessageOption } from "@/hooks/useMessageOption.tsx"
-import { Message } from "@/types/message.ts"
+import { AllIodRegistryEntry } from "@/types/iod.ts"
// 定义 Context 类型
interface IodPlaygroundContextType {
@@ -19,7 +19,7 @@ interface IodPlaygroundContextType {
setDetailHeader: React.Dispatch>
detailMain: React.ReactNode
setDetailMain: React.Dispatch>
- currentIodMessage: Message | null
+ currentIodMessage?: AllIodRegistryEntry
}
// 创建 Context
@@ -41,36 +41,34 @@ export const useIodPlaygroundContext = () => {
const PlaygroundIodProvider: React.FC<{ children: React.ReactNode }> = ({
children
}) => {
- const { messages, iodLoading, currentMessageId, iodSearch } =
- useMessageOption()
+ const { messages, iodLoading, currentMessageId } = useMessageOption()
const [showPlayground, setShowPlayground] = useState(true)
const [detailHeader, setDetailHeader] = useState(<>>)
const [detailMain, setDetailMain] = useState(<>>)
- const currentIodMessage = useMemo(() => {
- if (iodLoading) {
- return null
+ const currentIodMessage = useMemo(() => {
+ console.log('messages', messages)
+ console.log("currentMessageId", currentMessageId)
+ console.log("iodLoading", iodLoading)
+ // loading 返回 undefined是为了避免,数据不足三个的情况
+ if (iodLoading || !messages.length) {
+ return undefined
}
- if (messages.length && iodSearch) {
- // 如果不存在currentMessageId默认返回最后一个message
- if (!currentMessageId) {
- return messages.at(-1)
- }
-
- const currentMessage = messages?.find(
- (message) => message.id === currentMessageId
- )
- if (currentMessage) {
- return currentMessage
- }
- // 如果当前message不存在最后一个message
- return messages.at(-1)
+ // 如果不存在currentMessageId默认返回最后一个message
+ if (!currentMessageId) {
+ const lastMessage = messages.at(-1)
+ // 如果最后一次message没有开启数联网搜索,则返回undefined
+ return lastMessage?.iodSearch ? lastMessage.iodSources : undefined
}
- return null
- }, [currentMessageId, messages, iodLoading, iodSearch])
+ const currentMessage = messages?.find(
+ (message) => message.id === currentMessageId
+ )
+ console.log("currentMessage", currentMessage)
+ return currentMessage?.iodSearch ? currentMessage.iodSources : undefined
+ }, [currentMessageId, messages, iodLoading])
return (
{
)
}
-
export const PlaygroundIod = () => {
return (
diff --git a/src/components/Option/Playground/PlaygroundNewChat.tsx b/src/components/Option/Playground/PlaygroundNewChat.tsx
deleted file mode 100644
index d9816af..0000000
--- a/src/components/Option/Playground/PlaygroundNewChat.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { PencilIcon } from "lucide-react"
-import { useMessage } from "../../../hooks/useMessage"
-import { useTranslation } from 'react-i18next';
-
-export const PlaygroundNewChat = () => {
- const { setHistory, setMessages, setHistoryId } = useMessage()
- const { t } = useTranslation('optionChat')
-
- const handleClick = () => {
- setHistoryId(null)
- setMessages([])
- setHistory([])
- }
-
- return (
-
- )
-}
diff --git a/src/components/Option/Settings/iod.tsx b/src/components/Option/Settings/iod.tsx
index 70cf770..fb44d2e 100644
--- a/src/components/Option/Settings/iod.tsx
+++ b/src/components/Option/Settings/iod.tsx
@@ -1,41 +1,20 @@
import { useTranslation } from "react-i18next"
import TextArea from "antd/es/input/TextArea"
-import { useEffect, useState } from "react"
+import { IodDb } from "@/db/iod.ts"
+import { useState } from "react"
export const IodApp = () => {
const { t } = useTranslation("settings")
+ const db = IodDb.getInstance()
- const [connectVal, setConnectVal] = useState
('')
+ const [connection, setConnection] = useState(JSON.stringify(db.getIodConnection(), null, 2))
const setConnectValWrap = (val: string) => {
- localStorage.setItem("iod-connect", val)
- setConnectVal(val)
+ db.insertIodConnection(JSON.parse(val))
+ setConnection(val)
}
- useEffect(() => {
- const val = localStorage.getItem("iod-connect")
- const defaultVal = {
- gatewayUrl: "tcp://reg01.public.internetofdata.cn:21037",
- registry: "data/Registry",
- localRepository: "data/Repository",
- doBrowser: "http://021.node.internetapi.cn:21030/SCIDE/SCManager"
- }
- if (!val) {
- localStorage.setItem(
- "iod-connect",
- JSON.stringify(defaultVal)
- )
- setConnectVal(JSON.stringify(defaultVal, null, 2))
- return
- }
- try {
- const val = localStorage.getItem("iod-connect")
- setConnectVal(JSON.stringify(JSON.parse(val), null, 2))
- } catch (e) {
- setConnectVal(JSON.stringify(defaultVal, null, 2))
- }
- }, [])
return (
@@ -47,7 +26,7 @@ export const IodApp = () => {
连接配置
-
)
diff --git a/src/db/index.ts b/src/db/index.ts
index 7f33c4e..e67e3cb 100644
--- a/src/db/index.ts
+++ b/src/db/index.ts
@@ -1,8 +1,7 @@
-import {
- type ChatHistory as ChatHistoryType,
- type Message as MessageType
-} from "~/store/option"
+import { type ChatHistory as ChatHistoryType } from "~/store/option"
import { AllIodRegistryEntry } from "@/types/iod.ts"
+import { type Message as MessageType } from "@/types/message.ts"
+import { getDefaultIodSources } from "@/libs/iod.ts"
type HistoryInfo = {
id: string
@@ -249,38 +248,31 @@ export const saveHistory = async (
await db.addChatHistory(history)
return history
}
-
-export const saveMessage = async (
- history_id: string,
- name: string,
- role: string,
- content: string,
- images: string[],
- webSources?: any[],
- iodSources?: AllIodRegistryEntry,
- time?: number,
- message_type?: string,
- generationInfo?: any,
+export type HistoryMessage = {
+ history_id: string
+ name: string
+ role: string
+ content: string
+ images: string[]
+ iodSearch?: boolean
+ webSearch?: boolean
+ webSources?: any[]
+ iodSources?: AllIodRegistryEntry
+ createdAt?: number
+ messageType?: string
+ generationInfo?: any
reasoning_time_taken?: number
-) => {
+}
+export const saveMessage = async (msg: HistoryMessage): Promise => {
const id = generateID()
let createdAt = Date.now()
- if (time) {
- createdAt += time
+ if (msg.createdAt) {
+ createdAt += msg.createdAt
}
const message = {
+ ...msg,
id,
- history_id,
- name,
- role,
- content,
- images,
createdAt,
- webSources,
- iodSources,
- messageType: message_type,
- generationInfo: generationInfo,
- reasoning_time_taken
}
const db = new PageAssitDatabase()
await db.addMessage(message)
@@ -304,11 +296,12 @@ export const formatToMessage = (messages: MessageHistory): MessageType[] => {
messages.sort((a, b) => a.createdAt - b.createdAt)
return messages.map((message) => {
return {
+ ...message,
isBot: message.role === "assistant",
message: message.content,
name: message.name,
webSources: message?.webSources || [],
- iodSources: message?.iodSources || { data: [], scenario: [], organization: []},
+ iodSources: message?.iodSources || getDefaultIodSources(),
images: message.images || [],
generationInfo: message?.generationInfo,
reasoning_time_taken: message?.reasoning_time_taken
diff --git a/src/db/iod.ts b/src/db/iod.ts
new file mode 100644
index 0000000..8c9ab62
--- /dev/null
+++ b/src/db/iod.ts
@@ -0,0 +1,74 @@
+const iodConnection = "iodConnection-g3"
+
+export const defaultIodConnectionConfig = {
+ gatewayUrl: "tcp://reg01.public.internetofdata.cn:21037",
+ registry: "data/Registry",
+ localRepository: "data/Repository",
+ doBrowser: "http://021.node.internetapi.cn:21030/SCIDE/SCManager"
+} as const
+
+export type IodConnectionConfig = {
+ gatewayUrl: string
+ registry: string
+ localRepository: string
+ doBrowser: string
+}
+
+export class IodDb {
+ private static instance: IodDb
+ private static iodConnectionConfig: IodConnectionConfig | null = null
+
+ // 单例模式
+ static getInstance(): IodDb {
+ if (!IodDb.instance) {
+ IodDb.instance = new IodDb()
+ }
+ return IodDb.instance
+ }
+
+ insertIodConnection(config: IodConnectionConfig): void {
+ try {
+ localStorage.setItem(iodConnection, JSON.stringify(config))
+ IodDb.iodConnectionConfig = config
+ } catch (error) {
+ console.error('Failed to save IOD connection config:', error)
+ throw new Error('Failed to save IOD connection configuration')
+ }
+ }
+
+ getIodConnection(): IodConnectionConfig {
+ // 如果已经有缓存,直接返回
+ if (IodDb.iodConnectionConfig) {
+ return IodDb.iodConnectionConfig
+ }
+
+ try {
+ const val = localStorage.getItem(iodConnection)
+ if (!val) {
+ return defaultIodConnectionConfig
+ }
+ IodDb.iodConnectionConfig = JSON.parse(val)
+ } catch (error) {
+ console.warn('Failed to parse IOD connection config, using default:', error)
+ return defaultIodConnectionConfig
+ }
+
+ }
+
+ // 添加清除配置的方法
+ clearIodConnection(): void {
+ try {
+ localStorage.removeItem(iodConnection)
+ IodDb.iodConnectionConfig = null
+ } catch (error) {
+ console.error('Failed to clear IOD connection config:', error)
+ throw new Error('Failed to clear IOD connection configuration')
+ }
+ }
+
+ getIodConfig() {
+ return {
+ connection: this.getIodConnection(),
+ }
+ }
+}
diff --git a/src/hooks/chat-helper/index.ts b/src/hooks/chat-helper/index.ts
index e49cc31..a78b9cf 100644
--- a/src/hooks/chat-helper/index.ts
+++ b/src/hooks/chat-helper/index.ts
@@ -1,4 +1,4 @@
-import { saveHistory, saveMessage } from "@/db"
+import { HistoryMessage, saveHistory, saveMessage } from "@/db"
import {
setLastUsedChatModel,
setLastUsedChatSystemPrompt
@@ -23,7 +23,9 @@ export const saveMessageOnError = async ({
message_source = "web-ui",
message_type,
prompt_content,
- prompt_id
+ prompt_id,
+ iodSearch,
+ webSearch,
}: {
e: any
setHistory: (history: ChatHistory) => void
@@ -38,7 +40,9 @@ export const saveMessageOnError = async ({
message_source?: "copilot" | "web-ui"
message_type?: string
prompt_id?: string
- prompt_content?: string
+ prompt_content?: string,
+ iodSearch?: boolean,
+ webSearch?: boolean,
}) => {
if (
e?.name === "AbortError" ||
@@ -59,31 +63,31 @@ export const saveMessageOnError = async ({
}
])
+ const defaultMessage: HistoryMessage = {
+ history_id: historyId,
+ name: selectedModel,
+ role: "assistant",
+ content: botMessage,
+ webSources: [],
+ iodSources: getDefaultIodSources(),
+ messageType: message_type,
+ iodSearch,
+ webSearch,
+ images: []
+ }
+
if (historyId) {
if (!isRegenerating) {
- await saveMessage(
- historyId,
- selectedModel,
- "user",
- userMessage,
- [image],
- [],
- getDefaultIodSources(),
- 1,
- message_type
- )
+ await saveMessage({
+ ...JSON.parse(JSON.stringify(defaultMessage)),
+ role: "user",
+ content: userMessage,
+ images: [image]
+ })
}
- await saveMessage(
- historyId,
- selectedModel,
- "assistant",
- botMessage,
- [],
- [],
- getDefaultIodSources(),
- 2,
- message_type
- )
+ await saveMessage({
+ ...JSON.parse(JSON.stringify(defaultMessage))
+ })
await setLastUsedChatModel(historyId, selectedModel)
if (prompt_id || prompt_content) {
await setLastUsedChatSystemPrompt(historyId, {
@@ -95,28 +99,19 @@ export const saveMessageOnError = async ({
const title = await generateTitle(selectedModel, userMessage, userMessage)
const newHistoryId = await saveHistory(title, false, message_source)
if (!isRegenerating) {
- await saveMessage(
- newHistoryId.id,
- selectedModel,
- "user",
- userMessage,
- [image],
- [],
- getDefaultIodSources(),
- 1,
- message_type
- )
+ await saveMessage({
+ ...JSON.parse(JSON.stringify(defaultMessage)),
+ history_id: newHistoryId.id,
+ content: userMessage,
+ role: "user",
+ images: [image]
+ })
}
await saveMessage(
- newHistoryId.id,
- selectedModel,
- "assistant",
- botMessage,
- [],
- [],
- getDefaultIodSources(),
- 2,
- message_type
+ {
+ ...JSON.parse(JSON.stringify(defaultMessage)),
+ history_id: newHistoryId.id,
+ },
)
setHistoryId(newHistoryId.id)
await setLastUsedChatModel(newHistoryId.id, selectedModel)
@@ -142,6 +137,8 @@ export const saveMessageOnSuccess = async ({
message,
image,
fullText,
+ iodSearch,
+ webSearch,
webSources,
iodSources,
message_source = "web-ui",
@@ -158,6 +155,8 @@ export const saveMessageOnSuccess = async ({
message: string
image: string
fullText: string
+ iodSearch?: boolean
+ webSearch?: boolean
webSources: any[]
iodSources: AllIodRegistryEntry
message_source?: "copilot" | "web-ui"
@@ -168,34 +167,38 @@ export const saveMessageOnSuccess = async ({
reasoning_time_taken?: number
}) => {
var botMessage
+
+ const defaultMessage: HistoryMessage = {
+ history_id: historyId,
+ name: selectedModel,
+ role: "assistant",
+ content: fullText,
+ webSources: webSources,
+ iodSources: iodSources,
+ messageType: message_type,
+ images: [],
+ iodSearch,
+ webSearch,
+ generationInfo,
+ reasoning_time_taken,
+ }
if (historyId) {
if (!isRegenerate) {
await saveMessage(
- historyId,
- selectedModel,
- "user",
- message,
- [image],
- [],
- getDefaultIodSources(),
- 1,
- message_type,
- generationInfo,
- reasoning_time_taken
+ {
+ ...JSON.parse(JSON.stringify(defaultMessage)),
+ role: "user",
+ content: message,
+ images: [image],
+ webSources: [],
+ iodSources: getDefaultIodSources(),
+ },
)
}
botMessage = await saveMessage(
- historyId,
- selectedModel!,
- "assistant",
- fullText,
- [],
- webSources,
- iodSources,
- 2,
- message_type,
- generationInfo,
- reasoning_time_taken
+ {
+ ...JSON.parse(JSON.stringify(defaultMessage)),
+ }
)
updateDialog(historyId, botMessage)
await setLastUsedChatModel(historyId, selectedModel!)
@@ -209,30 +212,21 @@ export const saveMessageOnSuccess = async ({
const title = await generateTitle(selectedModel, message, message)
const newHistoryId = await saveHistory(title, false, message_source)
await saveMessage(
- newHistoryId.id,
- selectedModel,
- "user",
- message,
- [image],
- [],
- getDefaultIodSources(),
- 1,
- message_type,
- generationInfo,
- reasoning_time_taken
+ {
+ ...JSON.parse(JSON.stringify(defaultMessage)),
+ history_id: newHistoryId.id,
+ role: "user",
+ content: message,
+ images: [image],
+ webSources: [],
+ iodSources: getDefaultIodSources(),
+ },
)
botMessage = await saveMessage(
- newHistoryId.id,
- selectedModel!,
- "assistant",
- fullText,
- [],
- webSources,
- iodSources,
- 2,
- message_type,
- generationInfo,
- reasoning_time_taken
+ {
+ ...JSON.parse(JSON.stringify(defaultMessage)),
+ history_id: newHistoryId.id,
+ }
)
updateDialog(newHistoryId.id, botMessage)
setHistoryId(newHistoryId.id)
diff --git a/src/hooks/useMessage.tsx b/src/hooks/useMessage.tsx
index 088f6b7..315411c 100644
--- a/src/hooks/useMessage.tsx
+++ b/src/hooks/useMessage.tsx
@@ -2,12 +2,12 @@ import React from "react"
import { cleanUrl } from "~/libs/clean-url"
import {
defaultEmbeddingModelForRag,
- geWebSearchFollowUpPrompt,
getOllamaURL,
+ geWebSearchFollowUpPrompt,
promptForRag,
systemPromptForNonRag
} from "~/services/ollama"
-import { useStoreMessageOption, type Message } from "~/store/option"
+import { useStoreMessageOption } from "~/store/option"
import { useStoreMessage } from "~/store"
import { SystemMessage } from "@langchain/core/messages"
import { getDataFromCurrentTab } from "~/libs/get-html"
@@ -43,6 +43,7 @@ import {
} from "@/libs/reasoning"
import { AllIodRegistryEntry } from "@/types/iod.ts"
import { getDefaultIodSources } from "@/libs/iod.ts"
+import { Message } from "@/types/message.ts"
export const useMessage = () => {
const {
diff --git a/src/hooks/useMessageOption.tsx b/src/hooks/useMessageOption.tsx
index b6f1bda..f6128ab 100644
--- a/src/hooks/useMessageOption.tsx
+++ b/src/hooks/useMessageOption.tsx
@@ -7,7 +7,7 @@ import {
promptForRag,
systemPromptForNonRagOption
} from "~/services/ollama"
-import type { ChatHistory, Message, MeteringEntry } from "~/store/option"
+import type { ChatHistory, MeteringEntry } from "~/store/option"
import { useStoreMessageOption } from "~/store/option"
import { SystemMessage } from "@langchain/core/messages"
import {
@@ -47,6 +47,7 @@ import {
removeReasoning
} from "@/libs/reasoning"
import { getDefaultIodSources } from "@/libs/iod.ts"
+import type { Message } from "@/types/message.ts"
export const useMessageOption = () => {
const {
@@ -214,36 +215,39 @@ export const useMessageOption = () => {
data: meter
})
+ let defaultMessage: Message = {
+ isBot: true,
+ name: selectedModel,
+ message,
+ iodSearch,
+ webSearch,
+ webSources: [],
+ iodSources: getDefaultIodSources(),
+ images: [image]
+ }
+
if (!isRegenerate) {
newMessage = [
...messages,
{
+ ...JSON.parse(JSON.stringify(defaultMessage)),
+ id: generateID(),
isBot: false,
name: "You",
- message,
- webSources: [],
- iodSources: getDefaultIodSources(),
- images: [image]
},
{
- isBot: true,
- name: selectedModel,
+ ...JSON.parse(JSON.stringify(defaultMessage)),
+ id: generateMessageId,
message: "",
- webSources: [],
- iodSources: getDefaultIodSources(),
- id: generateMessageId
}
]
} else {
newMessage = [
...messages,
{
- isBot: true,
- name: selectedModel,
- message: "▋",
- webSources: [],
- iodSources: getDefaultIodSources(),
- id: generateMessageId
+ ...JSON.parse(JSON.stringify(defaultMessage)),
+ id: generateMessageId,
+ message: " ",
}
]
}
@@ -525,6 +529,8 @@ export const useMessageOption = () => {
message,
image,
fullText,
+ iodSearch,
+ webSearch,
webSources,
iodSources,
generationInfo,
@@ -566,7 +572,9 @@ export const useMessageOption = () => {
setHistory,
setHistoryId,
userMessage: message,
- isRegenerating: isRegenerate
+ isRegenerating: isRegenerate,
+ iodSearch,
+ webSearch,
})
if (!errorSave) {
@@ -672,6 +680,7 @@ export const useMessageOption = () => {
let newMessage: Message[] = []
let generateMessageId = generateID()
+ setCurrentMessageId(generateMessageId)
const meter: MeteringEntry = {
id: generateMessageId,
queryContent: message,
@@ -682,7 +691,6 @@ export const useMessageOption = () => {
loading: true,
data: meter
})
-
if (!isRegenerate) {
newMessage = [
...messages,
@@ -690,6 +698,7 @@ export const useMessageOption = () => {
isBot: false,
name: "You",
message,
+ id: generateID(),
webSources: [],
iodSources: getDefaultIodSources(),
images: [image]
@@ -889,7 +898,6 @@ export const useMessageOption = () => {
content: fullText
}
])
-
await saveMessageOnSuccess({
historyId,
setHistoryId,
@@ -898,6 +906,8 @@ export const useMessageOption = () => {
message,
image,
fullText,
+ iodSearch,
+ webSearch,
source: [],
generationInfo,
prompt_content: promptContent,
@@ -914,8 +924,8 @@ export const useMessageOption = () => {
const { cot, content } = responseResolver(fullText)
const currentMeteringEntry = {
...meter,
- modelInputTokenCount: prompt.length,
- modelOutputTokenCount: fullText.length,
+ modelInputTokenCount: prompt? prompt.length : 0,
+ modelOutputTokenCount: fullText? fullText.length : 0,
model: ollama.modelName ?? ollama.model,
relatedDataCount: 0,
timeTaken: new Date().getTime() - chatStartTime.getTime(),
@@ -943,7 +953,9 @@ export const useMessageOption = () => {
userMessage: message,
isRegenerating: isRegenerate,
prompt_content: promptContent,
- prompt_id: promptId
+ prompt_id: promptId,
+ iodSearch,
+ webSearch,
})
if (!errorSave) {
@@ -1274,7 +1286,9 @@ export const useMessageOption = () => {
fullText,
source,
generationInfo,
- reasoning_time_taken: timetaken
+ reasoning_time_taken: timetaken,
+ iodSearch,
+ webSearch,
})
setIsProcessing(false)
@@ -1290,7 +1304,9 @@ export const useMessageOption = () => {
setHistory,
setHistoryId,
userMessage: message,
- isRegenerating: isRegenerate
+ isRegenerating: isRegenerate,
+ iodSearch,
+ webSearch,
})
if (!errorSave) {
diff --git a/src/libs/export-import.ts b/src/libs/export-import.ts
index 50bda8b..0ec77ce 100644
--- a/src/libs/export-import.ts
+++ b/src/libs/export-import.ts
@@ -6,6 +6,7 @@ import {
} from "@/db"
import { exportKnowledge, importKnowledge } from "@/db/knowledge"
import { exportVectors, importVectors } from "@/db/vector"
+import { IodDb } from "@/db/iod"
import { message } from "antd"
export const exportPageAssistData = async () => {
@@ -13,12 +14,14 @@ export const exportPageAssistData = async () => {
const chat = await exportChatHistory()
const vector = await exportVectors()
const prompts = await exportPrompts()
+ const iod = IodDb.getInstance().getIodConfig()
const data = {
knowledge,
chat,
vector,
- prompts
+ prompts,
+ iod
}
const dataStr = JSON.stringify(data)
@@ -34,6 +37,7 @@ export const exportPageAssistData = async () => {
}
export const importPageAssistData = async (file: File) => {
+ debugger
const reader = new FileReader()
reader.onload = async () => {
try {
@@ -55,6 +59,10 @@ export const importPageAssistData = async (file: File) => {
await importPrompts(data.prompts)
}
+ if(data?.iod) {
+ IodDb.getInstance().insertIodConnection(data.iod)
+ }
+
message.success("Data imported successfully")
} catch (e) {
console.error(e)
diff --git a/src/store/option.tsx b/src/store/option.tsx
index 3eb253e..d2684e5 100644
--- a/src/store/option.tsx
+++ b/src/store/option.tsx
@@ -1,28 +1,6 @@
import { Knowledge } from "@/db/knowledge"
import { create } from "zustand"
-import { AllIodRegistryEntry } from "@/types/iod.ts"
-
-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
- webSources: any[]
- iodSources: AllIodRegistryEntry
- images?: string[]
- search?: WebSearch
- reasoning_time_taken?: number
- id?: string
- messageType?: string
-}
+import { Message } from "esbuild"
export type ChatHistory = {
role: "user" | "assistant" | "system"
@@ -36,8 +14,11 @@ type State = {
setMessages: (messages: Message[]) => void
history: ChatHistory
setHistory: (history: ChatHistory) => void
- currentMeteringEntry: {data: MeteringEntry, loading: boolean}
- setCurrentMeteringEntry: (meteringEntry: {data: MeteringEntry, loading: boolean}) => void
+ currentMeteringEntry: { data: MeteringEntry; loading: boolean }
+ setCurrentMeteringEntry: (meteringEntry: {
+ data: MeteringEntry
+ loading: boolean
+ }) => void
meteringEntries: MeteringEntry[]
setMeteringEntries: (meteringEntries: MeteringEntry[]) => void
streaming: boolean
@@ -123,9 +104,12 @@ export const useStoreMessageOption = create((set) => ({
setMessages: (messages) => set({ messages }),
history: [],
setHistory: (history) => set({ history }),
- currentMeteringEntry: {data: {} as MeteringEntry, loading: false},
- setCurrentMeteringEntry: (currentMeteringEntry) => set({ currentMeteringEntry }),
- meteringEntries: JSON.parse(localStorage.getItem("meteringEntries") || JSON.stringify([])),
+ currentMeteringEntry: { data: {} as MeteringEntry, loading: false },
+ setCurrentMeteringEntry: (currentMeteringEntry) =>
+ set({ currentMeteringEntry }),
+ meteringEntries: JSON.parse(
+ localStorage.getItem("meteringEntries") || JSON.stringify([])
+ ),
setMeteringEntries: (meteringEntries) => set({ meteringEntries }),
streaming: false,
setStreaming: (streaming) => set({ streaming }),
diff --git a/src/types/message.ts b/src/types/message.ts
index a232895..e12a6fc 100644
--- a/src/types/message.ts
+++ b/src/types/message.ts
@@ -13,7 +13,9 @@ export type Message = {
isBot: boolean
name: string
message: string
+ webSearch?: boolean
webSources: any[]
+ iodSearch?: boolean
iodSources: AllIodRegistryEntry
images?: string[]
search?: WebSearch
@@ -22,3 +24,5 @@ export type Message = {
generationInfo?: any
reasoning_time_taken?: number
}
+
+export type Messages = Message[]
diff --git a/src/web/iod.ts b/src/web/iod.ts
index 114edf3..1bd8e30 100644
--- a/src/web/iod.ts
+++ b/src/web/iod.ts
@@ -13,6 +13,7 @@ import { PageAssitDatabase } from "@/db"
import { enPOSTag, Segment, useDefault } from "segmentit"
import { getDefaultIodSources } from "@/libs/iod.ts"
+import { IodDb } from "@/db/iod.ts"
const segment = useDefault(new Segment())
export const tokenizeInput = function (input: string): string[] {
@@ -24,24 +25,9 @@ export const tokenizeInput = function (input: string): string[] {
)
return words.filter((word) => word.w.length > 1).map((word) => word.w)
}
-//doipUrl = tcp://reg01.public.internetofdata.cn:21037
-export const _iodConfig = {
- gatewayUrl: "tcp://reg01.public.internetofdata.cn:21037",
- registry: "data/Registry",
- localRepository: "data/Repository",
- doBrowser: "http://021.node.internetapi.cn:21030/SCIDE/SCManager"
-}
function getIodConfig() {
- const val = localStorage.getItem("iod-connect")
- if (!val) {
- return _iodConfig
- }
- try {
- return JSON.parse(val)
- } catch {
- return _iodConfig
- }
+ return IodDb.getInstance().getIodConnection()
}
export const iodConfigLocal = {
gatewayUrl: "tcp://127.0.0.1:21036",
@@ -271,7 +257,7 @@ export const updateDialog = async function (
traceId: r?.traceId
})) ?? []
updateBody.IoDSources =
- Object.values( botMessage.iodSources as AllIodRegistryEntry).flatMap(iod => iod.data)?.map((r) => ({
+ Object.values((botMessage?.iodSources ?? {}) as AllIodRegistryEntry).flatMap(iod => iod.data)?.map((r) => ({
id: r.doId,
tokenCount:
r.content || r.description