|
@@ -0,0 +1,269 @@
|
|
|
|
+package com.bosshand.virgo.api.workark.service;
|
|
|
|
+
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
+import com.bosshand.virgo.api.workark.dao.DifyCompletionDao;
|
|
|
|
+import com.bosshand.virgo.api.workark.dao.DifyTypeDao;
|
|
|
|
+import com.bosshand.virgo.api.workark.dao.DifyWorkFlowDao;
|
|
|
|
+import com.bosshand.virgo.api.workark.model.DifyCompletion;
|
|
|
|
+import com.bosshand.virgo.api.workark.model.DifyType;
|
|
|
|
+import com.bosshand.virgo.api.workark.model.DifyWorkFlow;
|
|
|
|
+import com.bosshand.virgo.core.model.UserContext;
|
|
|
|
+import com.bosshand.virgo.core.utils.ContextUtils;
|
|
|
|
+import io.github.imfangs.dify.client.DifyClientFactory;
|
|
|
|
+import io.github.imfangs.dify.client.DifyCompletionClient;
|
|
|
|
+import io.github.imfangs.dify.client.DifyWorkflowClient;
|
|
|
|
+import io.github.imfangs.dify.client.callback.CompletionStreamCallback;
|
|
|
|
+import io.github.imfangs.dify.client.callback.WorkflowStreamCallback;
|
|
|
|
+import io.github.imfangs.dify.client.enums.ResponseMode;
|
|
|
|
+import io.github.imfangs.dify.client.event.*;
|
|
|
|
+import io.github.imfangs.dify.client.exception.DifyApiException;
|
|
|
|
+import io.github.imfangs.dify.client.model.completion.CompletionRequest;
|
|
|
|
+import io.github.imfangs.dify.client.model.workflow.WorkflowRunRequest;
|
|
|
|
+import io.github.imfangs.dify.client.model.workflow.WorkflowRunStatusResponse;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+import java.util.UUID;
|
|
|
|
+
|
|
|
|
+@Service
|
|
|
|
+public class DifyService {
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ DifyWorkFlowDao difyWorkFlowDao;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ DifyTypeDao difyTypeDao;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ DifyCompletionDao difyCompletionDao;
|
|
|
|
+
|
|
|
|
+ public void saveType(DifyType difyType) {
|
|
|
|
+ difyTypeDao.save(difyType);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void updateType(DifyType difyType) {
|
|
|
|
+ difyTypeDao.update(difyType);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public List<DifyType> getListType() {
|
|
|
|
+ return difyTypeDao.getList();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public List<DifyWorkFlow> getList(DifyWorkFlow difyWorkFlow) {
|
|
|
|
+ return difyWorkFlowDao.getList(difyWorkFlow);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 工作流应用
|
|
|
|
+ */
|
|
|
|
+ public String workFlowRun(long difyTypeId, Map<String, Object> inputs) {
|
|
|
|
+
|
|
|
|
+ String simpleUUID = UUID.randomUUID().toString().replace("-", "");
|
|
|
|
+
|
|
|
|
+ UserContext userContext = ContextUtils.getUserContext();
|
|
|
|
+
|
|
|
|
+ DifyType difyType = difyTypeDao.get(difyTypeId);
|
|
|
|
+
|
|
|
|
+ // 创建工作流客户端
|
|
|
|
+ DifyWorkflowClient workFlowClient = DifyClientFactory.createWorkflowClient("http://203.110.233.149:9000/v1", difyType.getApiKey());
|
|
|
|
+
|
|
|
|
+ // 创建工作流请求
|
|
|
|
+ WorkflowRunRequest request = WorkflowRunRequest.builder()
|
|
|
|
+ .inputs(inputs)
|
|
|
|
+ .responseMode(ResponseMode.STREAMING)
|
|
|
|
+ .user(userContext.getUserName() + "-" + userContext.getUserId())
|
|
|
|
+ .build();
|
|
|
|
+
|
|
|
|
+ // 执行工作流流式请求
|
|
|
|
+ try {
|
|
|
|
+ workFlowClient.runWorkflowStream(request, new WorkflowStreamCallback() {
|
|
|
|
+ @Override
|
|
|
|
+ public void onWorkflowStarted(WorkflowStartedEvent event) {
|
|
|
|
+ System.out.println("工作流开始: " + event);
|
|
|
|
+ startedEvent(userContext.getUserId(), difyTypeId, event.getWorkflowRunId(), simpleUUID);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onNodeStarted(NodeStartedEvent event) {
|
|
|
|
+ //System.out.println("节点开始: " + event);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onNodeFinished(NodeFinishedEvent event) {
|
|
|
|
+ //System.out.println("节点完成: " + event);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onWorkflowFinished(WorkflowFinishedEvent event) {
|
|
|
|
+ //System.out.println("工作流完成: " + event);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onError(ErrorEvent event) {
|
|
|
|
+ System.err.println("错误: " + event.getMessage());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onException(Throwable throwable) {
|
|
|
|
+ System.err.println("异常: " + throwable.getMessage());
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ } catch (DifyApiException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return simpleUUID;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void startedEvent(long userId, long difyTypeId, String workflowRunId, String simpleUUID) {
|
|
|
|
+ DifyWorkFlow difyWorkFlow = new DifyWorkFlow();
|
|
|
|
+ difyWorkFlow.setSimpleUUID(simpleUUID);
|
|
|
|
+ difyWorkFlow.setDifyTypeId(difyTypeId);
|
|
|
|
+ difyWorkFlow.setUserId(userId);
|
|
|
|
+ difyWorkFlow.setWorkflowRunId(workflowRunId);
|
|
|
|
+ difyWorkFlow.setStatus("running");
|
|
|
|
+ difyWorkFlowDao.save(difyWorkFlow);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public DifyWorkFlow getWorkFlow(String simpleUUID) {
|
|
|
|
+ DifyWorkFlow df = difyWorkFlowDao.getSimpleUUID(simpleUUID);
|
|
|
|
+ if (df.getStatus().equals("succeeded")) {
|
|
|
|
+ return df;
|
|
|
|
+ }
|
|
|
|
+ WorkflowRunStatusResponse workflowRun = getWorkflowRun(df.getWorkflowRunId(), df.getDifyTypeId());
|
|
|
|
+ df.setCreatedAt(workflowRun.getCreatedAt());
|
|
|
|
+ df.setStatus(workflowRun.getStatus());
|
|
|
|
+ df.setError(workflowRun.getError());
|
|
|
|
+ df.setElapsedTime(workflowRun.getElapsedTime());
|
|
|
|
+ df.setFinishedAt(workflowRun.getFinishedAt());
|
|
|
|
+ df.setInputs(unicodeEscapeToChinese(workflowRun.getInputs().toString()));
|
|
|
|
+ df.setOutputs(unicodeEscapeToChinese(workflowRun.getOutputs().toString()));
|
|
|
|
+ df.setTotalSteps(workflowRun.getTotalSteps());
|
|
|
|
+ df.setTotalTokens(workflowRun.getTotalTokens());
|
|
|
|
+ difyWorkFlowDao.update(df);
|
|
|
|
+ return df;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private WorkflowRunStatusResponse getWorkflowRun(String workflowRunId, long difyTypeId) {
|
|
|
|
+
|
|
|
|
+ DifyType difyType = difyTypeDao.get(difyTypeId);
|
|
|
|
+
|
|
|
|
+ // 创建工作流客户端
|
|
|
|
+ DifyWorkflowClient workFlowClient = DifyClientFactory.createWorkflowClient("http://203.110.233.149:9000/v1", difyType.getApiKey());
|
|
|
|
+
|
|
|
|
+ WorkflowRunStatusResponse statusResponse = null;
|
|
|
|
+
|
|
|
|
+ // 获取工作流执行情况
|
|
|
|
+ try {
|
|
|
|
+ statusResponse = workFlowClient.getWorkflowRun(workflowRunId);
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ } catch (DifyApiException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return statusResponse;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * unicode转为中文
|
|
|
|
+ */
|
|
|
|
+ public String unicodeEscapeToChinese(String unicodeEscapedString) {
|
|
|
|
+ // 解码Unicode转义序列
|
|
|
|
+ StringBuilder decodedString = new StringBuilder();
|
|
|
|
+ int i = 0;
|
|
|
|
+ while (i < unicodeEscapedString.length()) {
|
|
|
|
+ if (unicodeEscapedString.startsWith("\\u", i)) {
|
|
|
|
+ // 找到一个Unicode转义序列
|
|
|
|
+ int codePoint = Integer.parseInt(unicodeEscapedString.substring(i + 2, i + 6), 16);
|
|
|
|
+ decodedString.appendCodePoint(codePoint);
|
|
|
|
+ // 跳过这个Unicode转义序列
|
|
|
|
+ i += 6;
|
|
|
|
+ } else {
|
|
|
|
+ // 不是Unicode转义序列,直接添加字符
|
|
|
|
+ decodedString.append(unicodeEscapedString.charAt(i));
|
|
|
|
+ i++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return decodedString.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 文本生成应用
|
|
|
|
+ */
|
|
|
|
+ public String completionRun(long difyTypeId, Map<String, Object> inputs) {
|
|
|
|
+
|
|
|
|
+ DifyType difyType = difyTypeDao.get(difyTypeId);
|
|
|
|
+
|
|
|
|
+ UserContext userContext = ContextUtils.getUserContext();
|
|
|
|
+
|
|
|
|
+ String simpleUUID = UUID.randomUUID().toString().replace("-", "");
|
|
|
|
+
|
|
|
|
+ DifyCompletion difyCompletion = new DifyCompletion();
|
|
|
|
+ difyCompletion.setDifyTypeId(difyTypeId);
|
|
|
|
+ difyCompletion.setStatus("running");
|
|
|
|
+ difyCompletion.setSimpleUUID(simpleUUID);
|
|
|
|
+ difyCompletion.setUserId(userContext.getUserId());
|
|
|
|
+ JSONObject json = new JSONObject(inputs);
|
|
|
|
+ difyCompletion.setInputs(json.toJSONString());
|
|
|
|
+ difyCompletionDao.save(difyCompletion);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ DifyCompletionClient completionClient = DifyClientFactory.createCompletionClient("http://203.110.233.149:9000/v1", difyType.getApiKey());
|
|
|
|
+
|
|
|
|
+ CompletionRequest request = CompletionRequest.builder()
|
|
|
|
+ .inputs(inputs)
|
|
|
|
+ .responseMode(ResponseMode.STREAMING)
|
|
|
|
+ .user(userContext.getUserName() + "-" + userContext.getUserId())
|
|
|
|
+ .build();
|
|
|
|
+
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
+
|
|
|
|
+ // 发送流式请求
|
|
|
|
+ try {
|
|
|
|
+ completionClient.sendCompletionMessageStream(request, new CompletionStreamCallback() {
|
|
|
|
+ @Override
|
|
|
|
+ public void onMessage(MessageEvent event) {
|
|
|
|
+ //System.out.println("收到消息片段: " + event.getAnswer());
|
|
|
|
+ sb.append(event.getAnswer());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onMessageEnd(MessageEndEvent event) {
|
|
|
|
+ System.out.println("消息结束,完整消息ID: " + event.getMessageId());
|
|
|
|
+ DifyCompletion difyCompletion = difyCompletionDao.getSimpleUUID(simpleUUID);
|
|
|
|
+ difyCompletion.setStatus("succeeded");
|
|
|
|
+ difyCompletion.setMessageId(event.getMessageId());
|
|
|
|
+ difyCompletion.setOutputs(sb.toString());
|
|
|
|
+ difyCompletionDao.update(difyCompletion);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onError(ErrorEvent event) {
|
|
|
|
+ System.err.println("错误: " + event.getMessage());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void onException(Throwable throwable) {
|
|
|
|
+ System.err.println("异常: " + throwable.getMessage());
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ } catch (DifyApiException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return simpleUUID;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public DifyCompletion getCompletion(String simpleUUID) {
|
|
|
|
+ return difyCompletionDao.getSimpleUUID(simpleUUID);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public List<DifyCompletion> getCompletionList(DifyCompletion difyCompletion) {
|
|
|
|
+ return difyCompletionDao.getList(difyCompletion);
|
|
|
|
+ }
|
|
|
|
+}
|