From 4eb46966002c6ca24cbb8cc8b519a05610e81649 Mon Sep 17 00:00:00 2001
From: admin <cgf12138@163.com>
Date: 星期一, 09 六月 2025 11:17:24 +0800
Subject: [PATCH] 0606
---
aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiBotController.java | 241 +++++++++++++++++++++++++++++++++++------------
1 files changed, 178 insertions(+), 63 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 60af52c..ed66287 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
@@ -15,22 +15,27 @@
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.jfinal.template.stat.ast.Break;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonObject;
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.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.*;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+import tech.aiflowy.ai.config.DifyStreamClient;
+import tech.aiflowy.ai.config.FileReference;
import tech.aiflowy.ai.entity.*;
import tech.aiflowy.ai.mapper.AiBotConversationMessageMapper;
import tech.aiflowy.ai.service.*;
@@ -48,12 +53,9 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.io.File;
import java.math.BigInteger;
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;
/**
* 鎺у埗灞傘��
@@ -77,6 +79,8 @@
private AiBotConversationMessageMapper aiBotConversationMessageMapper;
private static final Logger logger = LoggerFactory.getLogger(AiBotController.class);
+ @Autowired
+ private RestTemplate restTemplate;
public AiBotController(AiBotService service, AiLlmService aiLlmService, AiBotWorkflowService aiBotWorkflowService, AiBotKnowledgeService aiBotKnowledgeService, AiBotMessageService aiBotMessageService) {
super(service);
@@ -132,31 +136,66 @@
* @param response
* @return
*/
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+// @PostMapping("chat")
+// public SseEmitter chat2(@JsonBody(value = "prompt", required = true) String prompt,
+// @JsonBody(value = "botId", required = true) BigInteger botId,
+// @JsonBody(value = "sessionId", required = true) String sessionId,
+// @JsonBody(value = "isExternalMsg") int isExternalMsg,
+// @JsonBody("file") String file,//涓婁紶鏂囦欢
+// HttpServletResponse response){
+// File file =
+// }
+
@PostMapping("chat")
public SseEmitter chat(@JsonBody(value = "prompt", required = true) String prompt,
@JsonBody(value = "botId", required = true) BigInteger botId,
@JsonBody(value = "sessionId", required = true) String sessionId,
@JsonBody(value = "isExternalMsg") int isExternalMsg,
+ @JsonBody(value = "file") String file,//涓婁紶鏂囦欢
HttpServletResponse response) {
response.setContentType("text/event-stream");
AiBot aiBot = service.getById(botId);
if (aiBot == null) {
return ChatManager.getInstance().sseEmitterForContent("鏈哄櫒浜轰笉瀛樺湪");
}
- if (StringUtil.hasText(aiBot.getApiEndpoint())){
- // 鎯呭喌1锛歛iBot鑷甫澶фā鍨嬩俊鎭�
- try {
- // 浠巃iBot鏋勫缓鑷畾涔塋LM瀹炵幇
- Llm llm = null;
- if (llm == null) {
- return ChatManager.getInstance().sseEmitterForContent("LLM鑾峰彇涓虹┖");
- }
+ Map<String, Object> llmOptions = aiBot.getLlmOptions();
+ String systemPrompt = llmOptions != null ? (String) llmOptions.get("systemPrompt") : null;
+
+ if (StringUtil.hasText(aiBot.getModelAPI())){
+ if (aiBot.getBotTypeId() == 2) {
+
+ String apiUrl = aiBot.getModelAPI()+"/workflows/run"; // 鏇挎崲涓哄疄闄匒PI URL
+ String apiKey = aiBot.getModelKEY(); // 鏇挎崲涓哄疄闄匒PI Key
+
+ DifyStreamClient client = new DifyStreamClient(apiUrl, apiKey, aiBotMessageService);
+ DifyStreamClient uploadClient = new DifyStreamClient(aiBot.getModelAPI()+"/files/upload", apiKey, aiBotMessageService);
+ String fileId = file;
+
+ // 2. 鏋勫缓鏂囦欢鍙傛暟瀵硅薄
+ Map<String, Object> fileParam = new HashMap<>();
+ fileParam.put("transfer_method", "local_file");
+ fileParam.put("upload_file_id", fileId);
+// fileParam.put("type", fileJson.get("extension").getAsString()); // 渚嬪 "excel"銆�"pdf" 绛�
+ fileParam.put("type", "document"); // 渚嬪 "excel"銆�"pdf" 绛�
+
+ // 3. 缁勮 inputs 鍙傛暟
+ Map<String, Object> inputs = new HashMap<>();
+ inputs.put("w", fileParam); // 娣诲姞鏂囦欢鍙傛暟锛寁ariableName 濡� "document"
+
+
AiBotMessageMemory memory = new AiBotMessageMemory(botId, SaTokenUtil.getLoginAccount().getId(),
sessionId, isExternalMsg, aiBotMessageService, aiBotConversationMessageMapper,
aiBotConversationMessageService);
final HistoriesPrompt historiesPrompt = new HistoriesPrompt();
+ if (systemPrompt != null) {
+ historiesPrompt.setSystemMessage(SystemMessage.of(systemPrompt));
+ }
historiesPrompt.setMemory(memory);
@@ -173,59 +212,71 @@
historiesPrompt.addMessage(humanMessage);
- MySseEmitter emitter = new MySseEmitter((long) (1000 * 60 * 2));
final Boolean[] needClose = {true};
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- // 缁熶竴浣跨敤娴佸紡澶勭悊锛屾棤璁烘槸鍚︽湁 Function Calling
- llm.chatStream(historiesPrompt, new StreamResponseListener() {
- @Override
- public void onMessage(ChatContext context, AiMessageResponse response) {
- try {
- RequestContextHolder.setRequestAttributes(sra, true);
- if (response != null) {
- // 妫�鏌ユ槸鍚﹂渶瑕佽Е鍙� Function Calling
- if (response.getFunctionCallers() != null && CollectionUtil.hasItems(response.getFunctionCallers())) {
- needClose[0] = false;
- function_call(response, emitter, needClose, historiesPrompt, llm, prompt, false);
- } else {
- // 寮哄埗娴佸紡杩斿洖锛屽嵆浣挎湁 Function Calling 涔熷厛杩斿洖閮ㄥ垎缁撴灉
- if (response.getMessage() != null) {
- String content = response.getMessage().getContent();
- if (StringUtil.hasText(content)) {
- emitter.send(JSON.toJSONString(response.getMessage()));
- }
- }
- }
- }
- } catch (Exception e) {
- emitter.completeWithError(e);
- }
- }
+ MySseEmitter emitter = new MySseEmitter(1000L * 60 * 2); // 2鍒嗛挓瓒呮椂
- @Override
- public void onStop(ChatContext context) {
- if (needClose[0]) {
- emitter.complete();
- }
- }
-
- @Override
- public void onFailure(ChatContext context, Throwable throwable) {
- emitter.completeWithError(throwable);
- }
- });
+ try {
+ String userId = SaTokenUtil.getLoginAccount().getId() + "";
+ client.runWorkflow(inputs, prompt, userId, emitter, sessionId, botId);
+ } catch (Exception e) {
+ emitter.completeWithError(e);
+ }
+// System.out.println(emitter.toString());
return emitter;
- } catch (Exception e) {
- return ChatManager.getInstance().sseEmitterForContent("鑷畾涔塋LM閰嶇疆閿欒");
}
- }else{
- Map<String, Object> llmOptions = aiBot.getLlmOptions();
- String systemPrompt = llmOptions != null ? (String) llmOptions.get("systemPrompt") : null;
+ aiBot.setModelAPI(aiBot.getModelAPI()+"/chat-messages");
+ String apiUrl = aiBot.getModelAPI(); // 鏇挎崲涓哄疄闄匒PI URL
+ String apiKey = aiBot.getModelKEY(); // 鏇挎崲涓哄疄闄匒PI Key
+
+ DifyStreamClient client = new DifyStreamClient(apiUrl, apiKey, aiBotMessageService);
+ AiBotMessageMemory memory = new AiBotMessageMemory(botId, SaTokenUtil.getLoginAccount().getId(),
+ sessionId, isExternalMsg, aiBotMessageService, aiBotConversationMessageMapper,
+ aiBotConversationMessageService);
+
+ final HistoriesPrompt historiesPrompt = new HistoriesPrompt();
+ if (systemPrompt != null) {
+ historiesPrompt.setSystemMessage(SystemMessage.of(systemPrompt));
+ }
+
+ historiesPrompt.setMemory(memory);
+
+ HumanMessage humanMessage = new HumanMessage(prompt);
+
+ // 娣诲姞鎻掍欢鐩稿叧鐨刦unction calling
+ appendPluginToolFunction(botId, humanMessage);
+
+ //娣诲姞宸ヤ綔娴佺浉鍏崇殑 Function Calling
+ appendWorkflowFunctions(botId, humanMessage);
+
+ //娣诲姞鐭ヨ瘑搴撶浉鍏崇殑 Function Calling
+ appendKnowledgeFunctions(botId, humanMessage);
+
+ historiesPrompt.addMessage(humanMessage);
+
+
+ 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) {
@@ -282,6 +333,7 @@
if (response.getMessage() != null) {
String content = response.getMessage().getContent();
if (StringUtil.hasText(content)) {
+ System.out.println(response);
emitter.send(JSON.toJSONString(response.getMessage()));
}
}
@@ -307,10 +359,73 @@
}
});
+ System.out.println(emitter.toString());
return emitter;
}
}
+
+ @PostMapping("files/upload")
+ public Result filesUpload(@RequestParam("botId") BigInteger botId,
+ @RequestParam("file") MultipartFile file,
+ HttpServletResponse response){
+ try{
+ String userId = SaTokenUtil.getLoginAccount().getId() + "";
+ response.setContentType("text/event-stream");
+ AiBot aiBot = service.getById(botId);
+ aiBot.setModelAPI(aiBot.getModelAPI()+"/files/upload");
+ String apiUrl = aiBot.getModelAPI(); // 鏇挎崲涓哄疄闄匒PI URL
+ String apiKey = aiBot.getModelKEY(); // 鏇挎崲涓哄疄闄匒PI Key
+ DifyStreamClient client = new DifyStreamClient(apiUrl, apiKey, aiBotMessageService);
+ String s = client.fileUpload(userId, file);
+ return Result.success(s);
+ }catch (Exception e){
+ return Result.fail(400,String.valueOf(e));
+ }
+ }
+
+
+
+ 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);
+ }
+
+
/**
* 澶栭儴鐢ㄦ埛璋冪敤鏅鸿兘浣撹繘琛屽璇�
@@ -633,4 +748,4 @@
}
-}
+}
\ No newline at end of file
--
Gitblit v1.8.0