fix: v2 merge error (#10658)

* fix: v2 merge error

* fix: review improve

* fix: ci error

* fix: review

* Update index.tsx

* Update index.tsx
This commit is contained in:
Pleasure1234 2025-10-13 02:24:32 +01:00 committed by GitHub
parent 06b6f2b9d8
commit cb12bb5137
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 85 additions and 88 deletions

View File

@ -1,5 +1,5 @@
import { CacheService } from '@main/services/CacheService'
import { loggerService } from '@main/services/LoggerService'
import { cacheService } from '@data/CacheService'
import { loggerService } from '@logger'
import { reduxService } from '@main/services/ReduxService'
import type { ApiModel, Model, Provider } from '@types'
@ -12,7 +12,7 @@ const PROVIDERS_CACHE_TTL = 10 * 1000 // 10 seconds
export async function getAvailableProviders(): Promise<Provider[]> {
try {
// Try to get from cache first (faster)
const cachedSupportedProviders = CacheService.get<Provider[]>(PROVIDERS_CACHE_KEY)
const cachedSupportedProviders = cacheService.get<Provider[]>(PROVIDERS_CACHE_KEY)
if (cachedSupportedProviders && cachedSupportedProviders.length > 0) {
logger.debug('Providers resolved from cache', {
count: cachedSupportedProviders.length
@ -33,7 +33,7 @@ export async function getAvailableProviders(): Promise<Provider[]> {
)
// Cache the filtered results
CacheService.set(PROVIDERS_CACHE_KEY, supportedProviders, PROVIDERS_CACHE_TTL)
cacheService.set(PROVIDERS_CACHE_KEY, supportedProviders, PROVIDERS_CACHE_TTL)
logger.info('Providers filtered', {
supported: supportedProviders.length,

View File

@ -1,13 +1,12 @@
import { CacheService } from '@main/services/CacheService'
import { cacheService } from '@data/CacheService'
import { loggerService } from '@logger'
import mcpService from '@main/services/MCPService'
import { reduxService } from '@main/services/ReduxService'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import type { ListToolsResult } from '@modelcontextprotocol/sdk/types.js'
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'
import type { MCPServer } from '@types'
import { loggerService } from '../../services/LoggerService'
import { reduxService } from '../../services/ReduxService'
const logger = loggerService.withContext('MCPApiService')
// Cache configuration
@ -51,7 +50,7 @@ export async function getMCPServersFromRedux(): Promise<MCPServer[]> {
logger.debug('Getting servers from Redux store')
// Try to get from cache first (faster)
const cachedServers = CacheService.get<MCPServer[]>(MCP_SERVERS_CACHE_KEY)
const cachedServers = cacheService.get<MCPServer[]>(MCP_SERVERS_CACHE_KEY)
if (cachedServers) {
logger.debug('MCP servers resolved from cache', { count: cachedServers.length })
return cachedServers
@ -62,7 +61,7 @@ export async function getMCPServersFromRedux(): Promise<MCPServer[]> {
const serverList = servers || []
// Cache the results
CacheService.set(MCP_SERVERS_CACHE_KEY, serverList, MCP_SERVERS_CACHE_TTL)
cacheService.set(MCP_SERVERS_CACHE_KEY, serverList, MCP_SERVERS_CACHE_TTL)
logger.debug('Fetched servers from Redux store', { count: serverList.length })
return serverList

View File

@ -21,7 +21,8 @@ import type {
OcrProvider,
Provider,
Shortcut,
SupportedOcrFile} from '@types'
SupportedOcrFile
} from '@types'
import checkDiskSpace from 'check-disk-space'
import type { ProxyConfig } from 'electron'
import { BrowserWindow, dialog, ipcMain, session, shell, systemPreferences, webContents } from 'electron'

View File

@ -1,5 +1,5 @@
import { RowFlex } from '@cherrystudio/ui'
import { FreeTrialModelTag } from '@renderer/components/FreeTrialModelTag'
import { HStack } from '@renderer/components/Layout'
import ModelTagsWithLabel from '@renderer/components/ModelTagsWithLabel'
import { TopView } from '@renderer/components/TopView'
import { DynamicVirtualList, type DynamicVirtualListRef } from '@renderer/components/VirtualList'
@ -105,7 +105,7 @@ const PopupContainer: React.FC<Props> = ({ model, apiFilter, modelFilter, showTa
type: 'model',
name: (
<ModelName>
<HStack alignItems="center">{model.name}</HStack>
<RowFlex className="items-center">{model.name}</RowFlex>
{isCherryAi && <FreeTrialModelTag model={model} showLabel={false} />}
</ModelName>
),

View File

@ -1,7 +1,7 @@
import { Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ScrollShadow } from '@heroui/react'
import { loggerService } from '@logger'
import { handleSaveData } from '@renderer/store'
import { ReleaseNoteInfo, UpdateInfo } from 'builder-util-runtime'
import type { ReleaseNoteInfo, UpdateInfo } from 'builder-util-runtime'
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Markdown from 'react-markdown'

View File

@ -290,9 +290,11 @@ const AgentSessionInputbar: FC<Props> = ({ agentId, sessionId }) => {
<SendMessageButton sendMessage={sendMessage} disabled={sendDisabled} />
{canAbort && (
<Tooltip placement="top" content={t('chat.input.pause')}>
<ActionIconButton onClick={abortAgentSession} style={{ marginRight: -2 }}>
<CirclePause size={20} color="var(--color-error)" />
</ActionIconButton>
<ActionIconButton
onClick={abortAgentSession}
className="-mr-0.5"
icon={<CirclePause size={20} color="var(--color-error)" />}
/>
</Tooltip>
)}
</div>

View File

@ -1,4 +1,4 @@
import { Button, DescriptionSwitch, HelpTooltip, RowFlex, Selector, type SelectorItem } from '@cherrystudio/ui'
import { Button, DescriptionSwitch, HelpTooltip, RowFlex, Selector, type SelectorItem, Switch } from '@cherrystudio/ui'
import { useMultiplePreferences, usePreference } from '@data/hooks/usePreference'
import EditableNumber from '@renderer/components/EditableNumber'
import Scrollbar from '@renderer/components/Scrollbar'
@ -19,7 +19,7 @@ import { modalConfirm } from '@renderer/utils'
import { getSendMessageShortcutLabel } from '@renderer/utils/input'
import type { MultiModelMessageStyle, SendMessageShortcut } from '@shared/data/preference/preferenceTypes'
import { ThemeMode } from '@shared/data/preference/preferenceTypes'
import { Col, InputNumber, Row, Slider, Switch } from 'antd'
import { Col, InputNumber, Row, Slider } from 'antd'
import { Settings2 } from 'lucide-react'
import type { FC } from 'react'
import { useCallback, useEffect, useMemo, useState } from 'react'
@ -245,10 +245,10 @@ const SettingsTab: FC<Props> = (props) => {
<HelpTooltip title={t('chat.settings.temperature.tip')} />
</SettingRowTitleSmall>
<Switch
size="small"
size="sm"
style={{ marginLeft: 'auto' }}
checked={enableTemperature}
onChange={(enabled) => {
isSelected={enableTemperature}
onValueChange={(enabled) => {
setEnableTemperature(enabled)
onUpdateAssistantSettings({ enableTemperature: enabled })
}}
@ -292,9 +292,9 @@ const SettingsTab: FC<Props> = (props) => {
<SettingRow>
<SettingRowTitleSmall>{t('models.stream_output')}</SettingRowTitleSmall>
<Switch
size="small"
checked={streamOutput}
onChange={(checked) => {
size="sm"
isSelected={streamOutput}
onValueChange={(checked) => {
setStreamOutput(checked)
onUpdateAssistantSettings({ streamOutput: checked })
}}
@ -309,9 +309,9 @@ const SettingsTab: FC<Props> = (props) => {
</SettingRowTitleSmall>
</Row>
<Switch
size="small"
checked={enableMaxTokens}
onChange={async (enabled) => {
size="sm"
isSelected={enableMaxTokens}
onValueChange={async (enabled) => {
if (enabled) {
const confirmed = await modalConfirm({
title: t('chat.settings.max_tokens.confirm'),

View File

@ -1,8 +1,8 @@
import { SyncOutlined } from '@ant-design/icons'
import { Button } from '@cherrystudio/ui'
import { usePreference } from '@data/hooks/usePreference'
import { useDisclosure } from '@heroui/react'
import UpdateDialog from '@renderer/components/UpdateDialog'
import { usePreference } from '@data/hooks/usePreference'
import { useAppUpdateState } from '@renderer/hooks/useAppUpdate'
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'

View File

@ -2,7 +2,8 @@ import { Button, Input } from '@heroui/react'
import { loggerService } from '@logger'
import type { WebviewTag } from 'electron'
import { ChevronDown, ChevronUp, X } from 'lucide-react'
import { FC, useCallback, useEffect, useRef, useState } from 'react'
import type { FC } from 'react'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
type FoundInPageResult = Electron.FoundInPageResult
@ -121,7 +122,7 @@ const WebviewSearch: FC<WebviewSearchProps> = ({ webviewRef, isWebviewReady, app
const nextWebview = webviewRef.current ?? null
if (currentWebview === nextWebview) return
setCurrentWebview(nextWebview)
})
}, [webviewRef, currentWebview])
useEffect(() => {
const target = currentWebview

View File

@ -1,4 +1,4 @@
import { SpaceBetweenRowFlex } from '@cherrystudio/ui'
import { SpaceBetweenRowFlex, Tooltip } from '@cherrystudio/ui'
import { usePreference } from '@data/hooks/usePreference'
import ActionIconButton from '@renderer/components/Buttons/ActionIconButton'
import CodeEditor from '@renderer/components/CodeEditor'
@ -6,9 +6,8 @@ import RichEditor from '@renderer/components/RichEditor'
import type { RichEditorRef } from '@renderer/components/RichEditor/types'
import Selector from '@renderer/components/Selector'
import { useNotesSettings } from '@renderer/hooks/useNotesSettings'
import { useAppDispatch } from '@renderer/store'
import type { EditorView } from '@renderer/types'
import { Empty, Tooltip } from 'antd'
import { Empty } from 'antd'
import { SpellCheck } from 'lucide-react'
import type { FC, RefObject } from 'react'
import { memo, useCallback, useMemo, useState } from 'react'
@ -26,8 +25,6 @@ interface NotesEditorProps {
const NotesEditor: FC<NotesEditorProps> = memo(
({ activeNodeId, currentContent, tokenCount, onMarkdownChange, editorRef }) => {
const { t } = useTranslation()
// oxlint-disable-next-line no-unused-vars
const dispatch = useAppDispatch()
const { settings } = useNotesSettings()
const [enableSpellCheck, setEnableSpellCheck] = usePreference('app.spell_check.enabled')
const currentViewMode = useMemo(() => {
@ -103,8 +100,7 @@ const NotesEditor: FC<NotesEditorProps> = memo(
gap: 12
}}>
{tmpViewMode === 'preview' && (
// oxlint-disable-next-line no-undef
<Tooltip placement="top" title={t('notes.spell_check_tooltip')} mouseLeaveDelay={0} arrow>
<Tooltip placement="top" content={t('notes.spell_check_tooltip')} closeDelay={0}>
<ActionIconButton
active={enableSpellCheck}
onClick={() => {
@ -115,7 +111,6 @@ const NotesEditor: FC<NotesEditorProps> = memo(
icon={<SpellCheck size={18} />}>
<SpellCheck size={18} />
</ActionIconButton>
{/* oxlint-disable-next-line no-undef */}
</Tooltip>
)}
<Selector

View File

@ -1,5 +1,5 @@
import { GithubOutlined } from '@ant-design/icons'
import { RowFlex, Switch, Tooltip, Avatar, Button } from '@cherrystudio/ui'
import { Avatar, Button, RowFlex, Switch, Tooltip } from '@cherrystudio/ui'
import { usePreference } from '@data/hooks/usePreference'
import { Radio, RadioGroup, useDisclosure } from '@heroui/react'
import IndicatorLight from '@renderer/components/IndicatorLight'

View File

@ -1,6 +1,5 @@
import { Button } from '@cherrystudio/ui'
import { Button, SpaceBetweenRowFlex } from '@cherrystudio/ui'
import CodeEditor from '@renderer/components/CodeEditor'
import { HSpaceBetweenStack } from '@renderer/components/Layout'
import type { RichEditorRef } from '@renderer/components/RichEditor/types'
import type { useUpdateAgent } from '@renderer/hooks/agents/useUpdateAgent'
import type { useUpdateSession } from '@renderer/hooks/agents/useUpdateSession'
@ -83,14 +82,12 @@ const PromptSettings: FC<AgentPromptSettingsProps> = ({ agentBase, update }) =>
onChange={setInstructions}
height="100%"
expanded={false}
style={{
height: '100%'
}}
className="h-full"
/>
)}
</RichEditorContainer>
</TextAreaContainer>
<HSpaceBetweenStack width="100%" justifyContent="flex-end" mt="10px">
<SpaceBetweenRowFlex className="mt-2.5 w-full justify-end">
<TokenCount>Tokens: {tokenCount}</TokenCount>
<Button
variant="solid"
@ -111,7 +108,7 @@ const PromptSettings: FC<AgentPromptSettingsProps> = ({ agentBase, update }) =>
}}>
{showPreview ? t('common.edit') : t('common.save')}
</Button>
</HSpaceBetweenStack>
</SpaceBetweenRowFlex>
</SettingsItem>
</SettingsContainer>
)

View File

@ -1,13 +1,13 @@
import { Button, RowFlex } from '@cherrystudio/ui'
import { loggerService } from '@logger'
import { TopView } from '@renderer/components/TopView'
import { useTimer } from '@renderer/hooks/useTimer'
import type { Provider } from '@renderer/types'
import type { FormProps } from 'antd'
import { AutoComplete, Button, Flex, Form, Input, Modal, Progress, Select } from 'antd'
import { AutoComplete, Form, Input, Modal, Progress, Select } from 'antd'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useTimer } from '../../../../hooks/useTimer'
const logger = loggerService.withContext('OVMSClient')
interface ShowParams {
@ -233,7 +233,7 @@ const PopupContainer: React.FC<Props> = ({ title, resolve }) => {
labelCol={{ flex: '110px' }}
labelAlign="left"
colon={false}
style={{ marginTop: 25 }}
className="mt-[25px]"
onFinish={onFinish}
disabled={false}>
<Form.Item
@ -299,7 +299,7 @@ const PopupContainer: React.FC<Props> = ({ title, resolve }) => {
/>
</Form.Item>
{loading && (
<Form.Item style={{ marginBottom: 16 }}>
<Form.Item className="mb-4">
<Progress
percent={Math.round(progress)}
status={progress === 100 ? 'success' : 'active'}
@ -310,22 +310,21 @@ const PopupContainer: React.FC<Props> = ({ title, resolve }) => {
showInfo={true}
format={(percent) => `${percent}%`}
/>
<div style={{ textAlign: 'center', marginTop: 8, color: '#666', fontSize: '14px' }}>
{t('ovms.download.tip')}
</div>
<div className="mt-2 text-center text-[#666] text-sm">{t('ovms.download.tip')}</div>
</Form.Item>
)}
<Form.Item style={{ marginBottom: 8, textAlign: 'center' }}>
<Flex justify="end" align="center" style={{ position: 'relative' }}>
<Form.Item className="mb-2 text-center">
<RowFlex className="relative items-center justify-end">
<Button
type="primary"
htmlType={loading ? 'button' : 'submit'}
size="middle"
loading={false}
onClick={loading ? onCancel : undefined}>
color="primary"
variant="solid"
type={loading ? 'button' : 'submit'}
size="md"
isLoading={false}
onPress={loading ? onCancel : undefined}>
{loading ? t('common.cancel') : t('ovms.download.button')}
</Button>
</Flex>
</RowFlex>
</Form.Item>
</Form>
</Modal>

View File

@ -1,5 +1,5 @@
import { VStack } from '@renderer/components/Layout'
import { Alert, Button } from 'antd'
import { Button, ColFlex } from '@cherrystudio/ui'
import { Alert } from 'antd'
import type { FC } from 'react'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
@ -109,52 +109,55 @@ const OVMSSettings: FC = () => {
banner
style={{ borderRadius: 'var(--list-item-border-radius)' }}
description={
<VStack>
<ColFlex>
<SettingRow style={{ width: '100%' }}>
<SettingSubtitle style={{ margin: 0, fontWeight: 'normal' }}>{getStatusMessage()}</SettingSubtitle>
{ovmsStatus === 'not-installed' && (
<Button
type="primary"
onClick={installOvms}
loading={isInstallingOvms}
disabled={isInstallingOvms}
size="small">
color="primary"
variant="solid"
onPress={installOvms}
isLoading={isInstallingOvms}
isDisabled={isInstallingOvms}
size="sm">
{isInstallingOvms ? t('ovms.action.installing') : t('ovms.action.install')}
</Button>
)}
{ovmsStatus === 'not-running' && (
<div style={{ display: 'flex', gap: '8px' }}>
<Button
type="primary"
onClick={installOvms}
loading={isInstallingOvms}
disabled={isInstallingOvms || isRunningOvms}
size="small">
color="primary"
variant="solid"
onPress={installOvms}
isLoading={isInstallingOvms}
isDisabled={isInstallingOvms || isRunningOvms}
size="sm">
{isInstallingOvms ? t('ovms.action.installing') : t('ovms.action.reinstall')}
</Button>
<Button
type="primary"
onClick={runOvms}
loading={isRunningOvms}
disabled={isRunningOvms}
size="small">
color="primary"
variant="solid"
onPress={runOvms}
isLoading={isRunningOvms}
isDisabled={isRunningOvms}
size="sm">
{isRunningOvms ? t('ovms.action.starting') : t('ovms.action.run')}
</Button>
</div>
)}
{ovmsStatus === 'running' && (
<Button
type="primary"
danger
onClick={stopOvms}
loading={isStoppingOvms}
disabled={isStoppingOvms}
size="small">
color="danger"
variant="solid"
onPress={stopOvms}
isLoading={isStoppingOvms}
isDisabled={isStoppingOvms}
size="sm">
{isStoppingOvms ? t('ovms.action.stopping') : t('ovms.action.stop')}
</Button>
)}
</SettingRow>
</VStack>
</ColFlex>
}
/>
<Alert