diff --git a/.drone.yml b/.drone.yml
index 8c492b1..b4599fa 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -27,11 +27,9 @@ steps:
from_secret: docker_password
REGISTRY:
from_secret: registry
- REGISTRY_NAMESPACE:
- from_secret: registry_namespace
commands:
- sed -i 's/$REGISTRY/'"$REGISTRY"'/' deployment.yml
- - sed -i 's/$REGISTRY_NAMESPACE/'"$REGISTRY_NAMESPACE"'/' deployment.yml
+ - sed -i 's/$REGISTRY_NAMESPACE/'"metis"'/' deployment.yml
- sed -i 's/$DRONE_COMMIT/${DRONE_COMMIT}/' deployment.yml
- sed -i 's/$DRONE_REPO_NAME/${DRONE_REPO_NAME}/' deployment.yml
- echo $DOCKER_PASSWORD | docker login $REGISTRY --username $DOCKER_USERNAME --password-stdin
@@ -45,32 +43,37 @@ steps:
path: /app/config
commands:
- kubectl apply -f deployment.yml -n metis --kubeconfig=/app/config/base-taishan-kubectl.yml
- -
+
+
- name: notify
image: 10.7.127.190:38080/plugins/webhook:latest
environment:
- WEBHOOK_URL:
- from_secret: wechat_webhook_url
+ NOTIFY_WX_URL:
+ from_secret: notify_wx_url
when:
status: [ success,failure ]
settings:
- urls: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=f2b3fcbc-e70f-4826-8b08-340518b3a96f
+ urls:
+ from_secret: notify_wx_url
content_type: application/json
template: |
{
"msgtype": "markdown",
"markdown": {
- "content": "{{#success build.status}}✅{{else}}❌{{/success}}**{{ repo.owner }}/{{ repo.name }}** (Build #{{build.number}})\n
- >**构建结果**: {{ build.status }}
- >**构建详情**: [点击查看]({{ build.link }})
- >**代码分支**: {{ build.branch }}
- >**提交标识**: {{ build.commit }}
- >**提交发起**: {{ build.author }}
- >**提交信息**: {{ build.message }}
- "
+ "content": "{{#success build.status}}✅ 构建成功{{else}}❌ 构建失败{{/success}}
+ >**构建编号**: #{{build.number}}
+ >**构建状态**: {{build.status}}
+ >**代码分支**: {{build.branch}}
+ >**提交哈希**: {{build.commit}}
+ >**提交作者**: {{build.author}}
+ >**持续时间**: {{build.duration}}秒
+ >**提交信息**: {{build.message}}
+ >[查看构建详情]({{build.link}})
+ >{{^success build.status}}[查看失败日志]({{build.link}}/logs){{/success}}"
}
}
+
volumes:
- name: config
host:
diff --git a/Dockerfile b/Dockerfile
index 8da31a9..2d4faca 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,6 +6,6 @@ WORKDIR /app
# 定义时区参数并设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
-COPY ./target/metis-1.0.0-SNAPSHOT.jar /app/metis.jar
+COPY ./metis-applicant/target/metis-applicant-1.0.0-SNAPSHOT.jar /app/metis.jar
RUN chmod 755 -R /app/
CMD java -jar /app/metis.jar -Xms256m -Xmx512m --spring.profiles.active=${PROFILES} --server.port=${SERVICE_PORTS}
diff --git a/metis-applicant/pom.xml b/metis-applicant/pom.xml
new file mode 100644
index 0000000..6900ad5
--- /dev/null
+++ b/metis-applicant/pom.xml
@@ -0,0 +1,93 @@
+
+
+ 4.0.0
+
+ com.metis
+ metis
+ 1.0.0-SNAPSHOT
+
+
+ metis-applicant
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+ com.metis
+ metis-starter
+ 1.0.0-SNAPSHOT
+
+
+
+ com.github.xiaoymin
+ knife4j-openapi3-jakarta-spring-boot-starter
+ 4.4.0
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+
+
+ org.projectlombok
+ lombok
+
+
+ org.mapstruct
+ mapstruct-processor
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 17
+ 17
+ UTF-8
+
+ -parameters
+ --add-opens
+ java.base/java.lang=ALL-UNNAMED
+
+
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${org.mapstruct.version}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/metis/MetisApplication.java b/metis-applicant/src/main/java/com/metisapp/MetisApplication.java
similarity index 93%
rename from src/main/java/com/metis/MetisApplication.java
rename to metis-applicant/src/main/java/com/metisapp/MetisApplication.java
index b9dc604..5feb08a 100644
--- a/src/main/java/com/metis/MetisApplication.java
+++ b/metis-applicant/src/main/java/com/metisapp/MetisApplication.java
@@ -1,4 +1,4 @@
-package com.metis;
+package com.metisapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
diff --git a/src/main/java/com/metis/config/SwaggerConfig.java b/metis-applicant/src/main/java/com/metisapp/config/SwaggerConfig.java
similarity index 94%
rename from src/main/java/com/metis/config/SwaggerConfig.java
rename to metis-applicant/src/main/java/com/metisapp/config/SwaggerConfig.java
index 744fe14..77feba0 100644
--- a/src/main/java/com/metis/config/SwaggerConfig.java
+++ b/metis-applicant/src/main/java/com/metisapp/config/SwaggerConfig.java
@@ -1,7 +1,6 @@
-package com.metis.config;
+package com.metisapp.config;
import io.swagger.v3.oas.models.OpenAPI;
-import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;
diff --git a/src/main/java/com/metis/controller/TestController.java b/metis-applicant/src/main/java/com/metisapp/controller/TestController.java
similarity index 77%
rename from src/main/java/com/metis/controller/TestController.java
rename to metis-applicant/src/main/java/com/metisapp/controller/TestController.java
index daa011b..be0f467 100644
--- a/src/main/java/com/metis/controller/TestController.java
+++ b/metis-applicant/src/main/java/com/metisapp/controller/TestController.java
@@ -1,10 +1,10 @@
-package com.metis.controller;
+package com.metisapp.controller;
-import com.metis.flow.domain.bo.BuildApp;
-import com.metis.flow.engine.AppFlowEngineRunnerService;
-import com.metis.flow.runner.FlowRunningContext;
-import com.metis.flow.runner.RunnerResult;
-import com.metis.flow.validator.ValidatorService;
+import com.metis.domain.bo.BuildApp;
+import com.metis.engine.AppFlowEngineRunnerService;
+import com.metis.runner.FlowRunningContext;
+import com.metis.runner.RunnerResult;
+import com.metis.validator.ValidatorService;
import com.metis.result.Result;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
diff --git a/metis-applicant/src/main/java/com/metisapp/custom/CustomTestConfig.java b/metis-applicant/src/main/java/com/metisapp/custom/CustomTestConfig.java
new file mode 100644
index 0000000..b7028c1
--- /dev/null
+++ b/metis-applicant/src/main/java/com/metisapp/custom/CustomTestConfig.java
@@ -0,0 +1,10 @@
+package com.metisapp.custom;
+
+import com.metis.domain.entity.base.NodeConfig;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class CustomTestConfig extends NodeConfig {
+}
diff --git a/metis-applicant/src/main/java/com/metisapp/custom/CustomTestRunner.java b/metis-applicant/src/main/java/com/metisapp/custom/CustomTestRunner.java
new file mode 100644
index 0000000..d3ec3be
--- /dev/null
+++ b/metis-applicant/src/main/java/com/metisapp/custom/CustomTestRunner.java
@@ -0,0 +1,27 @@
+package com.metisapp.custom;
+
+import com.metis.domain.context.RunningContext;
+import com.metis.domain.context.RunningResult;
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.runner.CustomNodeRunner;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class CustomTestRunner implements CustomNodeRunner {
+
+ @Override
+ public String getCustomNodeType() {
+ return "test";
+ }
+
+ @Override
+ public RunningResult run(RunningContext context, Node node, List edges) {
+ log.info("自定义节点测试");
+ return RunningResult.buildResult();
+ }
+}
diff --git a/metis-applicant/src/main/java/com/metisapp/custom/CustomTestValidator.java b/metis-applicant/src/main/java/com/metisapp/custom/CustomTestValidator.java
new file mode 100644
index 0000000..60ce8b7
--- /dev/null
+++ b/metis-applicant/src/main/java/com/metisapp/custom/CustomTestValidator.java
@@ -0,0 +1,32 @@
+package com.metisapp.custom;
+
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.validator.CustomNodeValidator;
+import com.metis.validator.ValidatorResult;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class CustomTestValidator implements CustomNodeValidator {
+
+ @Override
+ public String getCustomNodeType() {
+ return "test";
+ }
+
+ @Override
+ public ValidatorResult validateValue(Node node) {
+ CustomTestConfig config = node.getConfig();
+ return ValidatorResult.valid();
+ }
+
+ @Override
+ public ValidatorResult validateRelation(Node node, List sources, List targets) {
+ CustomTestConfig config = node.getConfig();
+ return ValidatorResult.valid();
+ }
+}
diff --git a/src/main/resources/application-dev.yml b/metis-applicant/src/main/resources/application-dev.yml
similarity index 100%
rename from src/main/resources/application-dev.yml
rename to metis-applicant/src/main/resources/application-dev.yml
diff --git a/src/main/resources/application-test.yml b/metis-applicant/src/main/resources/application-test.yml
similarity index 100%
rename from src/main/resources/application-test.yml
rename to metis-applicant/src/main/resources/application-test.yml
diff --git a/src/main/resources/application.yml b/metis-applicant/src/main/resources/application.yml
similarity index 91%
rename from src/main/resources/application.yml
rename to metis-applicant/src/main/resources/application.yml
index 57c0935..d183ce5 100644
--- a/src/main/resources/application.yml
+++ b/metis-applicant/src/main/resources/application.yml
@@ -34,10 +34,6 @@ springdoc:
swagger-ui:
tags-sorter: alpha
group-configs:
- - group: bis
- display-name: "业务接口文档"
- paths-to-match: '/**'
- packages-to-scan: org.shi9.module.bis
- group: system
display-name: "系统接口文档"
paths-to-match: '/**'
diff --git a/src/main/resources/json/run.json b/metis-applicant/src/main/resources/json/run.json
similarity index 100%
rename from src/main/resources/json/run.json
rename to metis-applicant/src/main/resources/json/run.json
diff --git a/metis-applicant/src/main/resources/json/test.json b/metis-applicant/src/main/resources/json/test.json
new file mode 100644
index 0000000..05521ec
--- /dev/null
+++ b/metis-applicant/src/main/resources/json/test.json
@@ -0,0 +1,567 @@
+{
+ "id": 0,
+ "name": "测试流程",
+ "description": "测试流程",
+ "graph": {
+ "nodes": [
+ {
+ "id": "5",
+ "type": "start",
+ "initialized": false,
+ "position": {
+ "x": -81.81250000000003,
+ "y": 275.49609375
+ },
+ "data": {
+ "label": "开始",
+ "icon": "SuitcaseLine",
+ "toolbarPosition": "right",
+ "description": "开始述描述",
+ "config": {
+ "parent": "234"
+ },
+ "handles": [
+ {
+ "id": "51",
+ "position": "right",
+ "type": "source",
+ "connectable": true
+ }
+ ],
+ "item": {
+ "id": "2",
+ "type": "run",
+ "labelType": "knowledge",
+ "label": "知识检索"
+ }
+ },
+ "width": 200,
+ "height": 40
+ },
+ {
+ "id": "6",
+ "type": "end",
+ "initialized": false,
+ "position": {
+ "x": 1281.582055572882,
+ "y": 236.2912067630247
+ },
+ "data": {
+ "label": "结束",
+ "toolbarPosition": "right",
+ "handles": [
+ {
+ "id": "61",
+ "position": "left",
+ "type": "target",
+ "connectable": true
+ }
+ ]
+ },
+ "width": 200,
+ "height": 40
+ },
+ {
+ "id": "188",
+ "type": "custom",
+ "customType": "test",
+ "initialized": false,
+ "position": {
+ "x": 265.87532955148635,
+ "y": 71.40983063296031
+ },
+ "data": {
+ "label": "llm1",
+ "icon": "",
+ "description": "llm描述描述",
+ "toolbarPosition": "right",
+ "config": {
+ "labelType": "llm"
+ },
+ "handles": [
+ {
+ "id": "11",
+ "position": "left",
+ "type": "source",
+ "connectable": true
+ },
+ {
+ "id": "45",
+ "position": "right",
+ "type": "source",
+ "connectable": true
+ }
+ ]
+ },
+ "width": 200,
+ "height": null
+ },
+ {
+ "id": "850",
+ "type": "llm",
+ "initialized": false,
+ "position": {
+ "x": 269.7896091295129,
+ "y": 253.80570624004747
+ },
+ "data": {
+ "label": "llm2",
+ "icon": "",
+ "description": "llm描述描述",
+ "toolbarPosition": "right",
+ "config": {
+ "labelType": "llm"
+ },
+ "handles": [
+ {
+ "id": "43",
+ "position": "left",
+ "type": "source",
+ "connectable": true
+ },
+ {
+ "id": "57",
+ "position": "right",
+ "type": "source",
+ "connectable": true
+ }
+ ]
+ },
+ "width": 200,
+ "height": null
+ },
+ {
+ "id": "979",
+ "type": "llm",
+ "initialized": false,
+ "position": {
+ "x": 257.0893454883237,
+ "y": 360
+ },
+ "data": {
+ "label": "llm3",
+ "icon": "",
+ "description": "llm描述描述",
+ "toolbarPosition": "right",
+ "config": {
+ "labelType": "llm"
+ },
+ "handles": [
+ {
+ "id": "40",
+ "position": "left",
+ "type": "source",
+ "connectable": true
+ },
+ {
+ "id": "46",
+ "position": "right",
+ "type": "source",
+ "connectable": true
+ }
+ ],
+ "item": {
+ "id": "1",
+ "type": "run",
+ "labelType": "llm",
+ "label": "llm"
+ }
+ },
+ "width": 200,
+ "height": null
+ },
+ {
+ "id": "818",
+ "type": "questionClassifier",
+ "initialized": false,
+ "position": {
+ "x": 247.56414775743187,
+ "y": 467.44099824508874
+ },
+ "data": {
+ "label": "知识检索条件",
+ "icon": "",
+ "description": "知识检索描述描述",
+ "toolbarPosition": "right",
+ "config": {
+ "labelType": "knowledge"
+ },
+ "handles": [
+ {
+ "id": "86",
+ "position": "left",
+ "type": "source",
+ "connectable": true
+ },
+ {
+ "id": "11",
+ "position": "right",
+ "type": "source",
+ "connectable": true
+ }
+ ],
+ "item": {
+ "id": "1",
+ "type": "run",
+ "labelType": "llm",
+ "label": "llm"
+ }
+ },
+ "width": 200,
+ "height": null
+ },
+ {
+ "id": "288",
+ "type": "llm",
+ "initialized": false,
+ "position": {
+ "x": 545.6891477574318,
+ "y": 431.4042601585389
+ },
+ "data": {
+ "label": "llm5",
+ "icon": "",
+ "description": "llm描述描述",
+ "toolbarPosition": "right",
+ "config": {
+ "labelType": "llm"
+ },
+ "handles": [
+ {
+ "id": "27",
+ "position": "left",
+ "type": "source",
+ "connectable": true
+ },
+ {
+ "id": "90",
+ "position": "right",
+ "type": "source",
+ "connectable": true
+ }
+ ]
+ },
+ "width": 200,
+ "height": null
+ },
+ {
+ "id": "873",
+ "type": "llm",
+ "initialized": false,
+ "position": {
+ "x": 561.0654659633774,
+ "y": 547.6673703535477
+ },
+ "data": {
+ "label": "llm6",
+ "icon": "",
+ "description": "llm描述描述",
+ "toolbarPosition": "right",
+ "config": {
+ "labelType": "llm"
+ },
+ "handles": [
+ {
+ "id": "31",
+ "position": "left",
+ "type": "source",
+ "connectable": true
+ },
+ {
+ "id": "51",
+ "position": "right",
+ "type": "source",
+ "connectable": true
+ }
+ ]
+ },
+ "width": 200,
+ "height": null
+ },
+ {
+ "id": "244",
+ "type": "llm",
+ "initialized": false,
+ "position": {
+ "x": 543.1540601095024,
+ "y": 653.309197614774
+ },
+ "data": {
+ "label": "llm7",
+ "icon": "",
+ "description": "llm描述描述",
+ "toolbarPosition": "right",
+ "config": {
+ "labelType": "llm"
+ },
+ "handles": [
+ {
+ "id": "33",
+ "position": "left",
+ "type": "source",
+ "connectable": true
+ },
+ {
+ "id": "13",
+ "position": "right",
+ "type": "source",
+ "connectable": true
+ }
+ ]
+ },
+ "width": 200,
+ "height": null
+ },
+ {
+ "id": "308",
+ "type": "llm",
+ "initialized": false,
+ "position": {
+ "x": 588.7086470279171,
+ "y": 318.8609378786052
+ },
+ "data": {
+ "label": "llm4",
+ "icon": "",
+ "description": "llm描述描述",
+ "toolbarPosition": "right",
+ "config": {
+ "labelType": "llm"
+ },
+ "handles": [
+ {
+ "id": "17",
+ "position": "left",
+ "type": "source",
+ "connectable": true
+ },
+ {
+ "id": "73",
+ "position": "right",
+ "type": "source",
+ "connectable": true
+ }
+ ]
+ },
+ "width": 200,
+ "height": null
+ }
+ ],
+ "edges": [
+ {
+ "id": "188",
+ "type": "default",
+ "source": "5",
+ "target": "188",
+ "sourceHandle": "51",
+ "targetHandle": "11",
+ "data": {},
+ "label": "",
+ "animated": true,
+ "sourceX": 124.52083333333331,
+ "sourceY": 295.3294270833333,
+ "targetX": 262.70866773530213,
+ "targetY": 98.2431395846395
+ },
+ {
+ "id": "vueflow__edge-18845-661",
+ "type": "default",
+ "source": "188",
+ "target": "6",
+ "sourceHandle": "45",
+ "targetHandle": "61",
+ "data": {},
+ "label": "",
+ "sourceX": 472.20841119628,
+ "sourceY": 98.2431395846395,
+ "targetX": 1278.4153889062152,
+ "targetY": 256.12454009635803
+ },
+ {
+ "id": "850",
+ "type": "default",
+ "source": "5",
+ "target": "850",
+ "sourceHandle": "51",
+ "targetHandle": "43",
+ "data": {},
+ "label": "",
+ "animated": true,
+ "sourceX": 124.52083333333331,
+ "sourceY": 295.3294270833333,
+ "targetX": 266.62293379655364,
+ "targetY": 280.6389855757115
+ },
+ {
+ "id": "vueflow__edge-85057-661",
+ "type": "default",
+ "source": "850",
+ "target": "6",
+ "sourceHandle": "57",
+ "targetHandle": "61",
+ "data": {},
+ "label": "",
+ "sourceX": 476.1223496202179,
+ "sourceY": 280.6389855757115,
+ "targetX": 1278.4153889062152,
+ "targetY": 256.12454009635803
+ },
+ {
+ "id": "979",
+ "type": "default",
+ "source": "5",
+ "target": "979",
+ "sourceHandle": "51",
+ "targetHandle": "40",
+ "data": {},
+ "label": "",
+ "animated": true,
+ "sourceX": 124.52083333333331,
+ "sourceY": 295.3294270833333,
+ "targetX": 253.92267015536444,
+ "targetY": 386.83332778318527
+ },
+ {
+ "id": "818",
+ "type": "default",
+ "source": "5",
+ "target": "818",
+ "sourceHandle": "51",
+ "targetHandle": "86",
+ "data": {},
+ "label": "",
+ "animated": true,
+ "sourceX": 124.52083333333331,
+ "sourceY": 295.3294270833333,
+ "targetX": 244.3974724244726,
+ "targetY": 494.2742291332315
+ },
+ {
+ "id": "288",
+ "type": "default",
+ "source": "818",
+ "target": "288",
+ "sourceHandle": "11",
+ "targetHandle": "27",
+ "data": {},
+ "label": "",
+ "animated": true,
+ "sourceX": 453.89688824813686,
+ "sourceY": 494.2742291332315,
+ "targetX": 542.5224239769512,
+ "targetY": 458.2374910466816
+ },
+ {
+ "id": "873",
+ "type": "default",
+ "source": "818",
+ "target": "873",
+ "sourceHandle": "11",
+ "targetHandle": "31",
+ "data": {},
+ "label": "",
+ "animated": true,
+ "sourceX": 453.89688824813686,
+ "sourceY": 494.2742291332315,
+ "targetX": 557.8988921284383,
+ "targetY": 574.5006486940537
+ },
+ {
+ "id": "244",
+ "type": "default",
+ "source": "818",
+ "target": "244",
+ "sourceHandle": "11",
+ "targetHandle": "33",
+ "data": {},
+ "label": "",
+ "animated": true,
+ "sourceX": 453.89688824813686,
+ "sourceY": 494.2742291332315,
+ "targetX": 539.9875200651626,
+ "targetY": 680.1424930622838
+ },
+ {
+ "id": "vueflow__edge-28890-661",
+ "type": "default",
+ "source": "288",
+ "target": "6",
+ "sourceHandle": "90",
+ "targetHandle": "61",
+ "data": {},
+ "label": "",
+ "sourceX": 752.0218882481367,
+ "sourceY": 458.2374910466816,
+ "targetX": 1278.4153889062152,
+ "targetY": 256.12454009635803
+ },
+ {
+ "id": "vueflow__edge-87351-661",
+ "type": "default",
+ "source": "873",
+ "target": "6",
+ "sourceHandle": "51",
+ "targetHandle": "61",
+ "data": {},
+ "label": "",
+ "sourceX": 767.3988903613488,
+ "sourceY": 574.5006486940537,
+ "targetX": 1278.4153889062152,
+ "targetY": 256.12454009635803
+ },
+ {
+ "id": "vueflow__edge-24413-661",
+ "type": "default",
+ "source": "244",
+ "target": "6",
+ "sourceHandle": "13",
+ "targetHandle": "61",
+ "data": {},
+ "label": "",
+ "sourceX": 749.4874144445799,
+ "sourceY": 680.1424930622838,
+ "targetX": 1278.4153889062152,
+ "targetY": 256.12454009635803
+ },
+ {
+ "id": "308",
+ "type": "default",
+ "source": "979",
+ "target": "308",
+ "sourceHandle": "46",
+ "targetHandle": "17",
+ "data": {},
+ "label": "",
+ "animated": true,
+ "sourceX": 463.42208597902874,
+ "sourceY": 386.83332778318527,
+ "targetX": 585.5419963013785,
+ "targetY": 345.6941732530918
+ },
+ {
+ "id": "vueflow__edge-30873-661",
+ "type": "default",
+ "source": "308",
+ "target": "6",
+ "sourceHandle": "73",
+ "targetHandle": "61",
+ "data": {},
+ "label": "",
+ "sourceX": 795.0417833691082,
+ "sourceY": 345.6941732530918,
+ "targetX": 1278.4153889062152,
+ "targetY": 256.12454009635803
+ }
+ ],
+ "position": [
+ 447.2060780237498,
+ 377.80084997067763
+ ],
+ "zoom": 0.8311688311688327,
+ "viewport": {
+ "x": 447.2060780237498,
+ "y": 377.80084997067763,
+ "zoom": 0.8311688311688327
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/script/sse.html b/metis-applicant/src/main/resources/script/sse.html
similarity index 100%
rename from src/main/resources/script/sse.html
rename to metis-applicant/src/main/resources/script/sse.html
diff --git a/metis-starter/pom.xml b/metis-starter/pom.xml
new file mode 100644
index 0000000..ea66a81
--- /dev/null
+++ b/metis-starter/pom.xml
@@ -0,0 +1,104 @@
+
+
+ 4.0.0
+
+ com.metis
+ metis
+ 1.0.0-SNAPSHOT
+
+
+ metis-starter
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ dev.langchain4j
+ langchain4j-open-ai
+
+
+ dev.langchain4j
+ langchain4j-mcp
+
+
+ com.alibaba.fastjson2
+ fastjson2
+ 2.0.52
+
+
+ org.projectlombok
+ lombok
+
+
+ com.mikesamuel
+ json-sanitizer
+
+
+ com.baomidou
+ mybatis-plus-spring-boot3-starter
+
+
+ mysql
+ mysql-connector-java
+
+
+ cn.hutool
+ hutool-all
+
+
+
+ org.mapstruct
+ mapstruct
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-api
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 17
+ 17
+ UTF-8
+
+ -parameters
+
+
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${org.mapstruct.version}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/metis-starter/src/main/java/com/metis/config/MetisStarterAutoConfiguration.java b/metis-starter/src/main/java/com/metis/config/MetisStarterAutoConfiguration.java
new file mode 100644
index 0000000..f96631b
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/config/MetisStarterAutoConfiguration.java
@@ -0,0 +1,19 @@
+package com.metis.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Slf4j
+@Configuration
+@MapperScan(basePackages = {"com.metis.mapper"})
+@ComponentScan("com.metis.*")
+public class MetisStarterAutoConfiguration {
+
+
+ static {
+
+ }
+
+}
diff --git a/src/main/java/com/metis/flow/constant/BaseConstant.java b/metis-starter/src/main/java/com/metis/constant/BaseConstant.java
similarity index 67%
rename from src/main/java/com/metis/flow/constant/BaseConstant.java
rename to metis-starter/src/main/java/com/metis/constant/BaseConstant.java
index 7e0011a..bfac152 100644
--- a/src/main/java/com/metis/flow/constant/BaseConstant.java
+++ b/metis-starter/src/main/java/com/metis/constant/BaseConstant.java
@@ -1,4 +1,4 @@
-package com.metis.flow.constant;
+package com.metis.constant;
public interface BaseConstant {
diff --git a/src/main/java/com/metis/controller/ProcessDefinitionController.java b/metis-starter/src/main/java/com/metis/controller/ProcessDefinitionController.java
similarity index 96%
rename from src/main/java/com/metis/controller/ProcessDefinitionController.java
rename to metis-starter/src/main/java/com/metis/controller/ProcessDefinitionController.java
index ce90d34..8f16bc5 100644
--- a/src/main/java/com/metis/controller/ProcessDefinitionController.java
+++ b/metis-starter/src/main/java/com/metis/controller/ProcessDefinitionController.java
@@ -2,7 +2,7 @@ package com.metis.controller;
import com.metis.domain.bo.ProcessBo;
import com.metis.facade.ProcessDefinitionFacade;
-import com.metis.flow.domain.entity.App;
+import com.metis.domain.entity.App;
import com.metis.result.Result;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
diff --git a/src/main/java/com/metis/flow/convert/BaseAppConvert.java b/metis-starter/src/main/java/com/metis/convert/BaseAppConvert.java
similarity index 57%
rename from src/main/java/com/metis/flow/convert/BaseAppConvert.java
rename to metis-starter/src/main/java/com/metis/convert/BaseAppConvert.java
index 5029018..7a1122b 100644
--- a/src/main/java/com/metis/flow/convert/BaseAppConvert.java
+++ b/metis-starter/src/main/java/com/metis/convert/BaseAppConvert.java
@@ -1,9 +1,10 @@
-package com.metis.flow.convert;
+package com.metis.convert;
-import com.metis.flow.domain.entity.*;
-import com.metis.flow.domain.bo.BuildApp;
-import com.metis.flow.domain.bo.CreateApp;
-import com.metis.flow.domain.bo.UpdateApp;
+import com.metis.domain.bo.BuildApp;
+import com.metis.domain.bo.CreateApp;
+import com.metis.domain.bo.UpdateApp;
+import com.metis.domain.entity.App;
+import com.metis.domain.entity.BaseApp;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
@@ -23,6 +24,13 @@ public interface BaseAppConvert {
* @param buildApp 基础应用
* @return {@link App }
*/
+ @Mappings({
+ @Mapping(target = "id", ignore = true),
+ @Mapping(target = "workflowId", ignore = true),
+ @Mapping(target = "createTime", ignore = true),
+ @Mapping(target = "version", ignore = true),
+ @Mapping(target = "defaultUse", ignore = true),
+ })
App toApp(BuildApp buildApp);
/**
@@ -32,7 +40,7 @@ public interface BaseAppConvert {
* @return {@link App }
*/
@Mappings({
- @Mapping(target = "graph", expression = "java(com.alibaba.fastjson2.JSON.parseObject(baseApp.getGraphJson(), com.metis.flow.domain.bo.Graph.class))"),
+ @Mapping(target = "graph", expression = "java(com.alibaba.fastjson2.JSON.parseObject(baseApp.getGraphJson(), com.metis.domain.entity.base.Graph.class))"),
@Mapping(target = "workflowId", source = "id")
})
App toApp(BaseApp baseApp);
@@ -44,7 +52,13 @@ public interface BaseAppConvert {
* @return {@link BaseApp }
*/
@Mappings({
- @Mapping(target = "graphJson", expression = "java(com.alibaba.fastjson2.JSON.toJSONString(buildApp.getGraph()))")
+ @Mapping(target = "graphJson", expression = "java(com.alibaba.fastjson2.JSON.toJSONString(buildApp.getGraph()))"),
+ @Mapping(target = "createTime", ignore = true),
+ @Mapping(target = "updateTime", ignore = true),
+ @Mapping(target = "isDeleted", ignore = true),
+ @Mapping(target = "id", ignore = true),
+ @Mapping(target = "createUserId", ignore = true),
+ @Mapping(target = "defaultUse", ignore = true)
})
BaseApp toBaseApp(BuildApp buildApp);
@@ -63,6 +77,9 @@ public interface BaseAppConvert {
* @param createApp 创建应用程序
* @return {@link BuildApp }
*/
+ @Mappings({
+ @Mapping(target = "appId", ignore = true)
+ })
BuildApp toBuildApp(CreateApp createApp);
/**
@@ -71,6 +88,9 @@ public interface BaseAppConvert {
* @param updateApp 更新应用程序
* @return {@link BuildApp }
*/
+ @Mappings({
+ @Mapping(target = "userId", ignore = true)
+ })
BuildApp toBuildApp(UpdateApp updateApp);
}
diff --git a/metis-starter/src/main/java/com/metis/convert/GraphConvert.java b/metis-starter/src/main/java/com/metis/convert/GraphConvert.java
new file mode 100644
index 0000000..da2fa78
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/convert/GraphConvert.java
@@ -0,0 +1,17 @@
+package com.metis.convert;
+
+
+import com.metis.domain.bo.GraphBO;
+import com.metis.domain.entity.base.Graph;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface GraphConvert {
+
+ GraphConvert INSTANCE = Mappers.getMapper(GraphConvert.class);
+
+
+ Graph toEntity(GraphBO graph);
+
+}
diff --git a/src/main/java/com/metis/domain/SimpleBaseEntity.java b/metis-starter/src/main/java/com/metis/domain/SimpleBaseEntity.java
similarity index 100%
rename from src/main/java/com/metis/domain/SimpleBaseEntity.java
rename to metis-starter/src/main/java/com/metis/domain/SimpleBaseEntity.java
diff --git a/src/main/java/com/metis/flow/domain/bo/BuildApp.java b/metis-starter/src/main/java/com/metis/domain/bo/BuildApp.java
similarity index 88%
rename from src/main/java/com/metis/flow/domain/bo/BuildApp.java
rename to metis-starter/src/main/java/com/metis/domain/bo/BuildApp.java
index fd78ff5..28d6540 100644
--- a/src/main/java/com/metis/flow/domain/bo/BuildApp.java
+++ b/metis-starter/src/main/java/com/metis/domain/bo/BuildApp.java
@@ -1,5 +1,6 @@
-package com.metis.flow.domain.bo;
+package com.metis.domain.bo;
+import com.metis.domain.entity.base.Graph;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
diff --git a/src/main/java/com/metis/flow/domain/bo/CreateApp.java b/metis-starter/src/main/java/com/metis/domain/bo/CreateApp.java
similarity index 88%
rename from src/main/java/com/metis/flow/domain/bo/CreateApp.java
rename to metis-starter/src/main/java/com/metis/domain/bo/CreateApp.java
index 42f2a66..a8a9c1a 100644
--- a/src/main/java/com/metis/flow/domain/bo/CreateApp.java
+++ b/metis-starter/src/main/java/com/metis/domain/bo/CreateApp.java
@@ -1,5 +1,6 @@
-package com.metis.flow.domain.bo;
+package com.metis.domain.bo;
+import com.metis.domain.entity.base.Graph;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
diff --git a/metis-starter/src/main/java/com/metis/domain/bo/EdgeBO.java b/metis-starter/src/main/java/com/metis/domain/bo/EdgeBO.java
new file mode 100644
index 0000000..0de8c4b
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/bo/EdgeBO.java
@@ -0,0 +1,66 @@
+package com.metis.domain.bo;
+
+import com.metis.enums.EdgeType;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class EdgeBO {
+
+ /**
+ * 唯一标识符
+ */
+ @NotNull(message = "唯一标识符不能为空")
+ private String id;
+
+ /**
+ * 标签
+ */
+ private String label;
+
+ /**
+ * 节点类型
+ */
+ @NotNull(message = "线类型不能为空")
+ private EdgeType type;
+
+ /**
+ * 源节点ID,对应节点id
+ */
+ @NotNull(message = "源节点ID不能为空")
+ private Long source;
+
+ /**
+ * 目标节点ID,对应节点id
+ */
+ @NotNull(message = "目标节点ID不能为空")
+ private Long target;
+ /**
+ * 源句柄id
+ */
+ @NotNull(message = "源句柄ID不能为空")
+ private Long sourceHandle;
+
+ /**
+ * 目标句柄id
+ */
+ @NotNull(message = "目标句柄ID不能为空")
+ private Long targetHandle;
+
+ /**
+ * 边是否动画true/false
+ */
+ private Boolean animated;
+
+ /**
+ * 开始标志
+ */
+ private String markerStart;
+
+ /**
+ * 结束标记
+ */
+ private String markerEnd;
+
+
+}
diff --git a/metis-starter/src/main/java/com/metis/domain/bo/GraphBO.java b/metis-starter/src/main/java/com/metis/domain/bo/GraphBO.java
new file mode 100644
index 0000000..a5b51f5
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/bo/GraphBO.java
@@ -0,0 +1,43 @@
+package com.metis.domain.bo;
+
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class GraphBO {
+
+ /**
+ * 边缘
+ */
+ @Valid
+ @NotEmpty(message = "连线不能为空")
+ private List edges;
+
+ /**
+ * 节点
+ */
+ @Valid
+ @NotEmpty(message = "节点不能为空")
+ private List nodes;
+
+
+ /**
+ * 位置
+ */
+ private List position;
+
+ /**
+ * 变焦
+ */
+ private Double zoom;
+
+ /**
+ * 视窗
+ */
+ private ViewportBo viewport;
+
+
+}
diff --git a/metis-starter/src/main/java/com/metis/domain/bo/HandleBO.java b/metis-starter/src/main/java/com/metis/domain/bo/HandleBO.java
new file mode 100644
index 0000000..510557d
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/bo/HandleBO.java
@@ -0,0 +1,36 @@
+package com.metis.domain.bo;
+
+import com.metis.enums.HandleType;
+import com.metis.enums.PositionType;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 句柄对象
+ */
+@Data
+public class HandleBO {
+ /**
+ * 句柄id
+ */
+ @NotNull(message = "句柄id不能为空")
+ private Long id;
+
+ /**
+ * 句柄类型
+ */
+ @NotNull(message = "句柄类型不能为空")
+ private HandleType type;
+
+ /**
+ * 句柄位置
+ */
+ @NotNull(message = "句柄位置不能为空")
+ private PositionType position;
+
+ /**
+ * 是否可以连接
+ */
+ @NotNull(message = "是否可以连接不能为空")
+ private Boolean connectable;
+}
diff --git a/metis-starter/src/main/java/com/metis/domain/bo/NodeBO.java b/metis-starter/src/main/java/com/metis/domain/bo/NodeBO.java
new file mode 100644
index 0000000..9bab140
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/bo/NodeBO.java
@@ -0,0 +1,60 @@
+package com.metis.domain.bo;
+
+import com.metis.enums.NodeType;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class NodeBO {
+
+ /**
+ * id
+ */
+ @NotNull(message = "节点id不能为空")
+ private Long id;
+
+ /**
+ * 类型
+ */
+ @NotNull(message = "节点类型不能为空")
+ private NodeType type;
+
+ /**
+ * 自定义类型
+ */
+ private String customType;
+
+ /**
+ * 位置
+ */
+ @Valid
+ @NotNull(message = "节点位置不能为空")
+ private PositionBO position;
+
+ /**
+ * 业务数据
+ */
+ @Valid
+ @NotNull(message = "节点业务数据不能为空")
+ private NodeDataBO data;
+
+ /**
+ * 宽度
+ */
+// @NotNull(message = "节点宽度不能为空")
+ private Integer width;
+
+ /**
+ * 高度
+ */
+// @NotNull(message = "节点高度不能为空")
+ private Integer height;
+
+ /**
+ * 节点是否选中
+ */
+ private Boolean selected;
+
+
+}
diff --git a/metis-starter/src/main/java/com/metis/domain/bo/NodeDataBO.java b/metis-starter/src/main/java/com/metis/domain/bo/NodeDataBO.java
new file mode 100644
index 0000000..04e0c82
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/bo/NodeDataBO.java
@@ -0,0 +1,45 @@
+package com.metis.domain.bo;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.metis.enums.PositionType;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotEmpty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class NodeDataBO {
+
+ /**
+ * 标签
+ */
+ @NotBlank(message = "标签不能为空")
+ private String label;
+
+ /**
+ * 图标
+ */
+ private String icon;
+
+ /**
+ * 工具栏位置
+ */
+ private PositionType toolbarPosition;
+
+
+ /**
+ * 配置
+ */
+ private JSONObject config;
+
+ /**
+ * 句柄列表
+ */
+ @Valid
+ @NotEmpty(message = "句柄列表不能为空")
+ private List handles;
+
+
+}
diff --git a/metis-starter/src/main/java/com/metis/domain/bo/PositionBO.java b/metis-starter/src/main/java/com/metis/domain/bo/PositionBO.java
new file mode 100644
index 0000000..00f0b50
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/bo/PositionBO.java
@@ -0,0 +1,20 @@
+package com.metis.domain.bo;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class PositionBO {
+ /**
+ * x坐标
+ */
+ @NotNull(message = "x坐标不能为空")
+ private Double x;
+
+ /**
+ * y坐标
+ */
+ @NotNull(message = "y坐标不能为空")
+ private Double y;
+
+}
diff --git a/src/main/java/com/metis/domain/bo/ProcessBo.java b/metis-starter/src/main/java/com/metis/domain/bo/ProcessBo.java
similarity index 79%
rename from src/main/java/com/metis/domain/bo/ProcessBo.java
rename to metis-starter/src/main/java/com/metis/domain/bo/ProcessBo.java
index 325018e..c0075af 100644
--- a/src/main/java/com/metis/domain/bo/ProcessBo.java
+++ b/metis-starter/src/main/java/com/metis/domain/bo/ProcessBo.java
@@ -1,7 +1,7 @@
package com.metis.domain.bo;
import com.metis.enums.YesOrNoEnum;
-import com.metis.flow.domain.bo.Graph;
+import com.metis.domain.bo.GraphBO;
import lombok.Data;
@Data
@@ -13,7 +13,7 @@ public class ProcessBo {
private String description;
- private Graph graph;
+ private GraphBO graph;
private YesOrNoEnum defaultUse;
diff --git a/src/main/java/com/metis/flow/domain/bo/UpdateApp.java b/metis-starter/src/main/java/com/metis/domain/bo/UpdateApp.java
similarity index 89%
rename from src/main/java/com/metis/flow/domain/bo/UpdateApp.java
rename to metis-starter/src/main/java/com/metis/domain/bo/UpdateApp.java
index a6a0050..e4c3238 100644
--- a/src/main/java/com/metis/flow/domain/bo/UpdateApp.java
+++ b/metis-starter/src/main/java/com/metis/domain/bo/UpdateApp.java
@@ -1,6 +1,7 @@
-package com.metis.flow.domain.bo;
+package com.metis.domain.bo;
import com.metis.enums.YesOrNoEnum;
+import com.metis.domain.entity.base.Graph;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
diff --git a/metis-starter/src/main/java/com/metis/domain/bo/ViewportBo.java b/metis-starter/src/main/java/com/metis/domain/bo/ViewportBo.java
new file mode 100644
index 0000000..7209088
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/bo/ViewportBo.java
@@ -0,0 +1,10 @@
+package com.metis.domain.bo;
+
+import lombok.Data;
+
+@Data
+public class ViewportBo {
+ private Double x;
+ private Double y;
+ private Double zoom;
+}
diff --git a/src/main/java/com/metis/flow/domain/context/RunningContext.java b/metis-starter/src/main/java/com/metis/domain/context/RunningContext.java
similarity index 87%
rename from src/main/java/com/metis/flow/domain/context/RunningContext.java
rename to metis-starter/src/main/java/com/metis/domain/context/RunningContext.java
index 87d99d4..c2d1d68 100644
--- a/src/main/java/com/metis/flow/domain/context/RunningContext.java
+++ b/metis-starter/src/main/java/com/metis/domain/context/RunningContext.java
@@ -1,7 +1,7 @@
-package com.metis.flow.domain.context;
+package com.metis.domain.context;
import com.alibaba.fastjson2.JSONObject;
-import com.metis.flow.runner.FlowRunningContext;
+import com.metis.runner.FlowRunningContext;
import lombok.Builder;
import lombok.Getter;
@@ -44,6 +44,11 @@ public class RunningContext {
this.nodeRunningContext.put(nodeId, nodeRunningContext);
}
+ public JSONObject getRunningContext(Long nodeId) {
+ return this.nodeRunningContext.get(nodeId);
+ }
+
+
/**
* 构建上下文
*
@@ -58,4 +63,6 @@ public class RunningContext {
.build();
}
+
+
}
diff --git a/src/main/java/com/metis/flow/domain/context/RunningResult.java b/metis-starter/src/main/java/com/metis/domain/context/RunningResult.java
similarity index 77%
rename from src/main/java/com/metis/flow/domain/context/RunningResult.java
rename to metis-starter/src/main/java/com/metis/domain/context/RunningResult.java
index bb5b598..556e6a6 100644
--- a/src/main/java/com/metis/flow/domain/context/RunningResult.java
+++ b/metis-starter/src/main/java/com/metis/domain/context/RunningResult.java
@@ -1,4 +1,4 @@
-package com.metis.flow.domain.context;
+package com.metis.domain.context;
import com.alibaba.fastjson2.JSONObject;
import lombok.Builder;
@@ -35,6 +35,18 @@ public class RunningResult {
.build();
}
+ /**
+ * 构建结果
+ *
+ * @param nextRunNodeId 下一个运行节点id
+ * @return {@link RunningResult }
+ */
+ public static RunningResult buildResult(Set nextRunNodeId) {
+ return RunningResult.builder()
+ .nextRunNodeId(nextRunNodeId)
+ .build();
+ }
+
/**
* 构建结果
*
diff --git a/src/main/java/com/metis/flow/domain/context/SysContext.java b/metis-starter/src/main/java/com/metis/domain/context/SysContext.java
similarity index 94%
rename from src/main/java/com/metis/flow/domain/context/SysContext.java
rename to metis-starter/src/main/java/com/metis/domain/context/SysContext.java
index 54bc818..a2327e9 100644
--- a/src/main/java/com/metis/flow/domain/context/SysContext.java
+++ b/metis-starter/src/main/java/com/metis/domain/context/SysContext.java
@@ -1,4 +1,4 @@
-package com.metis.flow.domain.context;
+package com.metis.domain.context;
import lombok.Builder;
import lombok.Data;
diff --git a/src/main/java/com/metis/flow/domain/entity/App.java b/metis-starter/src/main/java/com/metis/domain/entity/App.java
similarity index 88%
rename from src/main/java/com/metis/flow/domain/entity/App.java
rename to metis-starter/src/main/java/com/metis/domain/entity/App.java
index 5b97af1..ef48d44 100644
--- a/src/main/java/com/metis/flow/domain/entity/App.java
+++ b/metis-starter/src/main/java/com/metis/domain/entity/App.java
@@ -1,8 +1,8 @@
-package com.metis.flow.domain.entity;
+package com.metis.domain.entity;
import com.metis.enums.YesOrNoEnum;
-import com.metis.flow.domain.bo.Graph;
+import com.metis.domain.entity.base.Graph;
import lombok.Data;
import java.time.LocalDateTime;
diff --git a/src/main/java/com/metis/flow/domain/entity/BaseApp.java b/metis-starter/src/main/java/com/metis/domain/entity/BaseApp.java
similarity index 97%
rename from src/main/java/com/metis/flow/domain/entity/BaseApp.java
rename to metis-starter/src/main/java/com/metis/domain/entity/BaseApp.java
index 48e9521..53204e0 100644
--- a/src/main/java/com/metis/flow/domain/entity/BaseApp.java
+++ b/metis-starter/src/main/java/com/metis/domain/entity/BaseApp.java
@@ -1,4 +1,4 @@
-package com.metis.flow.domain.entity;
+package com.metis.domain.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
diff --git a/metis-starter/src/main/java/com/metis/domain/entity/GraphDto.java b/metis-starter/src/main/java/com/metis/domain/entity/GraphDto.java
new file mode 100644
index 0000000..5de1cc2
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/entity/GraphDto.java
@@ -0,0 +1,131 @@
+package com.metis.domain.entity;
+
+
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Graph;
+import com.metis.domain.entity.base.Node;
+import com.metis.enums.NodeType;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class GraphDto {
+
+ private final Map nodeMap;
+
+ private final Map nodeReadyMap;
+
+ private final Map> edgeMap;
+
+ private final Map> adjacencyList = new HashMap<>();
+
+ private final List sortedNodes = new ArrayList<>();
+
+
+ public List getSortedNodes() {
+ return new ArrayList<>(sortedNodes);
+ }
+
+ public List getEdgeNodeId(Long nodeId) {
+ return edgeMap.getOrDefault(nodeId, new ArrayList<>());
+ }
+
+ public Node getEndNode(){
+ return sortedNodes.stream()
+ .filter(node -> NodeType.END.equals(node.getType()))
+ .findFirst()
+ .orElse(null);
+ }
+
+ public Node getNode(Long nodeId) {
+ return nodeMap.get(nodeId);
+ }
+
+ public void updateNodeReadyMap(Long nodeId, Boolean ready) {
+ nodeReadyMap.put(nodeId, ready);
+ }
+
+ public Boolean isNodeReady(Long nodeId) {
+ return nodeReadyMap.get(nodeId);
+ }
+
+
+ private GraphDto(List nodes, List edges) {
+ this.edgeMap = edges.stream()
+ .collect(Collectors.groupingBy(Edge::getSource));
+ this.nodeMap = nodes.stream()
+ .collect(Collectors.toMap(Node::getId, Function.identity()));
+ this.nodeReadyMap = nodes.stream()
+ .collect(Collectors.toMap(Node::getId, node -> false));
+ initAdjacencyList(edges);
+ List nodeList = topologicalSort();
+ this.sortedNodes.addAll(nodeList);
+ Node node = sortedNodes.get(0);
+ if (NodeType.START.equals(node.getType())) {
+ nodeReadyMap.put(node.getId(), true);
+ }
+ }
+
+ private void initAdjacencyList(List edges) {
+ for (Edge edge : edges) {
+ List targetList = adjacencyList.getOrDefault(edge.getSource(), new ArrayList<>());
+ targetList.add(edge.getTarget());
+ adjacencyList.put(edge.getSource(), targetList);
+ }
+ }
+
+
+ /**
+ * 拓扑排序
+ *
+ * @return {@link List }<{@link Node }>
+ */
+ private List topologicalSort() {
+ List sortedNodes = new ArrayList<>();
+ Set visited = new HashSet<>();
+ Set visiting = new HashSet<>();
+ for (Long nodeId : nodeMap.keySet()) {
+ if (!visited.contains(nodeId)) {
+ dfs(nodeId, visited, visiting, sortedNodes);
+ }
+ }
+ Collections.reverse(sortedNodes);
+ return sortedNodes;
+ }
+
+ /**
+ * 深度遍历找到运行顺序
+ *
+ * @param nodeId 节点id
+ * @param visited 参观了
+ * @param visiting 参观
+ * @param sortedNodes 排序节点
+ */
+ private void dfs(Long nodeId, Set visited, Set visiting, List sortedNodes) {
+ if (visiting.contains(nodeId)) {
+ throw new IllegalStateException("Cycle detected in the graph");
+ }
+ if (!visited.contains(nodeId)) {
+ visiting.add(nodeId);
+ for (Long neighbor : adjacencyList.getOrDefault(nodeId, new ArrayList<>())) {
+ dfs(neighbor, visited, visiting, sortedNodes);
+ }
+ visiting.remove(nodeId);
+ visited.add(nodeId);
+ sortedNodes.add(nodeMap.get(nodeId));
+ }
+ }
+
+
+ /**
+ * 构建对象
+ *
+ * @param graph 图
+ * @return {@link GraphDto }
+ */
+ public static GraphDto of(Graph graph) {
+ return new GraphDto(graph.getNodes(), graph.getEdges());
+ }
+
+}
diff --git a/src/main/java/com/metis/flow/domain/entity/base/Edge.java b/metis-starter/src/main/java/com/metis/domain/entity/base/Edge.java
similarity index 93%
rename from src/main/java/com/metis/flow/domain/entity/base/Edge.java
rename to metis-starter/src/main/java/com/metis/domain/entity/base/Edge.java
index 96e72d2..d389fec 100644
--- a/src/main/java/com/metis/flow/domain/entity/base/Edge.java
+++ b/metis-starter/src/main/java/com/metis/domain/entity/base/Edge.java
@@ -1,6 +1,6 @@
-package com.metis.flow.domain.entity.base;
+package com.metis.domain.entity.base;
-import com.metis.flow.enums.EdgeType;
+import com.metis.enums.EdgeType;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
diff --git a/metis-starter/src/main/java/com/metis/domain/entity/base/Graph.java b/metis-starter/src/main/java/com/metis/domain/entity/base/Graph.java
new file mode 100644
index 0000000..c440eb3
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/entity/base/Graph.java
@@ -0,0 +1,47 @@
+package com.metis.domain.entity.base;
+
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class Graph {
+
+ /**
+ * 边缘
+ */
+ @Valid
+ @NotEmpty(message = "连线不能为空")
+ private List edges;
+
+ /**
+ * 节点
+ */
+ @Valid
+ @NotEmpty(message = "节点不能为空")
+ private List nodes;
+
+ /**
+ * 位置
+ */
+ private List position;
+
+ /**
+ * 变焦
+ */
+ private Double zoom;
+
+ /**
+ * 视窗
+ */
+ private Viewport viewport;
+
+
+
+}
diff --git a/src/main/java/com/metis/flow/domain/entity/base/Handle.java b/metis-starter/src/main/java/com/metis/domain/entity/base/Handle.java
similarity index 82%
rename from src/main/java/com/metis/flow/domain/entity/base/Handle.java
rename to metis-starter/src/main/java/com/metis/domain/entity/base/Handle.java
index acaa9b5..f0e3e32 100644
--- a/src/main/java/com/metis/flow/domain/entity/base/Handle.java
+++ b/metis-starter/src/main/java/com/metis/domain/entity/base/Handle.java
@@ -1,7 +1,7 @@
-package com.metis.flow.domain.entity.base;
+package com.metis.domain.entity.base;
-import com.metis.flow.enums.HandleType;
-import com.metis.flow.enums.PositionType;
+import com.metis.enums.HandleType;
+import com.metis.enums.PositionType;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
diff --git a/src/main/java/com/metis/flow/domain/entity/base/Node.java b/metis-starter/src/main/java/com/metis/domain/entity/base/Node.java
similarity index 65%
rename from src/main/java/com/metis/flow/domain/entity/base/Node.java
rename to metis-starter/src/main/java/com/metis/domain/entity/base/Node.java
index 20dff37..c5d976b 100644
--- a/src/main/java/com/metis/flow/domain/entity/base/Node.java
+++ b/metis-starter/src/main/java/com/metis/domain/entity/base/Node.java
@@ -1,16 +1,11 @@
-package com.metis.flow.domain.entity.base;
+package com.metis.domain.entity.base;
-import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.metis.flow.enums.NodeType;
+import com.metis.enums.NodeType;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
-import java.util.Map;
-import java.util.stream.Collectors;
-
@Data
public class Node {
@@ -26,6 +21,8 @@ public class Node {
@NotNull(message = "节点类型不能为空")
private NodeType type;
+ private String customType;
+
/**
* 位置
*/
@@ -57,21 +54,31 @@ public class Node {
*/
private Boolean selected;
+ private transient Class> configClass;
- @JsonIgnore
- public Map getHandleMap() {
- if (CollUtil.isEmpty(data.getHandles())) {
- return Map.of();
- }
- return data.getHandles().stream().collect(Collectors.toMap(Handle::getId, handle -> handle));
- }
- @JsonIgnore
+ /**
+ * 获取配置
+ *
+ * @return {@link T }
+ */
public T getConfig() {
if (ObjectUtil.isNull(data.getConfig())) {
return null;
}
- return (T) data.getConfig().to(type.getConfigClass());
+ return (T) data.getConfig().to(configClass);
+ }
+
+ /**
+ * 设置配置类
+ *
+ * @param configClass 配置类
+ */
+ public void setConfigClass(Class configClass) {
+ if (ObjectUtil.isNotNull(this.configClass)) {
+ return;
+ }
+ this.configClass = configClass;
}
}
diff --git a/metis-starter/src/main/java/com/metis/domain/entity/base/NodeConfig.java b/metis-starter/src/main/java/com/metis/domain/entity/base/NodeConfig.java
new file mode 100644
index 0000000..f96afd2
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/entity/base/NodeConfig.java
@@ -0,0 +1,4 @@
+package com.metis.domain.entity.base;
+
+public abstract class NodeConfig {
+}
diff --git a/src/main/java/com/metis/flow/domain/entity/base/NodeData.java b/metis-starter/src/main/java/com/metis/domain/entity/base/NodeData.java
similarity index 67%
rename from src/main/java/com/metis/flow/domain/entity/base/NodeData.java
rename to metis-starter/src/main/java/com/metis/domain/entity/base/NodeData.java
index ed632d2..9aa53f7 100644
--- a/src/main/java/com/metis/flow/domain/entity/base/NodeData.java
+++ b/metis-starter/src/main/java/com/metis/domain/entity/base/NodeData.java
@@ -1,11 +1,10 @@
-package com.metis.flow.domain.entity.base;
+package com.metis.domain.entity.base;
import com.alibaba.fastjson2.JSONObject;
-import com.metis.flow.enums.PositionType;
+import com.metis.enums.PositionType;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Size;
+import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
@@ -30,8 +29,6 @@ public class NodeData {
private PositionType toolbarPosition;
-
-
/**
* 配置
*/
@@ -41,8 +38,7 @@ public class NodeData {
* 句柄列表
*/
@Valid
- @NotNull(message = "句柄列表不能为空")
- @Size(min = 1, message = "句柄列表不能为空")
+ @NotEmpty(message = "句柄列表不能为空")
private List handles;
diff --git a/src/main/java/com/metis/flow/domain/entity/base/NodeVariable.java b/metis-starter/src/main/java/com/metis/domain/entity/base/NodeVariable.java
similarity index 94%
rename from src/main/java/com/metis/flow/domain/entity/base/NodeVariable.java
rename to metis-starter/src/main/java/com/metis/domain/entity/base/NodeVariable.java
index 0a93469..3058bbd 100644
--- a/src/main/java/com/metis/flow/domain/entity/base/NodeVariable.java
+++ b/metis-starter/src/main/java/com/metis/domain/entity/base/NodeVariable.java
@@ -1,11 +1,11 @@
-package com.metis.flow.domain.entity.base;
+package com.metis.domain.entity.base;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.metis.flow.enums.FileUploadType;
-import com.metis.flow.enums.NodeVariableType;
+import com.metis.enums.FileUploadType;
+import com.metis.enums.NodeVariableType;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
diff --git a/src/main/java/com/metis/flow/domain/entity/base/Position.java b/metis-starter/src/main/java/com/metis/domain/entity/base/Position.java
similarity index 87%
rename from src/main/java/com/metis/flow/domain/entity/base/Position.java
rename to metis-starter/src/main/java/com/metis/domain/entity/base/Position.java
index 291cf55..2beec9f 100644
--- a/src/main/java/com/metis/flow/domain/entity/base/Position.java
+++ b/metis-starter/src/main/java/com/metis/domain/entity/base/Position.java
@@ -1,4 +1,4 @@
-package com.metis.flow.domain.entity.base;
+package com.metis.domain.entity.base;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
diff --git a/src/main/java/com/metis/flow/domain/entity/base/VariableOption.java b/metis-starter/src/main/java/com/metis/domain/entity/base/VariableOption.java
similarity index 85%
rename from src/main/java/com/metis/flow/domain/entity/base/VariableOption.java
rename to metis-starter/src/main/java/com/metis/domain/entity/base/VariableOption.java
index cc3a4ef..7ac3e13 100644
--- a/src/main/java/com/metis/flow/domain/entity/base/VariableOption.java
+++ b/metis-starter/src/main/java/com/metis/domain/entity/base/VariableOption.java
@@ -1,4 +1,4 @@
-package com.metis.flow.domain.entity.base;
+package com.metis.domain.entity.base;
import jakarta.validation.constraints.NotNull;
diff --git a/metis-starter/src/main/java/com/metis/domain/entity/base/Viewport.java b/metis-starter/src/main/java/com/metis/domain/entity/base/Viewport.java
new file mode 100644
index 0000000..039f996
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/entity/base/Viewport.java
@@ -0,0 +1,10 @@
+package com.metis.domain.entity.base;
+
+import lombok.Data;
+
+@Data
+public class Viewport {
+ private Double x;
+ private Double y;
+ private Double zoom;
+}
diff --git a/metis-starter/src/main/java/com/metis/domain/entity/config/node/DocumentExtractorNodeConfig.java b/metis-starter/src/main/java/com/metis/domain/entity/config/node/DocumentExtractorNodeConfig.java
new file mode 100644
index 0000000..eae223c
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/entity/config/node/DocumentExtractorNodeConfig.java
@@ -0,0 +1,15 @@
+package com.metis.domain.entity.config.node;
+
+import com.metis.domain.entity.base.NodeConfig;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class DocumentExtractorNodeConfig extends NodeConfig {
+
+ @NotBlank(message = "文件类型不能为空")
+ private String fileType;
+
+}
diff --git a/metis-starter/src/main/java/com/metis/domain/entity/config/node/EndNodeConfig.java b/metis-starter/src/main/java/com/metis/domain/entity/config/node/EndNodeConfig.java
new file mode 100644
index 0000000..202e601
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/entity/config/node/EndNodeConfig.java
@@ -0,0 +1,10 @@
+package com.metis.domain.entity.config.node;
+
+import com.metis.domain.entity.base.NodeConfig;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class EndNodeConfig extends NodeConfig {
+}
diff --git a/metis-starter/src/main/java/com/metis/domain/entity/config/node/LLMNodeConfig.java b/metis-starter/src/main/java/com/metis/domain/entity/config/node/LLMNodeConfig.java
new file mode 100644
index 0000000..6a2df06
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/entity/config/node/LLMNodeConfig.java
@@ -0,0 +1,10 @@
+package com.metis.domain.entity.config.node;
+
+import com.metis.domain.entity.base.NodeConfig;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class LLMNodeConfig extends NodeConfig {
+}
diff --git a/metis-starter/src/main/java/com/metis/domain/entity/config/node/QuestionClassifierConfig.java b/metis-starter/src/main/java/com/metis/domain/entity/config/node/QuestionClassifierConfig.java
new file mode 100644
index 0000000..caef097
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/entity/config/node/QuestionClassifierConfig.java
@@ -0,0 +1,10 @@
+package com.metis.domain.entity.config.node;
+
+import com.metis.domain.entity.base.NodeConfig;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class QuestionClassifierConfig extends NodeConfig {
+}
diff --git a/metis-starter/src/main/java/com/metis/domain/entity/config/node/StartNodeConfig.java b/metis-starter/src/main/java/com/metis/domain/entity/config/node/StartNodeConfig.java
new file mode 100644
index 0000000..4f37e13
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/entity/config/node/StartNodeConfig.java
@@ -0,0 +1,19 @@
+package com.metis.domain.entity.config.node;
+
+import com.metis.domain.entity.base.NodeConfig;
+import com.metis.domain.entity.base.NodeVariable;
+import jakarta.validation.Valid;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class StartNodeConfig extends NodeConfig {
+
+ @Valid
+ private List variables;
+
+
+}
diff --git a/metis-starter/src/main/java/com/metis/domain/entity/config/package-info.java b/metis-starter/src/main/java/com/metis/domain/entity/config/package-info.java
new file mode 100644
index 0000000..e836bd2
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/domain/entity/config/package-info.java
@@ -0,0 +1 @@
+package com.metis.domain.entity.config;
\ No newline at end of file
diff --git a/src/main/java/com/metis/flow/domain/query/AppQuery.java b/metis-starter/src/main/java/com/metis/domain/query/AppQuery.java
similarity index 82%
rename from src/main/java/com/metis/flow/domain/query/AppQuery.java
rename to metis-starter/src/main/java/com/metis/domain/query/AppQuery.java
index 2cd0ebe..5fb28ce 100644
--- a/src/main/java/com/metis/flow/domain/query/AppQuery.java
+++ b/metis-starter/src/main/java/com/metis/domain/query/AppQuery.java
@@ -1,4 +1,4 @@
-package com.metis.flow.domain.query;
+package com.metis.domain.query;
import lombok.Builder;
import lombok.Data;
diff --git a/src/main/java/com/metis/flow/engine/AppEngineService.java b/metis-starter/src/main/java/com/metis/engine/AppEngineService.java
similarity index 86%
rename from src/main/java/com/metis/flow/engine/AppEngineService.java
rename to metis-starter/src/main/java/com/metis/engine/AppEngineService.java
index 4ce22c8..dac3ee6 100644
--- a/src/main/java/com/metis/flow/engine/AppEngineService.java
+++ b/metis-starter/src/main/java/com/metis/engine/AppEngineService.java
@@ -1,9 +1,10 @@
-package com.metis.flow.engine;
+package com.metis.engine;
-import com.metis.flow.domain.query.AppQuery;
-import com.metis.flow.domain.entity.App;
-import com.metis.flow.domain.bo.CreateApp;
-import com.metis.flow.domain.bo.UpdateApp;
+
+import com.metis.domain.bo.CreateApp;
+import com.metis.domain.bo.UpdateApp;
+import com.metis.domain.entity.App;
+import com.metis.domain.query.AppQuery;
import java.util.List;
diff --git a/src/main/java/com/metis/flow/engine/AppFlowEngineRunnerService.java b/metis-starter/src/main/java/com/metis/engine/AppFlowEngineRunnerService.java
similarity index 70%
rename from src/main/java/com/metis/flow/engine/AppFlowEngineRunnerService.java
rename to metis-starter/src/main/java/com/metis/engine/AppFlowEngineRunnerService.java
index dfb85c3..fe0d367 100644
--- a/src/main/java/com/metis/flow/engine/AppFlowEngineRunnerService.java
+++ b/metis-starter/src/main/java/com/metis/engine/AppFlowEngineRunnerService.java
@@ -1,7 +1,7 @@
-package com.metis.flow.engine;
+package com.metis.engine;
-import com.metis.flow.runner.FlowRunningContext;
-import com.metis.flow.runner.RunnerResult;
+import com.metis.runner.FlowRunningContext;
+import com.metis.runner.RunnerResult;
/**
* 应用引擎运行器服务
diff --git a/src/main/java/com/metis/flow/engine/impl/AppEngineServiceImpl.java b/metis-starter/src/main/java/com/metis/engine/impl/AppEngineServiceImpl.java
similarity index 89%
rename from src/main/java/com/metis/flow/engine/impl/AppEngineServiceImpl.java
rename to metis-starter/src/main/java/com/metis/engine/impl/AppEngineServiceImpl.java
index 92c5bc1..0a3a993 100644
--- a/src/main/java/com/metis/flow/engine/impl/AppEngineServiceImpl.java
+++ b/metis-starter/src/main/java/com/metis/engine/impl/AppEngineServiceImpl.java
@@ -1,19 +1,20 @@
-package com.metis.flow.engine.impl;
+package com.metis.engine.impl;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
+import com.metis.constant.BaseConstant;
+import com.metis.convert.BaseAppConvert;
+import com.metis.domain.bo.BuildApp;
+import com.metis.domain.bo.CreateApp;
+import com.metis.domain.bo.UpdateApp;
+import com.metis.domain.entity.App;
+import com.metis.domain.entity.BaseApp;
+import com.metis.domain.query.AppQuery;
+import com.metis.engine.AppEngineService;
import com.metis.enums.YesOrNoEnum;
-import com.metis.flow.constant.BaseConstant;
-import com.metis.flow.convert.BaseAppConvert;
-import com.metis.flow.domain.bo.BuildApp;
-import com.metis.flow.domain.bo.CreateApp;
-import com.metis.flow.domain.bo.UpdateApp;
-import com.metis.flow.domain.query.AppQuery;
-import com.metis.flow.domain.entity.*;
-import com.metis.flow.engine.AppEngineService;
-import com.metis.flow.service.BaseAppService;
-import com.metis.flow.validator.ValidatorService;
+import com.metis.service.BaseAppService;
+import com.metis.validator.ValidatorService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -67,6 +68,7 @@ public class AppEngineServiceImpl implements AppEngineService {
}
@Override
+ @Transactional(rollbackFor = Exception.class)
public App create(CreateApp createApp) {
BuildApp buildApp = BaseAppConvert.INSTANCE.toBuildApp(createApp);
// 校验
diff --git a/metis-starter/src/main/java/com/metis/engine/impl/AppFlowEngineRunnerServiceImpl.java b/metis-starter/src/main/java/com/metis/engine/impl/AppFlowEngineRunnerServiceImpl.java
new file mode 100644
index 0000000..9f64f8f
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/engine/impl/AppFlowEngineRunnerServiceImpl.java
@@ -0,0 +1,159 @@
+package com.metis.engine.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.metis.domain.context.RunningContext;
+import com.metis.domain.context.RunningResult;
+import com.metis.domain.context.SysContext;
+import com.metis.domain.entity.App;
+import com.metis.domain.entity.GraphDto;
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.engine.AppEngineService;
+import com.metis.engine.AppFlowEngineRunnerService;
+import com.metis.enums.NodeType;
+import com.metis.runner.FlowRunningContext;
+import com.metis.runner.NodeRunner;
+import com.metis.runner.RunnerResult;
+import com.metis.runner.factory.NodeRunnerFactory;
+import com.metis.utils.GenericInterfacesUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class AppFlowEngineRunnerServiceImpl implements AppFlowEngineRunnerService {
+
+ private final AppEngineService appEngineService;
+
+
+ @Override
+ public RunnerResult running(FlowRunningContext context) {
+ App app = getApp(context);
+ Assert.isTrue(ObjectUtil.isNotNull(app), "app为空");
+ // 构建运行实例, 并将运行实例放入上下文
+ Long instanceId = IdUtil.getSnowflakeNextId();
+ // 构建系统上下文信息
+ SysContext sysContext = SysContext.builder()
+ .files(context.getFiles())
+ .appId(app.getId())
+ .workflowId(app.getWorkflowId())
+ .instanceId(instanceId)
+ .build();
+ // 构建运行中上下文
+ RunningContext runningContext = RunningContext.buildContext(sysContext, context);
+ // 构建节点映射对象
+ GraphDto graph = GraphDto.of(app.getGraph());
+ Set readyRunningNode = new HashSet<>();
+
+ // 获取到开始节点
+ // 开始节点为空,则表示数据存在异常
+ Assert.isTrue(ObjectUtil.isNotNull(readyRunningNode), "流程图不存在开始节点");
+ for (Node node : graph.getSortedNodes()) {
+ Long nodeId = node.getId();
+ if (!graph.isNodeReady(nodeId)) {
+ continue;
+ }
+ log.info("当前运行节点 id:{}, name:{}, type:{}", node.getId(), node.getData().getLabel(), node.getType());
+ // 当前节点接下来的连接线信息
+ List edges = graph.getEdgeNodeId(nodeId);
+ // 执行
+ NodeRunner nodeRunner = getNodeRunner(node);
+ node.setConfigClass(GenericInterfacesUtils.getClass(nodeRunner));
+ // 下一个需要运行的节点id加入到可以运行的节点中
+ // 获取到返回结果
+ RunningResult result = nodeRunner.run(runningContext, node, edges);
+ log.info("节点执行结果:{}", JSON.toJSONString(result));
+ // 节点执行结果参数放入上下文中
+ if (ObjectUtil.isNotNull(result.getNodeContext())) {
+ runningContext.addNodeRunningContext(node.getId(), result.getNodeContext());
+ }
+ // 下一个需要运行的节点id加入到可以运行的节点中
+ if (CollUtil.isNotEmpty(result.getNextRunNodeId())) {
+ for (Long nextNodeId : result.getNextRunNodeId()) {
+ graph.updateNodeReadyMap(nextNodeId, true);
+ }
+ } else {
+ // 如果没有返回, 则认为所有的下级节点都需要运行
+ edges.forEach(edge -> {
+ graph.updateNodeReadyMap(edge.getTarget(), true);
+ });
+ }
+ }
+ Node endNode = graph.getEndNode();
+
+ JSONObject endRunningContext = runningContext.getRunningContext(endNode.getId());
+
+ return RunnerResult.builder()
+ .result(endRunningContext)
+ .context(sysContext)
+ .build();
+
+ }
+
+ private void doRunning(Set readyRunningNode, Map> edgeMap, RunningContext runningContext) {
+ Set nextRunningNodeId = new HashSet<>();
+ for (Node runningNode : readyRunningNode) {
+ // 当前节点接下来的连接线信息
+ List edges = edgeMap.getOrDefault(runningNode.getId(), new ArrayList<>());
+ // 执行
+ NodeRunner nodeRunner = getNodeRunner(runningNode);
+ runningNode.setConfigClass(GenericInterfacesUtils.getClass(nodeRunner));
+ // 获取到返回结果
+ RunningResult result = nodeRunner.run(runningContext, runningNode, edges);
+ // 节点执行结果参数放入上下文中
+ if (ObjectUtil.isNotNull(result.getNodeContext())) {
+ runningContext.addNodeRunningContext(runningNode.getId(), result.getNodeContext());
+ }
+ if (CollUtil.isNotEmpty(result.getNextRunNodeId())) {
+ nextRunningNodeId.addAll(result.getNextRunNodeId());
+ }
+ }
+ }
+
+
+ private RunningResult doRunning(RunningContext runningContext, Node node, List edges) {
+ NodeRunner nodeRunner = getNodeRunner(node);
+ node.setConfigClass(GenericInterfacesUtils.getClass(nodeRunner));
+ // 获取到返回结果
+ return nodeRunner.run(runningContext, node, edges);
+ }
+
+
+ /**
+ * 获取节点运行程序
+ *
+ * @param node 节点
+ * @return {@link NodeRunner }
+ */
+ private NodeRunner getNodeRunner(Node node) {
+ if (NodeType.CUSTOM.equals(node.getType())) {
+ Assert.isTrue(StrUtil.isNotBlank(node.getCustomType()), "自定义节点类型不能为空");
+ return NodeRunnerFactory.getCustom(node.getCustomType());
+ }
+ return NodeRunnerFactory.get(node.getType());
+ }
+
+
+ /**
+ * 获取到应用程序信息
+ *
+ * @param context 上下文
+ * @return {@link App }
+ */
+ private App getApp(FlowRunningContext context) {
+ if (ObjectUtil.isNotNull(context.getWorkflowId())) {
+ return appEngineService.getByWorkflowId(context.getWorkflowId());
+ }
+ return appEngineService.getByAppId(context.getAppId());
+ }
+}
diff --git a/src/main/java/com/metis/enums/BaseEnum.java b/metis-starter/src/main/java/com/metis/enums/BaseEnum.java
similarity index 100%
rename from src/main/java/com/metis/enums/BaseEnum.java
rename to metis-starter/src/main/java/com/metis/enums/BaseEnum.java
diff --git a/src/main/java/com/metis/flow/enums/EdgeType.java b/metis-starter/src/main/java/com/metis/enums/EdgeType.java
similarity index 96%
rename from src/main/java/com/metis/flow/enums/EdgeType.java
rename to metis-starter/src/main/java/com/metis/enums/EdgeType.java
index 4113c13..0a53b1a 100644
--- a/src/main/java/com/metis/flow/enums/EdgeType.java
+++ b/metis-starter/src/main/java/com/metis/enums/EdgeType.java
@@ -1,4 +1,4 @@
-package com.metis.flow.enums;
+package com.metis.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
diff --git a/src/main/java/com/metis/flow/enums/FileUploadType.java b/metis-starter/src/main/java/com/metis/enums/FileUploadType.java
similarity index 96%
rename from src/main/java/com/metis/flow/enums/FileUploadType.java
rename to metis-starter/src/main/java/com/metis/enums/FileUploadType.java
index 15181df..f1bde0a 100644
--- a/src/main/java/com/metis/flow/enums/FileUploadType.java
+++ b/metis-starter/src/main/java/com/metis/enums/FileUploadType.java
@@ -1,4 +1,4 @@
-package com.metis.flow.enums;
+package com.metis.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
diff --git a/src/main/java/com/metis/flow/enums/HandleType.java b/metis-starter/src/main/java/com/metis/enums/HandleType.java
similarity index 96%
rename from src/main/java/com/metis/flow/enums/HandleType.java
rename to metis-starter/src/main/java/com/metis/enums/HandleType.java
index 37dc51e..227ac69 100644
--- a/src/main/java/com/metis/flow/enums/HandleType.java
+++ b/metis-starter/src/main/java/com/metis/enums/HandleType.java
@@ -1,4 +1,4 @@
-package com.metis.flow.enums;
+package com.metis.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
diff --git a/src/main/java/com/metis/flow/enums/NodeType.java b/metis-starter/src/main/java/com/metis/enums/NodeType.java
similarity index 65%
rename from src/main/java/com/metis/flow/enums/NodeType.java
rename to metis-starter/src/main/java/com/metis/enums/NodeType.java
index a56c7fb..89717e7 100644
--- a/src/main/java/com/metis/flow/enums/NodeType.java
+++ b/metis-starter/src/main/java/com/metis/enums/NodeType.java
@@ -1,9 +1,7 @@
-package com.metis.flow.enums;
+package com.metis.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
-import com.metis.flow.domain.entity.config.node.DocumentExtractorNodeConfig;
-import com.metis.flow.domain.entity.config.node.StartNodeConfig;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -13,9 +11,16 @@ import java.util.Arrays;
@AllArgsConstructor
public enum NodeType {
- START(1, "start", "开始", StartNodeConfig.class),
- END(2, "end", "结束", Object.class),
- DOCUMENT_EXTRACTOR(3, "document-extractor", "文档提取器", DocumentExtractorNodeConfig.class);
+ START(1, "start", "开始"),
+ END(2, "end", "结束"),
+ DOCUMENT_EXTRACTOR(3, "documentExtractor", "文档提取器"),
+ CUSTOM(4, "custom", "自定义节点"),
+ LLM(5, "llm", "LLM"),
+ QUESTION_CLASSIFIER(6, "questionClassifier", "问题分类器"),
+ IF_ELSE(7, "ifElse", "条件判断"),
+
+
+ ;
private final Integer code;
@@ -25,8 +30,6 @@ public enum NodeType {
private final String name;
- private final Class> configClass;
-
/**
* 枚举序列化器(前端传code时自动转换为对应枚举)
diff --git a/src/main/java/com/metis/flow/enums/NodeVariableType.java b/metis-starter/src/main/java/com/metis/enums/NodeVariableType.java
similarity index 97%
rename from src/main/java/com/metis/flow/enums/NodeVariableType.java
rename to metis-starter/src/main/java/com/metis/enums/NodeVariableType.java
index e9617ca..09ca06d 100644
--- a/src/main/java/com/metis/flow/enums/NodeVariableType.java
+++ b/metis-starter/src/main/java/com/metis/enums/NodeVariableType.java
@@ -1,4 +1,4 @@
-package com.metis.flow.enums;
+package com.metis.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
diff --git a/src/main/java/com/metis/flow/enums/PositionType.java b/metis-starter/src/main/java/com/metis/enums/PositionType.java
similarity index 97%
rename from src/main/java/com/metis/flow/enums/PositionType.java
rename to metis-starter/src/main/java/com/metis/enums/PositionType.java
index 98eb1d0..a5d67a1 100644
--- a/src/main/java/com/metis/flow/enums/PositionType.java
+++ b/metis-starter/src/main/java/com/metis/enums/PositionType.java
@@ -1,4 +1,4 @@
-package com.metis.flow.enums;
+package com.metis.enums;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
diff --git a/src/main/java/com/metis/enums/ResultEnum.java b/metis-starter/src/main/java/com/metis/enums/ResultEnum.java
similarity index 100%
rename from src/main/java/com/metis/enums/ResultEnum.java
rename to metis-starter/src/main/java/com/metis/enums/ResultEnum.java
diff --git a/src/main/java/com/metis/enums/YesOrNoEnum.java b/metis-starter/src/main/java/com/metis/enums/YesOrNoEnum.java
similarity index 100%
rename from src/main/java/com/metis/enums/YesOrNoEnum.java
rename to metis-starter/src/main/java/com/metis/enums/YesOrNoEnum.java
diff --git a/src/main/java/com/metis/facade/ProcessDefinitionFacade.java b/metis-starter/src/main/java/com/metis/facade/ProcessDefinitionFacade.java
similarity index 71%
rename from src/main/java/com/metis/facade/ProcessDefinitionFacade.java
rename to metis-starter/src/main/java/com/metis/facade/ProcessDefinitionFacade.java
index d1b4958..7926301 100644
--- a/src/main/java/com/metis/facade/ProcessDefinitionFacade.java
+++ b/metis-starter/src/main/java/com/metis/facade/ProcessDefinitionFacade.java
@@ -1,10 +1,12 @@
package com.metis.facade;
+import com.metis.convert.GraphConvert;
+import com.metis.domain.bo.CreateApp;
import com.metis.domain.bo.ProcessBo;
-import com.metis.flow.domain.entity.App;
-import com.metis.flow.domain.bo.CreateApp;
-import com.metis.flow.domain.bo.UpdateApp;
-import com.metis.flow.engine.AppEngineService;
+import com.metis.domain.bo.UpdateApp;
+import com.metis.domain.entity.App;
+import com.metis.domain.entity.base.Graph;
+import com.metis.engine.AppEngineService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -22,9 +24,10 @@ public class ProcessDefinitionFacade {
* @param processBo 过程业务对象
*/
public Long create(ProcessBo processBo) {
+ Graph graph = GraphConvert.INSTANCE.toEntity(processBo.getGraph());
CreateApp createApp = CreateApp.builder()
.name(processBo.getName())
- .graph(processBo.getGraph())
+ .graph(graph)
.build();
App app = appEngineService.create(createApp);
return app.getWorkflowId();
@@ -35,11 +38,12 @@ public class ProcessDefinitionFacade {
}
public void update(ProcessBo processBo) {
+ Graph graph = GraphConvert.INSTANCE.toEntity(processBo.getGraph());
appEngineService.update(UpdateApp.builder()
.defaultUse(processBo.getDefaultUse())
.appId(processBo.getAppId())
.name(processBo.getName())
- .graph(processBo.getGraph())
+ .graph(graph)
.build());
}
diff --git a/src/main/java/com/metis/handle/GlobalExceptionHandler.java b/metis-starter/src/main/java/com/metis/handle/GlobalExceptionHandler.java
similarity index 100%
rename from src/main/java/com/metis/handle/GlobalExceptionHandler.java
rename to metis-starter/src/main/java/com/metis/handle/GlobalExceptionHandler.java
diff --git a/src/main/java/com/metis/flow/mapper/BaseAppMapper.java b/metis-starter/src/main/java/com/metis/mapper/BaseAppMapper.java
similarity index 76%
rename from src/main/java/com/metis/flow/mapper/BaseAppMapper.java
rename to metis-starter/src/main/java/com/metis/mapper/BaseAppMapper.java
index cb09b20..e9b88fc 100644
--- a/src/main/java/com/metis/flow/mapper/BaseAppMapper.java
+++ b/metis-starter/src/main/java/com/metis/mapper/BaseAppMapper.java
@@ -1,6 +1,6 @@
-package com.metis.flow.mapper;
+package com.metis.mapper;
-import com.metis.flow.domain.entity.BaseApp;
+import com.metis.domain.entity.BaseApp;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
diff --git a/src/main/java/com/metis/mybatis/MybatisPlusConfiguration.java b/metis-starter/src/main/java/com/metis/mybatis/MybatisPlusConfiguration.java
similarity index 100%
rename from src/main/java/com/metis/mybatis/MybatisPlusConfiguration.java
rename to metis-starter/src/main/java/com/metis/mybatis/MybatisPlusConfiguration.java
diff --git a/src/main/java/com/metis/mybatis/handler/BaseEntityMetaObjectHandler.java b/metis-starter/src/main/java/com/metis/mybatis/handler/BaseEntityMetaObjectHandler.java
similarity index 100%
rename from src/main/java/com/metis/mybatis/handler/BaseEntityMetaObjectHandler.java
rename to metis-starter/src/main/java/com/metis/mybatis/handler/BaseEntityMetaObjectHandler.java
diff --git a/src/main/java/com/metis/mybatis/logic/SelectIgnoreLogicDelete.java b/metis-starter/src/main/java/com/metis/mybatis/logic/SelectIgnoreLogicDelete.java
similarity index 100%
rename from src/main/java/com/metis/mybatis/logic/SelectIgnoreLogicDelete.java
rename to metis-starter/src/main/java/com/metis/mybatis/logic/SelectIgnoreLogicDelete.java
diff --git a/src/main/java/com/metis/mybatis/support/CustomSqlInjector.java b/metis-starter/src/main/java/com/metis/mybatis/support/CustomSqlInjector.java
similarity index 100%
rename from src/main/java/com/metis/mybatis/support/CustomSqlInjector.java
rename to metis-starter/src/main/java/com/metis/mybatis/support/CustomSqlInjector.java
diff --git a/src/main/java/com/metis/result/Result.java b/metis-starter/src/main/java/com/metis/result/Result.java
similarity index 100%
rename from src/main/java/com/metis/result/Result.java
rename to metis-starter/src/main/java/com/metis/result/Result.java
diff --git a/src/main/java/com/metis/result/page/TableDataInfo.java b/metis-starter/src/main/java/com/metis/result/page/TableDataInfo.java
similarity index 100%
rename from src/main/java/com/metis/result/page/TableDataInfo.java
rename to metis-starter/src/main/java/com/metis/result/page/TableDataInfo.java
diff --git a/metis-starter/src/main/java/com/metis/runner/CustomNodeRunner.java b/metis-starter/src/main/java/com/metis/runner/CustomNodeRunner.java
new file mode 100644
index 0000000..c0b7143
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/runner/CustomNodeRunner.java
@@ -0,0 +1,33 @@
+package com.metis.runner;
+
+import com.metis.domain.entity.base.NodeConfig;
+import com.metis.enums.NodeType;
+
+/**
+ * 自定义节点运行器
+ *
+ * @author clay
+ * @date 2025/04/20
+ */
+public interface CustomNodeRunner extends NodeRunner {
+
+
+ /**
+ * 获取自定义节点的节点类型
+ *
+ * @return {@link String }
+ */
+ String getCustomNodeType();
+
+
+ /**
+ * 得到类型
+ *
+ * @return {@link NodeType }
+ */
+ default NodeType getType() {
+ return NodeType.CUSTOM;
+ }
+
+
+}
diff --git a/src/main/java/com/metis/flow/runner/FlowRunningContext.java b/metis-starter/src/main/java/com/metis/runner/FlowRunningContext.java
similarity index 95%
rename from src/main/java/com/metis/flow/runner/FlowRunningContext.java
rename to metis-starter/src/main/java/com/metis/runner/FlowRunningContext.java
index 5159a44..022f693 100644
--- a/src/main/java/com/metis/flow/runner/FlowRunningContext.java
+++ b/metis-starter/src/main/java/com/metis/runner/FlowRunningContext.java
@@ -1,4 +1,4 @@
-package com.metis.flow.runner;
+package com.metis.runner;
import com.alibaba.fastjson2.JSONObject;
import lombok.AllArgsConstructor;
diff --git a/metis-starter/src/main/java/com/metis/runner/NodeRunner.java b/metis-starter/src/main/java/com/metis/runner/NodeRunner.java
new file mode 100644
index 0000000..cd59b92
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/runner/NodeRunner.java
@@ -0,0 +1,56 @@
+package com.metis.runner;
+
+import cn.hutool.core.collection.CollUtil;
+import com.metis.domain.context.RunningContext;
+import com.metis.domain.context.RunningResult;
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.domain.entity.base.NodeConfig;
+import com.metis.enums.NodeType;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 内置节点运行器
+ *
+ * @author clay
+ * @date 2025/04/20
+ */
+public interface NodeRunner {
+
+
+ /**
+ * 运行
+ *
+ * @param context 上下文
+ * @param node 节点配置信息
+ * @param edges 当前接下来的连线信息, 一些特殊节点需要节点内部判断下一个运行节点
+ * @return {@link RunningContext }
+ */
+ RunningResult run(RunningContext context, Node node, List edges);
+
+
+ /**
+ * 获取节点类型
+ *
+ * @return {@link NodeType }
+ */
+ NodeType getType();
+
+
+ /**
+ * 获取下一个节点id
+ *
+ * @param edges 边缘
+ * @return {@link Set }<{@link Long }>
+ */
+ default Set getNextNodeIds(List edges) {
+ if (CollUtil.isEmpty(edges)) {
+ return Set.of();
+ }
+ return edges.stream().map(Edge::getTarget).collect(Collectors.toSet());
+ }
+
+}
diff --git a/src/main/java/com/metis/flow/runner/RunnerResult.java b/metis-starter/src/main/java/com/metis/runner/RunnerResult.java
similarity index 61%
rename from src/main/java/com/metis/flow/runner/RunnerResult.java
rename to metis-starter/src/main/java/com/metis/runner/RunnerResult.java
index 0b573f4..3306ea5 100644
--- a/src/main/java/com/metis/flow/runner/RunnerResult.java
+++ b/metis-starter/src/main/java/com/metis/runner/RunnerResult.java
@@ -1,10 +1,13 @@
-package com.metis.flow.runner;
+package com.metis.runner;
-import com.metis.flow.domain.context.SysContext;
+import com.alibaba.fastjson2.JSONObject;
+import com.metis.domain.context.SysContext;
import lombok.Builder;
import lombok.Data;
+import java.util.Map;
+
/**
* 运行结果
*
@@ -18,7 +21,7 @@ public class RunnerResult {
/**
* 运行内容
*/
- private String content;
+ private JSONObject result;
/**
* 上下文
diff --git a/metis-starter/src/main/java/com/metis/runner/factory/NodeRunnerFactory.java b/metis-starter/src/main/java/com/metis/runner/factory/NodeRunnerFactory.java
new file mode 100644
index 0000000..a2204fa
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/runner/factory/NodeRunnerFactory.java
@@ -0,0 +1,64 @@
+package com.metis.runner.factory;
+
+import cn.hutool.core.lang.Assert;
+import com.metis.enums.NodeType;
+import com.metis.runner.CustomNodeRunner;
+import com.metis.runner.NodeRunner;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public final class NodeRunnerFactory {
+
+ /**
+ * 内置节点运行器
+ */
+ private static final Map NODE_MAP = new ConcurrentHashMap<>(8);
+ /**
+ * 自定义节点映射
+ */
+ private static final Map CUSTOM_NODE_MAP = new ConcurrentHashMap<>(8);
+
+ /**
+ * 注册
+ *
+ * @param runner 跑步者
+ */
+ static void register(NodeRunner runner) {
+ NODE_MAP.put(runner.getType(), runner);
+ }
+
+
+ /**
+ * 得到
+ *
+ * @param type 类型
+ * @return {@link NodeRunner }
+ */
+ public static NodeRunner get(NodeType type) {
+ return NODE_MAP.get(type);
+ }
+
+
+ /**
+ * 注册自定义节点
+ *
+ * @param runner 跑步者
+ */
+ static void registerCustom(CustomNodeRunner runner) {
+ Assert.isTrue(!CUSTOM_NODE_MAP.containsKey(runner.getCustomNodeType()), "已存在类型:{}, class:{}的运行器", runner.getCustomNodeType(), runner.getClass());
+ CUSTOM_NODE_MAP.put(runner.getCustomNodeType(), runner);
+ }
+
+ /**
+ * 得到自定义节点运行器
+ *
+ * @param type 类型
+ * @return {@link NodeRunner }
+ */
+ public static NodeRunner getCustom(String type) {
+ return CUSTOM_NODE_MAP.get(type);
+ }
+
+
+}
diff --git a/src/main/java/com/metis/flow/runner/RunnerInitialize.java b/metis-starter/src/main/java/com/metis/runner/factory/RunnerInitialize.java
similarity index 51%
rename from src/main/java/com/metis/flow/runner/RunnerInitialize.java
rename to metis-starter/src/main/java/com/metis/runner/factory/RunnerInitialize.java
index 094d7fc..b02873a 100644
--- a/src/main/java/com/metis/flow/runner/RunnerInitialize.java
+++ b/metis-starter/src/main/java/com/metis/runner/factory/RunnerInitialize.java
@@ -1,6 +1,9 @@
-package com.metis.flow.runner;
+package com.metis.runner.factory;
-import com.metis.flow.runner.factory.RunnerFactory;
+import cn.hutool.core.lang.Assert;
+import com.metis.enums.NodeType;
+import com.metis.runner.CustomNodeRunner;
+import com.metis.runner.NodeRunner;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@@ -19,9 +22,16 @@ public class RunnerInitialize implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+
Map runnerMap = applicationContext.getBeansOfType(NodeRunner.class);
- runnerMap.forEach((k, v) -> {
- RunnerFactory.register(v);
+
+ runnerMap.forEach((runnerBeanName, runner) -> {
+ if (NodeType.CUSTOM.equals(runner.getType())) {
+ Assert.isTrue(runner instanceof CustomNodeRunner, "自定义节点必须实现CustomNodeRunner接口");
+ NodeRunnerFactory.registerCustom((CustomNodeRunner) runner);
+ } else {
+ NodeRunnerFactory.register(runner);
+ }
});
}
diff --git a/metis-starter/src/main/java/com/metis/runner/impl/EndNodeRunner.java b/metis-starter/src/main/java/com/metis/runner/impl/EndNodeRunner.java
new file mode 100644
index 0000000..4aacda8
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/runner/impl/EndNodeRunner.java
@@ -0,0 +1,33 @@
+package com.metis.runner.impl;
+
+
+import com.alibaba.fastjson2.JSONObject;
+import com.metis.domain.context.RunningContext;
+import com.metis.domain.context.RunningResult;
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.domain.entity.config.node.EndNodeConfig;
+import com.metis.enums.NodeType;
+import com.metis.runner.NodeRunner;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class EndNodeRunner implements NodeRunner {
+
+ @Override
+ public RunningResult run(RunningContext context, Node node, List edges) {
+ JSONObject contextNodeValue = new JSONObject();
+ contextNodeValue.put("userId", context.getSys().getAppId());
+ return RunningResult.buildResult(contextNodeValue);
+ }
+
+ @Override
+ public NodeType getType() {
+ return NodeType.END;
+ }
+
+}
diff --git a/metis-starter/src/main/java/com/metis/runner/impl/LLMNodeRunner.java b/metis-starter/src/main/java/com/metis/runner/impl/LLMNodeRunner.java
new file mode 100644
index 0000000..1779a34
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/runner/impl/LLMNodeRunner.java
@@ -0,0 +1,27 @@
+package com.metis.runner.impl;
+
+import com.metis.domain.context.RunningContext;
+import com.metis.domain.context.RunningResult;
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.domain.entity.config.node.LLMNodeConfig;
+import com.metis.enums.NodeType;
+import com.metis.runner.NodeRunner;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class LLMNodeRunner implements NodeRunner {
+ @Override
+ public RunningResult run(RunningContext context, Node node, List edges) {
+ return RunningResult.buildResult();
+ }
+
+ @Override
+ public NodeType getType() {
+ return NodeType.LLM;
+ }
+}
diff --git a/metis-starter/src/main/java/com/metis/runner/impl/QuestionClassifierRunner.java b/metis-starter/src/main/java/com/metis/runner/impl/QuestionClassifierRunner.java
new file mode 100644
index 0000000..d23f7a5
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/runner/impl/QuestionClassifierRunner.java
@@ -0,0 +1,36 @@
+package com.metis.runner.impl;
+
+import com.metis.domain.context.RunningContext;
+import com.metis.domain.context.RunningResult;
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.domain.entity.config.node.QuestionClassifierConfig;
+import com.metis.enums.NodeType;
+import com.metis.runner.NodeRunner;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+@Slf4j
+@Service
+public class QuestionClassifierRunner implements NodeRunner {
+
+ @Override
+ public RunningResult run(RunningContext context, Node node, List edges) {
+ Set nextNodeIds = getNextNodeIds(edges);
+ // 生成随机索引
+ Random random = new Random();
+ int randomIndex = random.nextInt(nextNodeIds.size());
+ List nodeIds = new ArrayList<>(nextNodeIds);
+ return RunningResult.buildResult(Set.of(nodeIds.get(randomIndex)));
+ }
+
+ @Override
+ public NodeType getType() {
+ return NodeType.QUESTION_CLASSIFIER;
+ }
+}
diff --git a/src/main/java/com/metis/flow/runner/impl/StartNodeRunner.java b/metis-starter/src/main/java/com/metis/runner/impl/StartNodeRunner.java
similarity index 68%
rename from src/main/java/com/metis/flow/runner/impl/StartNodeRunner.java
rename to metis-starter/src/main/java/com/metis/runner/impl/StartNodeRunner.java
index 2975174..7019f92 100644
--- a/src/main/java/com/metis/flow/runner/impl/StartNodeRunner.java
+++ b/metis-starter/src/main/java/com/metis/runner/impl/StartNodeRunner.java
@@ -1,15 +1,15 @@
-package com.metis.flow.runner.impl;
+package com.metis.runner.impl;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson2.JSONObject;
-import com.metis.flow.domain.context.RunningContext;
-import com.metis.flow.domain.context.RunningResult;
-import com.metis.flow.domain.entity.base.Edge;
-import com.metis.flow.domain.entity.base.Node;
-import com.metis.flow.domain.entity.base.NodeVariable;
-import com.metis.flow.domain.entity.config.node.StartNodeConfig;
-import com.metis.flow.enums.NodeType;
-import com.metis.flow.runner.NodeRunner;
+import com.metis.domain.context.RunningContext;
+import com.metis.domain.context.RunningResult;
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.domain.entity.base.NodeVariable;
+import com.metis.domain.entity.config.node.StartNodeConfig;
+import com.metis.enums.NodeType;
+import com.metis.runner.NodeRunner;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -23,11 +23,10 @@ import java.util.List;
*/
@Slf4j
@Service
-public class StartNodeRunner implements NodeRunner {
+public class StartNodeRunner implements NodeRunner {
@Override
public RunningResult run(RunningContext context, Node node, List edges) {
- log.info("开始节点{}, 节点id: {} 运行", node.getData().getLabel(), node.getId());
StartNodeConfig config = node.getConfig();
// 获取到节点的自定义参数
List variables = config.getVariables();
diff --git a/src/main/java/com/metis/flow/service/BaseAppService.java b/metis-starter/src/main/java/com/metis/service/BaseAppService.java
similarity index 92%
rename from src/main/java/com/metis/flow/service/BaseAppService.java
rename to metis-starter/src/main/java/com/metis/service/BaseAppService.java
index 2fa231b..96d1c31 100644
--- a/src/main/java/com/metis/flow/service/BaseAppService.java
+++ b/metis-starter/src/main/java/com/metis/service/BaseAppService.java
@@ -1,8 +1,8 @@
-package com.metis.flow.service;
+package com.metis.service;
import com.metis.enums.YesOrNoEnum;
-import com.metis.flow.domain.query.AppQuery;
-import com.metis.flow.domain.entity.BaseApp;
+import com.metis.domain.query.AppQuery;
+import com.metis.domain.entity.BaseApp;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
diff --git a/src/main/java/com/metis/flow/service/impl/BaseAppServiceImpl.java b/metis-starter/src/main/java/com/metis/service/impl/BaseAppServiceImpl.java
similarity index 93%
rename from src/main/java/com/metis/flow/service/impl/BaseAppServiceImpl.java
rename to metis-starter/src/main/java/com/metis/service/impl/BaseAppServiceImpl.java
index 5cbe09a..c9263ab 100644
--- a/src/main/java/com/metis/flow/service/impl/BaseAppServiceImpl.java
+++ b/metis-starter/src/main/java/com/metis/service/impl/BaseAppServiceImpl.java
@@ -1,4 +1,4 @@
-package com.metis.flow.service.impl;
+package com.metis.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
@@ -6,10 +6,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.metis.enums.YesOrNoEnum;
-import com.metis.flow.domain.query.AppQuery;
-import com.metis.flow.domain.entity.BaseApp;
-import com.metis.flow.mapper.BaseAppMapper;
-import com.metis.flow.service.BaseAppService;
+import com.metis.domain.query.AppQuery;
+import com.metis.domain.entity.BaseApp;
+import com.metis.mapper.BaseAppMapper;
+import com.metis.service.BaseAppService;
import com.metis.utils.PageConditionUtil;
import org.springframework.stereotype.Service;
diff --git a/src/main/java/com/metis/sseclient/ToolSpecificationHelper.java b/metis-starter/src/main/java/com/metis/sseclient/ToolSpecificationHelper.java
similarity index 100%
rename from src/main/java/com/metis/sseclient/ToolSpecificationHelper.java
rename to metis-starter/src/main/java/com/metis/sseclient/ToolSpecificationHelper.java
diff --git a/src/main/java/com/metis/sseclient/check/SseCheck.java b/metis-starter/src/main/java/com/metis/sseclient/check/SseCheck.java
similarity index 100%
rename from src/main/java/com/metis/sseclient/check/SseCheck.java
rename to metis-starter/src/main/java/com/metis/sseclient/check/SseCheck.java
diff --git a/src/main/java/com/metis/sseclient/event/SseEventListener.java b/metis-starter/src/main/java/com/metis/sseclient/event/SseEventListener.java
similarity index 100%
rename from src/main/java/com/metis/sseclient/event/SseEventListener.java
rename to metis-starter/src/main/java/com/metis/sseclient/event/SseEventListener.java
diff --git a/src/main/java/com/metis/sseclient/handler/McpOperationHandler.java b/metis-starter/src/main/java/com/metis/sseclient/handler/McpOperationHandler.java
similarity index 100%
rename from src/main/java/com/metis/sseclient/handler/McpOperationHandler.java
rename to metis-starter/src/main/java/com/metis/sseclient/handler/McpOperationHandler.java
diff --git a/metis-starter/src/main/java/com/metis/utils/GenericInterfacesUtils.java b/metis-starter/src/main/java/com/metis/utils/GenericInterfacesUtils.java
new file mode 100644
index 0000000..c8b14f8
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/utils/GenericInterfacesUtils.java
@@ -0,0 +1,25 @@
+package com.metis.utils;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+public class GenericInterfacesUtils {
+
+
+ public static Class getClass(Object object) {
+
+ Type[] genericInterfaces = object.getClass().getGenericInterfaces();
+ for (Type genericInterface : genericInterfaces) {
+ if (genericInterface instanceof ParameterizedType) {
+ ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
+ Type[] typeArguments = parameterizedType.getActualTypeArguments();
+ if (typeArguments.length > 0) {
+ return (Class) typeArguments[0];
+ }
+ }
+ }
+ throw new IllegalStateException("无法获取泛型类型");
+ }
+
+
+}
diff --git a/src/main/java/com/metis/utils/LocalDateTimeUtils.java b/metis-starter/src/main/java/com/metis/utils/LocalDateTimeUtils.java
similarity index 100%
rename from src/main/java/com/metis/utils/LocalDateTimeUtils.java
rename to metis-starter/src/main/java/com/metis/utils/LocalDateTimeUtils.java
diff --git a/src/main/java/com/metis/utils/PageConditionUtil.java b/metis-starter/src/main/java/com/metis/utils/PageConditionUtil.java
similarity index 100%
rename from src/main/java/com/metis/utils/PageConditionUtil.java
rename to metis-starter/src/main/java/com/metis/utils/PageConditionUtil.java
diff --git a/src/main/java/com/metis/utils/PageInfo.java b/metis-starter/src/main/java/com/metis/utils/PageInfo.java
similarity index 100%
rename from src/main/java/com/metis/utils/PageInfo.java
rename to metis-starter/src/main/java/com/metis/utils/PageInfo.java
diff --git a/src/main/java/com/metis/utils/TableSupport.java b/metis-starter/src/main/java/com/metis/utils/TableSupport.java
similarity index 100%
rename from src/main/java/com/metis/utils/TableSupport.java
rename to metis-starter/src/main/java/com/metis/utils/TableSupport.java
diff --git a/src/main/java/com/metis/utils/TransactionalUtils.java b/metis-starter/src/main/java/com/metis/utils/TransactionalUtils.java
similarity index 100%
rename from src/main/java/com/metis/utils/TransactionalUtils.java
rename to metis-starter/src/main/java/com/metis/utils/TransactionalUtils.java
diff --git a/metis-starter/src/main/java/com/metis/validator/CustomNodeValidator.java b/metis-starter/src/main/java/com/metis/validator/CustomNodeValidator.java
new file mode 100644
index 0000000..ee37924
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/validator/CustomNodeValidator.java
@@ -0,0 +1,34 @@
+package com.metis.validator;
+
+import com.metis.domain.entity.base.NodeConfig;
+import com.metis.enums.NodeType;
+
+/**
+ * 自定义节点验证器
+ *
+ * @author clay
+ * @date 2025/04/20
+ */
+public interface CustomNodeValidator extends NodeValidator {
+
+
+ /**
+ * 获取自定义节点的节点类型
+ *
+ * @return {@link String }
+ */
+ String getCustomNodeType();
+
+
+ /**
+ * 得到类型
+ *
+ * @return {@link NodeType }
+ */
+ default NodeType getType() {
+ return NodeType.CUSTOM;
+ }
+
+
+
+}
diff --git a/src/main/java/com/metis/flow/validator/EdgeValidator.java b/metis-starter/src/main/java/com/metis/validator/EdgeValidator.java
similarity index 70%
rename from src/main/java/com/metis/flow/validator/EdgeValidator.java
rename to metis-starter/src/main/java/com/metis/validator/EdgeValidator.java
index a02d1e2..74f87b7 100644
--- a/src/main/java/com/metis/flow/validator/EdgeValidator.java
+++ b/metis-starter/src/main/java/com/metis/validator/EdgeValidator.java
@@ -1,7 +1,7 @@
-package com.metis.flow.validator;
+package com.metis.validator;
-import com.metis.flow.domain.entity.base.Edge;
-import com.metis.flow.enums.EdgeType;
+import com.metis.domain.entity.base.Edge;
+import com.metis.enums.EdgeType;
public interface EdgeValidator {
diff --git a/src/main/java/com/metis/flow/validator/NodeValidator.java b/metis-starter/src/main/java/com/metis/validator/NodeValidator.java
similarity index 68%
rename from src/main/java/com/metis/flow/validator/NodeValidator.java
rename to metis-starter/src/main/java/com/metis/validator/NodeValidator.java
index 76f8211..27aac24 100644
--- a/src/main/java/com/metis/flow/validator/NodeValidator.java
+++ b/metis-starter/src/main/java/com/metis/validator/NodeValidator.java
@@ -1,12 +1,13 @@
-package com.metis.flow.validator;
+package com.metis.validator;
-import com.metis.flow.domain.entity.base.Edge;
-import com.metis.flow.domain.entity.base.Node;
-import com.metis.flow.enums.NodeType;
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.domain.entity.base.NodeConfig;
+import com.metis.enums.NodeType;
import java.util.List;
-public interface NodeValidator {
+public interface NodeValidator {
/**
diff --git a/src/main/java/com/metis/flow/validator/ValidatorCodeService.java b/metis-starter/src/main/java/com/metis/validator/ValidatorCodeService.java
similarity index 98%
rename from src/main/java/com/metis/flow/validator/ValidatorCodeService.java
rename to metis-starter/src/main/java/com/metis/validator/ValidatorCodeService.java
index 9ee3d25..a05e326 100644
--- a/src/main/java/com/metis/flow/validator/ValidatorCodeService.java
+++ b/metis-starter/src/main/java/com/metis/validator/ValidatorCodeService.java
@@ -1,4 +1,4 @@
-package com.metis.flow.validator;
+package com.metis.validator;
import cn.hutool.core.collection.CollUtil;
import jakarta.validation.ConstraintViolation;
diff --git a/src/main/java/com/metis/flow/validator/ValidatorResult.java b/metis-starter/src/main/java/com/metis/validator/ValidatorResult.java
similarity index 93%
rename from src/main/java/com/metis/flow/validator/ValidatorResult.java
rename to metis-starter/src/main/java/com/metis/validator/ValidatorResult.java
index 8666b6e..a9e502a 100644
--- a/src/main/java/com/metis/flow/validator/ValidatorResult.java
+++ b/metis-starter/src/main/java/com/metis/validator/ValidatorResult.java
@@ -1,4 +1,4 @@
-package com.metis.flow.validator;
+package com.metis.validator;
import lombok.Data;
diff --git a/src/main/java/com/metis/flow/validator/ValidatorService.java b/metis-starter/src/main/java/com/metis/validator/ValidatorService.java
similarity index 66%
rename from src/main/java/com/metis/flow/validator/ValidatorService.java
rename to metis-starter/src/main/java/com/metis/validator/ValidatorService.java
index ac5f11f..6cf5afb 100644
--- a/src/main/java/com/metis/flow/validator/ValidatorService.java
+++ b/metis-starter/src/main/java/com/metis/validator/ValidatorService.java
@@ -1,6 +1,6 @@
-package com.metis.flow.validator;
+package com.metis.validator;
-import com.metis.flow.domain.bo.BuildApp;
+import com.metis.domain.bo.BuildApp;
public interface ValidatorService {
diff --git a/src/main/java/com/metis/flow/validator/factory/EdgeValidatorFactory.java b/metis-starter/src/main/java/com/metis/validator/factory/EdgeValidatorFactory.java
similarity index 81%
rename from src/main/java/com/metis/flow/validator/factory/EdgeValidatorFactory.java
rename to metis-starter/src/main/java/com/metis/validator/factory/EdgeValidatorFactory.java
index d3e357f..03c2eab 100644
--- a/src/main/java/com/metis/flow/validator/factory/EdgeValidatorFactory.java
+++ b/metis-starter/src/main/java/com/metis/validator/factory/EdgeValidatorFactory.java
@@ -1,7 +1,7 @@
-package com.metis.flow.validator.factory;
+package com.metis.validator.factory;
-import com.metis.flow.enums.EdgeType;
-import com.metis.flow.validator.EdgeValidator;
+import com.metis.enums.EdgeType;
+import com.metis.validator.EdgeValidator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
diff --git a/metis-starter/src/main/java/com/metis/validator/factory/NodeValidatorFactory.java b/metis-starter/src/main/java/com/metis/validator/factory/NodeValidatorFactory.java
new file mode 100644
index 0000000..14a501b
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/validator/factory/NodeValidatorFactory.java
@@ -0,0 +1,56 @@
+package com.metis.validator.factory;
+
+import cn.hutool.core.lang.Assert;
+import com.metis.enums.NodeType;
+import com.metis.validator.CustomNodeValidator;
+import com.metis.validator.NodeValidator;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+public final class NodeValidatorFactory {
+
+ /**
+ * 内置节点验证器
+ */
+ private static final Map NODE_MAP = new ConcurrentHashMap<>(8);
+ /**
+ * 自定义节点验证器
+ */
+ private static final Map CUSTOM_NODE_MAP = new ConcurrentHashMap<>(8);
+
+
+ /**
+ * 注册
+ *
+ * @param validator 验证器
+ */
+ static void register(NodeValidator validator) {
+ NODE_MAP.put(validator.getType(), validator);
+ }
+
+ /**
+ * 得到
+ *
+ * @param type 类型
+ * @return {@link NodeValidator }
+ */
+ public static NodeValidator get(NodeType type) {
+ return NODE_MAP.get(type);
+ }
+
+ /**
+ * @param validator 验证器
+ */
+ static void registerCustom(CustomNodeValidator validator) {
+ Assert.isTrue(!CUSTOM_NODE_MAP.containsKey(validator.getCustomNodeType()), "已存在类型:{}, class:{}的验证器", validator.getCustomNodeType(), validator.getClass());
+ CUSTOM_NODE_MAP.put(validator.getCustomNodeType(), validator);
+ }
+
+ public static NodeValidator getCustom(String type) {
+ return CUSTOM_NODE_MAP.get(type);
+ }
+
+
+}
diff --git a/metis-starter/src/main/java/com/metis/validator/factory/ValidatorInitialize.java b/metis-starter/src/main/java/com/metis/validator/factory/ValidatorInitialize.java
new file mode 100644
index 0000000..40b92fe
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/validator/factory/ValidatorInitialize.java
@@ -0,0 +1,43 @@
+package com.metis.validator.factory;
+
+
+import cn.hutool.core.lang.Assert;
+import com.metis.enums.NodeType;
+import com.metis.validator.CustomNodeValidator;
+import com.metis.validator.EdgeValidator;
+import com.metis.validator.NodeValidator;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+@Service
+public class ValidatorInitialize implements ApplicationContextAware {
+
+
+ @Override
+ public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
+
+ Map edgeMap = applicationContext.getBeansOfType(EdgeValidator.class);
+
+ edgeMap.forEach((edgeValidatorBeanName, edgeValidator) -> {
+ EdgeValidatorFactory.register(edgeValidator);
+ });
+
+ Map nodeMap = applicationContext.getBeansOfType(NodeValidator.class);
+
+ nodeMap.forEach((nodeValidatorBeanName, nodeValidator) -> {
+ if (NodeType.CUSTOM.equals(nodeValidator.getType())) {
+ Assert.isTrue(nodeValidator instanceof CustomNodeValidator, "自定义节点必须实现CustomNodeValidator接口");
+ NodeValidatorFactory.registerCustom((CustomNodeValidator) nodeValidator);
+ } else {
+ NodeValidatorFactory.register(nodeValidator);
+ }
+ });
+ }
+
+
+}
diff --git a/src/main/java/com/metis/flow/validator/impl/ValidatorServiceImpl.java b/metis-starter/src/main/java/com/metis/validator/impl/ValidatorServiceImpl.java
similarity index 84%
rename from src/main/java/com/metis/flow/validator/impl/ValidatorServiceImpl.java
rename to metis-starter/src/main/java/com/metis/validator/impl/ValidatorServiceImpl.java
index 17b4e8d..bd42907 100644
--- a/src/main/java/com/metis/flow/validator/impl/ValidatorServiceImpl.java
+++ b/metis-starter/src/main/java/com/metis/validator/impl/ValidatorServiceImpl.java
@@ -1,17 +1,19 @@
-package com.metis.flow.validator.impl;
+package com.metis.validator.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
-import com.metis.flow.domain.bo.BuildApp;
-import com.metis.flow.domain.bo.Graph;
-import com.metis.flow.domain.entity.base.Edge;
-import com.metis.flow.domain.entity.base.Node;
-import com.metis.flow.enums.EdgeType;
-import com.metis.flow.enums.NodeType;
-import com.metis.flow.validator.*;
-import com.metis.flow.validator.factory.EdgeValidatorFactory;
-import com.metis.flow.validator.factory.NodeValidatorFactory;
+import cn.hutool.core.util.StrUtil;
+import com.metis.domain.bo.BuildApp;
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Graph;
+import com.metis.domain.entity.base.Node;
+import com.metis.enums.EdgeType;
+import com.metis.enums.NodeType;
+import com.metis.validator.*;
+import com.metis.validator.factory.EdgeValidatorFactory;
+import com.metis.validator.factory.NodeValidatorFactory;
+import com.metis.utils.GenericInterfacesUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -28,16 +30,16 @@ public class ValidatorServiceImpl implements ValidatorService {
private final ValidatorCodeService validatorCodeService;
@Override
- public void validate(BuildApp graph) {
+ public void validate(BuildApp buildApp) {
// validation 编程式校验
- validatorCodeService.validateThrow(graph);
- Graph model = graph.getGraph();
+ validatorCodeService.validateThrow(buildApp);
+ Graph graph = buildApp.getGraph();
// 节点参数校验
- validateNode(model.getNodes());
+ validateNode(graph.getNodes());
// 线参数校验
- validateEdge(model.getEdges());
+ validateEdge(graph.getEdges());
// 关系验证
- validateRelation(model.getNodes(), model.getEdges());
+ validateRelation(graph.getNodes(), graph.getEdges());
}
@@ -50,7 +52,8 @@ public class ValidatorServiceImpl implements ValidatorService {
List errorMessage = new ArrayList<>();
for (Node node : nodes) {
NodeType type = node.getType();
- NodeValidator validator = NodeValidatorFactory.get(type);
+ NodeValidator validator = getNodeValidator(node);
+ node.setConfigClass(GenericInterfacesUtils.getClass(validator));
// 节点校验器
Assert.isTrue(ObjectUtil.isNotNull(validator), "无:{}类型的节点校验器", type.getName());
ValidatorResult result = validator.validateValue(node);
@@ -237,7 +240,7 @@ public class ValidatorServiceImpl implements ValidatorService {
Map> targetMap = edges.stream().collect(Collectors.groupingBy(Edge::getTarget));
for (Node node : nodes) {
- NodeValidator validator = NodeValidatorFactory.get(node.getType());
+ NodeValidator validator = getNodeValidator(node);
// 获取当前节点的 source 和 target
List sources = targetMap.getOrDefault(node.getId(), new ArrayList<>());
List targets = sourceMap.getOrDefault(node.getId(), new ArrayList<>());
@@ -247,4 +250,19 @@ public class ValidatorServiceImpl implements ValidatorService {
}
}
+
+ /**
+ * 获取节点验证器
+ *
+ * @param node 节点
+ * @return {@link NodeValidator }
+ */
+ private NodeValidator getNodeValidator(Node node) {
+ if (NodeType.CUSTOM.equals(node.getType())) {
+ Assert.isTrue(StrUtil.isNotBlank(node.getCustomType()), "自定义节点类型不能为空");
+ return NodeValidatorFactory.getCustom(node.getCustomType());
+ }
+ return NodeValidatorFactory.get(node.getType());
+ }
+
}
diff --git a/src/main/java/com/metis/flow/validator/impl/edge/DefaultEdgeValidator.java b/metis-starter/src/main/java/com/metis/validator/impl/edge/DefaultEdgeValidator.java
similarity index 61%
rename from src/main/java/com/metis/flow/validator/impl/edge/DefaultEdgeValidator.java
rename to metis-starter/src/main/java/com/metis/validator/impl/edge/DefaultEdgeValidator.java
index 3012647..086d98e 100644
--- a/src/main/java/com/metis/flow/validator/impl/edge/DefaultEdgeValidator.java
+++ b/metis-starter/src/main/java/com/metis/validator/impl/edge/DefaultEdgeValidator.java
@@ -1,9 +1,9 @@
-package com.metis.flow.validator.impl.edge;
+package com.metis.validator.impl.edge;
-import com.metis.flow.domain.entity.base.Edge;
-import com.metis.flow.enums.EdgeType;
-import com.metis.flow.validator.EdgeValidator;
-import com.metis.flow.validator.ValidatorResult;
+import com.metis.domain.entity.base.Edge;
+import com.metis.enums.EdgeType;
+import com.metis.validator.EdgeValidator;
+import com.metis.validator.ValidatorResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
diff --git a/src/main/java/com/metis/flow/validator/impl/node/DocumentExtractorNodeValidator.java b/metis-starter/src/main/java/com/metis/validator/impl/node/DocumentExtractorNodeValidator.java
similarity index 72%
rename from src/main/java/com/metis/flow/validator/impl/node/DocumentExtractorNodeValidator.java
rename to metis-starter/src/main/java/com/metis/validator/impl/node/DocumentExtractorNodeValidator.java
index 6d82c99..7fd2ca8 100644
--- a/src/main/java/com/metis/flow/validator/impl/node/DocumentExtractorNodeValidator.java
+++ b/metis-starter/src/main/java/com/metis/validator/impl/node/DocumentExtractorNodeValidator.java
@@ -1,13 +1,13 @@
-package com.metis.flow.validator.impl.node;
+package com.metis.validator.impl.node;
import cn.hutool.core.lang.Assert;
-import com.metis.flow.domain.entity.base.Edge;
-import com.metis.flow.domain.entity.base.Node;
-import com.metis.flow.domain.entity.config.node.DocumentExtractorNodeConfig;
-import com.metis.flow.enums.NodeType;
-import com.metis.flow.validator.NodeValidator;
-import com.metis.flow.validator.ValidatorCodeService;
-import com.metis.flow.validator.ValidatorResult;
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.domain.entity.config.node.DocumentExtractorNodeConfig;
+import com.metis.enums.NodeType;
+import com.metis.validator.NodeValidator;
+import com.metis.validator.ValidatorCodeService;
+import com.metis.validator.ValidatorResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -17,7 +17,7 @@ import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
-public class DocumentExtractorNodeValidator implements NodeValidator {
+public class DocumentExtractorNodeValidator implements NodeValidator {
private final ValidatorCodeService validatorCodeService;
@Override
diff --git a/src/main/java/com/metis/flow/validator/impl/node/EndNodeValidator.java b/metis-starter/src/main/java/com/metis/validator/impl/node/EndNodeValidator.java
similarity index 58%
rename from src/main/java/com/metis/flow/validator/impl/node/EndNodeValidator.java
rename to metis-starter/src/main/java/com/metis/validator/impl/node/EndNodeValidator.java
index fbe87d0..9e62e56 100644
--- a/src/main/java/com/metis/flow/validator/impl/node/EndNodeValidator.java
+++ b/metis-starter/src/main/java/com/metis/validator/impl/node/EndNodeValidator.java
@@ -1,11 +1,12 @@
-package com.metis.flow.validator.impl.node;
+package com.metis.validator.impl.node;
import cn.hutool.core.lang.Assert;
-import com.metis.flow.domain.entity.base.Edge;
-import com.metis.flow.domain.entity.base.Node;
-import com.metis.flow.enums.NodeType;
-import com.metis.flow.validator.NodeValidator;
-import com.metis.flow.validator.ValidatorResult;
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.domain.entity.config.node.EndNodeConfig;
+import com.metis.enums.NodeType;
+import com.metis.validator.NodeValidator;
+import com.metis.validator.ValidatorResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -15,7 +16,7 @@ import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
-public class EndNodeValidator implements NodeValidator {
+public class EndNodeValidator implements NodeValidator {
@@ -30,8 +31,8 @@ public class EndNodeValidator implements NodeValidator {
Assert.isTrue(targets.isEmpty(), "结束节点 {} 不允许有目标连接", node.getId());
// 2. 检查 sources 数量是否小于 handles 数量
- int handleCount = node.getData().getHandles().size();
- Assert.isTrue(sources.size() <= handleCount, "结束节点 {} 的源连接数超过 handles 数量", node.getId());
+// int handleCount = node.getData().getHandles().size();
+// Assert.isTrue(sources.size() <= handleCount, "结束节点 {} 的源连接数超过 handles 数量", node.getId());
return ValidatorResult.valid();
}
diff --git a/metis-starter/src/main/java/com/metis/validator/impl/node/LLMNodeValidator.java b/metis-starter/src/main/java/com/metis/validator/impl/node/LLMNodeValidator.java
new file mode 100644
index 0000000..2dd04a6
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/validator/impl/node/LLMNodeValidator.java
@@ -0,0 +1,33 @@
+package com.metis.validator.impl.node;
+
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.domain.entity.config.node.LLMNodeConfig;
+import com.metis.enums.NodeType;
+import com.metis.validator.NodeValidator;
+import com.metis.validator.ValidatorResult;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class LLMNodeValidator implements NodeValidator {
+ @Override
+ public ValidatorResult validateValue(Node node) {
+ return ValidatorResult.valid();
+ }
+
+ @Override
+ public ValidatorResult validateRelation(Node node, List sources, List targets) {
+ return ValidatorResult.valid();
+ }
+
+ @Override
+ public NodeType getType() {
+ return NodeType.LLM;
+ }
+}
diff --git a/metis-starter/src/main/java/com/metis/validator/impl/node/QuestionClassifierValidator.java b/metis-starter/src/main/java/com/metis/validator/impl/node/QuestionClassifierValidator.java
new file mode 100644
index 0000000..23c3e19
--- /dev/null
+++ b/metis-starter/src/main/java/com/metis/validator/impl/node/QuestionClassifierValidator.java
@@ -0,0 +1,31 @@
+package com.metis.validator.impl.node;
+
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.domain.entity.config.node.QuestionClassifierConfig;
+import com.metis.enums.NodeType;
+import com.metis.validator.NodeValidator;
+import com.metis.validator.ValidatorResult;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class QuestionClassifierValidator implements NodeValidator {
+ @Override
+ public ValidatorResult validateValue(Node node) {
+ return ValidatorResult.valid();
+ }
+
+ @Override
+ public ValidatorResult validateRelation(Node node, List sources, List targets) {
+ return ValidatorResult.valid();
+ }
+
+ @Override
+ public NodeType getType() {
+ return NodeType.QUESTION_CLASSIFIER;
+ }
+}
diff --git a/src/main/java/com/metis/flow/validator/impl/node/StartNodeValidator.java b/metis-starter/src/main/java/com/metis/validator/impl/node/StartNodeValidator.java
similarity index 81%
rename from src/main/java/com/metis/flow/validator/impl/node/StartNodeValidator.java
rename to metis-starter/src/main/java/com/metis/validator/impl/node/StartNodeValidator.java
index 97dfc11..797873d 100644
--- a/src/main/java/com/metis/flow/validator/impl/node/StartNodeValidator.java
+++ b/metis-starter/src/main/java/com/metis/validator/impl/node/StartNodeValidator.java
@@ -1,16 +1,16 @@
-package com.metis.flow.validator.impl.node;
+package com.metis.validator.impl.node;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
-import com.metis.flow.domain.entity.base.Edge;
-import com.metis.flow.domain.entity.base.Node;
-import com.metis.flow.domain.entity.base.NodeVariable;
-import com.metis.flow.domain.entity.config.node.StartNodeConfig;
-import com.metis.flow.enums.NodeType;
-import com.metis.flow.validator.NodeValidator;
-import com.metis.flow.validator.ValidatorCodeService;
-import com.metis.flow.validator.ValidatorResult;
+import com.metis.domain.entity.base.Edge;
+import com.metis.domain.entity.base.Node;
+import com.metis.domain.entity.base.NodeVariable;
+import com.metis.domain.entity.config.node.StartNodeConfig;
+import com.metis.enums.NodeType;
+import com.metis.validator.NodeValidator;
+import com.metis.validator.ValidatorCodeService;
+import com.metis.validator.ValidatorResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -20,7 +20,7 @@ import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
-public class StartNodeValidator implements NodeValidator {
+public class StartNodeValidator implements NodeValidator {
private final ValidatorCodeService validatorCodeService;
@@ -84,8 +84,8 @@ public class StartNodeValidator implements NodeValidator {
Assert.isTrue(sources.isEmpty(), "开始节点 {} 不允许有源连接", node.getId());
// 2. 检查 targets 数量是否小于 handles 数量
- int handleCount = node.getData().getHandles().size();
- Assert.isTrue(targets.size() <= handleCount, "开始节点 {} 的目标连接数超过 handles 数量", node.getId());
+// int handleCount = node.getData().getHandles().size();
+// Assert.isTrue(targets.size() <= handleCount, "开始节点 {} 的目标连接数超过 handles 数量", node.getId());
return ValidatorResult.valid();
}
diff --git a/metis-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/metis-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 0000000..0e5852e
--- /dev/null
+++ b/metis-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+com.metis.config.MetisStarterAutoConfiguration
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index dbb661b..299c6b8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,6 +7,11 @@
com.metis
metis
1.0.0-SNAPSHOT
+ pom
+
+ metis-starter
+ metis-applicant
+
org.springframework.boot
@@ -19,8 +24,9 @@
17
UTF-8
3.3.4
- 2.0.45
+ 2.0.56
1.18.34
+ 1.6.2
1.2.3
1.0.0-beta2
3.5.8
@@ -36,126 +42,60 @@
pom
import
+
+ dev.langchain4j
+ langchain4j-open-ai
+ ${langchain4j.version}
+
+
+ dev.langchain4j
+ langchain4j-mcp
+ 1.0.0-beta2
+
+
+ com.alibaba.fastjson2
+ fastjson2
+ ${fastjson.version}
+
+
+ com.mikesamuel
+ json-sanitizer
+ ${sanitizer.version}
+
+
+ com.baomidou
+ mybatis-plus-spring-boot3-starter
+ ${mybatis-plus.version}
+
+
+ mysql
+ mysql-connector-java
+ 8.0.33
+
+
+ cn.hutool
+ hutool-all
+ 5.8.24
+
+
+
+ org.mapstruct
+ mapstruct
+ ${org.mapstruct.version}
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+ 0.2.0
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-api
+ 2.2.0
+
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-validation
-
-
- dev.langchain4j
- langchain4j-open-ai
- ${langchain4j.version}
-
-
- dev.langchain4j
- langchain4j-mcp
- 1.0.0-beta2
-
-
- com.alibaba.fastjson2
- fastjson2
- ${fastjson.version}
-
-
- org.projectlombok
- lombok
-
-
- com.mikesamuel
- json-sanitizer
- ${sanitizer.version}
-
-
- com.baomidou
- mybatis-plus-spring-boot3-starter
- ${mybatis-plus.version}
-
-
- mysql
- mysql-connector-java
- 8.0.33
-
-
- cn.hutool
- hutool-all
- 5.8.22
-
-
- org.mapstruct
- mapstruct
- 1.6.2
-
-
- org.projectlombok
- lombok-mapstruct-binding
- 0.2.0
-
-
- org.springdoc
- springdoc-openapi-starter-webmvc-api
- 2.2.0
-
-
- com.github.xiaoymin
- knife4j-openapi3-jakarta-spring-boot-starter
- 4.4.0
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
- repackage
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
- 17
- 17
- UTF-8
-
- -parameters
-
-
-
-
-
- org.mapstruct
- mapstruct-processor
- 1.6.2
-
-
- org.projectlombok
- lombok
- 1.18.34
-
-
- org.projectlombok
- lombok-mapstruct-binding
- 0.2.0
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/java/com/metis/domain/package-info.java b/src/main/java/com/metis/domain/package-info.java
deleted file mode 100644
index 8890ae6..0000000
--- a/src/main/java/com/metis/domain/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.metis.domain;
\ No newline at end of file
diff --git a/src/main/java/com/metis/flow/config/FlowMybatisPlusConfiguration.java b/src/main/java/com/metis/flow/config/FlowMybatisPlusConfiguration.java
deleted file mode 100644
index 77d35d6..0000000
--- a/src/main/java/com/metis/flow/config/FlowMybatisPlusConfiguration.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.metis.flow.config;
-
-import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-@MapperScan(basePackages = {"com.metis.flow.mapper"})
-public class FlowMybatisPlusConfiguration {
-}
diff --git a/src/main/java/com/metis/flow/domain/bo/Graph.java b/src/main/java/com/metis/flow/domain/bo/Graph.java
deleted file mode 100644
index 626974c..0000000
--- a/src/main/java/com/metis/flow/domain/bo/Graph.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.metis.flow.domain.bo;
-
-import com.metis.flow.domain.entity.base.Edge;
-import com.metis.flow.domain.entity.base.Node;
-import jakarta.validation.Valid;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Size;
-import lombok.Data;
-
-import java.util.List;
-
-@Data
-public class Graph {
-
- /**
- * 边缘
- */
- @Valid
- @NotNull(message = "连线不能为空")
- private List edges;
-
- /**
- * 节点
- */
- @Valid
- @NotNull(message = "节点不能为空")
- @Size(min = 1, message = "节点不能为空")
- private List nodes;
-}
diff --git a/src/main/java/com/metis/flow/domain/entity/config/node/DocumentExtractorNodeConfig.java b/src/main/java/com/metis/flow/domain/entity/config/node/DocumentExtractorNodeConfig.java
deleted file mode 100644
index 76d1fc4..0000000
--- a/src/main/java/com/metis/flow/domain/entity/config/node/DocumentExtractorNodeConfig.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.metis.flow.domain.entity.config.node;
-
-import jakarta.validation.constraints.NotBlank;
-import lombok.Data;
-
-@Data
-public class DocumentExtractorNodeConfig {
-
- @NotBlank(message = "文件类型不能为空")
- private String fileType;
-
-}
diff --git a/src/main/java/com/metis/flow/domain/entity/config/node/StartNodeConfig.java b/src/main/java/com/metis/flow/domain/entity/config/node/StartNodeConfig.java
deleted file mode 100644
index 685c1c4..0000000
--- a/src/main/java/com/metis/flow/domain/entity/config/node/StartNodeConfig.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.metis.flow.domain.entity.config.node;
-
-import com.metis.flow.domain.entity.base.NodeVariable;
-import jakarta.validation.Valid;
-import lombok.Data;
-
-import java.util.List;
-
-@Data
-public class StartNodeConfig {
-
-
- @Valid
- private List variables;
-
-
-}
diff --git a/src/main/java/com/metis/flow/domain/entity/config/package-info.java b/src/main/java/com/metis/flow/domain/entity/config/package-info.java
deleted file mode 100644
index a2ccdb1..0000000
--- a/src/main/java/com/metis/flow/domain/entity/config/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.metis.flow.domain.entity.config;
\ No newline at end of file
diff --git a/src/main/java/com/metis/flow/engine/impl/AppFlowEngineRunnerServiceImpl.java b/src/main/java/com/metis/flow/engine/impl/AppFlowEngineRunnerServiceImpl.java
deleted file mode 100644
index ff00289..0000000
--- a/src/main/java/com/metis/flow/engine/impl/AppFlowEngineRunnerServiceImpl.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package com.metis.flow.engine.impl;
-
-import cn.hutool.core.lang.Assert;
-import cn.hutool.core.util.IdUtil;
-import cn.hutool.core.util.ObjectUtil;
-import com.metis.flow.domain.bo.Graph;
-import com.metis.flow.domain.context.RunningContext;
-import com.metis.flow.domain.context.RunningResult;
-import com.metis.flow.domain.context.SysContext;
-import com.metis.flow.domain.entity.App;
-import com.metis.flow.domain.entity.base.Edge;
-import com.metis.flow.domain.entity.base.Node;
-import com.metis.flow.engine.AppEngineService;
-import com.metis.flow.engine.AppFlowEngineRunnerService;
-import com.metis.flow.enums.NodeType;
-import com.metis.flow.runner.FlowRunningContext;
-import com.metis.flow.runner.NodeRunner;
-import com.metis.flow.runner.RunnerResult;
-import com.metis.flow.runner.factory.RunnerFactory;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class AppFlowEngineRunnerServiceImpl implements AppFlowEngineRunnerService {
-
- private final AppEngineService appEngineService;
-
-
- @Override
- public RunnerResult running(FlowRunningContext context) {
- App app = getApp(context);
- // todo 构建运行实例, 并将运行实例放入上下文
-
- Long instanceId = IdUtil.getSnowflakeNextId();
- // 构建系统上下文信息
- SysContext sysContext = SysContext.builder()
- .files(context.getFiles())
- .appId(app.getId())
- .workflowId(app.getWorkflowId())
- .instanceId(instanceId)
- .build();
- // 构建运行中上下文
- RunningContext runningContext = RunningContext.buildContext(sysContext, context);
- // 构建节点映射对象
- Graph graph = app.getGraph();
- Map nodeMap = graph.getNodes().stream()
- .collect(Collectors.toMap(Node::getId, Function.identity()));
- Map> edgeMap = graph.getEdges().stream()
- .collect(Collectors.groupingBy(Edge::getSource));
- // 获取到开始节点
- Node runningNode = graph.getNodes().stream().filter(node -> node.getType() == NodeType.START)
- .findFirst().orElse(null);
- // 开始节点为空,则表示数据存在异常
- Assert.isTrue(ObjectUtil.isNotNull(runningNode), "流程图不存在开始节点");
- while (ObjectUtil.isNotNull(runningNode)) {
- NodeRunner nodeRunner = RunnerFactory.get(runningNode.getType());
- // 获取到返回结果
- RunningResult result = nodeRunner.run(runningContext, runningNode, edgeMap.get(runningNode.getId()));
- if (ObjectUtil.isNotNull(result.getNodeContext())) {
- runningContext.addNodeRunningContext(runningNode.getId(), result.getNodeContext());
- }
- runningNode = null;
- }
-
-
- return RunnerResult.builder()
- .content("你他妈的!")
- .context(sysContext)
- .build();
-
- }
-
-
- /**
- * 获取到应用程序信息
- *
- * @param context 上下文
- * @return {@link App }
- */
- private App getApp(FlowRunningContext context) {
- if (ObjectUtil.isNotNull(context.getWorkflowId())) {
- return appEngineService.getByWorkflowId(context.getWorkflowId());
- }
- return appEngineService.getByAppId(context.getAppId());
- }
-}
diff --git a/src/main/java/com/metis/flow/runner/NodeRunner.java b/src/main/java/com/metis/flow/runner/NodeRunner.java
deleted file mode 100644
index 855a7f7..0000000
--- a/src/main/java/com/metis/flow/runner/NodeRunner.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.metis.flow.runner;
-
-import com.metis.flow.domain.context.RunningContext;
-import com.metis.flow.domain.context.RunningResult;
-import com.metis.flow.domain.entity.base.Edge;
-import com.metis.flow.domain.entity.base.Node;
-import com.metis.flow.enums.NodeType;
-
-import java.util.List;
-
-public interface NodeRunner {
-
-
- /**
- * 运行
- *
- * @param context 上下文
- * @param node 节点配置信息
- * @param edges
- * @return {@link RunningContext }
- */
- RunningResult run(RunningContext context, Node node, List edges);
-
-
- /**
- * 获取节点类型
- *
- * @return {@link NodeType }
- */
- NodeType getType();
-
-}
diff --git a/src/main/java/com/metis/flow/runner/factory/RunnerFactory.java b/src/main/java/com/metis/flow/runner/factory/RunnerFactory.java
deleted file mode 100644
index 3a71a82..0000000
--- a/src/main/java/com/metis/flow/runner/factory/RunnerFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.metis.flow.runner.factory;
-
-import com.metis.flow.enums.NodeType;
-import com.metis.flow.runner.NodeRunner;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class RunnerFactory {
-
- private static final Map MAP = new ConcurrentHashMap<>(8);
-
-
- /**
- * 注册
- *
- * @param runner 跑步者
- */
- public static void register(NodeRunner runner) {
- MAP.put(runner.getType(), runner);
- }
-
-
- /**
- * 得到
- *
- * @param type 类型
- * @return {@link NodeRunner }
- */
- public static NodeRunner get(NodeType type) {
- return MAP.get(type);
- }
-
-
-
-}
diff --git a/src/main/java/com/metis/flow/runner/impl/EndNodeRunner.java b/src/main/java/com/metis/flow/runner/impl/EndNodeRunner.java
deleted file mode 100644
index 8b252c3..0000000
--- a/src/main/java/com/metis/flow/runner/impl/EndNodeRunner.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.metis.flow.runner.impl;
-
-
-import com.metis.flow.domain.context.RunningContext;
-import com.metis.flow.domain.context.RunningResult;
-import com.metis.flow.domain.entity.base.Edge;
-import com.metis.flow.domain.entity.base.Node;
-import com.metis.flow.enums.NodeType;
-import com.metis.flow.runner.NodeRunner;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-@Slf4j
-@Service
-public class EndNodeRunner implements NodeRunner {
-
- @Override
- public RunningResult run(RunningContext context, Node node, List edges) {
- return RunningResult.buildResult();
- }
-
- @Override
- public NodeType getType() {
- return NodeType.END;
- }
-
-}
diff --git a/src/main/java/com/metis/flow/validator/ValidatorInitialize.java b/src/main/java/com/metis/flow/validator/ValidatorInitialize.java
deleted file mode 100644
index 7201eb7..0000000
--- a/src/main/java/com/metis/flow/validator/ValidatorInitialize.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.metis.flow.validator;
-
-
-import com.metis.flow.validator.factory.EdgeValidatorFactory;
-import com.metis.flow.validator.factory.NodeValidatorFactory;
-import org.jetbrains.annotations.NotNull;
-import org.springframework.beans.BeansException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.stereotype.Service;
-
-import java.util.Map;
-
-@Service
-public class ValidatorInitialize implements ApplicationContextAware {
-
-
- @Override
- public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
- Map edgeMap = applicationContext.getBeansOfType(EdgeValidator.class);
-
- edgeMap.forEach((k, v) -> {
- EdgeValidatorFactory.register(v);
- });
-
-
- Map nodeMap = applicationContext.getBeansOfType(NodeValidator.class);
- nodeMap.forEach((k, v) -> {
- NodeValidatorFactory.register(v);
- });
- }
-
-
-}
diff --git a/src/main/java/com/metis/flow/validator/factory/NodeValidatorFactory.java b/src/main/java/com/metis/flow/validator/factory/NodeValidatorFactory.java
deleted file mode 100644
index ac00792..0000000
--- a/src/main/java/com/metis/flow/validator/factory/NodeValidatorFactory.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.metis.flow.validator.factory;
-
-import com.metis.flow.enums.NodeType;
-import com.metis.flow.validator.NodeValidator;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-
-public class NodeValidatorFactory {
-
- private static final Map MAP = new ConcurrentHashMap<>(8);
-
- /**
- * 注册
- *
- * @param validator 验证器
- */
- public static void register(NodeValidator validator) {
- MAP.put(validator.getType(), validator);
- }
-
- /**
- * 得到
- *
- * @param type 类型
- * @return {@link NodeValidator }
- */
- public static NodeValidator get(NodeType type) {
- return MAP.get(type);
- }
-
-
-}
diff --git a/src/main/resources/json/test.json b/src/main/resources/json/test.json
deleted file mode 100644
index 00df0ea..0000000
--- a/src/main/resources/json/test.json
+++ /dev/null
@@ -1,152 +0,0 @@
-
-{
- "id": 0,
- "name": "测试流程",
- "description": "测试流程",
- "graph": {
- "nodes": [
- {
- "id": "5",
- "type": "start",
- "dimensions": {
- "width": 300,
- "height": 300
- },
- "draggable": true,
- "resizing": false,
- "selected": true,
- "data": {
- "label": "开始",
- "toolbarPosition": "right",
- "config": {
- "variables": [
- {
- "variable": "context",
- "label": "段落",
- "type": "paragraph",
- "maxLength": 48,
- "required": true
- },
- {
- "variable": "text",
- "label": "文本",
- "type": "text-input",
- "maxLength": 48,
- "required": true,
- "options": []
- },
- {
- "variable": "select",
- "label": "下拉",
- "type": "select",
- "maxLength": 48,
- "required": true,
- "options": [
- {
- "label": "选型1",
- "value": "1"
- },
- {
- "label": "选型2",
- "value": "2"
- }
- ]
- },
- {
- "variable": "number",
- "label": "数字",
- "type": "number",
- "maxLength": 48,
- "required": true,
- "options": []
- },
- {
- "variable": "singlefile",
- "label": "singlefile单文件",
- "type": "file",
- "maxLength": 48,
- "required": true,
- "options": [],
- "allowedFileUploadMethods": [
- "local_file",
- "remote_url"
- ],
- "allowedFileTypes": [
- "image",
- "document",
- "audio",
- "video"
- ],
- "allowedFileExtensions": []
- },
- {
- "variable": "mufile",
- "label": "多文件",
- "type": "file-list",
- "maxLength": 5,
- "required": true,
- "options": [],
- "allowedFileUploadMethods": [
- "local_file"
- ],
- "allowedFileTypes": [
- "custom"
- ],
- "allowedFileExtensions": [
- "docx",
- "aaa"
- ]
- }
- ],
- "parent": "234"
- },
- "handles": [
- {
- "id": "7",
- "position": "right",
- "type": "source",
- "connectable": true
- }
- ]
- },
- "position": { "x": 0, "y": 300 }
- },
- {
- "id": "6",
- "type": "end",
- "selected": false,
- "data": {
- "label": "结束",
- "toolbarPosition": "right",
- "handles": [
- {
- "id": "8",
- "position": "left",
- "type": "target",
- "connectable": true
- }
- ]
- },
- "position": { "x": 500, "y": 300 }
- }
- ],
- "edges": [
- {
- "id": "6",
- "type": "default",
- "source": "5",
- "target": "6",
- "sourceHandle": "7",
- "animated": true,
- "targetHandle": "8",
- "label": "线标签",
- "markerEnd": "none",
- "markerStart": "none",
- "updatable": true,
- "selectable": true,
- "deletable": true
- }
- ]
- }
-
-}
\ No newline at end of file
diff --git a/src/test/java/AnsMsgHandler.java b/src/test/java/AnsMsgHandler.java
deleted file mode 100644
index 8d79f62..0000000
--- a/src/test/java/AnsMsgHandler.java
+++ /dev/null
@@ -1,8 +0,0 @@
-
-import java.io.InputStream;
-
-public interface AnsMsgHandler {
-
- void actMsg(InputStream is, String line);
-
-}
diff --git a/src/test/java/SSeTest.java b/src/test/java/SSeTest.java
deleted file mode 100644
index 63f3d19..0000000
--- a/src/test/java/SSeTest.java
+++ /dev/null
@@ -1,27 +0,0 @@
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.metis.sseclient.check.SseCheck;
-import dev.langchain4j.agent.tool.ToolSpecification;
-import dev.langchain4j.mcp.client.DefaultMcpClient;
-import dev.langchain4j.mcp.client.transport.McpTransport;
-import dev.langchain4j.mcp.client.transport.http.HttpMcpTransport;
-import lombok.extern.slf4j.Slf4j;
-
-import java.util.List;
-
-
-@Slf4j
-public class SSeTest {
- public static void main(String[] args) throws JsonProcessingException {
- McpTransport transport = new HttpMcpTransport.Builder()
- .sseUrl("http://localhost:8081/sse")
- .build();
- new DefaultMcpClient.Builder()
- .transport(transport)
- .build()
- .listTools();
-
- SseCheck sseCheck = new SseCheck("http://localhost:8081/sse");
- List listTools = sseCheck.listTools();
- System.out.println(listTools);
- }
-}
diff --git a/src/test/java/SseClient.java b/src/test/java/SseClient.java
deleted file mode 100644
index b3615f6..0000000
--- a/src/test/java/SseClient.java
+++ /dev/null
@@ -1,77 +0,0 @@
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.URL;
-
-/**
- *
- * @author hyd
- *
- */
-public class SseClient {
-
- /**
- * 获取SSE输入流。
- *
- * @param urlPath
- * @return
- * @throws IOException
- */
- public static InputStream getSseInputStream(String urlPath) throws IOException {
- URL url = new URL(urlPath);
- HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
- // 这儿根据自己的情况选择get或post
- urlConnection.setRequestMethod("GET");
- urlConnection.setDoOutput(true);
- urlConnection.setDoInput(true);
- urlConnection.setUseCaches(false);
- urlConnection.setRequestProperty("Connection", "Keep-Alive");
- urlConnection.setRequestProperty("Charset", "UTF-8");
- //读取过期时间(很重要,建议加上)
- urlConnection.setReadTimeout(60 * 1000);
- // text/plain模式
- urlConnection.setRequestProperty("Content-Type", "text/plain; charset=UTF-8");
- InputStream inputStream = urlConnection.getInputStream();
- InputStream is = new BufferedInputStream(inputStream);
- return is;
- }
-
- /**
- * 读取数据。
- *
- * @param is
- * @param ansMsgHandler
- * @throws IOException
- */
- public static void readStream(InputStream is, AnsMsgHandler ansMsgHandler) throws IOException {
- try {
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
- String line = "";
- while ((line = reader.readLine()) != null) {
- // 处理数据接口
- ansMsgHandler.actMsg(is, line);
- }
- // 当服务器端主动关闭的时候,客户端无法获取到信号。现在还不清楚原因。所以无法执行的此处。
- reader.close();
- } catch (IOException e) {
- e.printStackTrace();
- throw new IOException("关闭数据流!");
- }
- }
-
- public static void main(String[] args) throws IOException {
- String urlPath = "http://localhost:8081/sse";
- InputStream inputStream = getSseInputStream(urlPath);
- readStream(inputStream, new AnsMsgHandler() {
-
- public void actMsg(InputStream is, String line) {
- System.out.println(line);
- }
- });
- }
-
-}