refactor: integrate API server functionality into various components and enhance user notifications

This commit is contained in:
kangfenmao 2025-11-06 11:29:32 +08:00
parent 4e01210df4
commit 84f2281506
6 changed files with 30 additions and 21 deletions

View File

@ -24,6 +24,7 @@ import { useLiveQuery } from 'dexie-react-hooks'
import { useEffect } from 'react' import { useEffect } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useApiServer } from './useApiServer'
import { useDefaultModel } from './useAssistant' import { useDefaultModel } from './useAssistant'
import useFullScreenNotice from './useFullScreenNotice' import useFullScreenNotice from './useFullScreenNotice'
import { useRuntime } from './useRuntime' import { useRuntime } from './useRuntime'
@ -51,6 +52,8 @@ export function useAppInit() {
const avatar = useLiveQuery(() => db.settings.get('image://avatar')) const avatar = useLiveQuery(() => db.settings.get('image://avatar'))
const { theme } = useTheme() const { theme } = useTheme()
const memoryConfig = useAppSelector(selectMemoryConfig) const memoryConfig = useAppSelector(selectMemoryConfig)
const { apiServerConfig, startApiServer } = useApiServer()
const apiServerEnabled = apiServerConfig.enabled
useEffect(() => { useEffect(() => {
document.getElementById('spinner')?.remove() document.getElementById('spinner')?.remove()
@ -245,4 +248,9 @@ export function useAppInit() {
useEffect(() => { useEffect(() => {
checkDataLimit() checkDataLimit()
}, []) }, [])
useEffect(() => {
apiServerEnabled && startApiServer()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [apiServerEnabled])
} }

View File

@ -6,11 +6,9 @@ import { useAssistantPresets } from '@renderer/hooks/useAssistantPresets'
import { useRuntime } from '@renderer/hooks/useRuntime' import { useRuntime } from '@renderer/hooks/useRuntime'
import { useAssistantsTabSortType } from '@renderer/hooks/useStore' import { useAssistantsTabSortType } from '@renderer/hooks/useStore'
import { useTags } from '@renderer/hooks/useTags' import { useTags } from '@renderer/hooks/useTags'
import { useAppDispatch } from '@renderer/store'
import type { Assistant, AssistantsSortType, Topic } from '@renderer/types' import type { Assistant, AssistantsSortType, Topic } from '@renderer/types'
import type { FC } from 'react' import type { FC } from 'react'
import { useCallback, useRef, useState } from 'react' import { useCallback, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
import UnifiedAddButton from './components/UnifiedAddButton' import UnifiedAddButton from './components/UnifiedAddButton'
@ -28,16 +26,12 @@ interface AssistantsTabProps {
onCreateDefaultAssistant: () => void onCreateDefaultAssistant: () => void
} }
const ALERT_KEY = 'enable_api_server_to_use_agent'
const AssistantsTab: FC<AssistantsTabProps> = (props) => { const AssistantsTab: FC<AssistantsTabProps> = (props) => {
const { activeAssistant, setActiveAssistant, onCreateAssistant, onCreateDefaultAssistant } = props const { activeAssistant, setActiveAssistant, onCreateAssistant, onCreateDefaultAssistant } = props
const containerRef = useRef<HTMLDivElement>(null) const containerRef = useRef<HTMLDivElement>(null)
const { t } = useTranslation() const { apiServerConfig } = useApiServer()
const { apiServerConfig, apiServerRunning, apiServerLoading } = useApiServer()
const apiServerEnabled = apiServerConfig.enabled const apiServerEnabled = apiServerConfig.enabled
const { iknow, chat } = useRuntime() const { chat } = useRuntime()
const dispatch = useAppDispatch()
// Agent related hooks // Agent related hooks
const { agents, deleteAgent, isLoading: agentsLoading, error: agentsError } = useAgents() const { agents, deleteAgent, isLoading: agentsLoading, error: agentsError } = useAgents()

View File

@ -1,5 +1,6 @@
import AddAssistantOrAgentPopup from '@renderer/components/Popups/AddAssistantOrAgentPopup' import AddAssistantOrAgentPopup from '@renderer/components/Popups/AddAssistantOrAgentPopup'
import AgentModalPopup from '@renderer/components/Popups/agent/AgentModal' import AgentModalPopup from '@renderer/components/Popups/agent/AgentModal'
import { useApiServer } from '@renderer/hooks/useApiServer'
import { useAppDispatch } from '@renderer/store' import { useAppDispatch } from '@renderer/store'
import { setActiveTopicOrSessionAction } from '@renderer/store/runtime' import { setActiveTopicOrSessionAction } from '@renderer/store/runtime'
import type { AgentEntity, Assistant, Topic } from '@renderer/types' import type { AgentEntity, Assistant, Topic } from '@renderer/types'
@ -18,6 +19,7 @@ interface UnifiedAddButtonProps {
const UnifiedAddButton: FC<UnifiedAddButtonProps> = ({ onCreateAssistant, setActiveAssistant, setActiveAgentId }) => { const UnifiedAddButton: FC<UnifiedAddButtonProps> = ({ onCreateAssistant, setActiveAssistant, setActiveAgentId }) => {
const { t } = useTranslation() const { t } = useTranslation()
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const { apiServerRunning, startApiServer } = useApiServer()
const afterCreate = useCallback( const afterCreate = useCallback(
(a: AgentEntity) => { (a: AgentEntity) => {
@ -44,12 +46,15 @@ const UnifiedAddButton: FC<UnifiedAddButtonProps> = ({ onCreateAssistant, setAct
[dispatch, setActiveAgentId, setActiveAssistant] [dispatch, setActiveAgentId, setActiveAssistant]
) )
const handleAddButtonClick = () => { const handleAddButtonClick = async () => {
AddAssistantOrAgentPopup.show({ AddAssistantOrAgentPopup.show({
onSelect: (type) => { onSelect: (type) => {
if (type === 'assistant') { if (type === 'assistant') {
onCreateAssistant() onCreateAssistant()
} else if (type === 'agent') { }
if (type === 'agent') {
!apiServerRunning && startApiServer()
AgentModalPopup.show({ afterSubmit: afterCreate }) AgentModalPopup.show({ afterSubmit: afterCreate })
} }
} }

View File

@ -96,11 +96,14 @@ const NewApiPage: FC<{ Options: string[] }> = ({ Options }) => {
return editImageFiles return editImageFiles
}, [editImageFiles]) }, [editImageFiles])
const updatePaintingState = (updates: Partial<PaintingAction>) => { const updatePaintingState = useCallback(
(updates: Partial<PaintingAction>) => {
const updatedPainting = { ...painting, providerId: newApiProvider.id, ...updates } const updatedPainting = { ...painting, providerId: newApiProvider.id, ...updates }
setPainting(updatedPainting) setPainting(updatedPainting)
updatePainting(mode, updatedPainting) updatePainting(mode, updatedPainting)
} },
[mode, newApiProvider.id, painting, updatePainting]
)
// ---------------- Model Related Configurations ---------------- // ---------------- Model Related Configurations ----------------
// const modelOptions = MODELS.map((m) => ({ label: m.name, value: m.name })) // const modelOptions = MODELS.map((m) => ({ label: m.name, value: m.name }))

View File

@ -4,7 +4,7 @@ import type { RootState } from '@renderer/store'
import { useAppDispatch } from '@renderer/store' import { useAppDispatch } from '@renderer/store'
import { setApiServerApiKey, setApiServerPort } from '@renderer/store/settings' import { setApiServerApiKey, setApiServerPort } from '@renderer/store/settings'
import { formatErrorMessage } from '@renderer/utils/error' import { formatErrorMessage } from '@renderer/utils/error'
import { Button, Input, InputNumber, Tooltip, Typography } from 'antd' import { Alert, Button, Input, InputNumber, Tooltip, Typography } from 'antd'
import { Copy, ExternalLink, Play, RotateCcw, Square } from 'lucide-react' import { Copy, ExternalLink, Play, RotateCcw, Square } from 'lucide-react'
import type { FC } from 'react' import type { FC } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@ -85,6 +85,10 @@ const ApiServerSettings: FC = () => {
)} )}
</HeaderSection> </HeaderSection>
{!apiServerRunning && (
<Alert type="warning" message={t('agent.warning.enable_server')} style={{ marginBottom: 10 }} showIcon />
)}
{/* Server Control Panel with integrated configuration */} {/* Server Control Panel with integrated configuration */}
<ServerControlPanel $status={apiServerRunning}> <ServerControlPanel $status={apiServerRunning}>
<StatusSection> <StatusSection>

View File

@ -56,7 +56,6 @@ export interface RuntimeState {
export: ExportState export: ExportState
chat: ChatState chat: ChatState
websearch: WebSearchState websearch: WebSearchState
iknow: Record<string, boolean>
} }
export interface ExportState { export interface ExportState {
@ -186,9 +185,6 @@ const runtimeSlice = createSlice({
} }
state.websearch.activeSearches[requestId] = status state.websearch.activeSearches[requestId] = status
}, },
addIknowAction: (state, action: PayloadAction<string>) => {
state.iknow[action.payload] = true
},
setSessionWaitingAction: (state, action: PayloadAction<{ id: string; value: boolean }>) => { setSessionWaitingAction: (state, action: PayloadAction<{ id: string; value: boolean }>) => {
const { id, value } = action.payload const { id, value } = action.payload
state.chat.sessionWaiting[id] = value state.chat.sessionWaiting[id] = value
@ -210,7 +206,6 @@ export const {
setResourcesPath, setResourcesPath,
setUpdateState, setUpdateState,
setExportState, setExportState,
addIknowAction,
// Chat related actions // Chat related actions
toggleMultiSelectMode, toggleMultiSelectMode,
setSelectedMessageIds, setSelectedMessageIds,