mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-20 15:10:59 +08:00
fix: notify renderer when api server ready (#11049)
* fix: notify renderer when api server ready * chore: minor comment update Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: minor ui change to reflect server loading state --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
b586e1796e
commit
aa810a7ead
@ -322,6 +322,7 @@ export enum IpcChannel {
|
|||||||
ApiServer_Stop = 'api-server:stop',
|
ApiServer_Stop = 'api-server:stop',
|
||||||
ApiServer_Restart = 'api-server:restart',
|
ApiServer_Restart = 'api-server:restart',
|
||||||
ApiServer_GetStatus = 'api-server:get-status',
|
ApiServer_GetStatus = 'api-server:get-status',
|
||||||
|
ApiServer_Ready = 'api-server:ready',
|
||||||
// NOTE: This api is not be used.
|
// NOTE: This api is not be used.
|
||||||
ApiServer_GetConfig = 'api-server:get-config',
|
ApiServer_GetConfig = 'api-server:get-config',
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import { createServer } from 'node:http'
|
import { createServer } from 'node:http'
|
||||||
|
|
||||||
import { loggerService } from '@logger'
|
import { loggerService } from '@logger'
|
||||||
|
import { IpcChannel } from '@shared/IpcChannel'
|
||||||
|
|
||||||
import { agentService } from '../services/agents'
|
import { agentService } from '../services/agents'
|
||||||
|
import { windowService } from '../services/WindowService'
|
||||||
import { app } from './app'
|
import { app } from './app'
|
||||||
import { config } from './config'
|
import { config } from './config'
|
||||||
|
|
||||||
@ -43,6 +45,13 @@ export class ApiServer {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.server!.listen(port, host, () => {
|
this.server!.listen(port, host, () => {
|
||||||
logger.info('API server started', { host, port })
|
logger.info('API server started', { host, port })
|
||||||
|
|
||||||
|
// Notify renderer that API server is ready
|
||||||
|
const mainWindow = windowService.getMainWindow()
|
||||||
|
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||||
|
mainWindow.webContents.send(IpcChannel.ApiServer_Ready)
|
||||||
|
}
|
||||||
|
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -525,7 +525,16 @@ const api = {
|
|||||||
getStatus: (): Promise<GetApiServerStatusResult> => ipcRenderer.invoke(IpcChannel.ApiServer_GetStatus),
|
getStatus: (): Promise<GetApiServerStatusResult> => ipcRenderer.invoke(IpcChannel.ApiServer_GetStatus),
|
||||||
start: (): Promise<StartApiServerStatusResult> => ipcRenderer.invoke(IpcChannel.ApiServer_Start),
|
start: (): Promise<StartApiServerStatusResult> => ipcRenderer.invoke(IpcChannel.ApiServer_Start),
|
||||||
restart: (): Promise<RestartApiServerStatusResult> => ipcRenderer.invoke(IpcChannel.ApiServer_Restart),
|
restart: (): Promise<RestartApiServerStatusResult> => ipcRenderer.invoke(IpcChannel.ApiServer_Restart),
|
||||||
stop: (): Promise<StopApiServerStatusResult> => ipcRenderer.invoke(IpcChannel.ApiServer_Stop)
|
stop: (): Promise<StopApiServerStatusResult> => ipcRenderer.invoke(IpcChannel.ApiServer_Stop),
|
||||||
|
onReady: (callback: () => void): (() => void) => {
|
||||||
|
const listener = () => {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
ipcRenderer.on(IpcChannel.ApiServer_Ready, listener)
|
||||||
|
return () => {
|
||||||
|
ipcRenderer.removeListener(IpcChannel.ApiServer_Ready, listener)
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
claudeCodePlugin: {
|
claudeCodePlugin: {
|
||||||
listAvailable: (): Promise<PluginResult<ListAvailablePluginsResult>> =>
|
listAvailable: (): Promise<PluginResult<ListAvailablePluginsResult>> =>
|
||||||
|
|||||||
@ -25,6 +25,10 @@ export const useAgents = () => {
|
|||||||
const client = useAgentClient()
|
const client = useAgentClient()
|
||||||
const key = client.agentPaths.base
|
const key = client.agentPaths.base
|
||||||
const { apiServerConfig, apiServerRunning } = useApiServer()
|
const { apiServerConfig, apiServerRunning } = useApiServer()
|
||||||
|
|
||||||
|
// Disable SWR fetching when server is not running by setting key to null
|
||||||
|
const swrKey = apiServerRunning ? key : null
|
||||||
|
|
||||||
const fetcher = useCallback(async () => {
|
const fetcher = useCallback(async () => {
|
||||||
// API server will start on startup if enabled OR there are agents
|
// API server will start on startup if enabled OR there are agents
|
||||||
if (!apiServerConfig.enabled && !apiServerRunning) {
|
if (!apiServerConfig.enabled && !apiServerRunning) {
|
||||||
@ -37,7 +41,7 @@ export const useAgents = () => {
|
|||||||
// NOTE: We only use the array for now. useUpdateAgent depends on this behavior.
|
// NOTE: We only use the array for now. useUpdateAgent depends on this behavior.
|
||||||
return result.data
|
return result.data
|
||||||
}, [apiServerConfig.enabled, apiServerRunning, client, t])
|
}, [apiServerConfig.enabled, apiServerRunning, client, t])
|
||||||
const { data, error, isLoading, mutate } = useSWR(key, fetcher)
|
const { data, error, isLoading, mutate } = useSWR(swrKey, fetcher)
|
||||||
const { chat } = useRuntime()
|
const { chat } = useRuntime()
|
||||||
const { activeAgentId } = chat
|
const { activeAgentId } = chat
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|||||||
@ -14,8 +14,8 @@ export const useApiServer = () => {
|
|||||||
const apiServerConfig = useAppSelector((state) => state.settings.apiServer)
|
const apiServerConfig = useAppSelector((state) => state.settings.apiServer)
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
// Optimistic initial state.
|
// Initial state - no longer optimistic, wait for actual status
|
||||||
const [apiServerRunning, setApiServerRunning] = useState(apiServerConfig.enabled)
|
const [apiServerRunning, setApiServerRunning] = useState(false)
|
||||||
const [apiServerLoading, setApiServerLoading] = useState(true)
|
const [apiServerLoading, setApiServerLoading] = useState(true)
|
||||||
|
|
||||||
const setApiServerEnabled = useCallback(
|
const setApiServerEnabled = useCallback(
|
||||||
@ -99,6 +99,16 @@ export const useApiServer = () => {
|
|||||||
checkApiServerStatus()
|
checkApiServerStatus()
|
||||||
}, [checkApiServerStatus])
|
}, [checkApiServerStatus])
|
||||||
|
|
||||||
|
// Listen for API server ready event
|
||||||
|
useEffect(() => {
|
||||||
|
const cleanup = window.api.apiServer.onReady(() => {
|
||||||
|
logger.info('API server ready event received, checking status')
|
||||||
|
checkApiServerStatus()
|
||||||
|
})
|
||||||
|
|
||||||
|
return cleanup
|
||||||
|
}, [checkApiServerStatus])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
apiServerConfig,
|
apiServerConfig,
|
||||||
apiServerRunning,
|
apiServerRunning,
|
||||||
|
|||||||
@ -36,7 +36,7 @@ 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 { t } = useTranslation()
|
||||||
const { apiServerConfig, apiServerRunning } = useApiServer()
|
const { apiServerConfig, apiServerRunning, apiServerLoading } = useApiServer()
|
||||||
const apiServerEnabled = apiServerConfig.enabled
|
const apiServerEnabled = apiServerConfig.enabled
|
||||||
const { iknow, chat } = useRuntime()
|
const { iknow, chat } = useRuntime()
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
@ -113,8 +113,8 @@ const AssistantsTab: FC<AssistantsTabProps> = (props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{agentsLoading && <Spinner />}
|
{(agentsLoading || apiServerLoading) && <Spinner />}
|
||||||
{apiServerConfig.enabled && !apiServerRunning && (
|
{apiServerConfig.enabled && !apiServerLoading && !apiServerRunning && (
|
||||||
<Alert color="danger" title={t('agent.server.error.not_running')} isClosable className="mb-2" />
|
<Alert color="danger" title={t('agent.server.error.not_running')} isClosable className="mb-2" />
|
||||||
)}
|
)}
|
||||||
{apiServerRunning && agentsError && (
|
{apiServerRunning && agentsError && (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user