admin
2025-06-10 a5a9ac7c2a9fd6026b0d87e1b0eff763eb4512d0
0610
2个文件已修改
175 ■■■■ 已修改文件
aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/config/DifyStreamClient.java 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiBotController.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/config/DifyStreamClient.java
@@ -19,6 +19,8 @@
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class DifyStreamClient {
    private final OkHttpClient client;
    private final String apiUrl;
@@ -32,7 +34,8 @@
        this.apiUrl = apiUrl;
        this.apiKey = apiKey;
        this.gson = new GsonBuilder().setPrettyPrinting().create();
        this.client = new OkHttpClient.Builder().build();
        this.client = new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS) // 连接超时
                .readTimeout(120, TimeUnit.SECONDS).build();
        this.aiBotMessageService = aiBotMessageService;
    }
@@ -57,11 +60,11 @@
            }
        }
        requestBody.add("inputs", inputsJson);
        // 设置响应模式和用户ID
        requestBody.addProperty("response_mode", "streaming");
        requestBody.addProperty("user", userId);
//        System.out.println(requestBody+"==============================================================================================");
        // 创建请求
        RequestBody body = RequestBody.create(
                gson.toJson(requestBody),
@@ -105,6 +108,7 @@
            @Override
            public void onResponse(Call call, Response response) {
                StringBuffer sb = new StringBuffer();
                try (ResponseBody responseBody = response.body()) {
                    if (!response.isSuccessful()) {
                        emitter.completeWithError(new IOException("API错误: " + response.code()));
@@ -129,6 +133,7 @@
                                // 假设API返回的格式是{ "output": "消息内容" }
                                JsonObject jsonObject = gson.fromJson(data, JsonObject.class);
                                String title = null;
//                                System.out.println(jsonObject);
                                if (jsonObject != null && jsonObject.has("data")) {
                                    JsonElement dataElement = jsonObject.get("data");
                                    if (dataElement != null && !dataElement.isJsonNull()) {
@@ -142,10 +147,36 @@
                                                title = titleElement.getAsString();
                                            }
                                        }
                                        if (dataObject != null && dataObject.has("text")) {
                                        else if (dataObject != null && dataObject.has("text")) {
                                            JsonElement titleElement = dataObject.get("text");
                                            if (titleElement != null && !titleElement.isJsonNull()) {
                                                title = titleElement.getAsString();
                                            }
                                        }else if (dataObject != null && dataObject.has("outputs")) {
                                            JsonElement titleElement = dataObject.get("outputs");
                                            if (titleElement != null && !titleElement.isJsonNull()) {
                                                AiBotMessage aiBotMessage = new AiBotMessage();
                                                aiBotMessage.setBotId(botId);
                                                aiBotMessage.setSessionId(sessionId);
                                                aiBotMessage.setAccountId(new BigInteger(userId));
                                                aiBotMessage.setRole("assistant");
                                                aiBotMessage.setContent(sb.toString());
                                                aiBotMessage.setCreated(new Date());
                                                aiBotMessage.setIsExternalMsg(1);
                                                aiBotMessageService.save(aiBotMessage);
//                                                dataObject = titleElement.getAsJsonObject();
//                                                if (dataObject != null && dataObject.has("text")) {
//                                                    titleElement = dataObject.get("text");
//                                                    if (titleElement != null && !titleElement.isJsonNull()) {
//                                                        title = titleElement.getAsString();
//                                                    }
//                                                }else if (dataObject != null && dataObject.has("data")) {
//                                                    titleElement = dataObject.get("data");
//                                                    if (titleElement != null && !titleElement.isJsonNull()) {
//                                                        title = titleElement.getAsString();
//                                                    }
//                                                }
                                            }
                                        }
                                    }
@@ -155,8 +186,11 @@
                                AiMessage aiMessage = new AiMessage();
                                aiMessage.setContent(title);
                                System.out.println(gson.fromJson(data, JsonObject.class));
                                sb.append(aiMessage.getContent());
                                // 将消息发送给前端
                                emitter.send(JSON.toJSONString(aiMessage));
                                if (aiMessage.getContent() != null){
                                    emitter.send(JSON.toJSONString(aiMessage));
                                }
                            } catch (Exception e) {
                                // 记录解析错误但继续处理后续数据
@@ -252,13 +286,13 @@
        requestBody.addProperty("response_mode", "streaming");
        requestBody.addProperty("conversation_id", "");
        requestBody.addProperty("user", userId);
        requestBody.add("files", new JsonArray());
//        requestBody.add("files", new JsonArray());
        // 添加历史对话信息
        JsonArray historyArray = new JsonArray();
        for (AiBotMessage msg : history) {
            historyArray.add(String.valueOf(msg));
        }
        requestBody.add("history", historyArray);
//        for (AiBotMessage msg : history) {
//            historyArray.add(String.valueOf(msg));
//        }
//        requestBody.add("history", historyArray);
        RequestBody body = RequestBody.create(
                gson.toJson(requestBody),
aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiBotController.java
@@ -155,6 +155,7 @@
                           @JsonBody(value = "botId", required = true) BigInteger botId,
                           @JsonBody(value = "sessionId", required = true) String sessionId,
                           @JsonBody(value = "isExternalMsg") int isExternalMsg,
                           @JsonBody(value = "files") List<String> files,//上传文件
                           @JsonBody(value = "file") String file,//上传文件
                           HttpServletResponse response) {
        response.setContentType("text/event-stream");
@@ -166,27 +167,125 @@
        String systemPrompt = llmOptions != null ? (String) llmOptions.get("systemPrompt") : null;
        if (StringUtil.hasText(aiBot.getModelAPI())){
            if (aiBot.getBotTypeId() == 2) {
            if (aiBot.getBotTypeId() == 2 || aiBot.getBotTypeId() == 3) {
                String apiUrl = aiBot.getModelAPI()+"/workflows/run"; // 替换为实际API URL
                String apiKey = aiBot.getModelKEY(); // 替换为实际API Key
                DifyStreamClient client = new DifyStreamClient(apiUrl, apiKey, aiBotMessageService);
                DifyStreamClient uploadClient = new DifyStreamClient(aiBot.getModelAPI()+"/files/upload", apiKey, aiBotMessageService);
                String fileId = file;
//                DifyStreamClient uploadClient = new DifyStreamClient(aiBot.getModelAPI()+"/files/upload", apiKey, aiBotMessageService);
                // 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); // 添加文件参数,variableName 如 "document"
                if(aiBot.getBotTypeId() == 3){
                    // 2. 构建文件参数对象
                    HttpHeaders headers = new HttpHeaders();
                    headers.set("Authorization", apiKey);
                    HttpEntity<Object> requestEntity = new HttpEntity<>(null, headers);
                    ResponseEntity<String> parameters = restTemplate.exchange(
                            aiBot.getModelAPI()+"/parameters",
                            HttpMethod.GET,
                            requestEntity, // 请求体(GET 无请求体)
                            String.class // 响应结果类型
                    );
                    org.json.JSONObject jsonObj = new org.json.JSONObject(parameters.getBody());
                    // 先获取 user_input_form 数组
                    org.json.JSONArray userInputFormArr = jsonObj.getJSONArray("user_input_form");
                    String variable = null;
                    String type = "";
                    // 遍历数组,找到 file - list 结构
                    for (int i = 0; i < userInputFormArr.length(); i++) {
                        org.json.JSONObject formItem = userInputFormArr.getJSONObject(i);
                        if (formItem.has("file-list")) {
                            org.json.JSONObject fileListObj = formItem.getJSONObject("file-list");
                            // 提取 variable 参数
                            variable = fileListObj.getString("variable");
                            // 提取 allowed_file_types 参数(数组形式)
                            org.json.JSONArray allowedFileTypesArr = fileListObj.getJSONArray("allowed_file_types");
                            System.out.println("variable: " + variable);
                            System.out.println("allowed_file_types: " + allowedFileTypesArr.toString());
                            type = allowedFileTypesArr.toString().replace("[\"", "").replace("\"]", "");
                            break; // 这里假设只有一个符合的 file - list,找到就退出循环,可根据实际情况调整
                        }
                    }
                    List fileList = new ArrayList<>();
                    Map<String, Object> fileParam = new HashMap<>();
                    for (String fileId : files) {
                        fileParam.put("transfer_method", "local_file");
                        fileParam.put("upload_file_id", fileId);
                        fileParam.put("type", type); // 例如 "excel"、"pdf" 等
                        fileList.add(fileParam);
                    }
                    // 3. 组装 inputs 参数
                    inputs.put(variable, fileList); // 添加文件参数,variableName 如 "document"
                }
                else {
                    HttpHeaders headers = new HttpHeaders();
                    headers.set("Authorization", apiKey);
                    Map<String, Object> fileParam = new HashMap<>();
                    fileParam.put("transfer_method", "local_file");
                    fileParam.put("upload_file_id", file);
                    HttpEntity<Object> requestEntity = new HttpEntity<>(null, headers);
                    ResponseEntity<String> parameters = restTemplate.exchange(
                            aiBot.getModelAPI()+"/parameters",
                            HttpMethod.GET,
                            requestEntity, // 请求体(GET 无请求体)
                            String.class // 响应结果类型
                    );
//                    System.out.println("========================\n"+parameters.getBody()+"\n=====================");
                    String variable = null;
                    String type = "";
                    try {
                        // 解析 JSON 字符串
                        org.json.JSONObject configJson = new org.json.JSONObject(parameters.getBody());
                        // 获取 user_input_form 数组
                        org.json.JSONArray userInputFormArray = configJson.getJSONArray("user_input_form");
                        // 遍历 user_input_form 数组中的每个元素
                        for (int i = 0; i < userInputFormArray.length(); i++) {
                            org.json.JSONObject formElement = userInputFormArray.getJSONObject(i);
                            // 检查是否包含 "file" 对象
                            if (formElement.has("file")) {
                                org.json.JSONObject fileObject = formElement.getJSONObject("file");
                                // 提取 variable
                                variable = fileObject.getString("variable");
                                // 提取 allowed_file_types 数组
                                org.json.JSONArray allowedFileTypesArray = fileObject.getJSONArray("allowed_file_types");
                                // 打印结果
                                System.out.println("Variable: " + variable);
                                System.out.print("Document Types: ");
                                for (int j = 0; j < allowedFileTypesArray.length(); j++) {
                                    type = type + allowedFileTypesArray.getString(j);
                                    System.out.print(allowedFileTypesArray.getString(j) + " ");
                                }
                                System.out.println();
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    fileParam.put("type", type); // 例如 "excel"、"pdf" 等
                    // 3. 组装 inputs 参数
                    inputs.put(variable, fileParam); // 添加文件参数,variableName 如 "document"
                }
                AiBotMessageMemory memory = new AiBotMessageMemory(botId, SaTokenUtil.getLoginAccount().getId(),
                        sessionId, isExternalMsg, aiBotMessageService, aiBotConversationMessageMapper,
@@ -273,7 +372,7 @@
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
            System.out.println(emitter.toString());
//            System.out.println(emitter.toString());
            return emitter;
        }
        else{