diff --git a/src/renderer/src/hooks/useAppInit.ts b/src/renderer/src/hooks/useAppInit.ts index 3ecbdf762..beec6f819 100644 --- a/src/renderer/src/hooks/useAppInit.ts +++ b/src/renderer/src/hooks/useAppInit.ts @@ -24,6 +24,7 @@ import { useLiveQuery } from 'dexie-react-hooks' import { useEffect } from 'react' import { useTranslation } from 'react-i18next' +import { useApiServer } from './useApiServer' import { useDefaultModel } from './useAssistant' import useFullScreenNotice from './useFullScreenNotice' import { useRuntime } from './useRuntime' @@ -51,6 +52,8 @@ export function useAppInit() { const avatar = useLiveQuery(() => db.settings.get('image://avatar')) const { theme } = useTheme() const memoryConfig = useAppSelector(selectMemoryConfig) + const { apiServerConfig, startApiServer } = useApiServer() + const apiServerEnabled = apiServerConfig.enabled useEffect(() => { document.getElementById('spinner')?.remove() @@ -245,4 +248,9 @@ export function useAppInit() { useEffect(() => { checkDataLimit() }, []) + + useEffect(() => { + apiServerEnabled && startApiServer() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [apiServerEnabled]) } diff --git a/src/renderer/src/pages/home/Tabs/AssistantsTab.tsx b/src/renderer/src/pages/home/Tabs/AssistantsTab.tsx index 37e8b4805..3c0c9cf80 100644 --- a/src/renderer/src/pages/home/Tabs/AssistantsTab.tsx +++ b/src/renderer/src/pages/home/Tabs/AssistantsTab.tsx @@ -6,11 +6,9 @@ import { useAssistantPresets } from '@renderer/hooks/useAssistantPresets' import { useRuntime } from '@renderer/hooks/useRuntime' import { useAssistantsTabSortType } from '@renderer/hooks/useStore' import { useTags } from '@renderer/hooks/useTags' -import { useAppDispatch } from '@renderer/store' import type { Assistant, AssistantsSortType, Topic } from '@renderer/types' import type { FC } from 'react' import { useCallback, useRef, useState } from 'react' -import { useTranslation } from 'react-i18next' import styled from 'styled-components' import UnifiedAddButton from './components/UnifiedAddButton' @@ -28,16 +26,12 @@ interface AssistantsTabProps { onCreateDefaultAssistant: () => void } -const ALERT_KEY = 'enable_api_server_to_use_agent' - const AssistantsTab: FC = (props) => { const { activeAssistant, setActiveAssistant, onCreateAssistant, onCreateDefaultAssistant } = props const containerRef = useRef(null) - const { t } = useTranslation() - const { apiServerConfig, apiServerRunning, apiServerLoading } = useApiServer() + const { apiServerConfig } = useApiServer() const apiServerEnabled = apiServerConfig.enabled - const { iknow, chat } = useRuntime() - const dispatch = useAppDispatch() + const { chat } = useRuntime() // Agent related hooks const { agents, deleteAgent, isLoading: agentsLoading, error: agentsError } = useAgents() diff --git a/src/renderer/src/pages/home/Tabs/components/UnifiedAddButton.tsx b/src/renderer/src/pages/home/Tabs/components/UnifiedAddButton.tsx index 53e092fd5..967d62f83 100644 --- a/src/renderer/src/pages/home/Tabs/components/UnifiedAddButton.tsx +++ b/src/renderer/src/pages/home/Tabs/components/UnifiedAddButton.tsx @@ -1,5 +1,6 @@ import AddAssistantOrAgentPopup from '@renderer/components/Popups/AddAssistantOrAgentPopup' import AgentModalPopup from '@renderer/components/Popups/agent/AgentModal' +import { useApiServer } from '@renderer/hooks/useApiServer' import { useAppDispatch } from '@renderer/store' import { setActiveTopicOrSessionAction } from '@renderer/store/runtime' import type { AgentEntity, Assistant, Topic } from '@renderer/types' @@ -18,6 +19,7 @@ interface UnifiedAddButtonProps { const UnifiedAddButton: FC = ({ onCreateAssistant, setActiveAssistant, setActiveAgentId }) => { const { t } = useTranslation() const dispatch = useAppDispatch() + const { apiServerRunning, startApiServer } = useApiServer() const afterCreate = useCallback( (a: AgentEntity) => { @@ -44,12 +46,15 @@ const UnifiedAddButton: FC = ({ onCreateAssistant, setAct [dispatch, setActiveAgentId, setActiveAssistant] ) - const handleAddButtonClick = () => { + const handleAddButtonClick = async () => { AddAssistantOrAgentPopup.show({ onSelect: (type) => { if (type === 'assistant') { onCreateAssistant() - } else if (type === 'agent') { + } + + if (type === 'agent') { + !apiServerRunning && startApiServer() AgentModalPopup.show({ afterSubmit: afterCreate }) } } diff --git a/src/renderer/src/pages/paintings/NewApiPage.tsx b/src/renderer/src/pages/paintings/NewApiPage.tsx index 86571f446..b0c7a44df 100644 --- a/src/renderer/src/pages/paintings/NewApiPage.tsx +++ b/src/renderer/src/pages/paintings/NewApiPage.tsx @@ -96,11 +96,14 @@ const NewApiPage: FC<{ Options: string[] }> = ({ Options }) => { return editImageFiles }, [editImageFiles]) - const updatePaintingState = (updates: Partial) => { - const updatedPainting = { ...painting, providerId: newApiProvider.id, ...updates } - setPainting(updatedPainting) - updatePainting(mode, updatedPainting) - } + const updatePaintingState = useCallback( + (updates: Partial) => { + const updatedPainting = { ...painting, providerId: newApiProvider.id, ...updates } + setPainting(updatedPainting) + updatePainting(mode, updatedPainting) + }, + [mode, newApiProvider.id, painting, updatePainting] + ) // ---------------- Model Related Configurations ---------------- // const modelOptions = MODELS.map((m) => ({ label: m.name, value: m.name })) diff --git a/src/renderer/src/pages/settings/ToolSettings/ApiServerSettings/ApiServerSettings.tsx b/src/renderer/src/pages/settings/ToolSettings/ApiServerSettings/ApiServerSettings.tsx index 779906710..0205ec676 100644 --- a/src/renderer/src/pages/settings/ToolSettings/ApiServerSettings/ApiServerSettings.tsx +++ b/src/renderer/src/pages/settings/ToolSettings/ApiServerSettings/ApiServerSettings.tsx @@ -4,7 +4,7 @@ import type { RootState } from '@renderer/store' import { useAppDispatch } from '@renderer/store' import { setApiServerApiKey, setApiServerPort } from '@renderer/store/settings' 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 type { FC } from 'react' import { useTranslation } from 'react-i18next' @@ -85,6 +85,10 @@ const ApiServerSettings: FC = () => { )} + {!apiServerRunning && ( + + )} + {/* Server Control Panel with integrated configuration */} diff --git a/src/renderer/src/store/runtime.ts b/src/renderer/src/store/runtime.ts index c3487aaa1..22a6f4c4c 100644 --- a/src/renderer/src/store/runtime.ts +++ b/src/renderer/src/store/runtime.ts @@ -56,7 +56,6 @@ export interface RuntimeState { export: ExportState chat: ChatState websearch: WebSearchState - iknow: Record } export interface ExportState { @@ -186,9 +185,6 @@ const runtimeSlice = createSlice({ } state.websearch.activeSearches[requestId] = status }, - addIknowAction: (state, action: PayloadAction) => { - state.iknow[action.payload] = true - }, setSessionWaitingAction: (state, action: PayloadAction<{ id: string; value: boolean }>) => { const { id, value } = action.payload state.chat.sessionWaiting[id] = value @@ -210,7 +206,6 @@ export const { setResourcesPath, setUpdateState, setExportState, - addIknowAction, // Chat related actions toggleMultiSelectMode, setSelectedMessageIds,