@@ -1427,6 +1427,23 @@ const resolveCoworkAgentEngine = (): CoworkAgentEngine => {
14271427 return isCoworkAgentEngine ( configured ) ? configured : CoworkAgentEngineValue . YdCowork ;
14281428} ;
14291429
1430+ const ensureSelectedEngineReadyForStartup = async ( engine : CoworkAgentEngine ) : Promise < void > => {
1431+ if ( isOpenClawCoworkAgentEngine ( engine ) ) {
1432+ const status = await getOpenClawEngineManager ( ) . ensureReady ( ) ;
1433+ if ( status . phase === 'error' || status . phase === 'not_installed' ) {
1434+ throw new Error ( status . message || 'OpenClaw CLI is not ready.' ) ;
1435+ }
1436+ return ;
1437+ }
1438+
1439+ if ( engine === CoworkAgentEngineValue . Hermes ) {
1440+ const status = await getHermesEngineManager ( ) . ensureReady ( ) ;
1441+ if ( status . phase === 'error' || status . phase === 'not_installed' ) {
1442+ throw new Error ( status . message || 'Hermes Agent CLI is not ready.' ) ;
1443+ }
1444+ }
1445+ } ;
1446+
14301447type FeishuIMAgentEngine =
14311448 | typeof CoworkAgentEngineValue . OpenClaw
14321449 | typeof CoworkAgentEngineValue . Hermes
@@ -1676,6 +1693,13 @@ const isExternalAgentProviderAppType = (value: unknown): value is ExternalAgentP
16761693 || value === 'deepseek_tui'
16771694) ;
16781695
1696+ const normalizeAgentEngineSnapshotAppTypes = ( value : unknown ) : ExternalAgentProviderAppType [ ] => {
1697+ if ( ! Array . isArray ( value ) ) {
1698+ return [ ] ;
1699+ }
1700+ return Array . from ( new Set ( value . filter ( isExternalAgentProviderAppType ) ) ) ;
1701+ } ;
1702+
16791703const AGENT_ENGINE_SNAPSHOT_TTL_MS = 30_000 ;
16801704
16811705interface AgentEngineSnapshotResponse {
@@ -1774,6 +1798,20 @@ const getCachedAgentEngineSnapshot = (options: { forceRefresh?: boolean } = {}):
17741798 } ;
17751799} ;
17761800
1801+ const getFilteredAgentEngineSnapshot = async (
1802+ appTypes : ExternalAgentProviderAppType [ ] ,
1803+ ) : Promise < AgentEngineSnapshotResponse > => {
1804+ const { snapshot, report } = await getExternalAgentEnvironmentSnapshot ( { appTypes } ) ;
1805+ const mergedSnapshot = mergeCodexAppStatus ( snapshot ) ;
1806+ summarizeAgentEngineProbeReport ( report ) ;
1807+ return {
1808+ success : true ,
1809+ snapshot : mergedSnapshot ,
1810+ refreshing : false ,
1811+ cachedAt : Date . now ( ) ,
1812+ } ;
1813+ } ;
1814+
17771815const getOpenClawConfigSync = ( ) : OpenClawConfigSync => {
17781816 if ( ! openClawConfigSync ) {
17791817 openClawConfigSync = new OpenClawConfigSync ( {
@@ -5110,8 +5148,12 @@ if (!gotTheLock) {
51105148 }
51115149 } ) ;
51125150
5113- ipcMain . handle ( 'cowork:agentEngines:list' , async ( _event , input : { forceRefresh ?: unknown } = { } ) => {
5151+ ipcMain . handle ( 'cowork:agentEngines:list' , async ( _event , input : { forceRefresh ?: unknown ; appTypes ?: unknown } = { } ) => {
51145152 try {
5153+ const appTypes = normalizeAgentEngineSnapshotAppTypes ( input ?. appTypes ) ;
5154+ if ( appTypes . length > 0 ) {
5155+ return await getFilteredAgentEngineSnapshot ( appTypes ) ;
5156+ }
51155157 return getCachedAgentEngineSnapshot ( { forceRefresh : input ?. forceRefresh === true } ) ;
51165158 } catch ( error ) {
51175159 return {
@@ -7677,6 +7719,7 @@ if (!gotTheLock) {
76777719 | 'enterprise_sync'
76787720 | 'runtime_forwarders'
76797721 | 'openclaw_config_sync'
7722+ | 'openclaw_proxy_config_sync'
76807723 | 'hermes_config_sync'
76817724 | 'selected_engine'
76827725 | 'scheduled_tasks'
@@ -7704,6 +7747,7 @@ if (!gotTheLock) {
77047747 'enterprise_sync' ,
77057748 'runtime_forwarders' ,
77067749 'openclaw_config_sync' ,
7750+ 'openclaw_proxy_config_sync' ,
77077751 'hermes_config_sync' ,
77087752 'selected_engine' ,
77097753 'scheduled_tasks' ,
@@ -8060,12 +8104,13 @@ if (!gotTheLock) {
80608104 } , { degradedOnError : true } ) ;
80618105 await runStartupService ( 'selected_engine' , async ( ) => {
80628106 const selectedEngineDetectStartedAt = nowMs ( ) ;
8063- const selectedEngine = resolveCoworkAgentEngine ( ) ;
8064- markTiming ( 'selected_engine_detect_ms' , selectedEngineDetectStartedAt ) ;
8065- if ( isOpenClawCoworkAgentEngine ( selectedEngine ) ) {
8066- await ensureOpenClawRunningForCowork ( ) ;
8107+ try {
8108+ const selectedEngine = resolveCoworkAgentEngine ( ) ;
8109+ await ensureSelectedEngineReadyForStartup ( selectedEngine ) ;
8110+ } finally {
8111+ markTiming ( 'selected_engine_detect_ms' , selectedEngineDetectStartedAt ) ;
8112+ markTiming ( 'selected_engine_ready_ms' , selectedEngineDetectStartedAt ) ;
80678113 }
8068- markTiming ( 'selected_engine_ready_ms' , selectedEngineDetectStartedAt ) ;
80698114 } , { degradedOnError : true } ) ;
80708115
80718116 await runStartupService ( 'scheduled_tasks' , ( ) => {
@@ -8128,14 +8173,16 @@ if (!gotTheLock) {
81288173
81298174 // Re-sync OpenClaw config after proxy is ready so that providers that route
81308175 // through the proxy (e.g. github-copilot) get the correct baseUrl.
8131- if ( isOpenClawCoworkAgentEngine ( resolveCoworkAgentEngine ( ) ) ) {
8132- const proxyResync = await syncOpenClawConfig ( {
8133- reason : 'proxy-ready' ,
8134- } ) ;
8135- if ( proxyResync . changed ) {
8136- console . log ( '[Main] OpenClaw config updated after proxy ready, gateway will restart to pick up new config' ) ;
8176+ await runStartupService ( 'openclaw_proxy_config_sync' , async ( ) => {
8177+ if ( isOpenClawCoworkAgentEngine ( resolveCoworkAgentEngine ( ) ) ) {
8178+ const proxyResync = await syncOpenClawConfig ( {
8179+ reason : 'proxy-ready' ,
8180+ } ) ;
8181+ if ( proxyResync . changed ) {
8182+ console . log ( '[Main] OpenClaw config updated after proxy ready, gateway will restart to pick up new config' ) ;
8183+ }
81378184 }
8138- }
8185+ } , { degradedOnError : true } ) ;
81398186
81408187 // Auto-reconnect IM bots that were enabled before restart.
81418188 await runStartupService ( 'im_gateways' , async ( ) => {
0 commit comments