update web search results view && web search setting view

This commit is contained in:
duanfuxiang 2025-03-31 18:28:43 +08:00
parent be5b7455b5
commit 8e564950dc
6 changed files with 53 additions and 12 deletions

View File

@ -578,7 +578,13 @@ const Chat = forwardRef<ChatRef, ChatProps>((props, ref) => {
}
}
} else if (toolArgs.type === 'search_web') {
const results = await webSearch(toolArgs.query, settings.serperApiKey, settings.jinaApiKey, (await getRAGEngine()))
const results = await webSearch(
toolArgs.query,
settings.serperApiKey,
settings.serperSearchEngine,
settings.jinaApiKey,
(await getRAGEngine())
)
const formattedContent = `[search_web for '${toolArgs.query}'] Result:\n${results}\n`;
return {
type: 'search_web',

View File

@ -23,9 +23,7 @@ export default function MarkdownReadFileBlock({
}
React.useEffect(() => {
console.log('finish', finish, applyStatus)
if (finish && applyStatus === ApplyStatus.Idle) {
console.log('finish auto read file', path)
onApply({
type: 'read_file',
filepath: path

View File

@ -1,6 +1,7 @@
import { Search } from 'lucide-react'
import React from 'react'
import { useSettings } from '../../contexts/SettingsContext'
import { ApplyStatus, SearchWebToolArgs } from '../../types/apply'
export default function MarkdownWebSearchBlock({
@ -15,10 +16,20 @@ export default function MarkdownWebSearchBlock({
finish: boolean
}) {
const { settings } = useSettings()
const handleClick = () => {
if (settings.serperSearchEngine === 'google') {
window.open(`https://www.google.com/search?q=${query}`, '_blank')
} else if (settings.serperSearchEngine === 'bing') {
window.open(`https://www.bing.com/search?q=${query}`, '_blank')
} else {
window.open(`https://duckduckgo.com/?q=${query}`, '_blank')
}
}
React.useEffect(() => {
console.log('finish', finish, applyStatus)
if (finish && applyStatus === ApplyStatus.Idle) {
console.log('finish auto web search', query)
onApply({
type: 'search_web',
query: query,
@ -28,7 +39,9 @@ export default function MarkdownWebSearchBlock({
return (
<div
className={`infio-chat-code-block has-filename`}
className={`infio-chat-code-block has-filename`
}
onClick={handleClick}
>
<div className={'infio-chat-code-block-header'}>
<div className={'infio-chat-code-block-header-filename'}>

View File

@ -102,7 +102,7 @@ export class InfioSettingTab extends PluginSettingTab {
renderDeepResearchSection(containerEl: HTMLElement): void {
new Setting(containerEl)
.setHeading()
.setName('Deep research')
.setName('Web search')
new Setting(containerEl)
.setName('Serper API key')
@ -130,6 +130,23 @@ export class InfioSettingTab extends PluginSettingTab {
}
return t;
})
new Setting(containerEl)
.setName('Serper search engine')
.setDesc('Choose the search engine to use for web search.')
.addDropdown((dropdown) =>
dropdown
.addOption('google', 'Google')
.addOption('duckduckgo', 'DuckDuckGo')
.addOption('bing', 'Bing')
.setValue(this.plugin.settings.serperSearchEngine)
.onChange(async (value) => {
await this.plugin.setSettings({
...this.plugin.settings,
serperSearchEngine: value,
})
}),
)
new Setting(containerEl)
.setName('Jina API key (Optional)')

View File

@ -231,8 +231,9 @@ export const InfioSettingsSchema = z.object({
// Mode
mode: z.string().catch('ask'),
// Deep Research
// web search
serperApiKey: z.string().catch(''),
serperSearchEngine: z.enum(['google', 'duckduckgo', 'bing']).catch('google'),
jinaApiKey: z.string().catch(''),
// Files Search

View File

@ -29,9 +29,9 @@ function cosineSimilarity(vecA: number[], vecB: number[]): number {
return dotProduct / (magnitudeA * magnitudeB);
}
async function serperSearch(query: string, serperApiKey: string): Promise<SearchResult[]> {
async function serperSearch(query: string, serperApiKey: string, serperSearchEngine: string): Promise<SearchResult[]> {
return new Promise((resolve, reject) => {
const url = `${SERPER_BASE_URL}?q=${encodeURIComponent(query)}&engine=google&api_key=${serperApiKey}&num=20`;
const url = `${SERPER_BASE_URL}?q=${encodeURIComponent(query)}&engine=${serperSearchEngine}&api_key=${serperApiKey}&num=20`;
https.get(url, (res: any) => {
let data = '';
@ -192,9 +192,15 @@ export async function fetchUrlContent(url: string, apiKey: string): Promise<stri
}
}
export async function webSearch(query: string, serperApiKey: string, jinaApiKey: string, ragEngine: RAGEngine): Promise<string> {
export async function webSearch(
query: string,
serperApiKey: string,
jinaApiKey: string,
serperSearchEngine: string,
ragEngine: RAGEngine
): Promise<string> {
try {
const results = await serperSearch(query, serperApiKey);
const results = await serperSearch(query, serperApiKey, serperSearchEngine);
const filteredResults = await filterByEmbedding(query, results, ragEngine);
const filteredResultsWithContent = await Promise.all(filteredResults.map(async (result) => {
let content = await fetchUrlContent(result.link, jinaApiKey);