feat(iod): 重构数联网搜索功能

- 新增数联网设置页面
- 优化数联网搜索结果展示
- 添加数据集、科创场景和科技企业等不同类型的搜索结果
- 重构搜索结果卡片组件,支持加载状态和不同展示模式
- 更新数联网搜索相关的国际化文案
This commit is contained in:
zhaoweijie
2025-08-22 17:15:19 +08:00
parent efbf2a3eff
commit 17020e8755
33 changed files with 1321 additions and 773 deletions

View File

@@ -2,15 +2,14 @@ import React from "react"
import { cleanUrl } from "~/libs/clean-url"
import {
defaultEmbeddingModelForRag,
geWebSearchFollowUpPrompt,
geWebSearchKeywordsPrompt,
getOllamaURL,
geWebSearchFollowUpPrompt,
promptForRag,
systemPromptForNonRagOption
} from "~/services/ollama"
import type { ChatHistory, Message, MeteringEntry } from "~/store/option"
import { SystemMessage } from "@langchain/core/messages"
import { useStoreMessageOption } from "~/store/option"
import { SystemMessage } from "@langchain/core/messages"
import {
deleteChatForEdit,
generateID,
@@ -47,14 +46,20 @@ import {
mergeReasoningContent,
removeReasoning
} from "@/libs/reasoning"
import { getDefaultIodSources } from "@/libs/iod.ts"
export const useMessageOption = () => {
const {
controller: abortController,
setController: setAbortController,
iodLoading,
setIodLoading,
currentMessageId,
setCurrentMessageId,
messages,
setMessages
setMessages,
} = usePageAssist()
const {
history,
setHistory,
@@ -113,6 +118,8 @@ export const useMessageOption = () => {
setIsProcessing(false)
setStreaming(false)
currentChatModelSettings.reset()
setIodLoading(false)
setCurrentMessageId("")
textareaRef?.current?.focus()
if (defaultInternetSearchOn) {
setWebSearch(true)
@@ -195,6 +202,7 @@ export const useMessageOption = () => {
})
let newMessage: Message[] = []
let generateMessageId = generateID()
setCurrentMessageId(generateMessageId)
const meter: MeteringEntry = {
id: generateMessageId,
queryContent: message,
@@ -214,15 +222,15 @@ export const useMessageOption = () => {
name: "You",
message,
webSources: [],
iodSources: [],
iodSources: getDefaultIodSources(),
images: [image]
},
{
isBot: true,
name: selectedModel,
message: "",
message: "",
webSources: [],
iodSources: [],
iodSources: getDefaultIodSources(),
id: generateMessageId
}
]
@@ -234,7 +242,7 @@ export const useMessageOption = () => {
name: selectedModel,
message: "▋",
webSources: [],
iodSources: [],
iodSources: getDefaultIodSources(),
id: generateMessageId
}
]
@@ -316,7 +324,9 @@ export const useMessageOption = () => {
// Currently only IoD search use keywords
if (iodSearch) {
// Extract keywords
console.log("query:"+query+" --> "+JSON.stringify(tokenizeInput(query)));
console.log(
"query:" + query + " --> " + JSON.stringify(tokenizeInput(query))
)
keywords = tokenizeInput(query)
/*
const questionPrompt = await geWebSearchKeywordsPrompt()
@@ -335,15 +345,35 @@ export const useMessageOption = () => {
*/
}
const { prompt, webSources, iodSources, iodSearchResults: iodData, iodTokenCount } =
await getSystemPromptForWeb(query, keywords, webSearch, iodSearch)
const {
prompt,
webSources,
iodSources,
iodSearchResults: iodData,
iodTokenCount
} = await getSystemPromptForWeb(query, keywords, webSearch, iodSearch)
setIodLoading(false)
console.log("prompt:\n" + prompt)
setIsSearchingInternet(false)
meter.prompt = prompt
meter.iodKeywords = keywords
meter.iodData = iodData
meter.iodData = Object.values(iodData).flat()
meter.iodTokenCount = iodTokenCount
setMessages((prev) => {
return prev.map((message) => {
if (message.id === generateMessageId) {
return {
...message,
webSources,
iodSources,
}
}
return message
})
})
// message = message.trim().replaceAll("\n", " ")
let humanMessage = await humanMessageFormatter({
@@ -511,20 +541,17 @@ export const useMessageOption = () => {
modelInputTokenCount: prompt.length,
modelOutputTokenCount: fullText.length,
model: ollama.modelName ?? ollama.model,
relatedDataCount: iodData?.length ?? 0,
relatedDataCount: Object.values(iodData).flat()?.length ?? 0,
timeTaken: new Date().getTime() - chatStartTime.getTime(),
date: chatStartTime.getTime(),
cot,
responseContent: content,
modelResponseContent: fullText,
modelResponseContent: fullText
}
const _meteringEntries = [
currentMeteringEntry,
...meteringEntries,
]
const _meteringEntries = [currentMeteringEntry, ...meteringEntries]
setCurrentMeteringEntry({
loading: false,
data: currentMeteringEntry,
data: currentMeteringEntry
})
setMeteringEntries(_meteringEntries)
localStorage.setItem("meteringEntries", JSON.stringify(_meteringEntries))
@@ -653,7 +680,7 @@ export const useMessageOption = () => {
setCurrentMeteringEntry({
loading: true,
data: meter,
data: meter
})
if (!isRegenerate) {
@@ -664,7 +691,7 @@ export const useMessageOption = () => {
name: "You",
message,
webSources: [],
iodSources: [],
iodSources: getDefaultIodSources(),
images: [image]
},
{
@@ -672,7 +699,7 @@ export const useMessageOption = () => {
name: selectedModel,
message: "▋",
webSources: [],
iodSources: [],
iodSources: getDefaultIodSources(),
id: generateMessageId
}
]
@@ -684,7 +711,7 @@ export const useMessageOption = () => {
name: selectedModel,
message: "▋",
webSources: [],
iodSources: [],
iodSources: getDefaultIodSources(),
id: generateMessageId
}
]
@@ -883,7 +910,6 @@ export const useMessageOption = () => {
setIsProcessing(false)
setStreaming(false)
// Save metering entry
const { cot, content } = responseResolver(fullText)
const currentMeteringEntry = {
@@ -891,20 +917,17 @@ export const useMessageOption = () => {
modelInputTokenCount: prompt.length,
modelOutputTokenCount: fullText.length,
model: ollama.modelName ?? ollama.model,
relatedDataCount: 0,
relatedDataCount: 0,
timeTaken: new Date().getTime() - chatStartTime.getTime(),
date: chatStartTime.getTime(),
cot,
responseContent: content,
modelResponseContent: fullText,
modelResponseContent: fullText
}
const _meteringEntries = [
currentMeteringEntry,
...meteringEntries,
]
const _meteringEntries = [currentMeteringEntry, ...meteringEntries]
setCurrentMeteringEntry({
loading: false,
data: currentMeteringEntry,
data: currentMeteringEntry
})
setMeteringEntries(_meteringEntries)
} catch (e) {
@@ -996,7 +1019,7 @@ export const useMessageOption = () => {
name: "You",
message,
webSources: [],
iodSources: [],
iodSources: getDefaultIodSources(),
images: []
},
{
@@ -1004,7 +1027,7 @@ export const useMessageOption = () => {
name: selectedModel,
message: "▋",
webSources: [],
iodSources: [],
iodSources: getDefaultIodSources(),
id: generateMessageId
}
]
@@ -1016,7 +1039,7 @@ export const useMessageOption = () => {
name: selectedModel,
message: "▋",
webSources: [],
iodSources: [],
iodSources: getDefaultIodSources(),
id: generateMessageId
}
]
@@ -1319,6 +1342,7 @@ export const useMessageOption = () => {
)
} else {
if (webSearch || iodSearch) {
setIodLoading(iodSearch)
await searchChatMode(
webSearch,
iodSearch,
@@ -1435,6 +1459,10 @@ export const useMessageOption = () => {
editMessage,
messages,
setMessages,
iodLoading,
currentMessageId,
setIodLoading,
setCurrentMessageId,
onSubmit,
setStreaming,
streaming,