feat: add web search for google gemini modal gemini-2.0-flash-exp
This commit is contained in:
parent
f312c5fc40
commit
2fae6e4a3e
@ -62,12 +62,7 @@ electronDownload:
|
||||
afterSign: scripts/notarize.js
|
||||
releaseInfo:
|
||||
releaseNotes: |
|
||||
增加快捷键切换助手和话题显示
|
||||
历史消息懒加载 by @1355873789
|
||||
更快的应用更新下载速度 by @1355873789
|
||||
更加清晰的模型分组
|
||||
修复部分代码块无法正常显示问题
|
||||
增加应用更新内容显示
|
||||
消息发送增加 Ctrl + Enter 快捷键
|
||||
清除上下文消息点击可以撤销
|
||||
增加 Top-P 设置选项
|
||||
修复对话消息无法删除问题
|
||||
支持 Gemini 模型联网搜索
|
||||
发送消息增加 Command + Enter 快捷键 by @duanyongcheng
|
||||
Windows 版本样式优化
|
||||
|
||||
@ -57,7 +57,7 @@
|
||||
"@electron-toolkit/eslint-config-prettier": "^2.0.0",
|
||||
"@electron-toolkit/eslint-config-ts": "^1.0.1",
|
||||
"@electron-toolkit/tsconfig": "^1.0.1",
|
||||
"@google/generative-ai": "^0.16.0",
|
||||
"@google/generative-ai": "^0.21.0",
|
||||
"@hello-pangea/dnd": "^16.6.0",
|
||||
"@kangfenmao/keyv-storage": "^0.1.0",
|
||||
"@reduxjs/toolkit": "^2.2.5",
|
||||
|
||||
15
src/renderer/src/components/Icons/WebSearchIcon.tsx
Normal file
15
src/renderer/src/components/Icons/WebSearchIcon.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import { GlobalOutlined } from '@ant-design/icons'
|
||||
import React, { FC } from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const WebSearchIcon: FC<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>> = (props) => {
|
||||
return <Icon {...(props as any)} />
|
||||
}
|
||||
|
||||
const Icon = styled(GlobalOutlined)`
|
||||
color: var(--color-link);
|
||||
font-size: 12px;
|
||||
margin-left: 4px;
|
||||
`
|
||||
|
||||
export default WebSearchIcon
|
||||
@ -1,7 +1,7 @@
|
||||
import { PushpinOutlined, SearchOutlined } from '@ant-design/icons'
|
||||
import VisionIcon from '@renderer/components/Icons/VisionIcon'
|
||||
import { TopView } from '@renderer/components/TopView'
|
||||
import { getModelLogo, isVisionModel } from '@renderer/config/models'
|
||||
import { getModelLogo, isVisionModel, isWebSearchModel } from '@renderer/config/models'
|
||||
import db from '@renderer/databases'
|
||||
import { useProviders } from '@renderer/hooks/useProvider'
|
||||
import { getModelUniqId } from '@renderer/services/ModelService'
|
||||
@ -12,6 +12,7 @@ import { useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import WebSearchIcon from '../Icons/WebSearchIcon'
|
||||
import { HStack } from '../Layout'
|
||||
import Scrollbar from '../Scrollbar'
|
||||
|
||||
@ -73,7 +74,7 @@ const PopupContainer: React.FC<PopupContainerProps> = ({ model, resolve }) => {
|
||||
label: (
|
||||
<ModelItem>
|
||||
<span>
|
||||
{m?.name} {isVisionModel(m) && <VisionIcon />}
|
||||
{m?.name} {isVisionModel(m) && <VisionIcon />} {isWebSearchModel(m) && <WebSearchIcon />}
|
||||
</span>
|
||||
<PinIcon
|
||||
onClick={(e) => {
|
||||
|
||||
@ -1056,3 +1056,7 @@ export function isVisionModel(model: Model): boolean {
|
||||
export function isSupportedModel(model: OpenAI.Models.Model): boolean {
|
||||
return !NOT_SUPPORTED_REGEX.test(model.id)
|
||||
}
|
||||
|
||||
export function isWebSearchModel(model: Model): boolean {
|
||||
return model?.provider === 'gemini' && model?.id === 'gemini-2.0-flash-exp'
|
||||
}
|
||||
|
||||
@ -80,6 +80,7 @@
|
||||
"input.topics": " Topics ",
|
||||
"input.translate": "Translate to English",
|
||||
"input.upload": "Upload image or document file",
|
||||
"input.web_search": "Enable web search",
|
||||
"message.new.branch": "New Branch",
|
||||
"message.new.branch.created": "New Branch Created",
|
||||
"message.new.context": "New Context",
|
||||
|
||||
@ -80,6 +80,7 @@
|
||||
"input.topics": " Топики ",
|
||||
"input.translate": "Перевести на английский",
|
||||
"input.upload": "Загрузить изображение или документ",
|
||||
"input.web_search": "Включить веб-поиск",
|
||||
"message.new.branch": "Новая ветка",
|
||||
"message.new.branch.created": "Новая ветка создана",
|
||||
"message.new.context": "Новый контекст",
|
||||
|
||||
@ -80,6 +80,7 @@
|
||||
"input.topics": " 话题 ",
|
||||
"input.translate": "翻译成英文",
|
||||
"input.upload": "上传图片或文档",
|
||||
"input.web_search": "开启网络搜索",
|
||||
"message.new.branch": "新分支",
|
||||
"message.new.branch.created": "新分支已创建",
|
||||
"message.new.context": "清除上下文",
|
||||
|
||||
@ -80,6 +80,7 @@
|
||||
"input.topics": " 話題 ",
|
||||
"input.translate": "翻譯成英文",
|
||||
"input.upload": "上傳圖片或文檔",
|
||||
"input.web_search": "開啟網路搜索",
|
||||
"message.new.branch": "新分支",
|
||||
"message.new.branch.created": "新分支已建立",
|
||||
"message.new.context": "新上下文",
|
||||
|
||||
@ -4,13 +4,14 @@ import {
|
||||
FormOutlined,
|
||||
FullscreenExitOutlined,
|
||||
FullscreenOutlined,
|
||||
GlobalOutlined,
|
||||
PauseCircleOutlined,
|
||||
QuestionCircleOutlined
|
||||
} from '@ant-design/icons'
|
||||
import { PicCenterOutlined } from '@ant-design/icons'
|
||||
import TranslateButton from '@renderer/components/TranslateButton'
|
||||
import { isMac } from '@renderer/config/constant'
|
||||
import { isVisionModel } from '@renderer/config/models'
|
||||
import { isVisionModel, isWebSearchModel } from '@renderer/config/models'
|
||||
import db from '@renderer/databases'
|
||||
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||
import { useRuntime } from '@renderer/hooks/useRuntime'
|
||||
@ -48,10 +49,10 @@ interface Props {
|
||||
let _text = ''
|
||||
let _files: FileType[] = []
|
||||
|
||||
const Inputbar: FC<Props> = ({ assistant, setActiveTopic }) => {
|
||||
const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic }) => {
|
||||
const [text, setText] = useState(_text)
|
||||
const [inputFocus, setInputFocus] = useState(false)
|
||||
const { addTopic, model, setModel } = useAssistant(assistant.id)
|
||||
const { assistant, addTopic, model, setModel, updateAssistant } = useAssistant(_assistant.id)
|
||||
const {
|
||||
sendMessageShortcut,
|
||||
fontSize,
|
||||
@ -400,6 +401,17 @@ const Inputbar: FC<Props> = ({ assistant, setActiveTopic }) => {
|
||||
<FormOutlined />
|
||||
</ToolbarButton>
|
||||
</Tooltip>
|
||||
{isWebSearchModel(model) && (
|
||||
<Tooltip placement="top" title={t('chat.input.web_search')} arrow>
|
||||
<ToolbarButton
|
||||
type="text"
|
||||
onClick={() => updateAssistant({ ...assistant, enableWebSearch: !assistant.enableWebSearch })}>
|
||||
<GlobalOutlined
|
||||
style={{ color: assistant.enableWebSearch ? 'var(--color-link)' : 'var(--color-icon)' }}
|
||||
/>
|
||||
</ToolbarButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
<Tooltip placement="top" title={t('chat.input.clear')} arrow>
|
||||
<Popconfirm
|
||||
title={t('chat.input.clear.content')}
|
||||
|
||||
@ -8,7 +8,8 @@ import {
|
||||
SettingOutlined
|
||||
} from '@ant-design/icons'
|
||||
import VisionIcon from '@renderer/components/Icons/VisionIcon'
|
||||
import { getModelLogo, isVisionModel, VISION_REGEX } from '@renderer/config/models'
|
||||
import WebSearchIcon from '@renderer/components/Icons/WebSearchIcon'
|
||||
import { getModelLogo, isVisionModel, isWebSearchModel, VISION_REGEX } from '@renderer/config/models'
|
||||
import { PROVIDER_CONFIG } from '@renderer/config/providers'
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { useAssistants, useDefaultModel } from '@renderer/hooks/useAssistant'
|
||||
@ -261,20 +262,24 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
|
||||
title={group}
|
||||
style={{ marginBottom: '10px', border: '0.5px solid var(--color-border)' }}
|
||||
size="small">
|
||||
{modelGroups[group].map((model) => (
|
||||
<ModelListItem key={model.id}>
|
||||
<ModelListHeader>
|
||||
<Avatar src={getModelLogo(model.id)} size={22} style={{ marginRight: '8px' }}>
|
||||
{model.name[0].toUpperCase()}
|
||||
</Avatar>
|
||||
{model.name} {isVisionModel(model) && <VisionIcon />}
|
||||
<Popover content={modelTypeContent(model)} title={t('model.type.select')} trigger="click">
|
||||
<SettingIcon />
|
||||
</Popover>
|
||||
</ModelListHeader>
|
||||
<RemoveIcon onClick={() => removeModel(model)} />
|
||||
</ModelListItem>
|
||||
))}
|
||||
{modelGroups[group].map((model) => {
|
||||
console.debug(model)
|
||||
return (
|
||||
<ModelListItem key={model.id}>
|
||||
<ModelListHeader>
|
||||
<Avatar src={getModelLogo(model.id)} size={22} style={{ marginRight: '8px' }}>
|
||||
{model.name[0].toUpperCase()}
|
||||
</Avatar>
|
||||
{model.name} {isVisionModel(model) && <VisionIcon />}
|
||||
{isWebSearchModel(model) && <WebSearchIcon />}
|
||||
<Popover content={modelTypeContent(model)} title={t('model.type.select')} trigger="click">
|
||||
<SettingIcon />
|
||||
</Popover>
|
||||
</ModelListHeader>
|
||||
<RemoveIcon onClick={() => removeModel(model)} />
|
||||
</ModelListItem>
|
||||
)
|
||||
})}
|
||||
</Card>
|
||||
))}
|
||||
{docsWebsite && (
|
||||
|
||||
@ -84,6 +84,8 @@ export default class GeminiProvider extends BaseProvider {
|
||||
{
|
||||
model: model.id,
|
||||
systemInstruction: assistant.prompt,
|
||||
// @ts-ignore googleSearch is not a valid tool for Gemini
|
||||
tools: assistant.enableWebSearch ? [{ googleSearch: {} }] : [],
|
||||
generationConfig: {
|
||||
maxOutputTokens: maxTokens,
|
||||
temperature: assistant?.settings?.temperature,
|
||||
|
||||
@ -13,6 +13,7 @@ export type Assistant = {
|
||||
defaultModel?: Model
|
||||
settings?: Partial<AssistantSettings>
|
||||
messages?: AssistantMessage[]
|
||||
enableWebSearch?: boolean
|
||||
}
|
||||
|
||||
export type AssistantMessage = {
|
||||
|
||||
10
yarn.lock
10
yarn.lock
@ -798,10 +798,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@google/generative-ai@npm:^0.16.0":
|
||||
version: 0.16.1
|
||||
resolution: "@google/generative-ai@npm:0.16.1"
|
||||
checksum: 10c0/bad13a040e210a48a44272b81ef78213d23c17491ff3cb0a937952518c79e96005b78d8c3324342b5b8613b6b13f56fe9bc53447c5d2c7da4a9cd26c6a8d7de4
|
||||
"@google/generative-ai@npm:^0.21.0":
|
||||
version: 0.21.0
|
||||
resolution: "@google/generative-ai@npm:0.21.0"
|
||||
checksum: 10c0/cff5946c5964f2380e5097d82bd563d79be27a1a5ac604aaaad3f9ba3382992e4f0a371bd255baabfba4e5bdf296d8ce1410cbd65424afa98e64b2590fe49f3b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -2341,7 +2341,7 @@ __metadata:
|
||||
"@electron-toolkit/preload": "npm:^3.0.0"
|
||||
"@electron-toolkit/tsconfig": "npm:^1.0.1"
|
||||
"@electron-toolkit/utils": "npm:^3.0.0"
|
||||
"@google/generative-ai": "npm:^0.16.0"
|
||||
"@google/generative-ai": "npm:^0.21.0"
|
||||
"@hello-pangea/dnd": "npm:^16.6.0"
|
||||
"@kangfenmao/keyv-storage": "npm:^0.1.0"
|
||||
"@reduxjs/toolkit": "npm:^2.2.5"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user