diff --git a/pom.xml b/pom.xml index ec46a77..9cd47c0 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 3.4.4 + 3.5.8 com.cdw @@ -14,7 +14,10 @@ 智能客服 17 - 1.0.0.4 + + 1.1.2 + + 1.1.2.2 false @@ -44,10 +47,12 @@ + 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(); } }; }