This is an automated email from the ASF dual-hosted git repository.
liuhaopeng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/bigtop-manager.git
The following commit(s) were added to refs/heads/main by this push:
new c79478a7 refactor: replace langchain4j with Spring AI in
bigtop-manager-ai module (#291)
c79478a7 is described below
commit c79478a76ca22a92d44e5c99444f8adda97478a4
Author: haopeng <[email protected]>
AuthorDate: Thu Mar 26 01:58:13 2026 +0800
refactor: replace langchain4j with Spring AI in bigtop-manager-ai module
(#291)
---
bigtop-manager-ai/pom.xml | 26 +---
.../ai/assistant/GeneralAssistantFactory.java | 15 +-
.../provider/ChatMemoryStoreProvider.java | 20 ++-
.../assistant/store/PersistentChatMemoryStore.java | 84 +++++++-----
.../manager/ai/core/AbstractAIAssistant.java | 39 +++---
.../manager/ai/core/factory/AIAssistant.java | 13 +-
.../ai/core/factory/AIAssistantFactory.java | 8 +-
.../manager/ai/platform/DashScopeAssistant.java | 145 +++++++++++++++-----
.../manager/ai/platform/DeepSeekAssistant.java | 143 +++++++++++++------
.../manager/ai/platform/OpenAIAssistant.java | 140 ++++++++++++++-----
.../manager/ai/platform/QianFanAssistant.java | 152 +++++++++++++++------
.../assistant/GeneralAssistantFactoryTest.java | 1 -
.../store/PersistentChatMemoryStoreTest.java | 57 ++++----
bigtop-manager-bom/pom.xml | 47 ++++---
bigtop-manager-server/pom.xml | 8 ++
.../server/controller/ChatbotController.java | 10 +-
.../server/controller/LLMConfigController.java | 15 +-
.../manager/server/controller/LoginController.java | 5 +-
.../mcp/converter/JsonToolCallResultConverter.java | 3 +-
.../src/main/resources/ddl/MySQL-DDL-CREATE.sql | 6 +-
.../main/resources/ddl/PostgreSQL-DDL-CREATE.sql | 6 +-
21 files changed, 606 insertions(+), 337 deletions(-)
diff --git a/bigtop-manager-ai/pom.xml b/bigtop-manager-ai/pom.xml
index 1ba22acc..6eb68ca8 100644
--- a/bigtop-manager-ai/pom.xml
+++ b/bigtop-manager-ai/pom.xml
@@ -48,30 +48,12 @@
<artifactId>bigtop-manager-dao</artifactId>
</dependency>
<dependency>
- <groupId>dev.langchain4j</groupId>
- <artifactId>langchain4j</artifactId>
+ <groupId>org.springframework.ai</groupId>
+ <artifactId>spring-ai-openai</artifactId>
</dependency>
<dependency>
- <groupId>dev.langchain4j</groupId>
- <artifactId>langchain4j-reactor</artifactId>
- </dependency>
- <dependency>
- <groupId>dev.langchain4j</groupId>
- <artifactId>langchain4j-open-ai</artifactId>
- </dependency>
- <dependency>
- <groupId>dev.langchain4j</groupId>
- <artifactId>langchain4j-community-qianfan</artifactId>
- </dependency>
- <dependency>
- <groupId>dev.langchain4j</groupId>
- <artifactId>langchain4j-community-dashscope</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- </exclusion>
- </exclusions>
+ <groupId>org.springframework.ai</groupId>
+ <artifactId>spring-ai-deepseek</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
diff --git
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/assistant/GeneralAssistantFactory.java
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/assistant/GeneralAssistantFactory.java
index 5bad559b..38951c8e 100644
---
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/assistant/GeneralAssistantFactory.java
+++
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/assistant/GeneralAssistantFactory.java
@@ -34,8 +34,6 @@ import org.apache.bigtop.manager.ai.platform.QianFanAssistant;
import org.springframework.stereotype.Component;
-import dev.langchain4j.service.tool.ToolProvider;
-
import jakarta.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@@ -70,8 +68,7 @@ public class GeneralAssistantFactory extends
AbstractAIAssistantFactory {
}
@Override
- public AIAssistant createWithPrompt(
- AIAssistantConfig config, ToolProvider toolProvider, SystemPrompt
systemPrompt) {
+ public AIAssistant createWithPrompt(AIAssistantConfig config, Object
toolProvider, SystemPrompt systemPrompt) {
GeneralAssistantConfig generalAssistantConfig =
(GeneralAssistantConfig) config;
PlatformType platformType = generalAssistantConfig.getPlatformType();
Object id = generalAssistantConfig.getId();
@@ -81,9 +78,8 @@ public class GeneralAssistantFactory extends
AbstractAIAssistantFactory {
AIAssistant.Builder builder = initializeBuilder(platformType);
builder.id(id)
-
.memoryStore(chatMemoryStoreProvider.createPersistentChatMemoryStore())
- .withConfig(generalAssistantConfig)
- .withToolProvider(toolProvider);
+
.memoryStore(chatMemoryStoreProvider.createPersistentChatMemoryStore(id))
+ .withConfig(generalAssistantConfig);
configureSystemPrompt(builder, systemPrompt,
generalAssistantConfig.getLanguage());
@@ -91,15 +87,14 @@ public class GeneralAssistantFactory extends
AbstractAIAssistantFactory {
}
@Override
- public AIAssistant createForTest(AIAssistantConfig config, ToolProvider
toolProvider) {
+ public AIAssistant createForTest(AIAssistantConfig config, Object
toolProvider) {
GeneralAssistantConfig generalAssistantConfig =
(GeneralAssistantConfig) config;
PlatformType platformType = generalAssistantConfig.getPlatformType();
AIAssistant.Builder builder = initializeBuilder(platformType);
builder.id(null)
.memoryStore(chatMemoryStoreProvider.createInMemoryChatMemoryStore())
- .withConfig(generalAssistantConfig)
- .withToolProvider(toolProvider);
+ .withConfig(generalAssistantConfig);
return builder.build();
}
diff --git
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/assistant/provider/ChatMemoryStoreProvider.java
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/assistant/provider/ChatMemoryStoreProvider.java
index 67003f10..6e4a73aa 100644
---
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/assistant/provider/ChatMemoryStoreProvider.java
+++
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/assistant/provider/ChatMemoryStoreProvider.java
@@ -22,11 +22,11 @@ import
org.apache.bigtop.manager.ai.assistant.store.PersistentChatMemoryStore;
import org.apache.bigtop.manager.dao.repository.ChatMessageDao;
import org.apache.bigtop.manager.dao.repository.ChatThreadDao;
+import org.springframework.ai.chat.memory.ChatMemory;
+import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository;
+import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.stereotype.Component;
-import dev.langchain4j.store.memory.chat.ChatMemoryStore;
-import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;
-
import jakarta.annotation.Resource;
@Component
@@ -37,11 +37,17 @@ public class ChatMemoryStoreProvider {
@Resource
private ChatMessageDao chatMessageDao;
- public ChatMemoryStore createPersistentChatMemoryStore() {
- return new PersistentChatMemoryStore(chatThreadDao, chatMessageDao);
+ public ChatMemory createPersistentChatMemoryStore(Object conversationId) {
+ PersistentChatMemoryStore repository =
+ new PersistentChatMemoryStore((Long) conversationId,
chatThreadDao, chatMessageDao);
+ return MessageWindowChatMemory.builder()
+ .chatMemoryRepository(repository)
+ .build();
}
- public ChatMemoryStore createInMemoryChatMemoryStore() {
- return new InMemoryChatMemoryStore();
+ public ChatMemory createInMemoryChatMemoryStore() {
+ return MessageWindowChatMemory.builder()
+ .chatMemoryRepository(new InMemoryChatMemoryRepository())
+ .build();
}
}
diff --git
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/assistant/store/PersistentChatMemoryStore.java
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/assistant/store/PersistentChatMemoryStore.java
index 9349d4ad..aaf6f6e7 100644
---
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/assistant/store/PersistentChatMemoryStore.java
+++
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/assistant/store/PersistentChatMemoryStore.java
@@ -24,12 +24,12 @@ import org.apache.bigtop.manager.dao.po.ChatThreadPO;
import org.apache.bigtop.manager.dao.repository.ChatMessageDao;
import org.apache.bigtop.manager.dao.repository.ChatThreadDao;
-import dev.langchain4j.data.message.AiMessage;
-import dev.langchain4j.data.message.ChatMessage;
-import dev.langchain4j.data.message.ChatMessageType;
-import dev.langchain4j.data.message.SystemMessage;
-import dev.langchain4j.data.message.UserMessage;
-import dev.langchain4j.store.memory.chat.ChatMemoryStore;
+import org.springframework.ai.chat.memory.ChatMemoryRepository;
+import org.springframework.ai.chat.messages.AssistantMessage;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.ai.chat.messages.SystemMessage;
+import org.springframework.ai.chat.messages.UserMessage;
+
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
@@ -38,41 +38,49 @@ import java.util.Objects;
import java.util.stream.Collectors;
@Slf4j
-public class PersistentChatMemoryStore implements ChatMemoryStore {
+public class PersistentChatMemoryStore implements ChatMemoryRepository {
- private final List<ChatMessage> messagesInMemory = new ArrayList<>();
+ private final List<Message> messagesInMemory = new ArrayList<>();
private final ChatThreadDao chatThreadDao;
private final ChatMessageDao chatMessageDao;
+ private final Long conversationId;
- public PersistentChatMemoryStore(ChatThreadDao chatThreadDao,
ChatMessageDao chatMessageDao) {
+ public PersistentChatMemoryStore(Long conversationId, ChatThreadDao
chatThreadDao, ChatMessageDao chatMessageDao) {
+ this.conversationId = conversationId;
this.chatThreadDao = chatThreadDao;
this.chatMessageDao = chatMessageDao;
}
- private ChatMessage convertToChatMessage(ChatMessagePO chatMessagePO) {
+ private Message convertToChatMessage(ChatMessagePO chatMessagePO) {
String sender = chatMessagePO.getSender().toLowerCase();
if (sender.equals(MessageType.AI.getValue())) {
- return new AiMessage(chatMessagePO.getMessage());
+ return new AssistantMessage(chatMessagePO.getMessage());
} else if (sender.equals(MessageType.USER.getValue())) {
return new UserMessage(chatMessagePO.getMessage());
+ } else if (sender.equals(MessageType.SYSTEM.getValue())) {
+ return new SystemMessage(chatMessagePO.getMessage());
} else {
return null;
}
}
- private ChatMessagePO convertToChatMessagePO(ChatMessage chatMessage, Long
chatThreadId) {
+ private ChatMessagePO convertToChatMessagePO(Message message, Long
chatThreadId) {
ChatMessagePO chatMessagePO = new ChatMessagePO();
- if (chatMessage.type().equals(ChatMessageType.AI)) {
+ if (message.getMessageType() ==
org.springframework.ai.chat.messages.MessageType.ASSISTANT) {
chatMessagePO.setSender(MessageType.AI.getValue());
- AiMessage aiMessage = (AiMessage) chatMessage;
- if (aiMessage.text() == null) {
+ AssistantMessage assistantMessage = (AssistantMessage) message;
+ if (assistantMessage.getText() == null) {
return null;
}
- chatMessagePO.setMessage(aiMessage.text());
- } else if (chatMessage.type().equals(ChatMessageType.USER)) {
+ chatMessagePO.setMessage(assistantMessage.getText());
+ } else if (message.getMessageType() ==
org.springframework.ai.chat.messages.MessageType.USER) {
chatMessagePO.setSender(MessageType.USER.getValue());
- UserMessage userMessage = (UserMessage) chatMessage;
- chatMessagePO.setMessage(userMessage.singleText());
+ UserMessage userMessage = (UserMessage) message;
+ chatMessagePO.setMessage(userMessage.getText());
+ } else if (message.getMessageType() ==
org.springframework.ai.chat.messages.MessageType.SYSTEM) {
+ chatMessagePO.setSender(MessageType.SYSTEM.getValue());
+ SystemMessage systemMessage = (SystemMessage) message;
+ chatMessagePO.setMessage(systemMessage.getText());
} else {
return null;
}
@@ -82,11 +90,11 @@ public class PersistentChatMemoryStore implements
ChatMemoryStore {
return chatMessagePO;
}
- private List<ChatMessage> sortMessages(List<ChatMessage> messages) {
- List<ChatMessage> systemMessages = messages.stream()
+ private List<Message> sortMessages(List<Message> messages) {
+ List<Message> systemMessages = messages.stream()
.filter(message -> message instanceof SystemMessage)
.collect(Collectors.toList());
- List<ChatMessage> otherMessages = messages.stream()
+ List<Message> otherMessages = messages.stream()
.filter(message -> !(message instanceof SystemMessage))
.toList();
@@ -95,9 +103,15 @@ public class PersistentChatMemoryStore implements
ChatMemoryStore {
}
@Override
- public List<ChatMessage> getMessages(Object threadId) {
- List<ChatMessagePO> chatMessages =
chatMessageDao.findAllByThreadId((Long) threadId);
- List<ChatMessage> allChatMessages = new ArrayList<>();
+ public List<String> findConversationIds() {
+ // Return the current conversation ID as a list
+ return List.of(String.valueOf(conversationId));
+ }
+
+ @Override
+ public List<Message> findByConversationId(String conversationId) {
+ List<ChatMessagePO> chatMessages =
chatMessageDao.findAllByThreadId(this.conversationId);
+ List<Message> allChatMessages = new ArrayList<>();
if (!chatMessages.isEmpty()) {
allChatMessages.addAll(chatMessages.stream()
.map(this::convertToChatMessage)
@@ -111,20 +125,22 @@ public class PersistentChatMemoryStore implements
ChatMemoryStore {
}
@Override
- public void updateMessages(Object threadId, List<ChatMessage> messages) {
- ChatMessage newMessage = messages.get(messages.size() - 1);
- ChatMessagePO chatMessagePO = convertToChatMessagePO(newMessage,
(Long) threadId);
- if (chatMessagePO == null) {
- messagesInMemory.add(newMessage);
- return;
+ public void saveAll(String conversationId, List<Message> messages) {
+ for (Message message : messages) {
+ ChatMessagePO chatMessagePO = convertToChatMessagePO(message,
this.conversationId);
+ if (chatMessagePO == null) {
+ messagesInMemory.add(message);
+ continue;
+ }
+ chatMessageDao.save(chatMessagePO);
}
- chatMessageDao.save(chatMessagePO);
}
@Override
- public void deleteMessages(Object threadId) {
- List<ChatMessagePO> chatMessagePOS =
chatMessageDao.findAllByThreadId((Long) threadId);
+ public void deleteByConversationId(String conversationId) {
+ List<ChatMessagePO> chatMessagePOS =
chatMessageDao.findAllByThreadId(this.conversationId);
chatMessagePOS.forEach(chatMessage -> chatMessage.setIsDeleted(true));
chatMessageDao.partialUpdateByIds(chatMessagePOS);
+ messagesInMemory.clear();
}
}
diff --git
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/core/AbstractAIAssistant.java
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/core/AbstractAIAssistant.java
index 58e8268a..30ec7ab6 100644
---
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/core/AbstractAIAssistant.java
+++
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/core/AbstractAIAssistant.java
@@ -21,18 +21,20 @@ package org.apache.bigtop.manager.ai.core;
import org.apache.bigtop.manager.ai.core.config.AIAssistantConfig;
import org.apache.bigtop.manager.ai.core.factory.AIAssistant;
-import dev.langchain4j.memory.ChatMemory;
-import dev.langchain4j.memory.chat.MessageWindowChatMemory;
-import dev.langchain4j.service.tool.ToolProvider;
-import dev.langchain4j.store.memory.chat.ChatMemoryStore;
+import org.springframework.ai.chat.memory.ChatMemory;
+import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository;
+import org.springframework.ai.chat.memory.MessageWindowChatMemory;
+
import reactor.core.publisher.Flux;
public abstract class AbstractAIAssistant implements AIAssistant {
protected final AIAssistant.Service aiServices;
protected static final Integer MEMORY_LEN = 10;
protected final ChatMemory chatMemory;
+ protected final Object memoryId;
- protected AbstractAIAssistant(ChatMemory chatMemory, AIAssistant.Service
aiServices) {
+ protected AbstractAIAssistant(Object memoryId, ChatMemory chatMemory,
AIAssistant.Service aiServices) {
+ this.memoryId = memoryId;
this.chatMemory = chatMemory;
this.aiServices = aiServices;
}
@@ -44,7 +46,7 @@ public abstract class AbstractAIAssistant implements
AIAssistant {
@Override
public Object getId() {
- return chatMemory.id();
+ return memoryId;
}
@Override
@@ -60,19 +62,13 @@ public abstract class AbstractAIAssistant implements
AIAssistant {
public abstract static class Builder implements AIAssistant.Builder {
protected Object id;
- protected ChatMemoryStore chatMemoryStore;
+ protected ChatMemory chatMemory;
protected AIAssistantConfig config;
- protected ToolProvider toolProvider;
protected String systemPrompt;
public Builder() {}
- public Builder withToolProvider(ToolProvider toolProvider) {
- this.toolProvider = toolProvider;
- return this;
- }
-
public Builder withSystemPrompt(String systemPrompt) {
this.systemPrompt = systemPrompt;
return this;
@@ -88,19 +84,18 @@ public abstract class AbstractAIAssistant implements
AIAssistant {
return this;
}
- public Builder memoryStore(ChatMemoryStore chatMemoryStore) {
- this.chatMemoryStore = chatMemoryStore;
+ public Builder memoryStore(ChatMemory chatMemory) {
+ this.chatMemory = chatMemory;
return this;
}
- public MessageWindowChatMemory getChatMemory() {
- MessageWindowChatMemory.Builder builder =
MessageWindowChatMemory.builder()
- .chatMemoryStore(chatMemoryStore)
- .maxMessages(MEMORY_LEN);
- if (id != null) {
- builder.id(id);
+ public ChatMemory getChatMemory() {
+ if (chatMemory == null) {
+ chatMemory = MessageWindowChatMemory.builder()
+ .chatMemoryRepository(new
InMemoryChatMemoryRepository())
+ .build();
}
- return builder.build();
+ return chatMemory;
}
}
}
diff --git
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistant.java
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistant.java
index 6092590a..ff2b96f5 100644
---
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistant.java
+++
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistant.java
@@ -21,11 +21,10 @@ package org.apache.bigtop.manager.ai.core.factory;
import org.apache.bigtop.manager.ai.core.config.AIAssistantConfig;
import org.apache.bigtop.manager.ai.core.enums.PlatformType;
-import dev.langchain4j.memory.ChatMemory;
-import dev.langchain4j.model.chat.ChatModel;
-import dev.langchain4j.model.chat.StreamingChatModel;
-import dev.langchain4j.service.tool.ToolProvider;
-import dev.langchain4j.store.memory.chat.ChatMemoryStore;
+import org.springframework.ai.chat.memory.ChatMemory;
+import org.springframework.ai.chat.model.ChatModel;
+import org.springframework.ai.chat.model.StreamingChatModel;
+
import reactor.core.publisher.Flux;
public interface AIAssistant {
@@ -72,12 +71,10 @@ public interface AIAssistant {
interface Builder {
Builder id(Object id);
- Builder memoryStore(ChatMemoryStore memoryStore);
+ Builder memoryStore(ChatMemory memoryStore);
Builder withConfig(AIAssistantConfig configProvider);
- Builder withToolProvider(ToolProvider toolProvider);
-
Builder withSystemPrompt(String systemPrompt);
AIAssistant build();
diff --git
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistantFactory.java
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistantFactory.java
index d947e778..06e1dafe 100644
---
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistantFactory.java
+++
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistantFactory.java
@@ -21,15 +21,13 @@ package org.apache.bigtop.manager.ai.core.factory;
import org.apache.bigtop.manager.ai.core.config.AIAssistantConfig;
import org.apache.bigtop.manager.ai.core.enums.SystemPrompt;
-import dev.langchain4j.service.tool.ToolProvider;
-
public interface AIAssistantFactory {
- AIAssistant createWithPrompt(AIAssistantConfig config, ToolProvider
toolProvider, SystemPrompt systemPrompt);
+ AIAssistant createWithPrompt(AIAssistantConfig config, Object
toolProvider, SystemPrompt systemPrompt);
- AIAssistant createForTest(AIAssistantConfig config, ToolProvider
toolProvider);
+ AIAssistant createForTest(AIAssistantConfig config, Object toolProvider);
- default AIAssistant createAIService(AIAssistantConfig config, ToolProvider
toolProvider) {
+ default AIAssistant createAIService(AIAssistantConfig config, Object
toolProvider) {
return createWithPrompt(config, toolProvider,
SystemPrompt.DEFAULT_PROMPT);
}
}
diff --git
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/DashScopeAssistant.java
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/DashScopeAssistant.java
index cad0a9ee..6661e6e0 100644
---
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/DashScopeAssistant.java
+++
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/DashScopeAssistant.java
@@ -22,18 +22,29 @@ import
org.apache.bigtop.manager.ai.core.AbstractAIAssistant;
import org.apache.bigtop.manager.ai.core.enums.PlatformType;
import org.apache.bigtop.manager.ai.core.factory.AIAssistant;
-import dev.langchain4j.community.model.dashscope.QwenChatModel;
-import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel;
-import dev.langchain4j.internal.ValidationUtils;
-import dev.langchain4j.memory.ChatMemory;
-import dev.langchain4j.model.chat.ChatModel;
-import dev.langchain4j.model.chat.StreamingChatModel;
-import dev.langchain4j.service.AiServices;
+import org.springframework.ai.chat.memory.ChatMemory;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.ai.chat.messages.SystemMessage;
+import org.springframework.ai.chat.messages.UserMessage;
+import org.springframework.ai.chat.model.ChatModel;
+import org.springframework.ai.chat.model.StreamingChatModel;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.openai.OpenAiChatModel;
+import org.springframework.ai.openai.OpenAiChatOptions;
+import org.springframework.ai.openai.api.OpenAiApi;
+import org.springframework.util.Assert;
+
+import reactor.core.publisher.Flux;
+
+import java.util.ArrayList;
+import java.util.List;
public class DashScopeAssistant extends AbstractAIAssistant {
- public DashScopeAssistant(ChatMemory chatMemory, AIAssistant.Service
aiServices) {
- super(chatMemory, aiServices);
+ private static final String BASE_URL =
"https://dashscope.aliyuncs.com/compatible-mode";
+
+ public DashScopeAssistant(Object memoryId, ChatMemory chatMemory,
AIAssistant.Service aiServices) {
+ super(memoryId, chatMemory, aiServices);
}
@Override
@@ -47,39 +58,101 @@ public class DashScopeAssistant extends
AbstractAIAssistant {
public static class Builder extends AbstractAIAssistant.Builder {
- public AIAssistant build() {
- AIAssistant.Service aiService =
AiServices.builder(AIAssistant.Service.class)
- .chatModel(getChatModel())
- .streamingChatModel(getStreamingChatModel())
- .chatMemory(getChatMemory())
- .toolProvider(toolProvider)
- .systemMessageProvider(threadId -> {
- if (threadId != null) {
- return systemPrompt;
- }
- return null;
- })
- .build();
- return new DashScopeAssistant(getChatMemory(), aiService);
- }
-
@Override
public ChatModel getChatModel() {
- String model = ValidationUtils.ensureNotNull(config.getModel(),
"model");
- String apiKey =
-
ValidationUtils.ensureNotNull(config.getCredentials().get("apiKey"), "apiKey");
- return
QwenChatModel.builder().apiKey(apiKey).modelName(model).build();
+ String model = config.getModel();
+ Assert.notNull(model, "model must not be null");
+ String apiKey = config.getCredentials().get("apiKey");
+ Assert.notNull(apiKey, "apiKey must not be null");
+
+ OpenAiApi openAiApi =
+
OpenAiApi.builder().baseUrl(BASE_URL).apiKey(apiKey).build();
+ OpenAiChatOptions options =
OpenAiChatOptions.builder().model(model).build();
+ return OpenAiChatModel.builder()
+ .openAiApi(openAiApi)
+ .defaultOptions(options)
+ .build();
}
@Override
public StreamingChatModel getStreamingChatModel() {
- String model = ValidationUtils.ensureNotNull(config.getModel(),
"model");
- String apiKey =
-
ValidationUtils.ensureNotNull(config.getCredentials().get("apiKey"), "apiKey");
- return QwenStreamingChatModel.builder()
- .apiKey(apiKey)
- .modelName(model)
- .build();
+ // In Spring AI, OpenAiChatModel handles both sync and streaming
+ return getChatModel();
+ }
+
+ public AIAssistant build() {
+ ChatModel chatModel = getChatModel();
+ StreamingChatModel streamingChatModel = getStreamingChatModel();
+ ChatMemory memory = getChatMemory();
+
+ AIAssistant.Service aiService = new AIAssistant.Service() {
+ @Override
+ public String chat(String userMessage) {
+ List<Message> messages = new ArrayList<>();
+ if (systemPrompt != null) {
+ messages.add(new SystemMessage(systemPrompt));
+ }
+ // Add conversation history
+ String convId = String.valueOf(id);
+ List<Message> history = memory.get(convId);
+ messages.addAll(history);
+ // Add new user message
+ UserMessage newUserMessage = new UserMessage(userMessage);
+ messages.add(newUserMessage);
+
+ Prompt prompt = new Prompt(messages);
+ String response =
+
chatModel.call(prompt).getResult().getOutput().getText();
+
+ // Save to memory
+ memory.add(
+ convId,
+ List.of(
+ newUserMessage,
+ new
org.springframework.ai.chat.messages.AssistantMessage(response)));
+
+ return response;
+ }
+
+ @Override
+ public Flux<String> streamChat(String userMessage) {
+ List<Message> messages = new ArrayList<>();
+ if (systemPrompt != null) {
+ messages.add(new SystemMessage(systemPrompt));
+ }
+ // Add conversation history
+ String convId = String.valueOf(id);
+ List<Message> history = memory.get(convId);
+ messages.addAll(history);
+ // Add new user message
+ UserMessage newUserMessage = new UserMessage(userMessage);
+ messages.add(newUserMessage);
+
+ Prompt prompt = new Prompt(messages);
+
+ StringBuilder responseBuilder = new StringBuilder();
+ return streamingChatModel.stream(prompt)
+ .map(chatResponse -> {
+ String content =
+
chatResponse.getResult().getOutput().getText();
+ if (content != null) {
+ responseBuilder.append(content);
+ }
+ return content;
+ })
+ .doOnComplete(() -> {
+ // Save to memory when streaming completes
+ memory.add(
+ convId,
+ List.of(
+ newUserMessage,
+ new
org.springframework.ai.chat.messages.AssistantMessage(
+
responseBuilder.toString())));
+ });
+ }
+ };
+
+ return new DashScopeAssistant(id, memory, aiService);
}
}
}
diff --git
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/DeepSeekAssistant.java
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/DeepSeekAssistant.java
index ed39621c..962ad825 100644
---
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/DeepSeekAssistant.java
+++
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/DeepSeekAssistant.java
@@ -16,26 +16,34 @@
* specific language governing permissions and limitations
* under the License.
*/
+
package org.apache.bigtop.manager.ai.platform;
import org.apache.bigtop.manager.ai.core.AbstractAIAssistant;
import org.apache.bigtop.manager.ai.core.enums.PlatformType;
import org.apache.bigtop.manager.ai.core.factory.AIAssistant;
-import dev.langchain4j.internal.ValidationUtils;
-import dev.langchain4j.memory.ChatMemory;
-import dev.langchain4j.model.chat.ChatModel;
-import dev.langchain4j.model.chat.StreamingChatModel;
-import dev.langchain4j.model.openai.OpenAiChatModel;
-import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
-import dev.langchain4j.service.AiServices;
+import org.springframework.ai.chat.memory.ChatMemory;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.ai.chat.messages.SystemMessage;
+import org.springframework.ai.chat.messages.UserMessage;
+import org.springframework.ai.chat.model.ChatModel;
+import org.springframework.ai.chat.model.StreamingChatModel;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.deepseek.DeepSeekChatModel;
+import org.springframework.ai.deepseek.DeepSeekChatOptions;
+import org.springframework.ai.deepseek.api.DeepSeekApi;
+import org.springframework.util.Assert;
-public class DeepSeekAssistant extends AbstractAIAssistant {
+import reactor.core.publisher.Flux;
- private static final String BASE_URL = "https://api.deepseek.com/v1";
+import java.util.ArrayList;
+import java.util.List;
+
+public class DeepSeekAssistant extends AbstractAIAssistant {
- public DeepSeekAssistant(ChatMemory chatMemory, AIAssistant.Service
aiServices) {
- super(chatMemory, aiServices);
+ public DeepSeekAssistant(Object memoryId, ChatMemory chatMemory,
AIAssistant.Service aiServices) {
+ super(memoryId, chatMemory, aiServices);
}
@Override
@@ -51,42 +59,99 @@ public class DeepSeekAssistant extends AbstractAIAssistant {
@Override
public ChatModel getChatModel() {
- String model = ValidationUtils.ensureNotNull(config.getModel(),
"model");
- String apiKey =
-
ValidationUtils.ensureNotNull(config.getCredentials().get("apiKey"), "apiKey");
- return OpenAiChatModel.builder()
- .apiKey(apiKey)
- .baseUrl(BASE_URL)
- .modelName(model)
+ String model = config.getModel();
+ Assert.notNull(model, "model must not be null");
+ String apiKey = config.getCredentials().get("apiKey");
+ Assert.notNull(apiKey, "apiKey must not be null");
+
+ DeepSeekApi deepSeekApi =
DeepSeekApi.builder().apiKey(apiKey).build();
+ DeepSeekChatOptions options =
+ DeepSeekChatOptions.builder().model(model).build();
+ return DeepSeekChatModel.builder()
+ .deepSeekApi(deepSeekApi)
+ .defaultOptions(options)
.build();
}
@Override
public StreamingChatModel getStreamingChatModel() {
- String model = ValidationUtils.ensureNotNull(config.getModel(),
"model");
- String apiKey =
-
ValidationUtils.ensureNotNull(config.getCredentials().get("apiKey"), "apiKey");
- return OpenAiStreamingChatModel.builder()
- .apiKey(apiKey)
- .baseUrl(BASE_URL)
- .modelName(model)
- .build();
+ // DeepSeekChatModel handles both sync and streaming
+ return getChatModel();
}
public AIAssistant build() {
- AIAssistant.Service aiService =
AiServices.builder(AIAssistant.Service.class)
- .chatModel(getChatModel())
- .streamingChatModel(getStreamingChatModel())
- .chatMemory(getChatMemory())
- .toolProvider(toolProvider)
- .systemMessageProvider(threadId -> {
- if (threadId != null) {
- return systemPrompt;
- }
- return null;
- })
- .build();
- return new DeepSeekAssistant(getChatMemory(), aiService);
+ ChatModel chatModel = getChatModel();
+ StreamingChatModel streamingChatModel = getStreamingChatModel();
+ ChatMemory memory = getChatMemory();
+
+ AIAssistant.Service aiService = new AIAssistant.Service() {
+ @Override
+ public String chat(String userMessage) {
+ List<Message> messages = new ArrayList<>();
+ if (systemPrompt != null) {
+ messages.add(new SystemMessage(systemPrompt));
+ }
+ // Add conversation history
+ String convId = String.valueOf(id);
+ List<Message> history = memory.get(convId);
+ messages.addAll(history);
+ // Add new user message
+ UserMessage newUserMessage = new UserMessage(userMessage);
+ messages.add(newUserMessage);
+
+ Prompt prompt = new Prompt(messages);
+ String response =
+
chatModel.call(prompt).getResult().getOutput().getText();
+
+ // Save to memory
+ memory.add(
+ convId,
+ List.of(
+ newUserMessage,
+ new
org.springframework.ai.chat.messages.AssistantMessage(response)));
+
+ return response;
+ }
+
+ @Override
+ public Flux<String> streamChat(String userMessage) {
+ List<Message> messages = new ArrayList<>();
+ if (systemPrompt != null) {
+ messages.add(new SystemMessage(systemPrompt));
+ }
+ // Add conversation history
+ String convId = String.valueOf(id);
+ List<Message> history = memory.get(convId);
+ messages.addAll(history);
+ // Add new user message
+ UserMessage newUserMessage = new UserMessage(userMessage);
+ messages.add(newUserMessage);
+
+ Prompt prompt = new Prompt(messages);
+
+ StringBuilder responseBuilder = new StringBuilder();
+ return streamingChatModel.stream(prompt)
+ .map(chatResponse -> {
+ String content =
+
chatResponse.getResult().getOutput().getText();
+ if (content != null) {
+ responseBuilder.append(content);
+ }
+ return content;
+ })
+ .doOnComplete(() -> {
+ // Save to memory when streaming completes
+ memory.add(
+ convId,
+ List.of(
+ newUserMessage,
+ new
org.springframework.ai.chat.messages.AssistantMessage(
+
responseBuilder.toString())));
+ });
+ }
+ };
+
+ return new DeepSeekAssistant(id, memory, aiService);
}
}
}
diff --git
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/OpenAIAssistant.java
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/OpenAIAssistant.java
index ce2738ec..b51fa75e 100644
---
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/OpenAIAssistant.java
+++
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/OpenAIAssistant.java
@@ -22,20 +22,29 @@ import
org.apache.bigtop.manager.ai.core.AbstractAIAssistant;
import org.apache.bigtop.manager.ai.core.enums.PlatformType;
import org.apache.bigtop.manager.ai.core.factory.AIAssistant;
-import dev.langchain4j.internal.ValidationUtils;
-import dev.langchain4j.memory.ChatMemory;
-import dev.langchain4j.model.chat.ChatModel;
-import dev.langchain4j.model.chat.StreamingChatModel;
-import dev.langchain4j.model.openai.OpenAiChatModel;
-import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
-import dev.langchain4j.service.AiServices;
+import org.springframework.ai.chat.memory.ChatMemory;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.ai.chat.messages.SystemMessage;
+import org.springframework.ai.chat.messages.UserMessage;
+import org.springframework.ai.chat.model.ChatModel;
+import org.springframework.ai.chat.model.StreamingChatModel;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.openai.OpenAiChatModel;
+import org.springframework.ai.openai.OpenAiChatOptions;
+import org.springframework.ai.openai.api.OpenAiApi;
+import org.springframework.util.Assert;
+
+import reactor.core.publisher.Flux;
+
+import java.util.ArrayList;
+import java.util.List;
public class OpenAIAssistant extends AbstractAIAssistant {
- private static final String BASE_URL = "https://api.openai.com/v1";
+ private static final String BASE_URL = "https://api.openai.com";
- public OpenAIAssistant(ChatMemory chatMemory, AIAssistant.Service
aiServices) {
- super(chatMemory, aiServices);
+ public OpenAIAssistant(Object memoryId, ChatMemory chatMemory,
AIAssistant.Service aiServices) {
+ super(memoryId, chatMemory, aiServices);
}
@Override
@@ -51,42 +60,99 @@ public class OpenAIAssistant extends AbstractAIAssistant {
@Override
public ChatModel getChatModel() {
- String model = ValidationUtils.ensureNotNull(config.getModel(),
"model");
- String apiKey =
-
ValidationUtils.ensureNotNull(config.getCredentials().get("apiKey"), "apiKey");
+ String model = config.getModel();
+ Assert.notNull(model, "model must not be null");
+ String apiKey = config.getCredentials().get("apiKey");
+ Assert.notNull(apiKey, "apiKey must not be null");
+
+ OpenAiApi openAiApi =
+
OpenAiApi.builder().baseUrl(BASE_URL).apiKey(apiKey).build();
+ OpenAiChatOptions options =
OpenAiChatOptions.builder().model(model).build();
return OpenAiChatModel.builder()
- .apiKey(apiKey)
- .baseUrl(BASE_URL)
- .modelName(model)
+ .openAiApi(openAiApi)
+ .defaultOptions(options)
.build();
}
@Override
public StreamingChatModel getStreamingChatModel() {
- String model = ValidationUtils.ensureNotNull(config.getModel(),
"model");
- String apiKey =
-
ValidationUtils.ensureNotNull(config.getCredentials().get("apiKey"), "apiKey");
- return OpenAiStreamingChatModel.builder()
- .apiKey(apiKey)
- .baseUrl(BASE_URL)
- .modelName(model)
- .build();
+ // In Spring AI, OpenAiChatModel handles both sync and streaming
+ return getChatModel();
}
public AIAssistant build() {
- AIAssistant.Service aiService =
AiServices.builder(AIAssistant.Service.class)
- .chatModel(getChatModel())
- .streamingChatModel(getStreamingChatModel())
- .chatMemory(getChatMemory())
- .toolProvider(toolProvider)
- .systemMessageProvider(threadId -> {
- if (threadId != null) {
- return systemPrompt;
- }
- return null;
- })
- .build();
- return new OpenAIAssistant(getChatMemory(), aiService);
+ ChatModel chatModel = getChatModel();
+ StreamingChatModel streamingChatModel = getStreamingChatModel();
+ ChatMemory memory = getChatMemory();
+
+ AIAssistant.Service aiService = new AIAssistant.Service() {
+ @Override
+ public String chat(String userMessage) {
+ List<Message> messages = new ArrayList<>();
+ if (systemPrompt != null) {
+ messages.add(new SystemMessage(systemPrompt));
+ }
+ // Add conversation history
+ String convId = String.valueOf(id);
+ List<Message> history = memory.get(convId);
+ messages.addAll(history);
+ // Add new user message
+ UserMessage newUserMessage = new UserMessage(userMessage);
+ messages.add(newUserMessage);
+
+ Prompt prompt = new Prompt(messages);
+ String response =
+
chatModel.call(prompt).getResult().getOutput().getText();
+
+ // Save to memory
+ memory.add(
+ convId,
+ List.of(
+ newUserMessage,
+ new
org.springframework.ai.chat.messages.AssistantMessage(response)));
+
+ return response;
+ }
+
+ @Override
+ public Flux<String> streamChat(String userMessage) {
+ List<Message> messages = new ArrayList<>();
+ if (systemPrompt != null) {
+ messages.add(new SystemMessage(systemPrompt));
+ }
+ // Add conversation history
+ String convId = String.valueOf(id);
+ List<Message> history = memory.get(convId);
+ messages.addAll(history);
+ // Add new user message
+ UserMessage newUserMessage = new UserMessage(userMessage);
+ messages.add(newUserMessage);
+
+ Prompt prompt = new Prompt(messages);
+
+ StringBuilder responseBuilder = new StringBuilder();
+ return streamingChatModel.stream(prompt)
+ .map(chatResponse -> {
+ String content =
+
chatResponse.getResult().getOutput().getText();
+ if (content != null) {
+ responseBuilder.append(content);
+ }
+ return content;
+ })
+ .doOnComplete(() -> {
+ // Save to memory when streaming completes
+ memory.add(
+ convId,
+ List.of(
+ newUserMessage,
+ new
org.springframework.ai.chat.messages.AssistantMessage(
+
responseBuilder.toString())));
+ });
+ }
+ };
+
+ return new OpenAIAssistant(id, memory, aiService);
}
}
}
diff --git
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/QianFanAssistant.java
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/QianFanAssistant.java
index cf5db353..468020eb 100644
---
a/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/QianFanAssistant.java
+++
b/bigtop-manager-ai/src/main/java/org/apache/bigtop/manager/ai/platform/QianFanAssistant.java
@@ -22,18 +22,29 @@ import
org.apache.bigtop.manager.ai.core.AbstractAIAssistant;
import org.apache.bigtop.manager.ai.core.enums.PlatformType;
import org.apache.bigtop.manager.ai.core.factory.AIAssistant;
-import dev.langchain4j.community.model.qianfan.QianfanChatModel;
-import dev.langchain4j.community.model.qianfan.QianfanStreamingChatModel;
-import dev.langchain4j.internal.ValidationUtils;
-import dev.langchain4j.memory.ChatMemory;
-import dev.langchain4j.model.chat.ChatModel;
-import dev.langchain4j.model.chat.StreamingChatModel;
-import dev.langchain4j.service.AiServices;
+import org.springframework.ai.chat.memory.ChatMemory;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.ai.chat.messages.SystemMessage;
+import org.springframework.ai.chat.messages.UserMessage;
+import org.springframework.ai.chat.model.ChatModel;
+import org.springframework.ai.chat.model.StreamingChatModel;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.openai.OpenAiChatModel;
+import org.springframework.ai.openai.OpenAiChatOptions;
+import org.springframework.ai.openai.api.OpenAiApi;
+import org.springframework.util.Assert;
+
+import reactor.core.publisher.Flux;
+
+import java.util.ArrayList;
+import java.util.List;
public class QianFanAssistant extends AbstractAIAssistant {
- public QianFanAssistant(ChatMemory chatMemory, AIAssistant.Service
aiServices) {
- super(chatMemory, aiServices);
+ private static final String BASE_URL = "https://qianfan.baidubce.com";
+
+ public QianFanAssistant(Object memoryId, ChatMemory chatMemory,
AIAssistant.Service aiServices) {
+ super(memoryId, chatMemory, aiServices);
}
@Override
@@ -47,48 +58,103 @@ public class QianFanAssistant extends AbstractAIAssistant {
public static class Builder extends AbstractAIAssistant.Builder {
- public AIAssistant build() {
- AIAssistant.Service aiService =
AiServices.builder(AIAssistant.Service.class)
- .chatModel(getChatModel())
- .streamingChatModel(getStreamingChatModel())
- .chatMemory(getChatMemory())
- .toolProvider(toolProvider)
- .systemMessageProvider(threadId -> {
- if (threadId != null) {
- return systemPrompt;
- }
- return null;
- })
- .build();
- return new QianFanAssistant(getChatMemory(), aiService);
- }
-
@Override
public ChatModel getChatModel() {
- String model = ValidationUtils.ensureNotNull(config.getModel(),
"model");
- String apiKey =
-
ValidationUtils.ensureNotNull(config.getCredentials().get("apiKey"), "apiKey");
- String secretKey =
-
ValidationUtils.ensureNotNull(config.getCredentials().get("secretKey"),
"secretKey");
- return QianfanChatModel.builder()
+ String model = config.getModel();
+ Assert.notNull(model, "model must not be null");
+ String apiKey = config.getCredentials().get("apiKey");
+ Assert.notNull(apiKey, "apiKey must not be null");
+
+ OpenAiApi openAiApi = OpenAiApi.builder()
+ .baseUrl(BASE_URL)
+ .completionsPath("/v2/chat/completions")
.apiKey(apiKey)
- .secretKey(secretKey)
- .modelName(model)
+ .build();
+ OpenAiChatOptions options =
OpenAiChatOptions.builder().model(model).build();
+ return OpenAiChatModel.builder()
+ .openAiApi(openAiApi)
+ .defaultOptions(options)
.build();
}
@Override
public StreamingChatModel getStreamingChatModel() {
- String model = ValidationUtils.ensureNotNull(config.getModel(),
"model");
- String apiKey =
-
ValidationUtils.ensureNotNull(config.getCredentials().get("apiKey"), "apiKey");
- String secretKey =
-
ValidationUtils.ensureNotNull(config.getCredentials().get("secretKey"),
"secretKey");
- return QianfanStreamingChatModel.builder()
- .apiKey(apiKey)
- .secretKey(secretKey)
- .modelName(model)
- .build();
+ return getChatModel();
+ }
+
+ public AIAssistant build() {
+ ChatModel chatModel = getChatModel();
+ StreamingChatModel streamingChatModel = getStreamingChatModel();
+ ChatMemory memory = getChatMemory();
+
+ AIAssistant.Service aiService = new AIAssistant.Service() {
+ @Override
+ public String chat(String userMessage) {
+ List<Message> messages = new ArrayList<>();
+ if (systemPrompt != null) {
+ messages.add(new SystemMessage(systemPrompt));
+ }
+ // Add conversation history
+ String convId = String.valueOf(id);
+ List<Message> history = memory.get(convId);
+ messages.addAll(history);
+ // Add new user message
+ UserMessage newUserMessage = new UserMessage(userMessage);
+ messages.add(newUserMessage);
+
+ Prompt prompt = new Prompt(messages);
+ String response =
+
chatModel.call(prompt).getResult().getOutput().getText();
+
+ // Save to memory
+ memory.add(
+ convId,
+ List.of(
+ newUserMessage,
+ new
org.springframework.ai.chat.messages.AssistantMessage(response)));
+
+ return response;
+ }
+
+ @Override
+ public Flux<String> streamChat(String userMessage) {
+ List<Message> messages = new ArrayList<>();
+ if (systemPrompt != null) {
+ messages.add(new SystemMessage(systemPrompt));
+ }
+ // Add conversation history
+ String convId = String.valueOf(id);
+ List<Message> history = memory.get(convId);
+ messages.addAll(history);
+ // Add new user message
+ UserMessage newUserMessage = new UserMessage(userMessage);
+ messages.add(newUserMessage);
+
+ Prompt prompt = new Prompt(messages);
+
+ StringBuilder responseBuilder = new StringBuilder();
+ return streamingChatModel.stream(prompt)
+ .map(chatResponse -> {
+ String content =
+
chatResponse.getResult().getOutput().getText();
+ if (content != null) {
+ responseBuilder.append(content);
+ }
+ return content;
+ })
+ .doOnComplete(() -> {
+ // Save to memory when streaming completes
+ memory.add(
+ convId,
+ List.of(
+ newUserMessage,
+ new
org.springframework.ai.chat.messages.AssistantMessage(
+
responseBuilder.toString())));
+ });
+ }
+ };
+
+ return new QianFanAssistant(id, memory, aiService);
}
}
}
diff --git
a/bigtop-manager-ai/src/test/java/assistant/GeneralAssistantFactoryTest.java
b/bigtop-manager-ai/src/test/java/assistant/GeneralAssistantFactoryTest.java
index 778c1ffe..e87d2c41 100644
--- a/bigtop-manager-ai/src/test/java/assistant/GeneralAssistantFactoryTest.java
+++ b/bigtop-manager-ai/src/test/java/assistant/GeneralAssistantFactoryTest.java
@@ -58,7 +58,6 @@ class GeneralAssistantFactoryTest {
when(mockBuilder.id(any())).thenReturn(mockBuilder);
when(mockBuilder.memoryStore(any())).thenReturn(mockBuilder);
when(mockBuilder.withConfig(any())).thenReturn(mockBuilder);
- when(mockBuilder.withToolProvider(any())).thenReturn(mockBuilder);
when(mockBuilder.withSystemPrompt(any())).thenReturn(mockBuilder);
when(mockBuilder.build()).thenReturn(mock(AIAssistant.class));
diff --git
a/bigtop-manager-ai/src/test/java/assistant/store/PersistentChatMemoryStoreTest.java
b/bigtop-manager-ai/src/test/java/assistant/store/PersistentChatMemoryStoreTest.java
index 242bfc53..deeeab64 100644
---
a/bigtop-manager-ai/src/test/java/assistant/store/PersistentChatMemoryStoreTest.java
+++
b/bigtop-manager-ai/src/test/java/assistant/store/PersistentChatMemoryStoreTest.java
@@ -27,22 +27,18 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
-
-import dev.langchain4j.data.message.AiMessage;
-import dev.langchain4j.data.message.ChatMessage;
-import dev.langchain4j.data.message.ChatMessageType;
-import dev.langchain4j.data.message.SystemMessage;
-import dev.langchain4j.data.message.UserMessage;
+import org.springframework.ai.chat.messages.AssistantMessage;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.ai.chat.messages.SystemMessage;
+import org.springframework.ai.chat.messages.UserMessage;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
@@ -54,12 +50,12 @@ class PersistentChatMemoryStoreTest {
@Mock
private ChatMessageDao chatMessageDao;
- @InjectMocks
private PersistentChatMemoryStore persistentChatMemoryStore;
@BeforeEach
void setUp() {
- persistentChatMemoryStore = new
PersistentChatMemoryStore(chatThreadDao, chatMessageDao);
+ Long threadId = 1L;
+ persistentChatMemoryStore = new PersistentChatMemoryStore(threadId,
chatThreadDao, chatMessageDao);
}
@Test
@@ -81,37 +77,34 @@ class PersistentChatMemoryStoreTest {
chatMessagePOS.add(messagePO3);
when(chatMessageDao.findAllByThreadId(threadId)).thenReturn(chatMessagePOS);
- List<ChatMessage> result =
persistentChatMemoryStore.getMessages(threadId);
+ List<Message> result =
persistentChatMemoryStore.findByConversationId(String.valueOf(threadId));
assertEquals(2, result.size());
- assertTrue(result.get(0) instanceof AiMessage);
- assertEquals("Hello from AI", ((AiMessage) result.get(0)).text());
+ assertTrue(result.get(0) instanceof AssistantMessage);
+ assertEquals("Hello from AI", ((AssistantMessage)
result.get(0)).getText());
}
@Test
- void testUpdateMessages() {
+ void testAddMessages() {
Long threadId = 1L;
ChatThreadPO chatThreadPO = new ChatThreadPO();
chatThreadPO.setUserId(123L);
when(chatThreadDao.findById(threadId)).thenReturn(chatThreadPO);
- List<ChatMessage> messages = new ArrayList<>();
+ List<Message> messages = new ArrayList<>();
messages.add(new SystemMessage("Hello System"));
- persistentChatMemoryStore.updateMessages(threadId, messages);
+ persistentChatMemoryStore.saveAll(String.valueOf(threadId), messages);
+ messages.clear();
messages.add(new UserMessage("Hello User"));
- persistentChatMemoryStore.updateMessages(threadId, messages);
- messages.add(new AiMessage("Hello AI"));
- persistentChatMemoryStore.updateMessages(threadId, messages);
-
- ChatMessage mockMessage = mock(ChatMessage.class);
-
when(mockMessage.type()).thenReturn(ChatMessageType.TOOL_EXECUTION_RESULT);
- messages.add(mockMessage);
- persistentChatMemoryStore.updateMessages(threadId, messages);
+ persistentChatMemoryStore.saveAll(String.valueOf(threadId), messages);
+ messages.clear();
+ messages.add(new AssistantMessage("Hello AI"));
+ persistentChatMemoryStore.saveAll(String.valueOf(threadId), messages);
}
@Test
- void testDeleteMessages() {
+ void testClearMessages() {
Long threadId = 1L;
List<ChatMessagePO> chatMessagePOS = new ArrayList<>();
@@ -121,7 +114,7 @@ class PersistentChatMemoryStoreTest {
when(chatMessageDao.findAllByThreadId(threadId)).thenReturn(chatMessagePOS);
- persistentChatMemoryStore.deleteMessages(threadId);
+
persistentChatMemoryStore.deleteByConversationId(String.valueOf(threadId));
Assertions.assertTrue(chatMessagePOS.get(0).getIsDeleted());
}
@@ -130,12 +123,16 @@ class PersistentChatMemoryStoreTest {
void testSystemMessage() {
Long threadId = 1L;
- when(chatMessageDao.findAllByThreadId(threadId)).thenReturn(new
ArrayList<>());
- persistentChatMemoryStore.updateMessages(threadId, List.of(new
SystemMessage("Hello from System")));
- List<ChatMessage> result =
persistentChatMemoryStore.getMessages(threadId);
+ ChatMessagePO systemMessagePO = new ChatMessagePO();
+ systemMessagePO.setSender("system");
+ systemMessagePO.setMessage("Hello from System");
+
+
when(chatMessageDao.findAllByThreadId(threadId)).thenReturn(List.of(systemMessagePO));
+
+ List<Message> result =
persistentChatMemoryStore.findByConversationId(String.valueOf(threadId));
assertEquals(1, result.size());
assertTrue(result.get(0) instanceof SystemMessage);
- assertEquals("Hello from System", ((SystemMessage)
result.get(0)).text());
+ assertEquals("Hello from System", ((SystemMessage)
result.get(0)).getText());
}
}
diff --git a/bigtop-manager-bom/pom.xml b/bigtop-manager-bom/pom.xml
index d701c4f0..878ae561 100644
--- a/bigtop-manager-bom/pom.xml
+++ b/bigtop-manager-bom/pom.xml
@@ -32,7 +32,7 @@
<properties>
<spring-ai.version>1.0.0-RC1</spring-ai.version>
- <spring-boot.version>3.1.1</spring-boot.version>
+ <spring-boot.version>3.2.0</spring-boot.version>
<springdoc.version>2.2.0</springdoc.version>
<freemarker.version>2.3.32</freemarker.version>
<common-lang3.version>3.14.0</common-lang3.version>
@@ -52,8 +52,8 @@
<micrometer.version>1.12.4</micrometer.version>
<jdbc.dm.version>8.1.2.192</jdbc.dm.version>
<sshd.version>2.15.0</sshd.version>
- <langchain4j-core.version>1.0.1</langchain4j-core.version>
- <langchain4j.version>1.0.1-beta6</langchain4j.version>
+ <langchain4j.version>1.0.1</langchain4j.version>
+ <jetbrains-annotations.version>24.0.1</jetbrains-annotations.version>
<mybatis-spring-boot-starter.version>3.0.3</mybatis-spring-boot-starter.version>
<pagehelper-spring-boot-starter.version>2.1.0</pagehelper-spring-boot-starter.version>
<victools.version>4.29.0</victools.version>
@@ -261,19 +261,23 @@
<version>${grpc-spring-boot.version}</version>
</dependency>
<dependency>
- <groupId>dev.langchain4j</groupId>
- <artifactId>langchain4j</artifactId>
- <version>${langchain4j-core.version}</version>
+ <groupId>org.springframework.ai</groupId>
+ <artifactId>spring-ai-bom</artifactId>
+ <version>${spring-ai.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
</dependency>
+
<dependency>
- <groupId>dev.langchain4j</groupId>
- <artifactId>langchain4j-open-ai</artifactId>
- <version>${langchain4j-core.version}</version>
+ <groupId>org.springframework.ai</groupId>
+ <artifactId>spring-ai-openai</artifactId>
+ <version>${spring-ai.version}</version>
</dependency>
+
<dependency>
- <groupId>dev.langchain4j</groupId>
- <artifactId>langchain4j-community-qianfan</artifactId>
- <version>${langchain4j.version}</version>
+ <groupId>org.springframework.ai</groupId>
+ <artifactId>spring-ai-deepseek</artifactId>
+ <version>${spring-ai.version}</version>
</dependency>
<dependency>
@@ -282,22 +286,23 @@
<version>${spring-ai.version}</version>
</dependency>
+ <!-- Keep langchain4j for server module tool support -->
<dependency>
- <groupId>com.github.victools</groupId>
- <artifactId>jsonschema-module-jackson</artifactId>
- <version>${victools.version}</version>
+ <groupId>dev.langchain4j</groupId>
+ <artifactId>langchain4j</artifactId>
+ <version>${langchain4j.version}</version>
</dependency>
<dependency>
- <groupId>dev.langchain4j</groupId>
- <artifactId>langchain4j-community-dashscope</artifactId>
- <version>${langchain4j.version}</version>
+ <groupId>org.jetbrains</groupId>
+ <artifactId>annotations</artifactId>
+ <version>${jetbrains-annotations.version}</version>
</dependency>
<dependency>
- <groupId>dev.langchain4j</groupId>
- <artifactId>langchain4j-reactor</artifactId>
- <version>${langchain4j.version}</version>
+ <groupId>com.github.victools</groupId>
+ <artifactId>jsonschema-module-jackson</artifactId>
+ <version>${victools.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
diff --git a/bigtop-manager-server/pom.xml b/bigtop-manager-server/pom.xml
index 7d454574..e6d3ff38 100644
--- a/bigtop-manager-server/pom.xml
+++ b/bigtop-manager-server/pom.xml
@@ -63,6 +63,14 @@
<groupId>org.apache.bigtop</groupId>
<artifactId>bigtop-manager-ai</artifactId>
</dependency>
+ <dependency>
+ <groupId>dev.langchain4j</groupId>
+ <artifactId>langchain4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains</groupId>
+ <artifactId>annotations</artifactId>
+ </dependency>
<dependency>
<groupId>com.github.victools</groupId>
<artifactId>jsonschema-module-jackson</artifactId>
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/ChatbotController.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/ChatbotController.java
index 2206970e..c6b835d5 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/ChatbotController.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/ChatbotController.java
@@ -62,7 +62,7 @@ public class ChatbotController {
@Operation(summary = "update thread", description = "Update a chat thread")
@PutMapping("/threads/{threadId}")
public ResponseEntity<ChatThreadVO> updateChatThread(
- @PathVariable Long threadId, @RequestBody ChatbotThreadReq
chatbotThreadReq) {
+ @PathVariable(name = "threadId") Long threadId, @RequestBody
ChatbotThreadReq chatbotThreadReq) {
ChatThreadDTO chatThreadDTO =
ChatThreadConverter.INSTANCE.fromReq2DTO(chatbotThreadReq);
chatThreadDTO.setId(threadId);
return
ResponseEntity.success(chatbotService.updateChatThread(chatThreadDTO));
@@ -70,13 +70,13 @@ public class ChatbotController {
@Operation(summary = "delete thread", description = "Delete a chat thread")
@DeleteMapping("/threads/{threadId}")
- public ResponseEntity<Boolean> deleteChatThread(@PathVariable Long
threadId) {
+ public ResponseEntity<Boolean> deleteChatThread(@PathVariable(name =
"threadId") Long threadId) {
return
ResponseEntity.success(chatbotService.deleteChatThread(threadId));
}
@Operation(summary = "get thread", description = "Get a chat thread")
@GetMapping("/threads/{threadId}")
- public ResponseEntity<ChatThreadVO> getChatThread(@PathVariable Long
threadId) {
+ public ResponseEntity<ChatThreadVO> getChatThread(@PathVariable(name =
"threadId") Long threadId) {
return ResponseEntity.success(chatbotService.getChatThread(threadId));
}
@@ -88,7 +88,7 @@ public class ChatbotController {
@Operation(summary = "talk", description = "Talk with Chatbot")
@PostMapping("/threads/{threadId}/talk")
- public SseEmitter talk(@PathVariable Long threadId, @RequestBody
ChatbotMessageReq messageReq) {
+ public SseEmitter talk(@PathVariable(name = "threadId") Long threadId,
@RequestBody ChatbotMessageReq messageReq) {
ChatbotCommand command =
ChatbotCommand.getCommandFromMessage(messageReq.getMessage());
if (command != null) {
messageReq.setMessage(
@@ -99,7 +99,7 @@ public class ChatbotController {
@Operation(summary = "history", description = "Get chat records")
@GetMapping("/threads/{threadId}/history")
- public ResponseEntity<List<ChatMessageVO>> history(@PathVariable Long
threadId) {
+ public ResponseEntity<List<ChatMessageVO>> history(@PathVariable(name =
"threadId") Long threadId) {
return ResponseEntity.success(chatbotService.history(threadId));
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/LLMConfigController.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/LLMConfigController.java
index 2b27cbb6..141d5341 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/LLMConfigController.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/LLMConfigController.java
@@ -58,13 +58,14 @@ public class LLMConfigController {
@Operation(summary = "get platform", description = "Get platform")
@GetMapping("/platforms/{id}")
- public ResponseEntity<PlatformVO> getPlatform(@PathVariable Long id) {
+ public ResponseEntity<PlatformVO> getPlatform(@PathVariable(name = "id")
Long id) {
return ResponseEntity.success(llmConfigService.getPlatform(id));
}
@Operation(summary = "platform credentials", description = "Get platform
auth credentials")
@GetMapping("/platforms/{platformId}/auth-credentials")
- public ResponseEntity<List<PlatformAuthCredentialVO>>
platformsAuthCredential(@PathVariable Long platformId) {
+ public ResponseEntity<List<PlatformAuthCredentialVO>>
platformsAuthCredential(
+ @PathVariable(name = "platformId") Long platformId) {
return
ResponseEntity.success(llmConfigService.platformsAuthCredentials(platformId));
}
@@ -91,7 +92,7 @@ public class LLMConfigController {
@Operation(summary = "update auth platform", description = "Update
authorized platform")
@PutMapping("/auth-platforms/{authId}")
public ResponseEntity<AuthPlatformVO> updateAuthorizedPlatform(
- @PathVariable Long authId, @RequestBody AuthPlatformReq
authPlatformReq) {
+ @PathVariable(name = "authId") Long authId, @RequestBody
AuthPlatformReq authPlatformReq) {
AuthPlatformDTO authPlatformDTO =
AuthPlatformConverter.INSTANCE.fromReq2DTO(authPlatformReq);
authPlatformDTO.setId(authId);
return
ResponseEntity.success(llmConfigService.updateAuthorizedPlatform(authPlatformDTO));
@@ -99,25 +100,25 @@ public class LLMConfigController {
@Operation(summary = "get auth platform", description = "Get a authorized
platform")
@GetMapping("/auth-platforms/{authId}")
- public ResponseEntity<AuthPlatformVO> getAuthorizedPlatform(@PathVariable
Long authId) {
+ public ResponseEntity<AuthPlatformVO>
getAuthorizedPlatform(@PathVariable(name = "authId") Long authId) {
return
ResponseEntity.success(llmConfigService.getAuthorizedPlatform(authId));
}
@Operation(summary = "delete auth platform", description = "Delete a
authorized platform")
@DeleteMapping("/auth-platforms/{authId}")
- public ResponseEntity<Boolean> deleteAuthorizedPlatform(@PathVariable Long
authId) {
+ public ResponseEntity<Boolean> deleteAuthorizedPlatform(@PathVariable(name
= "authId") Long authId) {
return
ResponseEntity.success(llmConfigService.deleteAuthorizedPlatform(authId));
}
@Operation(summary = "activate auth platform", description = "Activate
authorized platform")
@PostMapping("/auth-platforms/{authId}/activate")
- public ResponseEntity<Boolean> activateAuthorizedPlatform(@PathVariable
Long authId) {
+ public ResponseEntity<Boolean>
activateAuthorizedPlatform(@PathVariable(name = "authId") Long authId) {
return
ResponseEntity.success(llmConfigService.activateAuthorizedPlatform(authId));
}
@Operation(summary = "deactivate auth platform", description = "Deactivate
authorized platform")
@PostMapping("/auth-platforms/{authId}/deactivate")
- public ResponseEntity<Boolean> deactivateAuthorizedPlatform(@PathVariable
Long authId) {
+ public ResponseEntity<Boolean>
deactivateAuthorizedPlatform(@PathVariable(name = "authId") Long authId) {
return
ResponseEntity.success(llmConfigService.deactivateAuthorizedPlatform(authId));
}
}
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/LoginController.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/LoginController.java
index 08be7024..0627bb58 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/LoginController.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/LoginController.java
@@ -36,6 +36,7 @@ import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
@@ -53,14 +54,14 @@ public class LoginController {
@Operation(summary = "salt", description = "Generate salt")
@GetMapping(value = "/salt")
- public ResponseEntity<String> salt(String username) {
+ public ResponseEntity<String> salt(@RequestParam("username") String
username) {
String salt = Pbkdf2Utils.generateSalt(username);
return ResponseEntity.success(salt);
}
@Operation(summary = "nonce", description = "Generate nonce")
@GetMapping(value = "/nonce")
- public ResponseEntity<String> nonce(String username) {
+ public ResponseEntity<String> nonce(@RequestParam("username") String
username) {
String nonce = PasswordUtils.randomString(16);
String cacheKey = username + ":" + nonce;
CacheUtils.setCache(Caches.CACHE_NONCE, cacheKey, nonce,
Caches.NONCE_EXPIRE_TIME_MINUTES, TimeUnit.MINUTES);
diff --git
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/mcp/converter/JsonToolCallResultConverter.java
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/mcp/converter/JsonToolCallResultConverter.java
index 3632001e..6cf6bce9 100644
---
a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/mcp/converter/JsonToolCallResultConverter.java
+++
b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/mcp/converter/JsonToolCallResultConverter.java
@@ -20,7 +20,6 @@ package org.apache.bigtop.manager.server.mcp.converter;
import org.apache.bigtop.manager.common.utils.JsonUtils;
-import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.tool.execution.ToolCallResultConverter;
@@ -43,7 +42,7 @@ public class JsonToolCallResultConverter implements
ToolCallResultConverter {
private static final Logger logger =
LoggerFactory.getLogger(JsonToolCallResultConverter.class);
- @NotNull @Override
+ @Override
public String convert(@Nullable Object result, @Nullable Type returnType) {
if (returnType == Void.TYPE) {
logger.debug("The tool has no return type. Converting to
conventional response.");
diff --git a/bigtop-manager-server/src/main/resources/ddl/MySQL-DDL-CREATE.sql
b/bigtop-manager-server/src/main/resources/ddl/MySQL-DDL-CREATE.sql
index aeab6931..773dd94f 100644
--- a/bigtop-manager-server/src/main/resources/ddl/MySQL-DDL-CREATE.sql
+++ b/bigtop-manager-server/src/main/resources/ddl/MySQL-DDL-CREATE.sql
@@ -355,8 +355,8 @@ VALUES
INSERT INTO llm_platform (credential, name, support_models)
VALUES
('{"apiKey": "API Key"}', 'OpenAI',
'gpt-3.5-turbo,gpt-4,gpt-4o,gpt-3.5-turbo-16k,gpt-4-turbo-preview,gpt-4-32k,gpt-4o-mini'),
-('{"apiKey": "API Key"}', 'DashScope',
'qwen-1.8b-chat,qwen-max,qwen-plus,qwen-turbo,qwen3-235b-a22b,qwen3-30b-a3b,qwen-plus-latest,qwen-turbo-latest'),
-('{"apiKey": "API Key", "secretKey": "Secret Key"}',
'QianFan','Yi-34B-Chat,ERNIE-4.0-8K,ERNIE-3.5-128K,ERNIE-Speed-8K,Llama-2-7B-Chat,Fuyu-8B'),
+('{"apiKey": "API Key"}', 'DashScope',
'qwen-max,qwen-plus,qwen-turbo,qwen3-235b-a22b,qwen3-30b-a3b,qwen-plus-latest,qwen-turbo-latest'),
+('{"apiKey": "API Key"}', 'QianFan','ernie-speed-8k'),
('{"apiKey": "API Key"}','DeepSeek','deepseek-chat,deepseek-reasoner');
UPDATE `llm_platform`
@@ -368,7 +368,7 @@ SET `desc` = 'Get your API Key in
https://bailian.console.aliyun.com/?apiKey=1#/
WHERE `name` = 'DashScope';
UPDATE `llm_platform`
-SET `desc` = 'Get API Key and Secret Key in
https://console.bce.baidu.com/qianfan/ais/console/applicationConsole/application/v1'
+SET `desc` = 'Get API Key and Secret Key in
https://console.bce.baidu.com/iam/#/iam/apikey/list'
WHERE `name` = 'QianFan';
UPDATE `llm_platform`
diff --git
a/bigtop-manager-server/src/main/resources/ddl/PostgreSQL-DDL-CREATE.sql
b/bigtop-manager-server/src/main/resources/ddl/PostgreSQL-DDL-CREATE.sql
index 35feb63f..eb34c0ba 100644
--- a/bigtop-manager-server/src/main/resources/ddl/PostgreSQL-DDL-CREATE.sql
+++ b/bigtop-manager-server/src/main/resources/ddl/PostgreSQL-DDL-CREATE.sql
@@ -366,8 +366,8 @@ VALUES
INSERT INTO llm_platform (credential, name, support_models)
VALUES
('{"apiKey": "API
Key"}','OpenAI','gpt-3.5-turbo,gpt-4,gpt-4o,gpt-3.5-turbo-16k,gpt-4-turbo-preview,gpt-4-32k,gpt-4o-mini'),
-('{"apiKey": "API
Key"}','DashScope','qwen-1.8b-chat,qwen-max,qwen-plus,qwen-turbo,qwen3-235b-a22b,qwen3-30b-a3b,qwen-plus-latest,qwen-turbo-latest'),
-('{"apiKey": "API Key", "secretKey": "Secret
Key"}','QianFan','Yi-34B-Chat,ERNIE-4.0-8K,ERNIE-3.5-128K,ERNIE-Speed-8K,Llama-2-7B-Chat,Fuyu-8B'),
+('{"apiKey": "API
Key"}','DashScope','qwen-max,qwen-plus,qwen-turbo,qwen3-235b-a22b,qwen3-30b-a3b,qwen-plus-latest,qwen-turbo-latest'),
+('{"apiKey": "API Key"}', 'QianFan','ernie-speed-8k'),
('{"apiKey": "API Key"}','DeepSeek','deepseek-chat,deepseek-reasoner');
UPDATE llm_platform
@@ -379,7 +379,7 @@ SET "desc" = 'Get your API Key in
https://bailian.console.aliyun.com/?apiKey=1#/
WHERE "name" = 'DashScope';
UPDATE llm_platform
-SET "desc" = 'Get API Key and Secret Key in
https://console.bce.baidu.com/qianfan/ais/console/applicationConsole/application/v1'
+SET "desc" = 'Get API Key and Secret Key in
https://console.bce.baidu.com/iam/#/iam/apikey/list'
WHERE "name" = 'QianFan';
UPDATE llm_platform