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 fd7d9980ee9f63bf63c6c5f72fc558226af3704f Author: tomsun28 <[email protected]> AuthorDate: Thu Oct 30 23:00:36 2025 +0800 refactor Signed-off-by: tomsun28 <[email protected]> --- .../org/apache/hertzbeat/ai/config/LlmConfig.java | 7 +- .../hertzbeat/ai/service/AiConfigService.java | 60 ------------- .../ai/service/impl/AiConfigServiceImpl.java | 100 --------------------- .../impl/ChatClientProviderServiceImpl.java | 2 +- .../common/entity/dto/ModelProviderConfig.java | 11 +-- web-app/src/app/pojo/ModelProviderConfig.ts | 2 - .../shared/components/ai-chat/chat.component.html | 2 +- .../shared/components/ai-chat/chat.component.ts | 16 +--- 8 files changed, 5 insertions(+), 195 deletions(-) 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 331006dbc..b14534461 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 @@ -72,12 +72,7 @@ public class LlmConfig { } ModelProviderConfig modelProviderConfig = JsonUtil.fromJson(providerConfig.getContent(), ModelProviderConfig.class); - if (!modelProviderConfig.isEnable() || !modelProviderConfig.isStatus()) { - log.warn("LLM Provider is not enabled or status is not valid, ChatClient bean will not be created"); - return null; - } - - if (modelProviderConfig.getApiKey() == null) { + if (modelProviderConfig == null || modelProviderConfig.getApiKey() == null) { log.warn("LLM Provider configuration is incomplete, ChatClient bean will not be created"); return null; } diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/AiConfigService.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/AiConfigService.java deleted file mode 100644 index 03134f7a8..000000000 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/AiConfigService.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.service; - -/** - * Ai Configuration Service - */ -public interface AiConfigService { - - /** - * Validate OpenAI API key by calling the OpenAI API - * @param apiKey the API key to validate - * @return validation result with success status and message - */ - ValidationResult validateApiKey(String apiKey); - - /** - * Validation result class - */ - class ValidationResult { - private final boolean valid; - private final String message; - - private ValidationResult(boolean valid, String message) { - this.valid = valid; - this.message = message; - } - - public static ValidationResult success(String message) { - return new ValidationResult(true, message); - } - - public static ValidationResult failure(String message) { - return new ValidationResult(false, message); - } - - public boolean isValid() { - return valid; - } - - public String getMessage() { - return message; - } - } -} diff --git a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/AiConfigServiceImpl.java b/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/AiConfigServiceImpl.java deleted file mode 100644 index 17cb772fe..000000000 --- a/hertzbeat-ai/src/main/java/org/apache/hertzbeat/ai/service/impl/AiConfigServiceImpl.java +++ /dev/null @@ -1,100 +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.service.impl; - -import lombok.extern.slf4j.Slf4j; -import org.apache.hertzbeat.ai.service.AiConfigService; -import org.apache.hertzbeat.base.dao.GeneralConfigDao; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; -import org.springframework.web.client.RestTemplate; - -/** - * Ai Configuration Service Implementation - */ -@Slf4j -@Service -public class AiConfigServiceImpl implements AiConfigService { - - private static final String OPENAI_MODELS_ENDPOINT = "https://api.openai.com/v1/models"; - private final RestTemplate restTemplate; - - private final GeneralConfigDao generalConfigDao; - - public AiConfigServiceImpl(GeneralConfigDao generalConfigDao, RestTemplate restTemplate) { - this.restTemplate = restTemplate; - this.generalConfigDao = generalConfigDao; - } - - @Override - public ValidationResult validateApiKey(String apiKey) { - if (!StringUtils.hasText(apiKey)) { - return ValidationResult.failure("API key cannot be empty"); - } - - if (!apiKey.startsWith("sk-")) { - return ValidationResult.failure("Invalid API key format. OpenAI API keys should start with 'sk-'"); - } - - try { - HttpHeaders headers = new HttpHeaders(); - headers.set("Authorization", "Bearer " + apiKey); - headers.set("Content-Type", "application/json"); - - HttpEntity<String> entity = new HttpEntity<>(headers); - - log.debug("Validating OpenAI API key by calling models endpoint"); - ResponseEntity<String> response = restTemplate.exchange( - OPENAI_MODELS_ENDPOINT, - HttpMethod.GET, - entity, - String.class - ); - - if (response.getStatusCode() == HttpStatus.OK) { - log.info("OpenAI API key validation successful"); - return ValidationResult.success("API key is valid"); - } else { - log.warn("OpenAI API key validation failed with status: {}", response.getStatusCode()); - return ValidationResult.failure("API key validation failed: " + response.getStatusCode()); - } - - } catch (Exception e) { - log.error("Error validating OpenAI API key", e); - String errorMessage = e.getMessage(); - - // Parse common error messages - if (errorMessage.contains("401")) { - return ValidationResult.failure("Invalid API key - authentication failed"); - } else if (errorMessage.contains("403")) { - return ValidationResult.failure("API key does not have permission to access models"); - } else if (errorMessage.contains("429")) { - return ValidationResult.failure("Rate limit exceeded - please try again later"); - } else if (errorMessage.contains("timeout") || errorMessage.contains("connect")) { - return ValidationResult.failure("Network error - unable to connect to OpenAI API"); - } else { - return ValidationResult.failure("API key validation failed: " + errorMessage); - } - } - } -} 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 63e2d2840..fe848efb5 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 @@ -117,7 +117,7 @@ public class ChatClientProviderServiceImpl implements ChatClientProviderService if (!isConfigured) { GeneralConfig providerConfig = generalConfigDao.findByType("provider"); ModelProviderConfig modelProviderConfig = JsonUtil.fromJson(providerConfig.getContent(), ModelProviderConfig.class); - isConfigured = modelProviderConfig != null && modelProviderConfig.isStatus(); + isConfigured = modelProviderConfig != null && modelProviderConfig.getApiKey() != null; } return isConfigured; } diff --git a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ModelProviderConfig.java b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ModelProviderConfig.java index db1b54072..527f65da7 100644 --- a/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ModelProviderConfig.java +++ b/hertzbeat-common/src/main/java/org/apache/hertzbeat/common/entity/dto/ModelProviderConfig.java @@ -32,15 +32,6 @@ import lombok.NoArgsConstructor; @Schema(description = "LLM Model Provider configuration") public class ModelProviderConfig { - @Schema(title = "Enable Provider", description = "Whether Provider is enabled", example = "true") - private boolean enable = false; - - @Schema(title = "Check the provider available status") - private boolean status = false; - - @Schema(title = "The error message when provider status check failed") - private String error; - @Schema(title = "Model type, text-generate, vision") private String type; @@ -56,4 +47,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/web-app/src/app/pojo/ModelProviderConfig.ts b/web-app/src/app/pojo/ModelProviderConfig.ts index 5fe6dbbe3..7a3d15525 100644 --- a/web-app/src/app/pojo/ModelProviderConfig.ts +++ b/web-app/src/app/pojo/ModelProviderConfig.ts @@ -18,8 +18,6 @@ */ export class ModelProviderConfig { - enable: boolean = false; - status: boolean = true; error!: string; type!: string; code: string = 'openai'; diff --git a/web-app/src/app/shared/components/ai-chat/chat.component.html b/web-app/src/app/shared/components/ai-chat/chat.component.html index a44748bb7..2224c6967 100644 --- a/web-app/src/app/shared/components/ai-chat/chat.component.html +++ b/web-app/src/app/shared/components/ai-chat/chat.component.html @@ -167,7 +167,7 @@ [nzClosable]="false" nzWidth="700px" [nzOkLoading]="configLoading" - nzOkText="Validate & Save" + nzOkText="Save" nzCancelText="Cancel" > <div *nzModalContent class="-inner-content"> diff --git a/web-app/src/app/shared/components/ai-chat/chat.component.ts b/web-app/src/app/shared/components/ai-chat/chat.component.ts index b47365bcd..73cb5afd0 100644 --- a/web-app/src/app/shared/components/ai-chat/chat.component.ts +++ b/web-app/src/app/shared/components/ai-chat/chat.component.ts @@ -249,7 +249,6 @@ export class ChatComponent implements OnInit, AfterViewChecked { // Check if this is a fallback conversation if (this.currentConversation?.conversationId.startsWith('fallback-')) { - console.log('Fallback mode - showing offline message'); setTimeout(() => { const offlineMessage: ChatMessage = { content: @@ -276,11 +275,8 @@ export class ChatComponent implements OnInit, AfterViewChecked { this.scrollToBottom(); // Send to AI service - console.log('Sending message to AI service:', messageContent); this.aiChatService.streamChat(messageContent, this.currentConversation?.conversationId).subscribe({ next: chunk => { - console.log('Received stream chunk:', chunk); - // Find the last assistant message and append content const lastMessage = this.messages[this.messages.length - 1]; if (lastMessage && lastMessage.role === 'assistant') { @@ -444,12 +440,7 @@ export class ChatComponent implements OnInit, AfterViewChecked { this.aiProviderConfig.model = defaultProvider.defaultModel; } } - - if (response.data.enable) { - this.loadConversations(); - } else { - this.showAiProviderConfigDialog(response.data.error); - } + this.loadConversations(); } else { // Initialize with default values if no config exists this.aiProviderConfig = new ModelProviderConfig(); @@ -539,12 +530,7 @@ export class ChatComponent implements OnInit, AfterViewChecked { return; } - // Always enable when saving an API key - this.aiProviderConfig.enable = true; - this.aiProviderConfig.status = true; - this.configLoading = true; - this.message.info('Validating API key...', { nzDuration: 2000 }); this.generalConfigSvc.saveModelProviderConfig(this.aiProviderConfig).subscribe({ next: response => { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
