refactor(iod): 重构数联网相关组件和逻辑

-优化了 Data、Scene 和 Team组件的逻辑,使用 currentIodMessage 替代复杂的条件判断- 改进了 IodRelevant 组件的动画和数据处理方式
- 调整了 Message 组件以支持数联网搜索功能
- 重构了 PlaygroundIodProvider,简化了上下文类型和数据处理
- 更新了数据库相关操作,使用新的 HistoryMessage 类型
- 新增了 IodDb 类来管理数联网连接配置
This commit is contained in:
zhaoweijie
2025-08-24 19:00:49 +08:00
parent f9763778fa
commit 2b4885ae2d
20 changed files with 415 additions and 399 deletions

View File

@@ -11,7 +11,8 @@ export const PlaygroundChat = () => {
regenerateLastMessage,
isSearchingInternet,
editMessage,
ttsEnabled
ttsEnabled,
setCurrentMessageId,
} = useMessageOption()
const [isSourceOpen, setIsSourceOpen] = React.useState(false)
const [source, setSource] = React.useState<any>(null)
@@ -27,6 +28,7 @@ export const PlaygroundChat = () => {
{messages.map((message, index) => (
<PlaygroundMessage
key={index}
id={message.id}
isBot={message.isBot}
message={message.message}
name={message.name}
@@ -49,6 +51,8 @@ export const PlaygroundChat = () => {
generationInfo={message?.generationInfo}
isStreaming={streaming}
reasoningTimeTaken={message?.reasoning_time_taken}
setCurrentMessageId={setCurrentMessageId}
iodSearch={message.iodSearch}
/>
))}
</div>

View File

@@ -218,7 +218,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
{
key: 0,
label: (
<p
<div
onClick={() => {
setIodSearch(true)
}}>
@@ -227,13 +227,13 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
<PiNetwork className="h-5 w-5" />
</p>
<p className="text-[#00000080]"></p>
</p>
</div>
)
},
{
key: 1,
label: (
<p
<div
onClick={() => {
setIodSearch(false)
}}>
@@ -242,7 +242,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
<PiNetwork className="h-5 w-5" />
</p>
<p className="text-[#00000080]"></p>
</p>
</div>
)
}
]
@@ -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"
}`}>
<ImageIcon stroke-width={1} className="h-5 w-5" />
<ImageIcon strokeWidth={1} className="h-5 w-5" />
</Button>
</Tooltip>
)}
@@ -420,12 +420,12 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
}}
className={`flex items-center justify-center dark:text-gray-300 !px-[5px]`}>
{!isListening ? (
<MicIcon stroke-width={1} className="h-5 w-5" />
<MicIcon strokeWidth={1} className="h-5 w-5" />
) : (
<div className="relative">
<span className="animate-ping absolute inline-flex h-3 w-3 rounded-full bg-red-400 opacity-75"></span>
<MicIcon
stroke-width={1}
strokeWidth={1}
className="h-5 w-5"
/>
</div>

View File

@@ -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<React.SetStateAction<React.ReactNode>>
detailMain: React.ReactNode
setDetailMain: React.Dispatch<React.SetStateAction<React.ReactNode>>
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<boolean>(true)
const [detailHeader, setDetailHeader] = useState(<></>)
const [detailMain, setDetailMain] = useState(<></>)
const currentIodMessage = useMemo<Message | null>(() => {
if (iodLoading) {
return null
const currentIodMessage = useMemo<AllIodRegistryEntry | undefined>(() => {
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 (
<PlaygroundContext.Provider
@@ -154,7 +152,6 @@ const PlaygroundContent = () => {
)
}
export const PlaygroundIod = () => {
return (
<div className="w-[36%] h-full pt-16 pr-5 pb-0">

View File

@@ -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 (
<button
onClick={handleClick}
className="flex w-full border bg-transparent hover:bg-gray-200 dark:hover:bg-gray-800 text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 focus:ring-offset-gray-100 rounded-md p-2 dark:border-gray-800">
<PencilIcon className="mx-3 h-5 w-5" aria-hidden="true" />
<span className="inline-flex font-semibol text-white text-sm">
{t('newChat')}
</span>
</button>
)
}