+
org.springframework.ai
spring-ai-bom
- 1.0.1
+ ${spring-ai.version}
pom
import
@@ -66,6 +71,7 @@
+
com.alibaba.cloud.ai
spring-ai-alibaba-starter-dashscope
@@ -79,7 +85,13 @@
-
+
org.springframework.ai
spring-ai-starter-mcp-client
@@ -91,7 +103,7 @@
-
+
io.modelcontextprotocol.sdk
mcp
@@ -102,7 +114,7 @@
cn.hutool
hutool-all
- 5.8.37
+ 5.8.41
@@ -114,28 +126,24 @@
com.github.xiaoymin
knife4j-openapi3-jakarta-spring-boot-starter
- 4.4.0
+ 4.5.0
-
+
+
- com.github.victools
- jsonschema-generator
- 4.38.0
-
-
-
- com.esotericsoftware
- kryo
- 5.6.2
+ com.knuddels
+ jtokkit
+ 1.1.0
org.springframework.ai
spring-ai-markdown-document-reader
+
org.projectlombok
lombok
- 1.18.36
true
@@ -172,31 +180,31 @@
io.jsonwebtoken
jjwt-api
- 0.12.6
+ 0.12.7
io.jsonwebtoken
jjwt-impl
- 0.12.6
+ 0.12.7
runtime
io.jsonwebtoken
jjwt-jackson
- 0.12.6
+ 0.12.7
runtime
-
-
- org.springframework.security
- spring-security-oauth2-client
-
+
com.baomidou
mybatis-plus-spring-boot3-starter
- 3.5.12
+ 3.5.14
@@ -238,7 +246,8 @@
org.projectlombok
lombok
- 1.18.36
+
+ ${lombok.version}
diff --git a/src/main/java/com/wok/supportbot/SupportBotApplication.java b/src/main/java/com/wok/supportbot/SupportBotApplication.java
index 78caa3b..57aad0c 100644
--- a/src/main/java/com/wok/supportbot/SupportBotApplication.java
+++ b/src/main/java/com/wok/supportbot/SupportBotApplication.java
@@ -8,8 +8,9 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* 主启动类
- * spring-security-oauth2-client 依赖已通过 pom.xml 补充,
- * 确保 ToolCallingAutoConfiguration 不会抛出 ClassNotFoundException
+ *
+ * ChatModel / EmbeddingModel / VectorStore 均由项目内工厂手动构建(见 ChatModelFactory、
+ * EmbeddingModelFactory、PgVectorStoreConfig),不使用 Spring AI 的自动配置。
*/
@SpringBootApplication
@EnableScheduling
diff --git a/src/main/java/com/wok/supportbot/chatmemory/FileBasedChatMemory.java b/src/main/java/com/wok/supportbot/chatmemory/FileBasedChatMemory.java
deleted file mode 100644
index 8fefb82..0000000
--- a/src/main/java/com/wok/supportbot/chatmemory/FileBasedChatMemory.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.wok.supportbot.chatmemory;
-
-import com.esotericsoftware.kryo.Kryo;
-import com.esotericsoftware.kryo.io.Input;
-import com.esotericsoftware.kryo.io.Output;
-import org.objenesis.strategy.StdInstantiatorStrategy;
-import org.springframework.ai.chat.memory.ChatMemory;
-import org.springframework.ai.chat.messages.Message;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 基于文件持久化的对话记忆
- */
-public class FileBasedChatMemory implements ChatMemory {
-
- private final String BASE_DIR;
- private static final Kryo kryo = new Kryo();
-
- static {
- kryo.setRegistrationRequired(false);
- // 设置实例化策略
- kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
- }
-
- // 构造对象时,指定文件保存目录
- public FileBasedChatMemory(String dir) {
- this.BASE_DIR = dir;
- File baseDir = new File(dir);
- if (!baseDir.exists()) {
- baseDir.mkdirs();
- }
- }
-
- @Override
- public void add(String conversationId, List messages) {
- List conversationMessages = getOrCreateConversation(conversationId);
- conversationMessages.addAll(messages);
- saveConversation(conversationId, conversationMessages);
- }
-
- @Override
- public List get(String conversationId) {
- return getOrCreateConversation(conversationId);
- }
-
- @Override
- public void clear(String conversationId) {
- File file = getConversationFile(conversationId);
- if (file.exists()) {
- file.delete();
- }
- }
-
- private List getOrCreateConversation(String conversationId) {
- File file = getConversationFile(conversationId);
- List messages = new ArrayList<>();
- if (file.exists()) {
- try (Input input = new Input(new FileInputStream(file))) {
- messages = kryo.readObject(input, ArrayList.class);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return messages;
- }
-
- private void saveConversation(String conversationId, List messages) {
- File file = getConversationFile(conversationId);
- try (Output output = new Output(new FileOutputStream(file))) {
- kryo.writeObject(output, messages);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- private File getConversationFile(String conversationId) {
- return new File(BASE_DIR, conversationId + ".kryo");
- }
-}
diff --git a/src/main/java/com/wok/supportbot/config/ChatModelFactory.java b/src/main/java/com/wok/supportbot/config/ChatModelFactory.java
index 15438cc..03185a4 100644
--- a/src/main/java/com/wok/supportbot/config/ChatModelFactory.java
+++ b/src/main/java/com/wok/supportbot/config/ChatModelFactory.java
@@ -157,7 +157,7 @@ public class ChatModelFactory {
}
DashScopeApi api = apiBuilder.build();
- DashScopeChatOptions.DashscopeChatOptionsBuilder optionsBuilder = DashScopeChatOptions.builder()
+ DashScopeChatOptions.DashScopeChatOptionsBuilder optionsBuilder = DashScopeChatOptions.builder()
.withModel(config.getModelName());
if (config.getTemperature() != null) {
optionsBuilder.withTemperature(config.getTemperature());
@@ -352,7 +352,7 @@ public class ChatModelFactory {
/**
* 从 extraConfig 中读取高级参数并设置到 DashScopeChatOptions.Builder
*/
- private void applyDashScopeExtraConfig(AiModelConfig config, DashScopeChatOptions.DashscopeChatOptionsBuilder optionsBuilder) {
+ private void applyDashScopeExtraConfig(AiModelConfig config, DashScopeChatOptions.DashScopeChatOptionsBuilder optionsBuilder) {
Map extra = config.getExtraConfig();
if (extra == null || extra.isEmpty()) return;
diff --git a/src/main/java/com/wok/supportbot/converter/MessageConverter.java b/src/main/java/com/wok/supportbot/converter/MessageConverter.java
index 45b6c73..3d2972c 100644
--- a/src/main/java/com/wok/supportbot/converter/MessageConverter.java
+++ b/src/main/java/com/wok/supportbot/converter/MessageConverter.java
@@ -110,12 +110,21 @@ public class MessageConverter {
}
case ASSISTANT -> {
List toolCalls = extractToolCalls(cleanMetadata);
- yield new AssistantMessage(text, cleanMetadata, toolCalls);
+ // Spring AI 1.1.x 起 AssistantMessage 带 metadata 的构造器为 protected,改用标准 builder
+ yield AssistantMessage.builder()
+ .content(text)
+ .properties(cleanMetadata)
+ .toolCalls(toolCalls)
+ .build();
}
case SYSTEM -> new SystemMessage(text);
case TOOL -> {
List responses = extractToolResponses(cleanMetadata);
- yield new ToolResponseMessage(responses, cleanMetadata);
+ // Spring AI 1.1.x 起 ToolResponseMessage 构造器为 protected,改用标准 builder
+ yield ToolResponseMessage.builder()
+ .responses(responses)
+ .metadata(cleanMetadata)
+ .build();
}
};
}