This is an automated email from the ASF dual-hosted git repository.

gongchao pushed a commit to branch update-ai-with
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git

commit 4a63eb5cc020ee4e4efc8324b0efa6bb93201c81
Author: tomsun28 <[email protected]>
AuthorDate: Thu Oct 30 22:38:45 2025 +0800

    refactor
    
    Signed-off-by: tomsun28 <[email protected]>
---
 hertzbeat-ai/pom.xml                               |   5 +-
 .../ai/adapters/AlertDefineServiceAdapter.java     |   2 +-
 .../hertzbeat/ai/adapters/AlertServiceAdapter.java |  60 -------
 .../impl/AlertDefineServiceAdapterImpl.java        | 122 ++-----------
 .../ai/adapters/impl/AlertServiceAdapterImpl.java  | 141 ---------------
 .../adapters/impl/MetricsServiceAdapterImpl.java   |  64 ++-----
 .../adapters/impl/MonitorServiceAdapterImpl.java   |  94 ++--------
 .../hertzbeat/ai/config/DynamicOpenAiApiKey.java   |  56 ------
 .../org/apache/hertzbeat/ai/config/LlmConfig.java  |   2 +-
 .../apache/hertzbeat/ai/entity/OpenAiConfig.java   |  80 ---------
 .../apache/hertzbeat/ai/pojo/dto/Hierarchy.java    |  87 ---------
 .../impl/ChatClientProviderServiceImpl.java        |   2 +-
 .../ai/tools/impl/AlertDefineToolsImpl.java        |   2 +-
 .../hertzbeat/ai/tools/impl/AlertToolsImpl.java    |  10 +-
 .../apache/hertzbeat/ai/utils/UtilityClass.java    | 198 +--------------------
 .../common/entity}/dto/ModelProviderConfig.java    |   4 +-
 hertzbeat-manager/pom.xml                          |   5 -
 .../impl/ModelProviderConfigServiceImpl.java       |   2 +-
 18 files changed, 62 insertions(+), 874 deletions(-)

diff --git a/hertzbeat-ai/pom.xml b/hertzbeat-ai/pom.xml
index 0fe8dc158..de91bf7fa 100644
--- a/hertzbeat-ai/pom.xml
+++ b/hertzbeat-ai/pom.xml
@@ -65,12 +65,15 @@
         <dependency>
             <groupId>org.apache.hertzbeat</groupId>
             <artifactId>hertzbeat-base</artifactId>
-            <scope>provided</scope>
         </dependency>
                <dependency>
                        <groupId>org.apache.hertzbeat</groupId>
                        <artifactId>hertzbeat-alerter</artifactId>
                </dependency>
+        <dependency>
+            <groupId>org.apache.hertzbeat</groupId>
+            <artifactId>hertzbeat-manager</artifactId>
+        </dependency>
                <dependency>
                        <groupId>com.usthe.sureness</groupId>
                        <artifactId>spring-boot3-starter-sureness</artifactId>
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertDefineServiceAdapter.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertDefineServiceAdapter.java
index 63ac256b6..74d088bb2 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertDefineServiceAdapter.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertDefineServiceAdapter.java
@@ -17,8 +17,8 @@
 
 package org.apache.hertzbeat.ai.adapters;
 
-import org.apache.hertzbeat.ai.pojo.dto.Hierarchy;
 import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
+import org.apache.hertzbeat.manager.pojo.dto.Hierarchy;
 import org.springframework.data.domain.Page;
 
 import java.util.List;
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertServiceAdapter.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertServiceAdapter.java
deleted file mode 100644
index b4dbb196c..000000000
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/AlertServiceAdapter.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hertzbeat.ai.adapters;
-
-import org.apache.hertzbeat.alert.dto.AlertSummary;
-import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
-import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
-import org.springframework.data.domain.Page;
-
-/**
- * Interface that provides access to alert information by retrieving alert data
- * through the underlying alert service.
- */
-public interface AlertServiceAdapter {
-
-    /**
-     * Get single alerts with filtering and pagination
-     * @param status Alert status
-     * @param search Search term
-     * @param sort Sort field
-     * @param order Sort order
-     * @param pageIndex Page index
-     * @param pageSize Page size
-     * @return Page of single alerts
-     */
-    Page<SingleAlert> getSingleAlerts(String status, String search, String 
sort, String order, int pageIndex, int pageSize);
-
-    /**
-     * Get group alerts with filtering and pagination
-     * @param status Alert status
-     * @param search Search term
-     * @param sort Sort field
-     * @param order Sort order
-     * @param pageIndex Page index
-     * @param pageSize Page size
-     * @return Page of group alerts
-     */
-    Page<GroupAlert> getGroupAlerts(String status, String search, String sort, 
String order, int pageIndex, int pageSize);
-
-    /**
-     * Get alerts summary statistics
-     * @return Alert summary information
-     */
-    AlertSummary getAlertsSummary();
-}
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertDefineServiceAdapterImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertDefineServiceAdapterImpl.java
index a22093c62..9c9b971ab 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertDefineServiceAdapterImpl.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertDefineServiceAdapterImpl.java
@@ -18,52 +18,42 @@
 package org.apache.hertzbeat.ai.adapters.impl;
 
 import com.usthe.sureness.subject.SubjectSum;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.ai.adapters.AlertDefineServiceAdapter;
 import org.apache.hertzbeat.ai.config.McpContextHolder;
-import org.apache.hertzbeat.ai.pojo.dto.Hierarchy;
-import org.apache.hertzbeat.ai.utils.UtilityClass;
+import org.apache.hertzbeat.alert.service.AlertDefineService;
 import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
-import org.apache.hertzbeat.common.support.SpringContextHolder;
+import org.apache.hertzbeat.manager.pojo.dto.Hierarchy;
+import org.apache.hertzbeat.manager.service.AppService;
 import org.springframework.data.domain.Page;
 import org.springframework.stereotype.Component;
 
-import java.lang.reflect.Method;
 import java.util.List;
 
 /**
  * Implementation of the AlertDefineServiceAdapter interface that provides 
access to alert definition information
- * through reflection by invoking the underlying alert define service 
implementation.
+ * through direct service injection instead of reflection.
  */
 @Slf4j
 @Component
+@RequiredArgsConstructor
 public class AlertDefineServiceAdapterImpl implements 
AlertDefineServiceAdapter {
 
+    private final AlertDefineService alertDefineService;
+    private final AppService appService;
+
     @Override
     public AlertDefine addAlertDefine(AlertDefine alertDefine) {
         try {
-            Object alertDefineService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject for addAlertDefine: {}", 
subjectSum);
 
-            try {
-                alertDefineService = 
SpringContextHolder.getBean("alertDefineServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 
'alertDefineServiceImpl'");
-            }
-
-            assert alertDefineService != null;
-            log.debug("AlertDefineService bean found: {}", 
alertDefineService.getClass().getSimpleName());
-            
-            Method method = 
alertDefineService.getClass().getMethod("addAlertDefine", AlertDefine.class);
-
-            method.invoke(alertDefineService, alertDefine);
+            alertDefineService.addAlertDefine(alertDefine);
             
             log.debug("Successfully added alert define with ID: {}", 
alertDefine.getId());
             return alertDefine;
 
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: addAlertDefine", e);
         } catch (Exception e) {
             log.error("Failed to invoke addAlertDefine via adapter", e);
             throw new RuntimeException("Failed to invoke addAlertDefine via 
adapter: " + e.getMessage(), e);
@@ -73,32 +63,14 @@ public class AlertDefineServiceAdapterImpl implements 
AlertDefineServiceAdapter
     @Override
     public Page<AlertDefine> getAlertDefines(String search, String app, 
Boolean enabled, String sort, String order, int pageIndex, int pageSize) {
         try {
-            Object alertDefineService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject for getAlertDefines: {}", 
subjectSum);
 
-            try {
-                alertDefineService = 
SpringContextHolder.getBean("alertDefineServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 
'alertDefineServiceImpl'");
-            }
-
-            assert alertDefineService != null;
-            log.debug("AlertDefineService bean found: {}", 
alertDefineService.getClass().getSimpleName());
-            
-            Method method = alertDefineService.getClass().getMethod(
-                    "getAlertDefines",
-                    List.class, String.class, String.class, String.class, 
int.class, int.class);
-
-            @SuppressWarnings("unchecked")
-            Page<AlertDefine> result = (Page<AlertDefine>) method.invoke(
-                    alertDefineService, null, search, sort, order, pageIndex, 
pageSize);
+            Page<AlertDefine> result = 
alertDefineService.getAlertDefines(null, search, sort, order, pageIndex, 
pageSize);
             
             log.debug("Successfully retrieved {} alert defines", 
result.getContent().size());
             return result;
 
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: getAlertDefines", e);
         } catch (Exception e) {
             log.error("Failed to invoke getAlertDefines via adapter", e);
             throw new RuntimeException("Failed to invoke getAlertDefines via 
adapter: " + e.getMessage(), e);
@@ -108,54 +80,28 @@ public class AlertDefineServiceAdapterImpl implements 
AlertDefineServiceAdapter
     @Override
     public AlertDefine getAlertDefine(Long id) {
         try {
-            Object alertDefineService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject for getAlertDefine: {}", 
subjectSum);
 
-            try {
-                alertDefineService = 
SpringContextHolder.getBean("alertDefineServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 
'alertDefineServiceImpl'");
-            }
-
-            assert alertDefineService != null;
-            log.debug("AlertDefineService bean found: {}", 
alertDefineService.getClass().getSimpleName());
-            
-            Method method = 
alertDefineService.getClass().getMethod("getAlertDefine", long.class);
-
-            AlertDefine result = (AlertDefine) 
method.invoke(alertDefineService, id);
+            AlertDefine result = alertDefineService.getAlertDefine(id);
             
             log.debug("Successfully retrieved alert define with ID: {}", id);
             return result;
 
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: getAlertDefine", e);
         } catch (Exception e) {
             log.error("Failed to invoke getAlertDefine via adapter for ID: 
{}", id, e);
             throw new RuntimeException("Failed to invoke getAlertDefine via 
adapter: " + e.getMessage(), e);
         }
     }
 
-
     @Override
     public void toggleAlertDefineStatus(Long id, boolean enabled) {
         try {
-            Object alertDefineService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject for toggleAlertDefineStatus: 
{}", subjectSum);
 
-            try {
-                alertDefineService = 
SpringContextHolder.getBean("alertDefineServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 
'alertDefineServiceImpl'");
-            }
-
-            assert alertDefineService != null;
-            log.debug("AlertDefineService bean found: {}", 
alertDefineService.getClass().getSimpleName());
-            
             // First get the existing AlertDefine
-            Method getMethod = 
alertDefineService.getClass().getMethod("getAlertDefine", long.class);
-            AlertDefine alertDefine = (AlertDefine) 
getMethod.invoke(alertDefineService, id);
+            AlertDefine alertDefine = alertDefineService.getAlertDefine(id);
             
             if (alertDefine == null) {
                 throw new RuntimeException("AlertDefine with ID " + id + " not 
found");
@@ -165,8 +111,7 @@ public class AlertDefineServiceAdapterImpl implements 
AlertDefineServiceAdapter
             alertDefine.setEnable(enabled);
             
             // Use modifyAlertDefine to save the changes
-            Method modifyMethod = 
alertDefineService.getClass().getMethod("modifyAlertDefine", AlertDefine.class);
-            modifyMethod.invoke(alertDefineService, alertDefine);
+            alertDefineService.modifyAlertDefine(alertDefine);
             
             log.debug("Successfully toggled alert define status for ID: {} to 
enabled: {}", id, enabled);
 
@@ -179,28 +124,14 @@ public class AlertDefineServiceAdapterImpl implements 
AlertDefineServiceAdapter
     @Override
     public AlertDefine modifyAlertDefine(AlertDefine alertDefine) {
         try {
-            Object alertDefineService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject for modifyAlertDefine: {}", 
subjectSum);
 
-            try {
-                alertDefineService = 
SpringContextHolder.getBean("alertDefineServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 
'alertDefineServiceImpl'");
-            }
-
-            assert alertDefineService != null;
-            log.debug("AlertDefineService bean found: {}", 
alertDefineService.getClass().getSimpleName());
-            
-            Method method = 
alertDefineService.getClass().getMethod("modifyAlertDefine", AlertDefine.class);
-
-            method.invoke(alertDefineService, alertDefine);
+            alertDefineService.modifyAlertDefine(alertDefine);
             
             log.debug("Successfully modified alert define with ID: {}", 
alertDefine.getId());
             return alertDefine;
 
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: modifyAlertDefine", 
e);
         } catch (Exception e) {
             log.error("Failed to invoke modifyAlertDefine via adapter", e);
             throw new RuntimeException("Failed to invoke modifyAlertDefine via 
adapter: " + e.getMessage(), e);
@@ -209,41 +140,25 @@ public class AlertDefineServiceAdapterImpl implements 
AlertDefineServiceAdapter
 
     /**
      * Retrieves the application hierarchy for a given app and language.
-     * Uses reflection to call the underlying app service method.
+     * Uses direct service injection instead of reflection.
      *
      * @param app  The application name
      * @param lang The language code (optional, defaults to "en-US")
      * @return List of Hierarchy objects representing the app hierarchy
      */
-
     @Override
     public List<Hierarchy> getAppHierarchy(String app, String lang) {
         try {
-            Object appService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject for getAppHierarchy: {}", 
subjectSum);
 
-            try {
-                appService = SpringContextHolder.getBean("appServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 'appServiceImpl', 
trying by class name");
-            }
-
-            assert appService != null;
-            log.debug("AppService bean found for getAppHierarchy: {}", 
appService.getClass().getSimpleName());
-
             // Provide default language if not specified
             if (lang == null || lang.trim().isEmpty()) {
                 lang = "en-US";
             }
 
-            // Call getAppHierarchy method: getAppHierarchy(String app, String 
lang)
-            Method method = appService.getClass().getMethod("getAppHierarchy", 
String.class, String.class);
-
-            List<?> managerHierarchies = (List<?>) method.invoke(appService, 
app, lang);
-
-            // Convert manager DTOs to ai-agent DTOs
-            List<Hierarchy> result = 
UtilityClass.convertToAgentHierarchies(managerHierarchies);
+            // Call getAppHierarchy method directly
+            List<Hierarchy> result = appService.getAppHierarchy(app, lang);
 
             log.debug("Successfully retrieved and converted {} hierarchies for 
app '{}'", result.size(), app);
             return result;
@@ -253,5 +168,4 @@ public class AlertDefineServiceAdapterImpl implements 
AlertDefineServiceAdapter
             throw new RuntimeException("Failed to get app hierarchy for " + 
app, e);
         }
     }
-
 }
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertServiceAdapterImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertServiceAdapterImpl.java
deleted file mode 100644
index 8caf902f5..000000000
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/AlertServiceAdapterImpl.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hertzbeat.ai.adapters.impl;
-
-import com.usthe.sureness.subject.SubjectSum;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.hertzbeat.ai.adapters.AlertServiceAdapter;
-import org.apache.hertzbeat.ai.config.McpContextHolder;
-import org.apache.hertzbeat.alert.dto.AlertSummary;
-import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
-import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
-import org.apache.hertzbeat.common.support.SpringContextHolder;
-import org.springframework.data.domain.Page;
-import org.springframework.stereotype.Component;
-
-import java.lang.reflect.Method;
-
-/**
- * Implementation of the AlertServiceAdapter interface that provides access to 
alert information
- * through reflection by invoking the underlying alert service implementation.
- */
-@Slf4j
-@Component
-public class AlertServiceAdapterImpl implements AlertServiceAdapter {
-
-    @Override
-    public Page<SingleAlert> getSingleAlerts(String status, String search, 
String sort, String order, int pageIndex, int pageSize) {
-        try {
-            Object alertService = null;
-            SubjectSum subjectSum = McpContextHolder.getSubject();
-            log.debug("Current security subject for getSingleAlerts: {}", 
subjectSum);
-
-            try {
-                alertService = SpringContextHolder.getBean("alertServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 'alertServiceImpl'");
-            }
-
-            assert alertService != null;
-            log.debug("AlertService bean found: {}", 
alertService.getClass().getSimpleName());
-            
-            Method method = alertService.getClass().getMethod(
-                    "getSingleAlerts",
-                    String.class, String.class, String.class, String.class, 
int.class, int.class);
-
-            @SuppressWarnings("unchecked")
-            Page<SingleAlert> result = (Page<SingleAlert>) method.invoke(
-                    alertService, status, search, sort, order, pageIndex, 
pageSize);
-            
-            log.debug("Successfully retrieved {} single alerts", 
result.getContent().size());
-            return result;
-
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: getSingleAlerts", e);
-        } catch (Exception e) {
-            log.error("Failed to invoke getSingleAlerts via adapter", e);
-            throw new RuntimeException("Failed to invoke getSingleAlerts via 
adapter: " + e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public Page<GroupAlert> getGroupAlerts(String status, String search, 
String sort, String order, int pageIndex, int pageSize) {
-        try {
-            Object alertService = null;
-            SubjectSum subjectSum = McpContextHolder.getSubject();
-            log.debug("Current security subject for getGroupAlerts: {}", 
subjectSum);
-
-            try {
-                alertService = SpringContextHolder.getBean("alertServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 'alertServiceImpl'");
-            }
-
-            assert alertService != null;
-            log.debug("AlertService bean found: {}", 
alertService.getClass().getSimpleName());
-            
-            Method method = alertService.getClass().getMethod(
-                    "getGroupAlerts",
-                    String.class, String.class, String.class, String.class, 
int.class, int.class);
-
-            @SuppressWarnings("unchecked")
-            Page<GroupAlert> result = (Page<GroupAlert>) method.invoke(
-                    alertService, status, search, sort, order, pageIndex, 
pageSize);
-            
-            log.debug("Successfully retrieved {} group alerts", 
result.getContent().size());
-            return result;
-
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: getGroupAlerts", e);
-        } catch (Exception e) {
-            log.error("Failed to invoke getGroupAlerts via adapter", e);
-            throw new RuntimeException("Failed to invoke getGroupAlerts via 
adapter: " + e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public AlertSummary getAlertsSummary() {
-        try {
-            Object alertService = null;
-            SubjectSum subjectSum = McpContextHolder.getSubject();
-            log.debug("Current security subject for getAlertsSummary: {}", 
subjectSum);
-
-            try {
-                alertService = SpringContextHolder.getBean("alertServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 'alertServiceImpl'");
-            }
-
-            assert alertService != null;
-            log.debug("AlertService bean found: {}", 
alertService.getClass().getSimpleName());
-            
-            Method method = 
alertService.getClass().getMethod("getAlertsSummary");
-
-            AlertSummary result = (AlertSummary) method.invoke(alertService);
-            
-            log.debug("Successfully retrieved alerts summary");
-            return result;
-
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: getAlertsSummary", 
e);
-        } catch (Exception e) {
-            log.error("Failed to invoke getAlertsSummary via adapter", e);
-            throw new RuntimeException("Failed to invoke getAlertsSummary via 
adapter: " + e.getMessage(), e);
-        }
-    }
-}
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MetricsServiceAdapterImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MetricsServiceAdapterImpl.java
index d225ba87f..6947dc187 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MetricsServiceAdapterImpl.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MetricsServiceAdapterImpl.java
@@ -18,49 +18,37 @@
 package org.apache.hertzbeat.ai.adapters.impl;
 
 import com.usthe.sureness.subject.SubjectSum;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.ai.adapters.MetricsServiceAdapter;
 import org.apache.hertzbeat.ai.config.McpContextHolder;
 import org.apache.hertzbeat.common.entity.dto.MetricsData;
 import org.apache.hertzbeat.common.entity.dto.MetricsHistoryData;
-import org.apache.hertzbeat.common.support.SpringContextHolder;
+import org.apache.hertzbeat.warehouse.service.MetricsDataService;
 import org.springframework.stereotype.Component;
 
-import java.lang.reflect.Method;
-
 /**
  * Implementation of the MetricsServiceAdapter interface that provides access 
to metrics information
- * through reflection by invoking the underlying metrics service 
implementation.
+ * through direct service injection instead of reflection.
  */
 @Slf4j
 @Component
+@RequiredArgsConstructor
 public class MetricsServiceAdapterImpl implements MetricsServiceAdapter {
 
+    private final MetricsDataService metricsDataService;
+
     @Override
     public Boolean getWarehouseStorageServerStatus() {
         try {
-            Object metricsDataService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject for 
getWarehouseStorageServerStatus: {}", subjectSum);
 
-            try {
-                metricsDataService = 
SpringContextHolder.getBean("metricsDataServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 
'metricsDataServiceImpl'");
-            }
-
-            assert metricsDataService != null;
-            log.debug("MetricsDataService bean found: {}", 
metricsDataService.getClass().getSimpleName());
-            
-            Method method = 
metricsDataService.getClass().getMethod("getWarehouseStorageServerStatus");
-
-            Boolean result = (Boolean) method.invoke(metricsDataService);
+            Boolean result = 
metricsDataService.getWarehouseStorageServerStatus();
             
             log.debug("Successfully retrieved warehouse storage server status: 
{}", result);
             return result;
 
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: 
getWarehouseStorageServerStatus", e);
         } catch (Exception e) {
             log.error("Failed to invoke getWarehouseStorageServerStatus via 
adapter", e);
             throw new RuntimeException("Failed to invoke 
getWarehouseStorageServerStatus via adapter: " + e.getMessage(), e);
@@ -70,30 +58,14 @@ public class MetricsServiceAdapterImpl implements 
MetricsServiceAdapter {
     @Override
     public MetricsData getMetricsData(Long monitorId, String metrics) {
         try {
-            Object metricsDataService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject for getMetricsData: {}", 
subjectSum);
 
-            try {
-                metricsDataService = 
SpringContextHolder.getBean("metricsDataServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 
'metricsDataServiceImpl'");
-            }
-
-            assert metricsDataService != null;
-            log.debug("MetricsDataService bean found: {}", 
metricsDataService.getClass().getSimpleName());
-            
-            Method method = metricsDataService.getClass().getMethod(
-                    "getMetricsData",
-                    Long.class, String.class);
-
-            MetricsData result = (MetricsData) 
method.invoke(metricsDataService, monitorId, metrics);
+            MetricsData result = metricsDataService.getMetricsData(monitorId, 
metrics);
             
             log.debug("Successfully retrieved metrics data for monitor {} and 
metrics {}", monitorId, metrics);
             return result;
 
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: getMetricsData", e);
         } catch (Exception e) {
             log.error("Failed to invoke getMetricsData via adapter for monitor 
{} and metrics {}", monitorId, metrics, e);
             throw new RuntimeException("Failed to invoke getMetricsData via 
adapter: " + e.getMessage(), e);
@@ -103,31 +75,15 @@ public class MetricsServiceAdapterImpl implements 
MetricsServiceAdapter {
     @Override
     public MetricsHistoryData getMetricHistoryData(Long monitorId, String app, 
String metrics, String metric, String label, String history, Boolean interval) {
         try {
-            Object metricsDataService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject for getMetricHistoryData: {}", 
subjectSum);
 
-            try {
-                metricsDataService = 
SpringContextHolder.getBean("metricsDataServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 
'metricsDataServiceImpl'");
-            }
-
-            assert metricsDataService != null;
-            log.debug("MetricsDataService bean found: {}", 
metricsDataService.getClass().getSimpleName());
-            
-            Method method = metricsDataService.getClass().getMethod(
-                    "getMetricHistoryData",
-                    Long.class, String.class, String.class, String.class, 
String.class, String.class, Boolean.class);
-
-            MetricsHistoryData result = (MetricsHistoryData) method.invoke(
-                    metricsDataService, monitorId, app, metrics, metric, 
label, history, interval);
+            MetricsHistoryData result = 
metricsDataService.getMetricHistoryData(
+                    monitorId, app, metrics, metric, label, history, interval);
             
             log.debug("Successfully retrieved historical metrics data for 
monitor {} and metrics {}", monitorId, metrics);
             return result;
 
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: 
getMetricHistoryData", e);
         } catch (Exception e) {
             log.error("Failed to invoke getMetricHistoryData via adapter for 
monitor {} and metrics {}", monitorId, metrics, e);
             throw new RuntimeException("Failed to invoke getMetricHistoryData 
via adapter: " + e.getMessage(), e);
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MonitorServiceAdapterImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MonitorServiceAdapterImpl.java
index 8a4f381fc..125e73ac9 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MonitorServiceAdapterImpl.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/adapters/impl/MonitorServiceAdapterImpl.java
@@ -19,6 +19,7 @@
 package org.apache.hertzbeat.ai.adapters.impl;
 
 import com.usthe.sureness.subject.SubjectSum;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.ai.adapters.MonitorServiceAdapter;
 import org.apache.hertzbeat.ai.config.McpContextHolder;
@@ -26,21 +27,26 @@ import org.springframework.data.domain.Page;
 import org.apache.hertzbeat.common.entity.manager.Monitor;
 import org.apache.hertzbeat.common.entity.manager.Param;
 import org.apache.hertzbeat.common.entity.manager.ParamDefine;
-import org.apache.hertzbeat.common.support.SpringContextHolder;
+import org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard;
+import org.apache.hertzbeat.manager.service.MonitorService;
+import org.apache.hertzbeat.manager.service.AppService;
 import org.springframework.stereotype.Component;
 
-import java.lang.reflect.Method;
 import java.util.List;
 import java.util.Map;
 
 /**
  * Implementation of the MonitorServiceAdapter interface that provides access 
to monitor information
- * through reflection by invoking the underlying monitor service 
implementation.
+ * through direct service injection instead of reflection.
  */
 @Slf4j
 @Component
+@RequiredArgsConstructor
 public class MonitorServiceAdapterImpl implements MonitorServiceAdapter {
 
+    private final MonitorService monitorService;
+    private final AppService appService;
+
     @Override
     public Page<Monitor> getMonitors(
             List<Long> ids,
@@ -67,33 +73,15 @@ public class MonitorServiceAdapterImpl implements 
MonitorServiceAdapter {
                 pageSize = 8;
             }
 
-            Object monitorService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject: {}", subjectSum);
 
-            try {
-                monitorService = 
SpringContextHolder.getBean("monitorServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 'monitorServiceImpl', 
trying by class name");
-            }
-
-            assert monitorService != null;
-            log.debug("MonitorService bean found: {}", 
monitorService.getClass().getSimpleName());
-            Method method = monitorService.getClass().getMethod(
-                    "getMonitors",
-                    List.class, String.class, String.class, Byte.class,
-                    String.class, String.class, int.class, int.class, 
String.class);
-
-
-            @SuppressWarnings("unchecked")
-            Page<Monitor> result = (Page<Monitor>) method.invoke(
-                    monitorService,
+            Page<Monitor> result = monitorService.getMonitors(
                     ids, app, search, status, sort, order, pageIndex, 
pageSize, labels);
+            
             log.debug("MonitorServiceAdapter.getMonitors result: {}", 
result.getContent());
             return result;
 
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: getMonitors", e);
         } catch (Exception e) {
             log.debug("Failed to invoke getMonitors via adapter", e);
             throw new RuntimeException("Failed to invoke getMonitors via 
adapter", e);
@@ -103,33 +91,15 @@ public class MonitorServiceAdapterImpl implements 
MonitorServiceAdapter {
     @Override
     public Long addMonitor(Monitor monitor, List<Param> params, String 
collector) {
         try {
-            Object monitorService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject for addMonitor: {}", 
subjectSum);
 
-            try {
-                monitorService = 
SpringContextHolder.getBean("monitorServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 'monitorServiceImpl', 
trying by class name");
-            }
-
-            assert monitorService != null;
-            log.debug("MonitorService bean found for addMonitor: {}", 
monitorService.getClass().getSimpleName());
-
-            // Call addMonitor method: addMonitor(Monitor monitor, List<Param> 
params, String collector, GrafanaDashboard dashboard)
-            Method method = monitorService.getClass().getMethod(
-                    "addMonitor",
-                    Monitor.class, List.class, String.class,
-                    
Class.forName("org.apache.hertzbeat.common.entity.grafana.GrafanaDashboard"));
-
-            // Call the method with null dashboard
-            method.invoke(monitorService, monitor, params, collector, null);
+            // Call addMonitor method with null dashboard
+            monitorService.addMonitor(monitor, params, collector, 
(GrafanaDashboard) null);
 
             log.debug("Successfully added monitor: {} with ID: {}", 
monitor.getName(), monitor.getId());
             return monitor.getId();
 
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: addMonitor", e);
         } catch (Exception e) {
             log.error("Failed to invoke addMonitor via adapter", e);
             throw new RuntimeException("Failed to invoke addMonitor via 
adapter: " + e.getMessage(), e);
@@ -139,35 +109,20 @@ public class MonitorServiceAdapterImpl implements 
MonitorServiceAdapter {
     @Override
     public Map<String, String> getAvailableMonitorTypes(String language) {
         try {
-            Object appService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject for getAvailableMonitorTypes: 
{}", subjectSum);
 
-            try {
-                appService = SpringContextHolder.getBean("appServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 'appServiceImpl', 
trying by class name");
-            }
-
-            assert appService != null;
-            log.debug("AppService bean found for getAvailableMonitorTypes: 
{}", appService.getClass().getSimpleName());
-
             // Provide default language if not specified
             if (language == null || language.trim().isEmpty()) {
                 language = "en-US";
             }
 
-            // Call getI18nApps method: getI18nApps(String lang)
-            Method method = appService.getClass().getMethod("getI18nApps", 
String.class);
-
-            @SuppressWarnings("unchecked")
-            Map<String, String> result = (Map<String, String>) 
method.invoke(appService, language);
+            // Call getI18nApps method directly
+            Map<String, String> result = appService.getI18nApps(language);
 
             log.debug("Successfully retrieved {} monitor types", 
result.size());
             return result;
 
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: getI18nApps", e);
         } catch (Exception e) {
             log.error("Failed to invoke getI18nApps via adapter", e);
             throw new RuntimeException("Failed to invoke getI18nApps via 
adapter: " + e.getMessage(), e);
@@ -177,35 +132,20 @@ public class MonitorServiceAdapterImpl implements 
MonitorServiceAdapter {
     @Override
     public List<ParamDefine> getMonitorParamDefines(String app) {
         try {
-            Object appService = null;
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current security subject for getMonitorParamDefines: 
{}", subjectSum);
 
-            try {
-                appService = SpringContextHolder.getBean("appServiceImpl");
-            } catch (Exception e) {
-                log.debug("Could not find bean by name 'appServiceImpl', 
trying by class name");
-            }
-
-            assert appService != null;
-            log.debug("AppService bean found for getMonitorParamDefines: {}", 
appService.getClass().getSimpleName());
-
             // Validate app parameter
             if (app == null || app.trim().isEmpty()) {
                 throw new IllegalArgumentException("Monitor type/app parameter 
is required");
             }
 
-            // Call getAppParamDefines method: getAppParamDefines(String app)
-            Method method = 
appService.getClass().getMethod("getAppParamDefines", String.class);
-
-            @SuppressWarnings("unchecked")
-            List<ParamDefine> result = (List<ParamDefine>) 
method.invoke(appService, app.toLowerCase().trim());
+            // Call getAppParamDefines method directly
+            List<ParamDefine> result = 
appService.getAppParamDefines(app.toLowerCase().trim());
 
             log.debug("Successfully retrieved {} parameter definitions for 
monitor type: {}", result.size(), app);
             return result;
 
-        } catch (NoSuchMethodException e) {
-            throw new RuntimeException("Method not found: getAppParamDefines", 
e);
         } catch (Exception e) {
             log.error("Failed to invoke getAppParamDefines via adapter for 
app: {}", app, e);
             throw new RuntimeException("Failed to invoke getAppParamDefines 
via adapter: " + e.getMessage(), e);
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/DynamicOpenAiApiKey.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/DynamicOpenAiApiKey.java
deleted file mode 100644
index 3750db9dd..000000000
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/DynamicOpenAiApiKey.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hertzbeat.ai.config;
-
-import lombok.extern.slf4j.Slf4j;
-import org.apache.hertzbeat.ai.pojo.dto.ModelProviderConfig;
-import org.apache.hertzbeat.base.dao.GeneralConfigDao;
-import org.apache.hertzbeat.common.entity.manager.GeneralConfig;
-import org.apache.hertzbeat.common.util.JsonUtil;
-import org.jetbrains.annotations.NotNull;
-import org.springframework.ai.model.ApiKey;
-import org.springframework.stereotype.Component;
-
-/**
- * Dynamic LLM Provider API Key implementation that retrieves the API key
- */
-@Slf4j
-@Component
-public class DynamicOpenAiApiKey implements ApiKey {
-
-    private final GeneralConfigDao generalConfigDao;
-    
-    public DynamicOpenAiApiKey(GeneralConfigDao generalConfigDao) {
-        this.generalConfigDao = generalConfigDao;
-    }
-
-    @NotNull
-    @Override
-    public String getValue() {
-        GeneralConfig providerConfig = generalConfigDao.findByType("provider");
-        ModelProviderConfig modelProviderConfig = 
JsonUtil.fromJson(providerConfig.getContent(), ModelProviderConfig.class);
-
-        if (modelProviderConfig != null && modelProviderConfig.isEnable() && 
modelProviderConfig.isStatus()) {
-            log.debug("Retrieved {} API key from configuration service", 
modelProviderConfig.getCode());
-            return modelProviderConfig.getApiKey();
-        } else {
-            log.warn("No valid LLM Provider API key found in configuration");
-            return "";
-        }
-    }
-}
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/LlmConfig.java 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/LlmConfig.java
index 60a6db740..331006dbc 100644
--- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/LlmConfig.java
+++ b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/config/LlmConfig.java
@@ -20,7 +20,7 @@ package org.apache.hertzbeat.ai.config;
 
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.common.support.event.AiProviderConfigChangeEvent;
-import org.apache.hertzbeat.ai.pojo.dto.ModelProviderConfig;
+import org.apache.hertzbeat.common.entity.dto.ModelProviderConfig;
 import org.apache.hertzbeat.base.dao.GeneralConfigDao;
 import org.apache.hertzbeat.common.entity.manager.GeneralConfig;
 import org.apache.hertzbeat.common.util.JsonUtil;
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/entity/OpenAiConfig.java 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/entity/OpenAiConfig.java
deleted file mode 100644
index 7795acea7..000000000
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/entity/OpenAiConfig.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hertzbeat.ai.entity;
-
-import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_ONLY;
-import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_WRITE;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.EntityListeners;
-import jakarta.persistence.Id;
-import jakarta.persistence.Table;
-import jakarta.validation.constraints.NotBlank;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.springframework.data.annotation.CreatedBy;
-import org.springframework.data.annotation.CreatedDate;
-import org.springframework.data.annotation.LastModifiedBy;
-import org.springframework.data.annotation.LastModifiedDate;
-import org.springframework.data.jpa.domain.support.AuditingEntityListener;
-
-import java.time.LocalDateTime;
-
-/**
- * OpenAI Agent Config Entity
- */
-@Entity
-@Table(name = "hzb_ai_agent_config")
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-@Schema(description = "OpenAI Agent config entity")
-@EntityListeners(AuditingEntityListener.class)
-public class OpenAiConfig {
-
-    @Id
-    @Schema(title = "Config type: openai, primary key", description = "Config 
type: openai, primary key",
-            accessMode = READ_WRITE)
-    @NotBlank(message = "type can not null")
-    private String type;
-
-    @Schema(title = "Config content", description = "Config content,format 
json", accessMode = READ_WRITE)
-    @Column(length = 8192)
-    private String content;
-
-    @Schema(title = "The creator of this record", example = "tom", accessMode 
= READ_ONLY)
-    @CreatedBy
-    private String creator;
-
-    @Schema(title = "This record was last modified by", example = "tom", 
accessMode = READ_ONLY)
-    @LastModifiedBy
-    private String modifier;
-
-    @Schema(title = "This record creation time (millisecond timestamp)", 
accessMode = READ_ONLY)
-    @CreatedDate
-    private LocalDateTime gmtCreate;
-
-    @Schema(title = "Record the latest modification time (timestamp in 
milliseconds)", accessMode = READ_ONLY)
-    @LastModifiedDate
-    private LocalDateTime gmtUpdate;
-}
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/pojo/dto/Hierarchy.java 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/pojo/dto/Hierarchy.java
deleted file mode 100644
index 2d750fe52..000000000
--- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/pojo/dto/Hierarchy.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hertzbeat.ai.pojo.dto;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_WRITE;
-
-/**
- * Hierarchical structure
- * eg: Monitoring Type metrics Information Hierarchy Relationship
- */
-@AllArgsConstructor
-@NoArgsConstructor
-@Data
-@Schema(description = "Monitor Hierarchy")
-public class Hierarchy {
-
-    /**
-     * Category value
-     */
-    @Schema(description = "Category Value", example = "os", accessMode = 
READ_WRITE)
-    String category;
-
-    /**
-     * Attribute value
-     */
-    @Schema(description = "Attribute value", example = "linux", accessMode = 
READ_WRITE)
-    String value;
-
-    /**
-     * Attribute internationalization tag
-     */
-    @Schema(description = "Attribute internationalization tag", example = 
"Linux system", accessMode = READ_WRITE)
-    String label;
-
-    /**
-     * Is it a leaf node
-     */
-    @Schema(description = "Is it a leaf node", example = "true", accessMode = 
READ_WRITE)
-    Boolean isLeaf = false;
-
-    /**
-     * Is hide this app type in main menus layout
-     */
-    @Schema(description = "Is hide this app in main menus layout, only for app 
type, default true.", example = "true")
-    Boolean hide = true;
-    
-    /**
-     * For leaf metric
-     * metric type 0-number: number 1-string: string
-     */
-    @Schema(description = "metric type 0-number: number 1-string: string")
-    private Byte type;
-    
-    /**
-     * metric unit
-     */
-    @Schema(description = "metric unit")
-    private String unit;
-
-    /**
-     * Next level of association
-     */
-    @Schema(description = "Next Hierarchy", accessMode = READ_WRITE)
-    private List<Hierarchy> children;
-}
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/ChatClientProviderServiceImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/ChatClientProviderServiceImpl.java
index 565740711..63e2d2840 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/ChatClientProviderServiceImpl.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/ChatClientProviderServiceImpl.java
@@ -21,7 +21,7 @@ package org.apache.hertzbeat.ai.service.impl;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.ai.config.PromptProvider;
 import org.apache.hertzbeat.ai.pojo.dto.MessageDto;
-import org.apache.hertzbeat.ai.pojo.dto.ModelProviderConfig;
+import org.apache.hertzbeat.common.entity.dto.ModelProviderConfig;
 import org.apache.hertzbeat.ai.service.ChatClientProviderService;
 import org.apache.hertzbeat.base.dao.GeneralConfigDao;
 import org.apache.hertzbeat.common.entity.manager.GeneralConfig;
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertDefineToolsImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertDefineToolsImpl.java
index 2fd8257b9..4e49b714f 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertDefineToolsImpl.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertDefineToolsImpl.java
@@ -23,11 +23,11 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.usthe.sureness.subject.SubjectSum;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.hertzbeat.ai.adapters.AlertDefineServiceAdapter;
-import org.apache.hertzbeat.ai.pojo.dto.Hierarchy;
 import org.apache.hertzbeat.ai.config.McpContextHolder;
 import org.apache.hertzbeat.ai.tools.AlertDefineTools;
 import org.apache.hertzbeat.ai.utils.UtilityClass;
 import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
+import org.apache.hertzbeat.manager.pojo.dto.Hierarchy;
 import org.springframework.ai.tool.annotation.Tool;
 import org.springframework.ai.tool.annotation.ToolParam;
 import org.springframework.beans.factory.annotation.Autowired;
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertToolsImpl.java
 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertToolsImpl.java
index 176876999..ad1f97882 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertToolsImpl.java
+++ 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/tools/impl/AlertToolsImpl.java
@@ -20,11 +20,11 @@ package org.apache.hertzbeat.ai.tools.impl;
 
 import com.usthe.sureness.subject.SubjectSum;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.hertzbeat.ai.adapters.AlertServiceAdapter;
 import org.apache.hertzbeat.ai.config.McpContextHolder;
 import org.apache.hertzbeat.ai.tools.AlertTools;
 import org.apache.hertzbeat.ai.utils.UtilityClass;
 import org.apache.hertzbeat.alert.dto.AlertSummary;
+import org.apache.hertzbeat.alert.service.AlertService;
 import org.apache.hertzbeat.common.entity.alerter.GroupAlert;
 import org.apache.hertzbeat.common.entity.alerter.SingleAlert;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -41,7 +41,7 @@ import org.springframework.stereotype.Service;
 @Service
 public class AlertToolsImpl implements AlertTools {
     @Autowired
-    private AlertServiceAdapter alertServiceAdapter;
+    private AlertService alertService;
 
     @Override
     @Tool(name = "query_alerts", description = """
@@ -116,7 +116,7 @@ public class AlertToolsImpl implements AlertTools {
 
             // Handle different alert types
             if ("single".equalsIgnoreCase(alertType) || 
"both".equalsIgnoreCase(alertType)) {
-                Page<SingleAlert> singleResult = 
alertServiceAdapter.getSingleAlerts(status, search, sort, order, pageIndex, 
pageSize);
+                Page<SingleAlert> singleResult = 
alertService.getSingleAlerts(status, search, sort, order, pageIndex, pageSize);
                 
                 response.append("SINGLE ALERTS:\n");
                 response.append("Found 
").append(singleResult.getContent().size()).append(" single alerts (Total: 
").append(singleResult.getTotalElements()).append("):\n\n");
@@ -154,7 +154,7 @@ public class AlertToolsImpl implements AlertTools {
                     response.append("\n");
                 }
                 
-                Page<GroupAlert> groupResult = 
alertServiceAdapter.getGroupAlerts(status, search, sort, order, pageIndex, 
pageSize);
+                Page<GroupAlert> groupResult = 
alertService.getGroupAlerts(status, search, sort, order, pageIndex, pageSize);
                 
                 response.append("GROUP ALERTS:\n");
                 response.append("Found 
").append(groupResult.getContent().size()).append(" group alerts (Total: 
").append(groupResult.getTotalElements()).append("):\n\n");
@@ -205,7 +205,7 @@ public class AlertToolsImpl implements AlertTools {
             SubjectSum subjectSum = McpContextHolder.getSubject();
             log.debug("Current subject in get_alerts_summary tool: {}", 
subjectSum);
 
-            AlertSummary summary = alertServiceAdapter.getAlertsSummary();
+            AlertSummary summary = alertService.getAlertsSummary();
 
             StringBuilder response = new StringBuilder();
             response.append("ALERTS SUMMARY\n");
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/utils/UtilityClass.java 
b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/utils/UtilityClass.java
index 64c1a06f8..05e8506a3 100644
--- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/utils/UtilityClass.java
+++ b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/utils/UtilityClass.java
@@ -22,9 +22,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.hertzbeat.ai.pojo.dto.Hierarchy;
 
-import java.lang.reflect.Method;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -33,6 +31,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import org.apache.hertzbeat.manager.pojo.dto.Hierarchy;
 
 /**
  * Utility class providing helper methods for field expression validation, 
parsing,
@@ -227,51 +226,6 @@ public class UtilityClass {
         return "VALID";
     }
 
-    /**
-     * Helper method to validate operator
-     */
-    public boolean isValidOperator(String operator) {
-        return operator != null && (operator.equals(">") || 
operator.equals("<")
-                || operator.equals(">=") || operator.equals("<=")
-                || operator.equals("==") || operator.equals("!="));
-    }
-
-    /**
-     * Helper method to validate priority
-     */
-    public boolean isValidPriority(String priority) {
-        return priority != null && (priority.equalsIgnoreCase("critical")
-                || priority.equalsIgnoreCase("warning") || 
priority.equalsIgnoreCase("info"));
-    }
-
-    /**
-     * Helper method to build expression
-     */
-    public String buildExpression(String metric, String operator, String 
threshold) {
-        return String.format("%s %s %s", metric, operator, threshold);
-    }
-
-    /**
-     * Helper method to parse existing expression into components
-     */
-    public String[] parseExpression(String expression) {
-        if (expression == null || expression.trim().isEmpty()) {
-            return null;
-        }
-
-        // Simple parsing for basic expressions like "metric > value"
-        String[] operators = {">", "<", ">=", "<=", "==", "!="};
-        for (String op : operators) {
-            if (expression.contains(" " + op + " ")) {
-                String[] parts = expression.split(" " + op + " ");
-                if (parts.length == 2) {
-                    return new String[]{parts[0].trim(), op, parts[1].trim()};
-                }
-            }
-        }
-        return null;
-    }
-
     /**
      * Helper method to parse key-value pairs from a string
      * Format: "key1:value1, key2:value2, ..."
@@ -473,19 +427,6 @@ public class UtilityClass {
         return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd 
HH:mm:ss"));
     }
 
-    /**
-     * Parse time range string to milliseconds
-     */
-    public long parseTimeRangeToMillis(String timeRange) {
-        return switch (timeRange.toLowerCase()) {
-            case "1h" -> 60 * 60 * 1000L;
-            case "6h" -> 6 * 60 * 60 * 1000L;
-            case "24h" -> 24 * 60 * 60 * 1000L;
-            case "7d" -> 7 * 24 * 60 * 60 * 1000L;
-            default -> 24 * 60 * 60 * 1000L; // default to 24h
-        };
-    }
-
     /**
      * Helper method to convert monitor status byte to readable text
      * @param status The status byte from monitor
@@ -504,143 +445,6 @@ public class UtilityClass {
         };
     }
 
-    /**
-     * Helper method to get metrics name for a metric type
-     */
-    public String getMetricsNameForType(String metricType) {
-        return switch (metricType.toLowerCase()) {
-            case "cpu" -> "cpu";
-            case "memory" -> "memory";
-            case "disk" -> "disk";
-            case "network" -> "network";
-            default -> "system";
-        };
-    }
-
-    /**
-     * Helper method to check if a field represents usage for a metric type
-     */
-    public boolean isUsageField(String field, String metricType) {
-        if (field == null) return false;
-
-        String fieldLower = field.toLowerCase();
-        String typeLower = metricType.toLowerCase();
-
-        return fieldLower.contains("usage")
-                || fieldLower.contains("percent")
-                || fieldLower.contains("util")
-                || (typeLower.equals("cpu") && (fieldLower.contains("cpu") || 
fieldLower.contains("idle")))
-                || (typeLower.equals("memory") && 
fieldLower.contains("memory"))
-                || (typeLower.equals("disk") && fieldLower.contains("disk"));
-    }
-
-    /**
-     * Convert manager module Hierarchy objects to ai-agent module Hierarchy 
objects
-     * This handles the cross-module DTO conversion to avoid ClassCastException
-     */
-    public List<Hierarchy> convertToAgentHierarchies(List<?> 
managerHierarchies) {
-        List<Hierarchy> agentHierarchies = new ArrayList<>();
-
-        for (Object managerHierarchy : managerHierarchies) {
-            Hierarchy agentHierarchy = 
convertToAgentHierarchy(managerHierarchy);
-            agentHierarchies.add(agentHierarchy);
-        }
-
-        return agentHierarchies;
-    }
-
-    /**
-     * Convert a single manager Hierarchy object to ai-agent Hierarchy object 
using reflection
-     */
-    public Hierarchy convertToAgentHierarchy(Object managerHierarchy) {
-        try {
-            Hierarchy agentHierarchy = new Hierarchy();
-
-            // Use reflection to copy properties from manager DTO to agent DTO
-            Class<?> managerClass = managerHierarchy.getClass();
-
-            // Copy basic properties
-            agentHierarchy.setCategory(getStringField(managerHierarchy, 
managerClass, "category"));
-            agentHierarchy.setValue(getStringField(managerHierarchy, 
managerClass, "value"));
-            agentHierarchy.setLabel(getStringField(managerHierarchy, 
managerClass, "label"));
-            agentHierarchy.setIsLeaf(getBooleanField(managerHierarchy, 
managerClass, "isLeaf"));
-            agentHierarchy.setHide(getBooleanField(managerHierarchy, 
managerClass, "hide"));
-            agentHierarchy.setType(getByteField(managerHierarchy, 
managerClass, "type"));
-            agentHierarchy.setUnit(getStringField(managerHierarchy, 
managerClass, "unit"));
-
-            // Handle children recursively
-            List<?> managerChildren = getListField(managerHierarchy, 
managerClass, "children");
-            if (managerChildren != null && !managerChildren.isEmpty()) {
-                List<Hierarchy> agentChildren = 
convertToAgentHierarchies(managerChildren);
-                agentHierarchy.setChildren(agentChildren);
-            }
-
-            return agentHierarchy;
-
-        } catch (Exception e) {
-            log.error("Failed to convert manager hierarchy to agent hierarchy: 
{}", e.getMessage(), e);
-            throw new RuntimeException("Failed to convert hierarchy", e);
-        }
-    }
-
-    public String getStringField(Object obj, Class<?> clazz, String fieldName) 
{
-        try {
-            Method getter = clazz.getMethod("get" + capitalize(fieldName));
-            Object value = getter.invoke(obj);
-            return value != null ? value.toString() : null;
-        } catch (Exception e) {
-            log.debug("Could not get string field '{}': {}", fieldName, 
e.getMessage());
-            return null;
-        }
-    }
-
-    public Boolean getBooleanField(Object obj, Class<?> clazz, String 
fieldName) {
-        try {
-            Method getter = clazz.getMethod("get" + capitalize(fieldName));
-            Object value = getter.invoke(obj);
-            return value instanceof Boolean ? (Boolean) value : null;
-        } catch (Exception e) {
-            try {
-                // Try alternative getter pattern for boolean fields
-                Method isGetter = clazz.getMethod("is" + 
capitalize(fieldName));
-                Object value = isGetter.invoke(obj);
-                return value instanceof Boolean ? (Boolean) value : null;
-            } catch (Exception e2) {
-                log.debug("Could not get boolean field '{}': {}", fieldName, 
e.getMessage());
-                return null;
-            }
-        }
-    }
-
-    public Byte getByteField(Object obj, Class<?> clazz, String fieldName) {
-        try {
-            Method getter = clazz.getMethod("get" + capitalize(fieldName));
-            Object value = getter.invoke(obj);
-            return value instanceof Byte ? (Byte) value : null;
-        } catch (Exception e) {
-            log.debug("Could not get byte field '{}': {}", fieldName, 
e.getMessage());
-            return null;
-        }
-    }
-
-    public List<?> getListField(Object obj, Class<?> clazz, String fieldName) {
-        try {
-            Method getter = clazz.getMethod("get" + capitalize(fieldName));
-            Object value = getter.invoke(obj);
-            return value instanceof List ? (List<?>) value : null;
-        } catch (Exception e) {
-            log.debug("Could not get list field '{}': {}", fieldName, 
e.getMessage());
-            return null;
-        }
-    }
-
-    public String capitalize(String str) {
-        if (str == null || str.isEmpty()) {
-            return str;
-        }
-        return str.substring(0, 1).toUpperCase() + str.substring(1);
-    }
-
 
     /**
      * Extract existing monitor IDs from the alert expression
diff --git 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/pojo/dto/ModelProviderConfig.java
 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ModelProviderConfig.java
similarity index 97%
rename from 
hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/pojo/dto/ModelProviderConfig.java
rename to 
hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ModelProviderConfig.java
index e463dfda2..db1b54072 100644
--- 
a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/pojo/dto/ModelProviderConfig.java
+++ 
b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ModelProviderConfig.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.hertzbeat.ai.pojo.dto;
+package org.apache.hertzbeat.common.entity.dto;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import jakarta.validation.constraints.NotBlank;
@@ -56,4 +56,4 @@ public class ModelProviderConfig {
     @Schema(title = "API Key", description = "API key", example = "sk-...")
     @NotBlank(message = "API Key cannot be empty when enabled")
     private String apiKey;
-}
+}
\ No newline at end of file
diff --git a/hertzbeat-manager/pom.xml b/hertzbeat-manager/pom.xml
index 31650f8a2..5f3671242 100644
--- a/hertzbeat-manager/pom.xml
+++ b/hertzbeat-manager/pom.xml
@@ -212,11 +212,6 @@
             <groupId>org.apache.arrow</groupId>
             <artifactId>arrow-memory-netty</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.apache.hertzbeat</groupId>
-            <artifactId>hertzbeat-ai</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <dependency>
             <groupId>io.micrometer</groupId>
             <artifactId>micrometer-registry-prometheus</artifactId>
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ModelProviderConfigServiceImpl.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ModelProviderConfigServiceImpl.java
index 22d93909d..160c2b921 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ModelProviderConfigServiceImpl.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ModelProviderConfigServiceImpl.java
@@ -20,7 +20,7 @@ package org.apache.hertzbeat.manager.service.impl;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import java.lang.reflect.Type;
-import org.apache.hertzbeat.ai.pojo.dto.ModelProviderConfig;
+import org.apache.hertzbeat.common.entity.dto.ModelProviderConfig;
 import org.apache.hertzbeat.base.dao.GeneralConfigDao;
 import org.apache.hertzbeat.common.constants.GeneralConfigTypeEnum;
 import org.apache.hertzbeat.common.support.event.AiProviderConfigChangeEvent;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to