From 9cd825aea53fa5ba0cda1485464af027e27f0ce4 Mon Sep 17 00:00:00 2001
From: admin <cgf12138@163.com>
Date: 星期五, 06 六月 2025 08:57:36 +0800
Subject: [PATCH] 0606
---
aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiBotController.java | 165 ++++++++++++++++++++++++++++--------------------------
1 files changed, 86 insertions(+), 79 deletions(-)
diff --git a/aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiBotController.java b/aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiBotController.java
index c66f69e..555afa2 100644
--- a/aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiBotController.java
+++ b/aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiBotController.java
@@ -2,8 +2,6 @@
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.json.JSONArray;
-import cn.hutool.json.JSONObject;
import com.agentsflex.core.llm.ChatContext;
import com.agentsflex.core.llm.Llm;
import com.agentsflex.core.llm.StreamResponseListener;
@@ -17,32 +15,28 @@
import com.agentsflex.core.prompt.ToolPrompt;
import com.agentsflex.core.util.CollectionUtil;
import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.jfinal.template.stat.ast.Break;
-import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.table.TableInfo;
import com.mybatisflex.core.table.TableInfoFactory;
-import io.milvus.param.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+import tech.aiflowy.ai.config.DifyStreamClient;
import tech.aiflowy.ai.entity.*;
import tech.aiflowy.ai.mapper.AiBotConversationMessageMapper;
import tech.aiflowy.ai.service.*;
-import tech.aiflowy.ai.vo.ModelConfig;
import tech.aiflowy.common.ai.ChatManager;
import tech.aiflowy.common.ai.MySseEmitter;
import tech.aiflowy.common.domain.Result;
@@ -57,14 +51,8 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
import java.math.BigInteger;
-import java.time.Duration;
import java.util.*;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
/**
* 鎺у埗灞傘��
@@ -149,6 +137,7 @@
@Autowired
private ObjectMapper objectMapper;
+
@PostMapping("chat")
public SseEmitter chat(@JsonBody(value = "prompt", required = true) String prompt,
@JsonBody(value = "botId", required = true) BigInteger botId,
@@ -160,80 +149,55 @@
if (aiBot == null) {
return ChatManager.getInstance().sseEmitterForContent("鏈哄櫒浜轰笉瀛樺湪");
}
+ Map<String, Object> llmOptions = aiBot.getLlmOptions();
+ String systemPrompt = llmOptions != null ? (String) llmOptions.get("systemPrompt") : null;
if (StringUtil.hasText(aiBot.getModelAPI())){
- // 浣跨敤Dify妯″瀷鐨勯�昏緫
- String apiUrl = aiBot.getModelAPI();
- String bearerToken = aiBot.getModelKey();
+ String apiUrl = aiBot.getModelAPI(); // 鏇挎崲涓哄疄闄匒PI URL
+ String apiKey = aiBot.getModelKEY(); // 鏇挎崲涓哄疄闄匒PI Key
- // 鏋勫缓璇锋眰JSON
- JSONObject jsonBody = new JSONObject();
- jsonBody.put("inputs", new JSONObject());
- jsonBody.put("query", prompt);
- jsonBody.put("response_mode", "blocking");
- jsonBody.put("conversation_id", "");
- jsonBody.put("user", userId.toString());
+ DifyStreamClient client = new DifyStreamClient(apiUrl, apiKey, aiBotMessageService);
+ AiBotMessageMemory memory = new AiBotMessageMemory(botId, SaTokenUtil.getLoginAccount().getId(),
+ sessionId, isExternalMsg, aiBotMessageService, aiBotConversationMessageMapper,
+ aiBotConversationMessageService);
- JSONArray files = new JSONArray();
- JSONObject fileObj = new JSONObject();
- fileObj.put("type", "");
- fileObj.put("transfer_method", "");
- fileObj.put("url", "");
- files.put(fileObj);
- jsonBody.put("files", files);
+ final HistoriesPrompt historiesPrompt = new HistoriesPrompt();
+ if (systemPrompt != null) {
+ historiesPrompt.setSystemMessage(SystemMessage.of(systemPrompt));
+ }
- // 鍙戦�丠TTP璇锋眰
- HttpClient client = HttpClient.newBuilder()
- .connectTimeout(Duration.ofSeconds(30))
- .build();
+ historiesPrompt.setMemory(memory);
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(apiUrl))
- .header("Content-Type", "application/json")
- .header("Authorization", "Bearer " + bearerToken)
- .POST(HttpRequest.BodyPublishers.ofString(jsonBody.toString()))
- .build();
+ HumanMessage humanMessage = new HumanMessage(prompt);
- HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ // 娣诲姞鎻掍欢鐩稿叧鐨刦unction calling
+ appendPluginToolFunction(botId, humanMessage);
- // 澶勭悊鎴愬姛鍝嶅簲
- JSONObject responseJson = new JSONObject(response.body());
+ //娣诲姞宸ヤ綔娴佺浉鍏崇殑 Function Calling
+ appendWorkflowFunctions(botId, humanMessage);
- // 淇濆瓨鐢ㄦ埛娑堟伅鍒板巻鍙茶褰�
- ChatHistory userChat = new ChatHistory();
- userChat.setContent(prompt);
- userChat.setRole("user");
- userChat.setUserId(userId);
- userChat.setBotId(botId.intValue());
- userChat.setModel("dify");
- userChat.setChatId(responseJson.optString("conversation_id", ""));
- Integer userHistoryId = chatHistoryService.saveChatHistory(userChat);
+ //娣诲姞鐭ヨ瘑搴撶浉鍏崇殑 Function Calling
+ appendKnowledgeFunctions(botId, humanMessage);
- // 淇濆瓨AI鍥炲鍒板巻鍙茶褰�
- ChatHistory assistantChat = new ChatHistory();
- assistantChat.setContent(responseJson.getString("answer"));
- assistantChat.setRole("assistant");
- assistantChat.setUserId(userId);
- assistantChat.setBotId(botId.intValue());
- assistantChat.setModel("dify");
- assistantChat.setChatId(userChat.getChatId());
- Integer assistantHistoryId = chatHistoryService.saveChatHistory(assistantChat);
+ historiesPrompt.addMessage(humanMessage);
- // 鏋勫缓鍝嶅簲鏁版嵁
- int count = chatHistoryService.getChatHistoryCount(userId, botId.intValue());
- JSONObject result = new JSONObject();
- result.put("Count", count);
- result.put("Data", responseJson.getString("answer"));
- result.put("UserId", userHistoryId);
- result.put("AssistantId", assistantHistoryId);
- // 鍙戦�丼SE鍝嶅簲
- emitter.send(SseEmitter.event()
- .name("message")
- .data(result.toString()));
- emitter.complete();
- }else{
- Map<String, Object> llmOptions = aiBot.getLlmOptions();
- String systemPrompt = llmOptions != null ? (String) llmOptions.get("systemPrompt") : null;
+ final Boolean[] needClose = {true};
+
+ ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+
+
+ MySseEmitter emitter = new MySseEmitter(1000L * 60 * 2); // 2鍒嗛挓瓒呮椂
+
+ try {
+ String userId = SaTokenUtil.getLoginAccount().getId() + "";
+ client.chatStream(prompt, userId, emitter, sessionId, botId);
+ } catch (Exception e) {
+ emitter.completeWithError(e);
+ }
+ System.out.println(emitter.toString());
+ return emitter;
+ }
+ else{
AiLlm aiLlm = aiLlmService.getById(aiBot.getLlmId());
if (aiLlm == null) {
@@ -290,6 +254,7 @@
if (response.getMessage() != null) {
String content = response.getMessage().getContent();
if (StringUtil.hasText(content)) {
+ System.out.println(response);
emitter.send(JSON.toJSONString(response.getMessage()));
}
}
@@ -315,10 +280,52 @@
}
});
+ System.out.println(emitter.toString());
return emitter;
}
}
+
+ public Result save(@RequestBody String jsonStr) {
+ // 瑙f瀽JSON
+ JSONObject json = JSONObject.parseObject(jsonStr);
+
+ // 鍚堝苟鎵�鏈塻econdMenuId*瀛楁
+ List<Integer> menuIds = new ArrayList<>();
+ for (String key : json.keySet()) {
+ if (key.startsWith("secondMenuId")) {
+ Object value = json.get(key);
+ if (value instanceof Integer) {
+ menuIds.add((Integer) value);
+ }
+ }
+ }
+
+ // 淇濈暀绗竴涓狪D锛堟牴鎹渶瑕佽皟鏁达級
+ if (!menuIds.isEmpty()) {
+ json.put("secondMenuId", menuIds.get(0));
+ }
+
+ // 杞崲涓哄疄浣撶被
+ AiBot entity = json.toJavaObject(AiBot.class);
+
+ // 鍚庣画澶勭悊淇濇寔涓嶅彉
+ Result result = onSaveOrUpdateBefore(entity, true);
+ if (result != null) return result;
+
+ if (entity == null) {
+ throw new NullPointerException("entity is null");
+ }
+ LoginAccount loginAccount = SaTokenUtil.getLoginAccount();
+ commonFiled(entity,loginAccount.getId(),loginAccount.getTenantId(),loginAccount.getDeptId());
+ boolean success = service.save(entity);
+ onSaveOrUpdateAfter(entity, true);
+ TableInfo tableInfo = TableInfoFactory.ofEntityClass(entity.getClass());
+ Object[] pkArgs = tableInfo.buildPkSqlArgs(entity);
+ return Result.create(success).set("id", pkArgs);
+ }
+
+
/**
* 澶栭儴鐢ㄦ埛璋冪敤鏅鸿兘浣撹繘琛屽璇�
@@ -641,4 +648,4 @@
}
-}
+}
\ No newline at end of file
--
Gitblit v1.8.0