feat: add IoD search
This commit is contained in:
parent
691575e449
commit
e8471f1802
@ -109,7 +109,7 @@
|
||||
"translate": "ترجمة",
|
||||
"custom": "مخصص"
|
||||
},
|
||||
"citations": "الاقتباسات",
|
||||
"webCitations": "الاقتباسات",
|
||||
"segmented": {
|
||||
"ollama": "نماذج Ollama",
|
||||
"custom": "نماذج مخصصة"
|
||||
|
@ -106,7 +106,7 @@
|
||||
"translate": "Oversæt",
|
||||
"custom": "Brugerdefineret"
|
||||
},
|
||||
"citations": "Citater",
|
||||
"webCitations": "Citater",
|
||||
"downloadCode": "Download Kode",
|
||||
"date": {
|
||||
"pinned": "Fastgjort",
|
||||
|
@ -106,7 +106,7 @@
|
||||
"translate": "Übersetzen",
|
||||
"custom": "Benutzerdefiniert"
|
||||
},
|
||||
"citations": "Zitate",
|
||||
"webCitations": "Zitate",
|
||||
"downloadCode": "Code herunterladen",
|
||||
"date": {
|
||||
"pinned": "Angepinnt",
|
||||
|
@ -39,6 +39,7 @@
|
||||
},
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"webSearch": "Searching the web",
|
||||
"iodSearch": "Searching the Internet of Data",
|
||||
"regenerate": "Regenerate",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
@ -136,7 +137,8 @@
|
||||
"translate": "Translate",
|
||||
"custom": "Custom"
|
||||
},
|
||||
"citations": "Citations",
|
||||
"webCitations": "Web Citations",
|
||||
"iodCitations": "Internet of Data Citations",
|
||||
"segmented": {
|
||||
"ollama": "Ollama Models",
|
||||
"custom": "Custom Models"
|
||||
|
@ -20,6 +20,7 @@
|
||||
},
|
||||
"tooltip": {
|
||||
"searchInternet": "Search Internet",
|
||||
"searchIod": "Search Internet of Data",
|
||||
"speechToText": "Speech to Text",
|
||||
"uploadImage": "Upload Image",
|
||||
"stopStreaming": "Stop Streaming",
|
||||
|
@ -105,7 +105,7 @@
|
||||
"rephrase": "Reformular",
|
||||
"translate": "Traducir"
|
||||
},
|
||||
"citations": "Citas",
|
||||
"webCitations": "Citas",
|
||||
"downloadCode": "Descargar Código",
|
||||
"date": {
|
||||
"pinned": "Fijado",
|
||||
|
@ -99,7 +99,7 @@
|
||||
},
|
||||
"advanced": "تنظیمات بیشتر مدل"
|
||||
},
|
||||
"citations": "منابع",
|
||||
"webCitations": "منابع",
|
||||
"downloadCode": "دانلود کد",
|
||||
"date": {
|
||||
"pinned": "پین شده",
|
||||
|
@ -105,7 +105,7 @@
|
||||
"rephrase": "Reformuler",
|
||||
"translate": "Traduire"
|
||||
},
|
||||
"citations": "Citations",
|
||||
"webCitations": "Citations",
|
||||
"downloadCode": "Télécharger le code",
|
||||
"date": {
|
||||
"pinned": "Épinglé",
|
||||
|
@ -105,7 +105,7 @@
|
||||
"rephrase": "Riformulare",
|
||||
"translate": "Tradurre"
|
||||
},
|
||||
"citations": "Citazioni",
|
||||
"webCitations": "Citazioni",
|
||||
"downloadCode": "Scarica Codice",
|
||||
"date": {
|
||||
"pinned": "Fissato",
|
||||
|
@ -105,7 +105,7 @@
|
||||
"rephrase": "言い換え",
|
||||
"translate": "翻訳"
|
||||
},
|
||||
"citations": "引用",
|
||||
"webCitations": "引用",
|
||||
"downloadCode": "コードをダウンロード",
|
||||
"date": {
|
||||
"pinned": "固定",
|
||||
|
@ -105,7 +105,7 @@
|
||||
"rephrase": "다르게 표현",
|
||||
"translate": "번역"
|
||||
},
|
||||
"citations": "인용",
|
||||
"webCitations": "인용",
|
||||
"downloadCode": "코드 다운로드",
|
||||
"date": {
|
||||
"pinned": "고정됨",
|
||||
|
@ -104,7 +104,7 @@
|
||||
"rephrase": "പുനഃരൂപീകരിക്കുക",
|
||||
"translate": "വിവർത്തനം ചെയ്യുക"
|
||||
},
|
||||
"citations": "ഉദ്ധരണികൾ",
|
||||
"webCitations": "ഉദ്ധരണികൾ",
|
||||
"downloadCode": "കോഡ് ഡൗൺലോഡ് ചെയ്യുക",
|
||||
"date": {
|
||||
"pinned": "പിൻ ചെയ്തത്",
|
||||
|
@ -106,7 +106,7 @@
|
||||
"translate": "Oversett",
|
||||
"custom": "Egendefinert"
|
||||
},
|
||||
"citations": "Sitater",
|
||||
"webCitations": "Sitater",
|
||||
"downloadCode": "Last ned kode",
|
||||
"date": {
|
||||
"pinned": "Festet",
|
||||
|
@ -105,7 +105,7 @@
|
||||
"rephrase": "Reformular",
|
||||
"translate": "Traduzir"
|
||||
},
|
||||
"citations": "Citações",
|
||||
"webCitations": "Citações",
|
||||
"downloadCode": "Baixar Código",
|
||||
"date": {
|
||||
"pinned": "Fixado",
|
||||
|
@ -105,7 +105,7 @@
|
||||
"rephrase": "Перефразировать",
|
||||
"translate": "Перевести"
|
||||
},
|
||||
"citations": "Цитаты",
|
||||
"webCitations": "Цитаты",
|
||||
"downloadCode": "Скачать код",
|
||||
"date": {
|
||||
"pinned": "Закреплено",
|
||||
|
@ -106,7 +106,7 @@
|
||||
"translate": "Översätt",
|
||||
"custom": "Custom"
|
||||
},
|
||||
"citations": "Citat",
|
||||
"webCitations": "Citat",
|
||||
"segmented": {
|
||||
"ollama": "Ollama-modeller",
|
||||
"custom": "Custom modeller"
|
||||
|
@ -106,7 +106,7 @@
|
||||
"translate": "Перекласти",
|
||||
"custom": "Власне"
|
||||
},
|
||||
"citations": "Цитати",
|
||||
"webCitations": "Цитати",
|
||||
"segmented": {
|
||||
"ollama": "Моделі Ollama",
|
||||
"custom": "Власні моделі"
|
||||
|
@ -38,7 +38,8 @@
|
||||
}
|
||||
},
|
||||
"copyToClipboard": "复制到剪贴板",
|
||||
"webSearch": "搜索网络",
|
||||
"webSearch": "搜索万维网",
|
||||
"iodSearch": "搜索数联网",
|
||||
"regenerate": "重新生成",
|
||||
"edit": "编辑",
|
||||
"delete": "删除",
|
||||
@ -105,7 +106,8 @@
|
||||
"rephrase": "重述",
|
||||
"translate": "翻译"
|
||||
},
|
||||
"citations": "引用",
|
||||
"webCitations": "万维网引用",
|
||||
"iodCitations": "数联网引用",
|
||||
"downloadCode": "下载代码",
|
||||
"date": {
|
||||
"pinned": "已置顶",
|
||||
|
@ -19,7 +19,8 @@
|
||||
}
|
||||
},
|
||||
"tooltip": {
|
||||
"searchInternet": "搜索互联网",
|
||||
"searchInternet": "搜索万维网",
|
||||
"searchIod": "搜索数联网",
|
||||
"speechToText": "语音到文本",
|
||||
"uploadImage": "上传图片",
|
||||
"stopStreaming": "停止流媒体",
|
||||
|
@ -18,7 +18,7 @@ import { useTTS } from "@/hooks/useTTS"
|
||||
import { tagColors } from "@/utils/color"
|
||||
import { removeModelSuffix } from "@/db/models"
|
||||
import { GenerationInfo } from "./GenerationInfo"
|
||||
import { parseReasoning, } from "@/libs/reasoning"
|
||||
import { parseReasoning } from "@/libs/reasoning"
|
||||
import { humanizeMilliseconds } from "@/utils/humanize-milliseconds"
|
||||
type Props = {
|
||||
message: string
|
||||
@ -36,7 +36,8 @@ type Props = {
|
||||
isProcessing: boolean
|
||||
webSearch?: {}
|
||||
isSearchingInternet?: boolean
|
||||
sources?: any[]
|
||||
webSources?: any[]
|
||||
iodSources?: any[]
|
||||
hideEditAndRegenerate?: boolean
|
||||
onSourceClick?: (source: any) => void
|
||||
isTTSEnabled?: boolean
|
||||
@ -166,7 +167,7 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{props.isBot && props?.sources && props?.sources.length > 0 && (
|
||||
{props.isBot && props?.webSources && props?.webSources.length > 0 && (
|
||||
<Collapse
|
||||
className="mt-6"
|
||||
ghost
|
||||
@ -175,15 +176,44 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
key: "1",
|
||||
label: (
|
||||
<div className="italic text-gray-500 dark:text-gray-400">
|
||||
{t("citations")}
|
||||
{t("webCitations")}
|
||||
</div>
|
||||
),
|
||||
children: (
|
||||
<div className="mb-3 flex flex-wrap gap-2">
|
||||
{props?.sources?.map((source, index) => (
|
||||
{props?.webSources?.map((source, index) => (
|
||||
<MessageSource
|
||||
onSourceClick={props.onSourceClick}
|
||||
key={index}
|
||||
index={index}
|
||||
source={source}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
{props.isBot && props?.iodSources && props?.iodSources.length > 0 && (
|
||||
<Collapse
|
||||
className="mt-6"
|
||||
ghost
|
||||
items={[
|
||||
{
|
||||
key: "1",
|
||||
label: (
|
||||
<div className="italic text-gray-500 dark:text-gray-400">
|
||||
{t("iodCitations")}
|
||||
</div>
|
||||
),
|
||||
children: (
|
||||
<div className="mb-3 flex flex-wrap gap-2">
|
||||
{props?.iodSources?.map((source, index) => (
|
||||
<MessageSource
|
||||
onSourceClick={props.onSourceClick}
|
||||
key={index}
|
||||
index={index}
|
||||
source={source}
|
||||
/>
|
||||
))}
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { useState } from "react"
|
||||
import type React from "react"
|
||||
import { KnowledgeIcon } from "@/components/Option/Knowledge/KnowledgeIcon"
|
||||
|
||||
type Props = {
|
||||
index: number
|
||||
source: {
|
||||
name?: string
|
||||
url?: string
|
||||
@ -8,11 +11,20 @@ type Props = {
|
||||
type?: string
|
||||
pageContent?: string
|
||||
content?: string
|
||||
doId?: string
|
||||
description?: string
|
||||
}
|
||||
onSourceClick?: (source: any) => void
|
||||
}
|
||||
|
||||
export const MessageSource: React.FC<Props> = ({ source, onSourceClick }) => {
|
||||
export const MessageSource: React.FC<Props> = ({
|
||||
index,
|
||||
source,
|
||||
onSourceClick
|
||||
}) => {
|
||||
// Add state for tracking and content visibility
|
||||
const [showContent, setShowContent] = useState(false)
|
||||
|
||||
if (source?.mode === "rag" || source?.mode === "chat") {
|
||||
return (
|
||||
<button
|
||||
@ -26,12 +38,46 @@ export const MessageSource: React.FC<Props> = ({ source, onSourceClick }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const onContextMenu = (e: React.MouseEvent) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation
|
||||
setShowContent(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<a
|
||||
href={source?.url}
|
||||
target="_blank"
|
||||
className="inline-flex cursor-pointer transition-shadow duration-300 ease-in-out hover:shadow-lg items-center rounded-md bg-gray-100 p-1 text-xs text-gray-800 border border-gray-300 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-100 opacity-80 hover:opacity-100">
|
||||
<span className="text-xs">{source.name}</span>
|
||||
</a>
|
||||
<div className="block items-center gap-1 text-xs text-gray-800 dark:text-gray-100 mb-1">
|
||||
<span className="text-xs font-medium"></span>{" "}
|
||||
<a
|
||||
href={source?.url}
|
||||
target="_blank"
|
||||
onContextMenu={onContextMenu}
|
||||
className="inline-block cursor-pointer transition-shadow duration-300 ease-in-out hover:shadow-lg items-center rounded-md bg-gray-100 p-1 text-xs text-gray-800 border border-gray-300 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-100 opacity-80 hover:opacity-100">
|
||||
{source.doId ? (
|
||||
<>
|
||||
<span className="text-xs">
|
||||
[{index + 1}] doid: {source.doId}
|
||||
</span>
|
||||
<br />
|
||||
<span className="text-xs">{source.name}</span>
|
||||
{showContent && (
|
||||
<div className="mt-2 p-2 border-t border-gray-200 dark:border-gray-700">
|
||||
{source.content || source.pageContent || source.description}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-xs">
|
||||
[{index + 1}] {source.name}
|
||||
</span>
|
||||
{showContent && (
|
||||
<div className="mt-2 p-2 border-t border-gray-200 dark:border-gray-700">
|
||||
{source.content || source.pageContent}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ export const PlaygroundChat = () => {
|
||||
onRengerate={regenerateLastMessage}
|
||||
isProcessing={streaming}
|
||||
isSearchingInternet={isSearchingInternet}
|
||||
sources={message.sources}
|
||||
webSources={message.webSources}
|
||||
iodSources={message.iodSources}
|
||||
onEditFormSubmit={(value, isSend) => {
|
||||
editMessage(index, value, !message.isBot, isSend)
|
||||
}}
|
||||
|
@ -13,7 +13,7 @@ import { getVariable } from "@/utils/select-variable"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { KnowledgeSelect } from "../Knowledge/KnowledgeSelect"
|
||||
import { useSpeechRecognition } from "@/hooks/useSpeechRecognition"
|
||||
import { PiGlobe } from "react-icons/pi"
|
||||
import { PiGlobe, PiNetwork } from "react-icons/pi"
|
||||
import { handleChatInputKeyDown } from "@/utils/key-down"
|
||||
import { getIsSimpleInternetSearch } from "@/services/search"
|
||||
|
||||
@ -34,6 +34,8 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
|
||||
streaming: isSending,
|
||||
webSearch,
|
||||
setWebSearch,
|
||||
iodSearch,
|
||||
setIodSearch,
|
||||
selectedQuickPrompt,
|
||||
textareaRef,
|
||||
setSelectedQuickPrompt,
|
||||
@ -301,6 +303,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
|
||||
<div className="mt-2 flex justify-between items-center">
|
||||
<div className="flex">
|
||||
{!selectedKnowledge && (
|
||||
<div>
|
||||
<Tooltip title={t("tooltip.searchInternet")}>
|
||||
<div className="inline-flex items-center gap-2">
|
||||
<PiGlobe
|
||||
@ -314,6 +317,20 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title={t("tooltip.searchIod")} className="ml-3">
|
||||
<div className="inline-flex items-center gap-2">
|
||||
<PiNetwork
|
||||
className={`h-5 w-5 dark:text-gray-300 `}
|
||||
/>
|
||||
<Switch
|
||||
value={iodSearch}
|
||||
onChange={(e) => setIodSearch(e)}
|
||||
checkedChildren={t("form.webSearch.on")}
|
||||
unCheckedChildren={t("form.webSearch.off")}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex !justify-end gap-3">
|
||||
|
@ -39,7 +39,8 @@ export const SidePanelBody = () => {
|
||||
message_type={message.messageType}
|
||||
isProcessing={streaming}
|
||||
isSearchingInternet={isSearchingInternet}
|
||||
sources={message.sources}
|
||||
webSources={message.webSources}
|
||||
iodSources={message.iodSources}
|
||||
onEditFormSubmit={(value) => {
|
||||
editMessage(index, value, !message.isBot)
|
||||
}}
|
||||
|
@ -29,7 +29,8 @@ type Message = {
|
||||
role: string
|
||||
content: string
|
||||
images?: string[]
|
||||
sources?: string[]
|
||||
webSources?: string[]
|
||||
iodSources?: string[]
|
||||
search?: WebSearch
|
||||
createdAt: number
|
||||
reasoning_time_taken?: number
|
||||
@ -254,7 +255,8 @@ export const saveMessage = async (
|
||||
role: string,
|
||||
content: string,
|
||||
images: string[],
|
||||
source?: any[],
|
||||
webSources?: any[],
|
||||
iodSources?: any[],
|
||||
time?: number,
|
||||
message_type?: string,
|
||||
generationInfo?: any,
|
||||
@ -273,7 +275,8 @@ export const saveMessage = async (
|
||||
content,
|
||||
images,
|
||||
createdAt,
|
||||
sources: source,
|
||||
webSources,
|
||||
iodSources,
|
||||
messageType: message_type,
|
||||
generationInfo: generationInfo,
|
||||
reasoning_time_taken
|
||||
@ -303,7 +306,8 @@ export const formatToMessage = (messages: MessageHistory): MessageType[] => {
|
||||
isBot: message.role === "assistant",
|
||||
message: message.content,
|
||||
name: message.name,
|
||||
sources: message?.sources || [],
|
||||
webSources: message?.webSources || [],
|
||||
iodSources: message?.iodSources || [],
|
||||
images: message.images || [],
|
||||
generationInfo: message?.generationInfo,
|
||||
reasoning_time_taken: message?.reasoning_time_taken
|
||||
|
@ -62,6 +62,7 @@ export const saveMessageOnError = async ({
|
||||
userMessage,
|
||||
[image],
|
||||
[],
|
||||
[],
|
||||
1,
|
||||
message_type
|
||||
)
|
||||
@ -73,6 +74,7 @@ export const saveMessageOnError = async ({
|
||||
botMessage,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
2,
|
||||
message_type
|
||||
)
|
||||
@ -91,6 +93,7 @@ export const saveMessageOnError = async ({
|
||||
userMessage,
|
||||
[image],
|
||||
[],
|
||||
[],
|
||||
1,
|
||||
message_type
|
||||
)
|
||||
@ -102,6 +105,7 @@ export const saveMessageOnError = async ({
|
||||
botMessage,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
2,
|
||||
message_type
|
||||
)
|
||||
@ -126,7 +130,8 @@ export const saveMessageOnSuccess = async ({
|
||||
message,
|
||||
image,
|
||||
fullText,
|
||||
source,
|
||||
webSources,
|
||||
iodSources,
|
||||
message_source = "web-ui",
|
||||
message_type, generationInfo,
|
||||
prompt_id,
|
||||
@ -140,7 +145,8 @@ export const saveMessageOnSuccess = async ({
|
||||
message: string
|
||||
image: string
|
||||
fullText: string
|
||||
source: any[]
|
||||
webSources: any[]
|
||||
iodSources: any[]
|
||||
message_source?: "copilot" | "web-ui",
|
||||
message_type?: string
|
||||
generationInfo?: any
|
||||
@ -157,6 +163,7 @@ export const saveMessageOnSuccess = async ({
|
||||
message,
|
||||
[image],
|
||||
[],
|
||||
[],
|
||||
1,
|
||||
message_type,
|
||||
generationInfo,
|
||||
@ -169,7 +176,8 @@ export const saveMessageOnSuccess = async ({
|
||||
"assistant",
|
||||
fullText,
|
||||
[],
|
||||
source,
|
||||
webSources,
|
||||
iodSources,
|
||||
2,
|
||||
message_type,
|
||||
generationInfo,
|
||||
@ -189,6 +197,7 @@ export const saveMessageOnSuccess = async ({
|
||||
message,
|
||||
[image],
|
||||
[],
|
||||
[],
|
||||
1,
|
||||
message_type,
|
||||
generationInfo,
|
||||
@ -200,7 +209,8 @@ export const saveMessageOnSuccess = async ({
|
||||
"assistant",
|
||||
fullText,
|
||||
[],
|
||||
source,
|
||||
webSources,
|
||||
iodSources,
|
||||
2,
|
||||
message_type,
|
||||
generationInfo,
|
||||
|
@ -59,6 +59,8 @@ export const useMessage = () => {
|
||||
setIsSearchingInternet,
|
||||
webSearch,
|
||||
setWebSearch,
|
||||
iodSearch,
|
||||
setIodSearch,
|
||||
isSearchingInternet
|
||||
} = useStoreMessageOption()
|
||||
const [defaultInternetSearchOn] = useStorage("defaultInternetSearchOn", false)
|
||||
@ -185,14 +187,16 @@ export const useMessage = () => {
|
||||
isBot: false,
|
||||
name: "You",
|
||||
message,
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
images: []
|
||||
},
|
||||
{
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -203,7 +207,8 @@ export const useMessage = () => {
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -334,7 +339,16 @@ export const useMessage = () => {
|
||||
}
|
||||
|
||||
let context: string = ""
|
||||
let source: {
|
||||
let webSources: {
|
||||
name: any
|
||||
type: any
|
||||
mode: string
|
||||
url: string
|
||||
pageContent: string
|
||||
metadata: Record<string, any>
|
||||
}[] = []
|
||||
// TODO: update type
|
||||
let iodSources: {
|
||||
name: any
|
||||
type: any
|
||||
mode: string
|
||||
@ -346,7 +360,7 @@ export const useMessage = () => {
|
||||
if (chatWithWebsiteEmbedding) {
|
||||
const docs = await vectorstore.similaritySearch(query, 4)
|
||||
context = formatDocs(docs)
|
||||
source = docs.map((doc) => {
|
||||
webSources = docs.map((doc) => {
|
||||
return {
|
||||
...doc,
|
||||
name: doc?.metadata?.source || "untitled",
|
||||
@ -365,7 +379,7 @@ export const useMessage = () => {
|
||||
.slice(0, maxWebsiteContext)
|
||||
}
|
||||
|
||||
source = [
|
||||
webSources = [
|
||||
{
|
||||
name: embedURL,
|
||||
type: type,
|
||||
@ -476,7 +490,8 @@ export const useMessage = () => {
|
||||
return {
|
||||
...message,
|
||||
message: fullText,
|
||||
sources: source,
|
||||
webSources,
|
||||
iodSources,
|
||||
generationInfo,
|
||||
reasoning_time_taken: timetaken
|
||||
}
|
||||
@ -506,7 +521,8 @@ export const useMessage = () => {
|
||||
message,
|
||||
image,
|
||||
fullText,
|
||||
source,
|
||||
webSources,
|
||||
iodSources,
|
||||
message_source: "copilot",
|
||||
generationInfo,
|
||||
reasoning_time_taken: timetaken
|
||||
@ -606,14 +622,16 @@ export const useMessage = () => {
|
||||
isBot: false,
|
||||
name: "You",
|
||||
message,
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
images: []
|
||||
},
|
||||
{
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -624,7 +642,8 @@ export const useMessage = () => {
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -787,7 +806,8 @@ export const useMessage = () => {
|
||||
message,
|
||||
image,
|
||||
fullText,
|
||||
source: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
message_source: "copilot",
|
||||
generationInfo,
|
||||
reasoning_time_taken: timetaken
|
||||
@ -891,14 +911,16 @@ export const useMessage = () => {
|
||||
isBot: false,
|
||||
name: "You",
|
||||
message,
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
images: [image]
|
||||
},
|
||||
{
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -909,7 +931,8 @@ export const useMessage = () => {
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -1077,7 +1100,8 @@ export const useMessage = () => {
|
||||
message,
|
||||
image,
|
||||
fullText,
|
||||
source: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
message_source: "copilot",
|
||||
generationInfo,
|
||||
reasoning_time_taken: timetaken
|
||||
@ -1114,12 +1138,14 @@ export const useMessage = () => {
|
||||
}
|
||||
|
||||
const searchChatMode = async (
|
||||
webSearch: boolean,
|
||||
iodSearch,
|
||||
message: string,
|
||||
image: string,
|
||||
isRegenerate: boolean,
|
||||
messages: Message[],
|
||||
history: ChatHistory,
|
||||
signal: AbortSignal
|
||||
signal: AbortSignal,
|
||||
) => {
|
||||
const url = await getOllamaURL()
|
||||
setStreaming(true)
|
||||
@ -1176,14 +1202,16 @@ export const useMessage = () => {
|
||||
isBot: false,
|
||||
name: "You",
|
||||
message,
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
images: [image]
|
||||
},
|
||||
{
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -1194,7 +1222,8 @@ export const useMessage = () => {
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -1271,7 +1300,8 @@ export const useMessage = () => {
|
||||
query = removeReasoning(query)
|
||||
}
|
||||
|
||||
const { prompt, source } = await getSystemPromptForWeb(query)
|
||||
const { prompt, webSources, iodSources } =
|
||||
await getSystemPromptForWeb(query, [], webSearch, iodSearch)
|
||||
setIsSearchingInternet(false)
|
||||
|
||||
// message = message.trim().replaceAll("\n", " ")
|
||||
@ -1394,7 +1424,8 @@ export const useMessage = () => {
|
||||
return {
|
||||
...message,
|
||||
message: fullText,
|
||||
sources: source,
|
||||
webSources,
|
||||
iodSources,
|
||||
generationInfo,
|
||||
reasoning_time_taken: timetaken
|
||||
}
|
||||
@ -1424,7 +1455,8 @@ export const useMessage = () => {
|
||||
message,
|
||||
image,
|
||||
fullText,
|
||||
source,
|
||||
webSources,
|
||||
iodSources,
|
||||
generationInfo,
|
||||
reasoning_time_taken: timetaken
|
||||
})
|
||||
@ -1523,7 +1555,8 @@ export const useMessage = () => {
|
||||
isBot: false,
|
||||
name: "You",
|
||||
message,
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
images: [image],
|
||||
messageType: messageType
|
||||
},
|
||||
@ -1531,7 +1564,8 @@ export const useMessage = () => {
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -1542,7 +1576,8 @@ export const useMessage = () => {
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -1688,7 +1723,8 @@ export const useMessage = () => {
|
||||
message,
|
||||
image,
|
||||
fullText,
|
||||
source: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
message_source: "copilot",
|
||||
message_type: messageType,
|
||||
generationInfo,
|
||||
@ -1766,14 +1802,16 @@ export const useMessage = () => {
|
||||
)
|
||||
} else {
|
||||
if (chatMode === "normal") {
|
||||
if (webSearch) {
|
||||
if (webSearch || iodSearch) {
|
||||
await searchChatMode(
|
||||
webSearch,
|
||||
iodSearch,
|
||||
message,
|
||||
image,
|
||||
isRegenerate || false,
|
||||
messages,
|
||||
memory || history,
|
||||
signal
|
||||
signal,
|
||||
)
|
||||
} else {
|
||||
await normalChatMode(
|
||||
@ -1906,6 +1944,8 @@ export const useMessage = () => {
|
||||
regenerateLastMessage,
|
||||
webSearch,
|
||||
setWebSearch,
|
||||
iodSearch,
|
||||
setIodSearch,
|
||||
isSearchingInternet,
|
||||
selectedQuickPrompt,
|
||||
setSelectedQuickPrompt,
|
||||
|
@ -3,6 +3,7 @@ import { cleanUrl } from "~/libs/clean-url"
|
||||
import {
|
||||
defaultEmbeddingModelForRag,
|
||||
geWebSearchFollowUpPrompt,
|
||||
geWebSearchKeywordsPrompt,
|
||||
getOllamaURL,
|
||||
promptForRag,
|
||||
systemPromptForNonRagOption
|
||||
@ -67,6 +68,8 @@ export const useMessageOption = () => {
|
||||
setChatMode,
|
||||
webSearch,
|
||||
setWebSearch,
|
||||
iodSearch,
|
||||
setIodSearch,
|
||||
isSearchingInternet,
|
||||
setIsSearchingInternet,
|
||||
selectedQuickPrompt,
|
||||
@ -111,6 +114,8 @@ export const useMessageOption = () => {
|
||||
}
|
||||
|
||||
const searchChatMode = async (
|
||||
webSearch: boolean,
|
||||
iodSearch: boolean,
|
||||
message: string,
|
||||
image: string,
|
||||
isRegenerate: boolean,
|
||||
@ -172,14 +177,16 @@ export const useMessageOption = () => {
|
||||
isBot: false,
|
||||
name: "You",
|
||||
message,
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
images: [image]
|
||||
},
|
||||
{
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -190,7 +197,8 @@ export const useMessageOption = () => {
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -204,6 +212,7 @@ export const useMessageOption = () => {
|
||||
setIsSearchingInternet(true)
|
||||
|
||||
let query = message
|
||||
let keywords: string[] = []
|
||||
|
||||
if (newMessage.length > 2) {
|
||||
let questionPrompt = await geWebSearchFollowUpPrompt()
|
||||
@ -268,7 +277,23 @@ export const useMessageOption = () => {
|
||||
query = removeReasoning(query)
|
||||
}
|
||||
|
||||
const { prompt, source } = await getSystemPromptForWeb(query)
|
||||
// Currently only IoD search use keywords
|
||||
if (iodSearch) {
|
||||
// Extract keywords
|
||||
const questionPrompt = await geWebSearchKeywordsPrompt()
|
||||
const promptForQuestion = questionPrompt.replaceAll("{query}", query)
|
||||
const response = await ollama.invoke(promptForQuestion)
|
||||
let res = response.content.toString()
|
||||
res = removeReasoning(res)
|
||||
keywords = res.replace(/^Keywords:/i, '').split(', ').map(k => k.trim())
|
||||
}
|
||||
|
||||
const { prompt, webSources, iodSources } = await getSystemPromptForWeb(
|
||||
query,
|
||||
keywords,
|
||||
webSearch,
|
||||
iodSearch,
|
||||
)
|
||||
setIsSearchingInternet(false)
|
||||
|
||||
// message = message.trim().replaceAll("\n", " ")
|
||||
@ -390,7 +415,8 @@ export const useMessageOption = () => {
|
||||
return {
|
||||
...message,
|
||||
message: fullText,
|
||||
sources: source,
|
||||
webSources,
|
||||
iodSources,
|
||||
generationInfo,
|
||||
reasoning_time_taken: timetaken
|
||||
}
|
||||
@ -420,7 +446,8 @@ export const useMessageOption = () => {
|
||||
message,
|
||||
image,
|
||||
fullText,
|
||||
source,
|
||||
webSources,
|
||||
iodSources,
|
||||
generationInfo,
|
||||
reasoning_time_taken: timetaken
|
||||
})
|
||||
@ -552,14 +579,16 @@ export const useMessageOption = () => {
|
||||
isBot: false,
|
||||
name: "You",
|
||||
message,
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
images: [image]
|
||||
},
|
||||
{
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -570,7 +599,8 @@ export const useMessageOption = () => {
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -855,14 +885,16 @@ export const useMessageOption = () => {
|
||||
isBot: false,
|
||||
name: "You",
|
||||
message,
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
images: []
|
||||
},
|
||||
{
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -873,7 +905,8 @@ export const useMessageOption = () => {
|
||||
isBot: true,
|
||||
name: selectedModel,
|
||||
message: "▋",
|
||||
sources: [],
|
||||
webSources: [],
|
||||
iodSources: [],
|
||||
id: generateMessageId
|
||||
}
|
||||
]
|
||||
@ -1076,7 +1109,7 @@ export const useMessageOption = () => {
|
||||
return {
|
||||
...message,
|
||||
message: fullText,
|
||||
sources: source,
|
||||
webSources: source,
|
||||
generationInfo,
|
||||
reasoning_time_taken: timetaken
|
||||
}
|
||||
@ -1175,8 +1208,10 @@ export const useMessageOption = () => {
|
||||
signal
|
||||
)
|
||||
} else {
|
||||
if (webSearch) {
|
||||
if (webSearch || iodSearch) {
|
||||
await searchChatMode(
|
||||
webSearch,
|
||||
iodSearch,
|
||||
message,
|
||||
image,
|
||||
isRegenerate,
|
||||
@ -1311,6 +1346,8 @@ export const useMessageOption = () => {
|
||||
regenerateLastMessage,
|
||||
webSearch,
|
||||
setWebSearch,
|
||||
iodSearch,
|
||||
setIodSearch,
|
||||
isSearchingInternet,
|
||||
setIsSearchingInternet,
|
||||
selectedQuickPrompt,
|
||||
|
@ -58,6 +58,30 @@ Follow-up question: {question}
|
||||
Rephrased question:
|
||||
`
|
||||
|
||||
const DEFAULT_WEBSEARCH_KEYWORDS_PROMPT = `Extract the most important keywords from the query (at most 3), and give me English and Chinese versions of the keywords.
|
||||
|
||||
The result format should be: keyword_1, keyword_2, ..., keyword_n
|
||||
|
||||
Example:
|
||||
|
||||
Query: What are the symptoms of a heart attack?
|
||||
|
||||
Keywords: symptoms, 症状, heart attack, 心臟病
|
||||
|
||||
Query: 什么是物联网?
|
||||
|
||||
Keywords: Internet of Things, IoT, 物联网
|
||||
|
||||
Query: 人工智能的发展趋势?
|
||||
|
||||
Keywords: Artificial Intelligence, AI, 人工智能, trend, 趋势
|
||||
|
||||
|
||||
Query: {query}
|
||||
|
||||
Keywords:
|
||||
`
|
||||
|
||||
export const getOllamaURL = async () => {
|
||||
const ollamaURL = await storage.get("ollamaURL")
|
||||
if (!ollamaURL || ollamaURL.length === 0) {
|
||||
@ -411,6 +435,18 @@ export const setWebPrompts = async (prompt: string, followUpPrompt: string) => {
|
||||
await setWebSearchFollowUpPrompt(followUpPrompt)
|
||||
}
|
||||
|
||||
export const geWebSearchKeywordsPrompt = async () => {
|
||||
const prompt = await storage.get("webSearchKeywordsPrompt")
|
||||
if (!prompt || prompt.length === 0) {
|
||||
return DEFAULT_WEBSEARCH_KEYWORDS_PROMPT
|
||||
}
|
||||
return prompt
|
||||
}
|
||||
|
||||
export const setWebSearchKeywordsPrompt = async (prompt: string) => {
|
||||
await storage.set("webSearchKeywordsPrompt", prompt)
|
||||
}
|
||||
|
||||
export const getPageShareUrl = async () => {
|
||||
const pageShareUrl = await storage.get("pageShareUrl")
|
||||
if (!pageShareUrl || pageShareUrl.length === 0) {
|
||||
|
@ -14,7 +14,8 @@ export type Message = {
|
||||
isBot: boolean
|
||||
name: string
|
||||
message: string
|
||||
sources: any[]
|
||||
webSources: any[]
|
||||
iodSources: any[]
|
||||
images?: string[]
|
||||
search?: WebSearch
|
||||
reasoning_time_taken?: number
|
||||
@ -52,6 +53,8 @@ type State = {
|
||||
setIsEmbedding: (isEmbedding: boolean) => void
|
||||
webSearch: boolean
|
||||
setWebSearch: (webSearch: boolean) => void
|
||||
iodSearch: boolean
|
||||
setIodSearch: (iodSearch: boolean) => void
|
||||
isSearchingInternet: boolean
|
||||
setIsSearchingInternet: (isSearchingInternet: boolean) => void
|
||||
|
||||
@ -100,6 +103,8 @@ export const useStoreMessageOption = create<State>((set) => ({
|
||||
setIsEmbedding: (isEmbedding) => set({ isEmbedding }),
|
||||
webSearch: false,
|
||||
setWebSearch: (webSearch) => set({ webSearch }),
|
||||
iodSearch: false,
|
||||
setIodSearch: (iodSearch) => set({ iodSearch }),
|
||||
isSearchingInternet: false,
|
||||
setIsSearchingInternet: (isSearchingInternet) => set({ isSearchingInternet }),
|
||||
selectedSystemPrompt: null,
|
||||
|
@ -11,7 +11,8 @@ export type Message = {
|
||||
isBot: boolean
|
||||
name: string
|
||||
message: string
|
||||
sources: any[]
|
||||
webSources: any[]
|
||||
iodSources: any[]
|
||||
images?: string[]
|
||||
search?: WebSearch
|
||||
messageType?: string
|
||||
|
148
src/web/iod.ts
Normal file
148
src/web/iod.ts
Normal file
@ -0,0 +1,148 @@
|
||||
import { cleanUrl } from "@/libs/clean-url"
|
||||
import { PageAssistHtmlLoader } from "@/loader/html"
|
||||
import { pageAssistEmbeddingModel } from "@/models/embedding"
|
||||
import { defaultEmbeddingModelForRag, getOllamaURL } from "@/services/ollama"
|
||||
import {
|
||||
getIsSimpleInternetSearch,
|
||||
totalSearchResults
|
||||
} from "@/services/search"
|
||||
import { getPageAssistTextSplitter } from "@/utils/text-splitter"
|
||||
import type { Document } from "@langchain/core/documents"
|
||||
import { MemoryVectorStore } from "langchain/vectorstores/memory"
|
||||
|
||||
const makeRegSearchParams = (count: number, keyword: string) => ({
|
||||
action: "executeContract",
|
||||
contractID: "BDBrowser",
|
||||
operation: "sendRequestDirectly",
|
||||
arg: {
|
||||
id: "670E241C9937B3537047C87053E3AA36",
|
||||
doipUrl: "tcp://reg01.public.internetofdata.cn:21037",
|
||||
op: "Search",
|
||||
attributes: {
|
||||
offset: 0,
|
||||
count,
|
||||
bodyBase64Encoded: false,
|
||||
searchMode: [
|
||||
{
|
||||
key: "data_type",
|
||||
type: "MUST",
|
||||
value: "paper"
|
||||
},
|
||||
// {
|
||||
// key: "title",
|
||||
// type: "MUST",
|
||||
// value: keyword,
|
||||
// },
|
||||
{
|
||||
key: "description",
|
||||
type: "MUST",
|
||||
value: keyword
|
||||
}
|
||||
]
|
||||
},
|
||||
body: ""
|
||||
}
|
||||
})
|
||||
|
||||
export const localIodSearch = async (query: string, keywords: string[]) => {
|
||||
const TOTAL_SEARCH_RESULTS = await totalSearchResults()
|
||||
|
||||
const results = (
|
||||
await Promise.all(
|
||||
keywords.map(async (keyword) => {
|
||||
const abortController = new AbortController()
|
||||
setTimeout(() => abortController.abort(), 10000)
|
||||
|
||||
const params = makeRegSearchParams(TOTAL_SEARCH_RESULTS, keyword)
|
||||
|
||||
return fetch("http://47.93.156.31:21033/SCIDE/SCManager", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(params),
|
||||
signal: abortController.signal
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((res) => {
|
||||
if (res.status !== "Success") {
|
||||
console.log(res)
|
||||
return []
|
||||
}
|
||||
const body = JSON.parse(res.result.body)
|
||||
if (body.code !== 0) {
|
||||
console.log(body)
|
||||
return []
|
||||
}
|
||||
const results =
|
||||
body.data?.results?.filter((r) => r.url || r.pdf_url) || []
|
||||
results.forEach((r) => {
|
||||
r.url = r.url || r.pdf_url
|
||||
})
|
||||
return results
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e)
|
||||
return []
|
||||
})
|
||||
})
|
||||
)
|
||||
).flat()
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
const ARXIV_URL = /^https:\/\/arxiv.org\//
|
||||
|
||||
export const searchIod = async (query: string, keywords: string[]) => {
|
||||
const searchResults = await localIodSearch(query, keywords)
|
||||
|
||||
const isSimpleMode = await getIsSimpleInternetSearch()
|
||||
|
||||
if (isSimpleMode) {
|
||||
await getOllamaURL()
|
||||
return searchResults
|
||||
}
|
||||
|
||||
const docs: Document<Record<string, any>>[] = []
|
||||
for (const result of searchResults) {
|
||||
let url = result.url
|
||||
if (ARXIV_URL.test(result.url)) {
|
||||
url = result.url.replace("/pdf/", "/abs/").replace(".pdf", "")
|
||||
}
|
||||
|
||||
const loader = new PageAssistHtmlLoader({
|
||||
html: "",
|
||||
url
|
||||
})
|
||||
|
||||
const documents = await loader.loadByURL()
|
||||
|
||||
documents.forEach((doc) => {
|
||||
docs.push(doc)
|
||||
})
|
||||
}
|
||||
const ollamaUrl = await getOllamaURL()
|
||||
|
||||
const embeddingModle = await defaultEmbeddingModelForRag()
|
||||
const ollamaEmbedding = await pageAssistEmbeddingModel({
|
||||
model: embeddingModle || "",
|
||||
baseUrl: cleanUrl(ollamaUrl)
|
||||
})
|
||||
|
||||
const textSplitter = await getPageAssistTextSplitter()
|
||||
|
||||
const chunks = await textSplitter.splitDocuments(docs)
|
||||
|
||||
const store = new MemoryVectorStore(ollamaEmbedding)
|
||||
|
||||
await store.addDocuments(chunks)
|
||||
|
||||
const resultsWithEmbeddings = await store.similaritySearch(query, 3)
|
||||
|
||||
const searchResult = resultsWithEmbeddings.map((result) => {
|
||||
return {
|
||||
url: result.metadata.url,
|
||||
content: result.pageContent
|
||||
}
|
||||
})
|
||||
|
||||
return searchResult
|
||||
}
|
@ -8,6 +8,7 @@ import { getWebsiteFromQuery, processSingleWebsite } from "./website"
|
||||
import { searxngSearch } from "./search-engines/searxng"
|
||||
import { braveAPISearch } from "./search-engines/brave-api"
|
||||
import { webBaiduSearch } from "./search-engines/baidu"
|
||||
import { searchIod } from "./iod"
|
||||
|
||||
const getHostName = (url: string) => {
|
||||
try {
|
||||
@ -37,30 +38,66 @@ const searchWeb = (provider: string, query: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
export const getSystemPromptForWeb = async (query: string) => {
|
||||
export const getSystemPromptForWeb = async (
|
||||
query: string,
|
||||
keywords: string[] = [],
|
||||
webSearch = true,
|
||||
iodSearch = false
|
||||
) => {
|
||||
try {
|
||||
|
||||
const websiteVisit = getWebsiteFromQuery(query)
|
||||
let search: {
|
||||
url: any;
|
||||
content: string;
|
||||
let webSearchResults: {
|
||||
url: any
|
||||
content: string
|
||||
}[] = []
|
||||
// let search_results_web = ""
|
||||
|
||||
const isVisitSpecificWebsite = await getIsVisitSpecificWebsite()
|
||||
if (webSearch) {
|
||||
const isVisitSpecificWebsite = await getIsVisitSpecificWebsite()
|
||||
|
||||
if (isVisitSpecificWebsite && websiteVisit.hasUrl) {
|
||||
if (isVisitSpecificWebsite && websiteVisit.hasUrl) {
|
||||
const url = websiteVisit.url
|
||||
const queryWithoutUrl = websiteVisit.queryWithouUrls
|
||||
webSearchResults = await processSingleWebsite(url, queryWithoutUrl)
|
||||
} else {
|
||||
const searchProvider = await getSearchProvider()
|
||||
webSearchResults = await searchWeb(searchProvider, query)
|
||||
}
|
||||
|
||||
const url = websiteVisit.url
|
||||
const queryWithoutUrl = websiteVisit.queryWithouUrls
|
||||
search = await processSingleWebsite(url, queryWithoutUrl)
|
||||
|
||||
} else {
|
||||
const searchProvider = await getSearchProvider()
|
||||
search = await searchWeb(searchProvider, query)
|
||||
// search_results_web = webSearchResults
|
||||
// .map(
|
||||
// (result, idx) =>
|
||||
// `<result source="${result.url}" id="${idx}">${result.content}</result>`
|
||||
// )
|
||||
// .join("\n")
|
||||
}
|
||||
|
||||
let iodSearchResults: {
|
||||
doId: string
|
||||
name: string
|
||||
url?: string
|
||||
// pdf_url?: string
|
||||
description: string
|
||||
}[] = []
|
||||
// let search_results_iod = ""
|
||||
|
||||
const search_results = search
|
||||
if (iodSearch) {
|
||||
iodSearchResults = await searchIod(query, keywords)
|
||||
// search_results_iod = iodSearchResults
|
||||
// .map(
|
||||
// (result, idx) =>
|
||||
// `<result source="${result.url}" id="${idx}">${result.content}</result>`
|
||||
// )
|
||||
// .join("\n")
|
||||
}
|
||||
|
||||
const search_results = iodSearchResults.map((res) => ({
|
||||
url: `${res.doId}: ${res.name}`,
|
||||
content: res.description
|
||||
}))
|
||||
.concat(
|
||||
webSearchResults
|
||||
)
|
||||
.map(
|
||||
(result, idx) =>
|
||||
`<result source="${result.url}" id="${idx}">${result.content}</result>`
|
||||
@ -77,13 +114,14 @@ export const getSystemPromptForWeb = async (query: string) => {
|
||||
|
||||
return {
|
||||
prompt,
|
||||
source: search.map((result) => {
|
||||
webSources: webSearchResults.map((result) => {
|
||||
return {
|
||||
url: result.url,
|
||||
name: getHostName(result.url),
|
||||
type: "url"
|
||||
}
|
||||
})
|
||||
}),
|
||||
iodSources: iodSearchResults,
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
|
Loading…
x
Reference in New Issue
Block a user