fix: 网络搜索添加时间信息 (#2255)

* fix: add time when using web search

* feat: add optional

* chore

* chore

* chore

* clean code
This commit is contained in:
Chen Tao 2025-02-25 13:20:53 +08:00 committed by GitHub
parent ff14dcc559
commit c7071a98f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 65 additions and 30 deletions

View File

@ -807,7 +807,8 @@
"description": "Tavily is a web search tool that integrates multiple search engines. It supports multiple languages and search engines.",
"api_key": "Tavily API Key",
"api_key.placeholder": "Enter Tavily API Key"
}
},
"search_with_time": "Search with dates included"
}
},
"translate": {
@ -845,4 +846,4 @@
"visualization": "Visualization"
}
}
}
}

View File

@ -807,7 +807,8 @@
"description": "Tavily は、複数の検索エンジンを統合したウェブ検索ツールです。多くの言語と検索エンジンをサポートしています。",
"api_key": "Tavily API キー",
"api_key.placeholder": "Tavily API キーを入力してください"
}
},
"search_with_time": "日付を含む検索"
}
},
"translate": {
@ -845,4 +846,4 @@
"visualization": "可視化"
}
}
}
}

View File

@ -807,7 +807,8 @@
"description": "Tavily — это инструмент поиска в Интернете, интегрирующий несколько поисковых систем. Он поддерживает несколько языков и поисковых систем.",
"api_key": "Ключ API Tavily",
"api_key.placeholder": "Введите ключ API Tavily"
}
},
"search_with_time": "Поиск, содержащий дату"
}
},
"translate": {
@ -845,4 +846,4 @@
"visualization": "Визуализация"
}
}
}
}

View File

@ -600,11 +600,11 @@
"notion.api_key_placeholder": "请输入Notion 密钥",
"notion.check": {
"button": "检查",
"empty_api_key": "未配置Api_key",
"empty_database_id": "未配置Database_id",
"error": "连接异常请检查网络及Api_key和Database_id是否正确",
"fail": "连接失败请检查网络及Api_key和Database_id是否正确",
"success": "连接成功"
"success": "连接成功",
"error": "连接异常请检查网络及Api_key和Database_id是否正确",
"empty_api_key": "未配置Api_key",
"empty_database_id": "未配置Database_id"
},
"notion.database_id": "Notion 数据库 ID",
"notion.database_id_placeholder": "请输入Notion 数据库 ID",
@ -612,15 +612,6 @@
"notion.page_name_key": "页面标题字段名",
"notion.page_name_key_placeholder": "请输入页面标题字段名,默认为 Name",
"notion.title": "Notion 配置",
"notion.help": "Notion 配置文档",
"notion.check": {
"button": "检查",
"fail": "连接失败请检查网络及Api_key和Database_id是否正确",
"success": "连接成功",
"error": "连接异常请检查网络及Api_key和Database_id是否正确",
"empty_api_key": "未配置Api_key",
"empty_database_id": "未配置Database_id"
},
"notion.auto_split_tip": "当要导出的话题过长时自动分页导出到Notion",
"notion.auto_split": "导出对话时自动分页",
"notion.split_size": "自动分页大小",
@ -816,7 +807,8 @@
"description": "Tavily 是一个集成了多个搜索引擎的网络搜索工具,支持多种语言和多种搜索引擎。",
"api_key": "Tavily API 密钥",
"api_key.placeholder": "请输入 Tavily API 密钥"
}
},
"search_with_time": "搜索包含日期"
}
},
"translate": {
@ -854,4 +846,4 @@
"visualization": "可视化"
}
}
}
}

View File

@ -807,7 +807,8 @@
"description": "Tavily 是一個集成了多個搜索引擎的網路搜索工具,支持多種語言和多種搜索引擎。",
"api_key": "Tavily API 密鑰",
"api_key.placeholder": "請輸入 Tavily API 密鑰"
}
},
"search_with_time": "搜尋包含日期"
}
},
"translate": {
@ -845,4 +846,4 @@
"visualization": "可視化"
}
}
}
}

View File

@ -3,12 +3,23 @@ import tavilyLogoDark from '@renderer/assets/images/search/tavily-dark.svg'
import { HStack } from '@renderer/components/Layout'
import { useTheme } from '@renderer/context/ThemeProvider'
import { useWebSearchProvider } from '@renderer/hooks/useWebSearchProviders'
import { Input, Typography } from 'antd'
import { useAppDispatch, useAppSelector } from '@renderer/store'
import { setSearchWithTime } from '@renderer/store/websearch'
import { Input, Switch, Typography } from 'antd'
import { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
import { SettingContainer, SettingDivider, SettingGroup, SettingHelpLink, SettingHelpTextRow } from '.'
import {
SettingContainer,
SettingDivider,
SettingGroup,
SettingHelpLink,
SettingHelpTextRow,
SettingRow,
SettingRowTitle,
SettingTitle
} from '.'
const WebSearchSettings: FC = () => {
const { t } = useTranslation()
@ -16,8 +27,9 @@ const WebSearchSettings: FC = () => {
const { theme } = useTheme()
const { provider, updateProvider } = useWebSearchProvider('tavily')
const [apiKey, setApiKey] = useState(provider.apiKey)
const logo = theme === 'dark' ? tavilyLogoDark : tavilyLogo
const searchWithTime = useAppSelector((state) => state.websearch.searchWithTime)
const dispatch = useAppDispatch()
useEffect(() => {
return () => {
@ -51,6 +63,15 @@ const WebSearchSettings: FC = () => {
</SettingHelpLink>
</SettingHelpTextRow>
</SettingGroup>
<SettingGroup theme={theme}>
<SettingTitle>{t('settings.general.title')}</SettingTitle>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.websearch.search_with_time')}</SettingRowTitle>
<Switch checked={searchWithTime} onChange={(checked) => dispatch(setSearchWithTime(checked))} />
</SettingRow>
</SettingGroup>
</SettingContainer>
)
}

View File

@ -1,6 +1,7 @@
import store from '@renderer/store'
import { WebSearchProvider } from '@renderer/types'
import { tavily } from '@tavily/core'
import dayjs from 'dayjs'
class WebSearchService {
public isWebSearchEnabled(): boolean {
@ -23,9 +24,16 @@ class WebSearchService {
}
public async search(query: string) {
const searchWithTime = store.getState().websearch.searchWithTime
console.log('searchWithTime', searchWithTime)
let formatted_query = query
if (searchWithTime) {
formatted_query = `today is ${dayjs().format('YYYY-MM-DD')} \r\n ${query}`
}
console.log('formatted_query', formatted_query)
const provider = this.getWebSearchProvider()
const tvly = tavily({ apiKey: provider.apiKey })
return await tvly.search(query, {
return await tvly.search(formatted_query, {
maxResults: 5
})
}

View File

@ -32,7 +32,7 @@ const persistedReducer = persistReducer(
{
key: 'cherry-studio',
storage,
version: 72,
version: 73,
blacklist: ['runtime'],
migrate
},

View File

@ -1120,6 +1120,10 @@ const migrateConfig = {
state.llm.providers.splice(emptyLmStudioProviderIndex, 1)
}
return state
},
'73': (state: RootState) => {
state.websearch.searchWithTime = true
return state
}
}

View File

@ -3,6 +3,7 @@ import type { WebSearchProvider } from '@renderer/types'
export interface WebSearchState {
defaultProvider: string
providers: WebSearchProvider[]
searchWithTime: boolean
}
const initialState: WebSearchState = {
@ -13,7 +14,8 @@ const initialState: WebSearchState = {
name: 'Tavily',
apiKey: ''
}
]
],
searchWithTime: true
}
const websearchSlice = createSlice({
@ -31,10 +33,14 @@ const websearchSlice = createSlice({
if (index !== -1) {
state.providers[index] = action.payload
}
},
setSearchWithTime: (state, action: PayloadAction<boolean>) => {
state.searchWithTime = action.payload
}
}
})
export const { setWebSearchProviders, updateWebSearchProvider, setDefaultProvider } = websearchSlice.actions
export const { setWebSearchProviders, updateWebSearchProvider, setDefaultProvider, setSearchWithTime } =
websearchSlice.actions
export default websearchSlice.reducer