Compare commits
15 Commits
master
...
codex/back
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8a7bdc0f8 | ||
|
|
041964132a | ||
|
|
474a4866d2 | ||
|
|
ab4e84004f | ||
|
|
d5b7178f72 | ||
|
|
a1a38f62d8 | ||
|
|
e612f5e434 | ||
|
|
1148bf9213 | ||
|
|
d08d30a7ab | ||
|
|
a69bb4b8a8 | ||
|
|
f8ee4023ff | ||
|
|
f0a2986cf3 | ||
|
|
38adf72939 | ||
|
|
a574b2c661 | ||
|
|
5d87c9eee7 |
@@ -143,6 +143,12 @@ public class AuthInterceptor implements HandlerInterceptor {
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (tenantId == null) {
|
||||||
|
// 对于无需鉴权的路径(如飞书/钉钉 webhook),使用默认租户,不要求登录
|
||||||
|
if (isExcludedPath(originalRequestUri)) {
|
||||||
|
tenantId = 1L;
|
||||||
|
}
|
||||||
if (tenantId == null) {
|
if (tenantId == null) {
|
||||||
tenantId = 1L;
|
tenantId = 1L;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ spring:
|
|||||||
datasource:
|
datasource:
|
||||||
# 主数据源 (MySQL)
|
# 主数据源 (MySQL)
|
||||||
master:
|
master:
|
||||||
url: jdbc:mysql://${DB_HOST:localhost}:3306/${DB_NAME:agent_platform}?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&allowMultiQueries=true&socketTimeout=300000&useSSL=false
|
url: jdbc:mysql://${DB_HOST:localhost}:3306/${DB_NAME:agent_platform}?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&allowMultiQueries=true&socketTimeout=300000&allowPublicKeyRetrieval=true&useSSL=false
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
username: ${DB_USERNAME:root}
|
username: ${DB_USERNAME:root}
|
||||||
password: ${DB_PASSWORD:your_mysql_password}
|
password: ${DB_PASSWORD:your_mysql_password}
|
||||||
@@ -48,7 +48,7 @@ spring:
|
|||||||
filters: stat # 启用 stat filter 用于监控
|
filters: stat # 启用 stat filter 用于监控
|
||||||
# Doris 数据源
|
# Doris 数据源
|
||||||
doris:
|
doris:
|
||||||
url: jdbc:mysql://${DORIS_HOST:localhost}:3306/${DORIS_DB_NAME:agent_custom_table}?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&allowMultiQueries=true&socketTimeout=300000&useSSL=false
|
url: jdbc:mysql://${DORIS_HOST:localhost}:3306/${DORIS_DB_NAME:agent_custom_table}?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&allowMultiQueries=true&socketTimeout=300000&allowPublicKeyRetrieval=true&useSSL=false
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
username: ${DORIS_USERNAME:root}
|
username: ${DORIS_USERNAME:root}
|
||||||
password: ${DORIS_PASSWORD:your_doris_password}
|
password: ${DORIS_PASSWORD:your_doris_password}
|
||||||
@@ -165,12 +165,17 @@ search:
|
|||||||
username: ${ES_USERNAME:elastic}
|
username: ${ES_USERNAME:elastic}
|
||||||
password: ${ES_PASSWORD:your_elasticsearch_password}
|
password: ${ES_PASSWORD:your_elasticsearch_password}
|
||||||
api_key: ${ES_API_KEY:}
|
api_key: ${ES_API_KEY:}
|
||||||
|
text_analyzer: ${ES_TEXT_ANALYZER:standard}
|
||||||
|
search_analyzer: ${ES_SEARCH_ANALYZER:standard}
|
||||||
# 生态市场模块配置
|
# 生态市场模块配置
|
||||||
eco-market:
|
eco-market:
|
||||||
# 服务端配置
|
# 服务端配置
|
||||||
server:
|
server:
|
||||||
# 远程server端的 ip端口配置
|
# 远程server端的 ip端口配置
|
||||||
base-url: ${ECO_MARKET_SERVER_URL:https://test-agent-market-api.xspaceagi.com}
|
enabled: ${ECO_MARKET_SERVER_ENABLED:false}
|
||||||
|
base-url: ${ECO_MARKET_SERVER_URL:}
|
||||||
|
# 是否拉取官方生态市场通知,私有化部署默认关闭
|
||||||
|
pull-message-enabled: ${ECO_MARKET_PULL_MESSAGE_ENABLED:false}
|
||||||
client:
|
client:
|
||||||
# 客户端配置
|
# 客户端配置
|
||||||
retry:
|
retry:
|
||||||
@@ -180,6 +185,15 @@ eco-market:
|
|||||||
mcp:
|
mcp:
|
||||||
proxy-base-url: ${MCP_PROXY_URL:http://localhost:8020}
|
proxy-base-url: ${MCP_PROXY_URL:http://localhost:8020}
|
||||||
|
|
||||||
|
overview-page:
|
||||||
|
service-url: ${OVERVIEW_SERVICE_URL:http://127.0.0.1:5173/_app/digital}
|
||||||
|
|
||||||
|
intelligent-data:
|
||||||
|
service-url: ${INTELLIGENT_DATA_SERVICE_URL:http://192.168.2.106:3000/test-console}
|
||||||
|
|
||||||
|
document-editor:
|
||||||
|
service-url: ${DOCUMENT_EDITOR_SERVICE_URL:}
|
||||||
|
|
||||||
knife4j:
|
knife4j:
|
||||||
# 开启增强配置
|
# 开启增强配置
|
||||||
enable: true
|
enable: true
|
||||||
@@ -230,4 +244,4 @@ model-api-proxy:
|
|||||||
enable-model-proxy: ${MODEL_PROXY_ENABLE:true}
|
enable-model-proxy: ${MODEL_PROXY_ENABLE:true}
|
||||||
port: ${MODEL_PROXY_PORT:18086}
|
port: ${MODEL_PROXY_PORT:18086}
|
||||||
#记录日志
|
#记录日志
|
||||||
save-log: ${MODEL_PROXY_SAVE_LOG:true}
|
save-log: ${MODEL_PROXY_SAVE_LOG:true}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ spring:
|
|||||||
datasource:
|
datasource:
|
||||||
# 主数据源 (MySQL)
|
# 主数据源 (MySQL)
|
||||||
master:
|
master:
|
||||||
url: jdbc:mysql://${DB_HOST:localhost}:3306/${DB_NAME:agent_platform}?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&allowMultiQueries=true&socketTimeout=300000&useSSL=false
|
url: jdbc:mysql://${DB_HOST:localhost}:3306/${DB_NAME:agent_platform}?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&allowMultiQueries=true&socketTimeout=300000&allowPublicKeyRetrieval=true&useSSL=false
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
username: ${DB_USERNAME:root}
|
username: ${DB_USERNAME:root}
|
||||||
password: ${DB_PASSWORD:Byyagz@121}
|
password: ${DB_PASSWORD:Byyagz@121}
|
||||||
@@ -48,7 +48,7 @@ spring:
|
|||||||
filters: stat # 启用 stat filter 用于监控
|
filters: stat # 启用 stat filter 用于监控
|
||||||
# Doris 数据源
|
# Doris 数据源
|
||||||
doris:
|
doris:
|
||||||
url: jdbc:mysql://${DORIS_HOST:localhost}:3306/${DORIS_DB_NAME:agent_platform}?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&allowMultiQueries=true&socketTimeout=300000&useSSL=false
|
url: jdbc:mysql://${DORIS_HOST:localhost}:3306/${DORIS_DB_NAME:agent_platform}?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&allowMultiQueries=true&socketTimeout=300000&allowPublicKeyRetrieval=true&useSSL=false
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
username: ${DORIS_USERNAME:root}
|
username: ${DORIS_USERNAME:root}
|
||||||
password: ${DORIS_PASSWORD:Byyagz@121}
|
password: ${DORIS_PASSWORD:Byyagz@121}
|
||||||
@@ -89,7 +89,7 @@ jwt:
|
|||||||
secretKey: ${JWT_SECRET_KEY:qiming-local-dev-jwt-secret-key-32-chars}
|
secretKey: ${JWT_SECRET_KEY:qiming-local-dev-jwt-secret-key-32-chars}
|
||||||
|
|
||||||
file:
|
file:
|
||||||
uploadFolder: ${FILE_UPLOAD_FOLDER:D:/work/workspace/feitian-base/nvw/.dev/uploads}
|
uploadFolder: ${FILE_UPLOAD_FOLDER:/Users/qiming/qiming-work/uploads}
|
||||||
baseUrl: ${FILE_BASE_URL:http://localhost:18081/files/}
|
baseUrl: ${FILE_BASE_URL:http://localhost:18081/files/}
|
||||||
|
|
||||||
# Storage configuration
|
# Storage configuration
|
||||||
@@ -98,7 +98,7 @@ storage:
|
|||||||
|
|
||||||
local:
|
local:
|
||||||
upload:
|
upload:
|
||||||
folder: ${LOCAL_UPLOAD_FOLDER:D:/work/workspace/feitian-base/nvw/.dev/uploads}
|
folder: ${LOCAL_UPLOAD_FOLDER:/Users/qiming/qiming-work/uploads}
|
||||||
|
|
||||||
# Tencent Cloud COS configuration (takes effect when storage.type=cos)
|
# Tencent Cloud COS configuration (takes effect when storage.type=cos)
|
||||||
cos:
|
cos:
|
||||||
@@ -165,12 +165,17 @@ search:
|
|||||||
username: ${ES_USERNAME:}
|
username: ${ES_USERNAME:}
|
||||||
password: ${ES_PASSWORD:}
|
password: ${ES_PASSWORD:}
|
||||||
api_key: ${ES_API_KEY:}
|
api_key: ${ES_API_KEY:}
|
||||||
|
text_analyzer: ${ES_TEXT_ANALYZER:standard}
|
||||||
|
search_analyzer: ${ES_SEARCH_ANALYZER:standard}
|
||||||
# 生态市场模块配置
|
# 生态市场模块配置
|
||||||
eco-market:
|
eco-market:
|
||||||
# 服务端配置
|
# 服务端配置
|
||||||
server:
|
server:
|
||||||
# 远程server端的 ip端口配置
|
# 远程server端的 ip端口配置
|
||||||
base-url: ${ECO_MARKET_SERVER_URL:https://test-agent-market-api.xspaceagi.com}
|
enabled: ${ECO_MARKET_SERVER_ENABLED:false}
|
||||||
|
base-url: ${ECO_MARKET_SERVER_URL:}
|
||||||
|
# 是否拉取官方生态市场通知,私有化部署默认关闭
|
||||||
|
pull-message-enabled: ${ECO_MARKET_PULL_MESSAGE_ENABLED:false}
|
||||||
client:
|
client:
|
||||||
# 客户端配置
|
# 客户端配置
|
||||||
retry:
|
retry:
|
||||||
@@ -180,6 +185,15 @@ eco-market:
|
|||||||
mcp:
|
mcp:
|
||||||
proxy-base-url: ${MCP_PROXY_URL:http://localhost:18020}
|
proxy-base-url: ${MCP_PROXY_URL:http://localhost:18020}
|
||||||
|
|
||||||
|
overview-page:
|
||||||
|
service-url: ${OVERVIEW_SERVICE_URL:http://127.0.0.1:5173/_app/digital}
|
||||||
|
|
||||||
|
intelligent-data:
|
||||||
|
service-url: ${INTELLIGENT_DATA_SERVICE_URL:http://192.168.2.106:3000/test-console}
|
||||||
|
|
||||||
|
document-editor:
|
||||||
|
service-url: ${DOCUMENT_EDITOR_SERVICE_URL:}
|
||||||
|
|
||||||
knife4j:
|
knife4j:
|
||||||
# 开启增强配置
|
# 开启增强配置
|
||||||
enable: true
|
enable: true
|
||||||
|
|||||||
@@ -169,7 +169,10 @@ eco-market:
|
|||||||
# 服务端配置
|
# 服务端配置
|
||||||
server:
|
server:
|
||||||
# 远程server端的 ip端口配置
|
# 远程server端的 ip端口配置
|
||||||
base-url: ${ECO_MARKET_SERVER_URL:https://agent-market-api.xspaceagi.com}
|
enabled: ${ECO_MARKET_SERVER_ENABLED:false}
|
||||||
|
base-url: ${ECO_MARKET_SERVER_URL:}
|
||||||
|
# 是否拉取官方生态市场通知,私有化部署默认关闭
|
||||||
|
pull-message-enabled: ${ECO_MARKET_PULL_MESSAGE_ENABLED:false}
|
||||||
client:
|
client:
|
||||||
# 客户端配置
|
# 客户端配置
|
||||||
retry:
|
retry:
|
||||||
@@ -179,6 +182,15 @@ eco-market:
|
|||||||
mcp:
|
mcp:
|
||||||
proxy-base-url: ${MCP_PROXY_URL:http://localhost:8020}
|
proxy-base-url: ${MCP_PROXY_URL:http://localhost:8020}
|
||||||
|
|
||||||
|
overview-page:
|
||||||
|
service-url: ${OVERVIEW_SERVICE_URL:http://127.0.0.1:5173/_app/digital}
|
||||||
|
|
||||||
|
intelligent-data:
|
||||||
|
service-url: ${INTELLIGENT_DATA_SERVICE_URL:http://192.168.2.106:3000/test-console}
|
||||||
|
|
||||||
|
document-editor:
|
||||||
|
service-url: ${DOCUMENT_EDITOR_SERVICE_URL:}
|
||||||
|
|
||||||
knife4j:
|
knife4j:
|
||||||
# 开启增强配置
|
# 开启增强配置
|
||||||
enable: true
|
enable: true
|
||||||
@@ -229,4 +241,4 @@ model-api-proxy:
|
|||||||
enable-model-proxy: ${MODEL_PROXY_ENABLE:true}
|
enable-model-proxy: ${MODEL_PROXY_ENABLE:true}
|
||||||
port: ${MODEL_PROXY_PORT:18086}
|
port: ${MODEL_PROXY_PORT:18086}
|
||||||
#记录日志
|
#记录日志
|
||||||
save-log: ${MODEL_PROXY_SAVE_LOG:true}
|
save-log: ${MODEL_PROXY_SAVE_LOG:true}
|
||||||
|
|||||||
@@ -169,7 +169,10 @@ eco-market:
|
|||||||
# 服务端配置
|
# 服务端配置
|
||||||
server:
|
server:
|
||||||
# 远程server端的 ip端口配置
|
# 远程server端的 ip端口配置
|
||||||
base-url: ${ECO_MARKET_SERVER_URL:https://test-agent-market-api.xspaceagi.com}
|
enabled: ${ECO_MARKET_SERVER_ENABLED:false}
|
||||||
|
base-url: ${ECO_MARKET_SERVER_URL:}
|
||||||
|
# 是否拉取官方生态市场通知,私有化部署默认关闭
|
||||||
|
pull-message-enabled: ${ECO_MARKET_PULL_MESSAGE_ENABLED:false}
|
||||||
client:
|
client:
|
||||||
# 客户端配置
|
# 客户端配置
|
||||||
retry:
|
retry:
|
||||||
@@ -179,6 +182,15 @@ eco-market:
|
|||||||
mcp:
|
mcp:
|
||||||
proxy-base-url: ${MCP_PROXY_URL:http://localhost:8020}
|
proxy-base-url: ${MCP_PROXY_URL:http://localhost:8020}
|
||||||
|
|
||||||
|
overview-page:
|
||||||
|
service-url: ${OVERVIEW_SERVICE_URL:http://127.0.0.1:5173/_app/digital}
|
||||||
|
|
||||||
|
intelligent-data:
|
||||||
|
service-url: ${INTELLIGENT_DATA_SERVICE_URL:http://192.168.2.106:3000/test-console}
|
||||||
|
|
||||||
|
document-editor:
|
||||||
|
service-url: ${DOCUMENT_EDITOR_SERVICE_URL:}
|
||||||
|
|
||||||
knife4j:
|
knife4j:
|
||||||
# 开启增强配置
|
# 开启增强配置
|
||||||
enable: true
|
enable: true
|
||||||
@@ -229,4 +241,4 @@ model-api-proxy:
|
|||||||
enable-model-proxy: ${MODEL_PROXY_ENABLE:true}
|
enable-model-proxy: ${MODEL_PROXY_ENABLE:true}
|
||||||
port: ${MODEL_PROXY_PORT:18086}
|
port: ${MODEL_PROXY_PORT:18086}
|
||||||
#记录日志
|
#记录日志
|
||||||
save-log: ${MODEL_PROXY_SAVE_LOG:true}
|
save-log: ${MODEL_PROXY_SAVE_LOG:true}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
package com.xspaceagi.agent.core.adapter.application;
|
package com.xspaceagi.agent.core.adapter.application;
|
||||||
|
|
||||||
import com.xspaceagi.agent.core.adapter.dto.AgentDetailDto;
|
import com.xspaceagi.agent.core.adapter.dto.*;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.CardDto;
|
|
||||||
import com.xspaceagi.agent.core.adapter.dto.UserAgentDto;
|
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.AgentComponentConfigDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.AgentComponentConfigDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.AgentConfigDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.AgentConfigDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.Arg;
|
import com.xspaceagi.agent.core.adapter.dto.config.Arg;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.ModelConfigDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.ModelConfigDto;
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.AgentComponentConfig;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -121,6 +120,8 @@ public interface AgentApplicationService {
|
|||||||
*/
|
*/
|
||||||
AgentComponentConfigDto queryComponentConfig(Long id);
|
AgentComponentConfigDto queryComponentConfig(Long id);
|
||||||
|
|
||||||
|
List<AgentComponentConfigDto> queryComponentConfigListByAgentIdAndType(Long agentId, AgentComponentConfig.Type type);
|
||||||
|
|
||||||
List<Arg> getAgentNoneSystemVariables(Long agentId, Long spaceId);
|
List<Arg> getAgentNoneSystemVariables(Long agentId, Long spaceId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -232,10 +233,17 @@ public interface AgentApplicationService {
|
|||||||
/**
|
/**
|
||||||
* 获取用户可选择的模型列表
|
* 获取用户可选择的模型列表
|
||||||
*
|
*
|
||||||
* @param userId 用户ID
|
* @param userId 用户ID
|
||||||
* @param agentId 智能体ID
|
* @param agentId 智能体ID
|
||||||
* @return 模型列表
|
* @return 模型列表
|
||||||
*/
|
*/
|
||||||
List<ModelConfigDto> queryUserCanSelectModelListForAgent(Long userId, Long agentId);
|
List<ModelConfigDto> queryUserCanSelectModelListForAgent(Long userId, Long agentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AI生成项目信息(名称、描述、图标)
|
||||||
|
*/
|
||||||
|
GenerateInfoResultDto generateInfo(GenerateInfoReqDto req);
|
||||||
|
|
||||||
|
String uploadSvgIcon(String svgIcon, String fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package com.xspaceagi.agent.core.adapter.application;
|
package com.xspaceagi.agent.core.adapter.application;
|
||||||
|
|
||||||
import com.xspaceagi.agent.core.adapter.dto.AddSkillsToWorkspaceDto;
|
import com.xspaceagi.agent.core.adapter.dto.*;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.CreateWorkspaceDto;
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface AgentWorkspaceApplicationService {
|
public interface AgentWorkspaceApplicationService {
|
||||||
|
|
||||||
@@ -19,4 +20,48 @@ public interface AgentWorkspaceApplicationService {
|
|||||||
*/
|
*/
|
||||||
void addSkillsToWorkspace(AddSkillsToWorkspaceDto addSkillsToWorkspaceDto);
|
void addSkillsToWorkspace(AddSkillsToWorkspaceDto addSkillsToWorkspaceDto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化项目模板
|
||||||
|
* 根据项目类型和编程语言从 classpath 读取模板 zip,传到工作空间,
|
||||||
|
* 根据 git版本开关决定是否执行 git init + commit
|
||||||
|
*/
|
||||||
|
void initProjectTemplate(InitProjectTemplateDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安装项目依赖
|
||||||
|
* TypeScript 项目执行 pnpm install,Python 项目执行 pip install
|
||||||
|
*/
|
||||||
|
void installProject(InstallProjectDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打包 Agent:在沙箱工作空间执行打包脚本,生成各平台压缩包,上传到平台文件存储
|
||||||
|
*/
|
||||||
|
List<AgentPublishVersionDto> packageAgent(PackageAgentDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从沙箱工作空间取回技能文件,上传到文件服务,用于技能发布
|
||||||
|
*/
|
||||||
|
List<SkillFileDto> snapshotSkillFilesFromSandbox(Long userId, Long cId, String targetType, Long skillId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除沙箱工作空间
|
||||||
|
*/
|
||||||
|
void deleteWorkspace(Long userId, Long cId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从沙箱导出技能为 zip 包
|
||||||
|
*/
|
||||||
|
SkillExportResultDto exportSkillFromSandbox(Long userId, Long cId, String skillName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制源沙箱工作空间到新的工作空间,并初始化 git
|
||||||
|
* 采用先打包下载,后上传到新空间的方式,可以实现跨主机的复制
|
||||||
|
*/
|
||||||
|
void copySandboxWorkspace(Long srcUserId, Long srcCId, Long destUserId, Long destCId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从指定 url 地址下载 zip 文件并上传到工作空间,初始化项目模板
|
||||||
|
*/
|
||||||
|
void uploadZipToWorkspace(Long userId, Long cId, String zipFileUrl);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,9 @@ package com.xspaceagi.agent.core.adapter.application;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.xspaceagi.agent.core.adapter.dto.ComponentDto;
|
import com.xspaceagi.agent.core.adapter.dto.ComponentDto;
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
||||||
|
|
||||||
public interface ComponentApplicationService {
|
public interface ComponentApplicationService {
|
||||||
|
|
||||||
List<ComponentDto> getComponentListBySpaceId(Long spaceId);
|
List<ComponentDto> getComponentListBySpaceId(Long spaceId, Long groupId, List<Published.TargetType> types);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import com.xspaceagi.agent.core.adapter.repository.entity.Conversation;
|
|||||||
import org.springframework.ai.chat.messages.Message;
|
import org.springframework.ai.chat.messages.Message;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -26,6 +25,8 @@ public interface ConversationApplicationService {
|
|||||||
|
|
||||||
ConversationDto createConversationForTaskCenter(Long tenantId, Long userId, Long agentId);
|
ConversationDto createConversationForTaskCenter(Long tenantId, Long userId, Long agentId);
|
||||||
|
|
||||||
|
ConversationDto createConversationForProjectDevelopment(Long tenantId, Long userId, Long spaceId, Long devAgentId, String targetType, Long targetId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建任务会话,返回会话
|
* 创建任务会话,返回会话
|
||||||
*
|
*
|
||||||
@@ -52,6 +53,8 @@ public interface ConversationApplicationService {
|
|||||||
|
|
||||||
void updateConversationStatus(Long cid, Conversation.ConversationTaskStatus status);
|
void updateConversationStatus(Long cid, Conversation.ConversationTaskStatus status);
|
||||||
|
|
||||||
|
void updateConversationVariables(Long id, Map<String, Object> variables);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除会话
|
* 删除会话
|
||||||
*
|
*
|
||||||
@@ -134,7 +137,15 @@ public interface ConversationApplicationService {
|
|||||||
|
|
||||||
Long nextConversationId(Long agentId, String sandboxServerId);
|
Long nextConversationId(Long agentId, String sandboxServerId);
|
||||||
|
|
||||||
Collection<? extends Message> getRoundMessages(String conversationId, int i);
|
List<Message> getRoundMessages(String conversationId, int i);
|
||||||
|
|
||||||
|
List<ChatMessageDto> getRoundMessages(String conversationId, Long minId);
|
||||||
|
|
||||||
void addRoundMessage(String conversationId, Message message);
|
void addRoundMessage(String conversationId, Message message);
|
||||||
|
|
||||||
|
void setChatStopStatus(String conversationId);
|
||||||
|
|
||||||
|
boolean isChatStop(String conversationId);
|
||||||
|
|
||||||
|
void clearChatStopStatus(String conversationId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,31 +19,41 @@ public interface IComputerFileApplicationService {
|
|||||||
/**
|
/**
|
||||||
* 查询文件列表
|
* 查询文件列表
|
||||||
*/
|
*/
|
||||||
Map<String, Object> getFileList(Long userId, Long cId, String proxyPath, UserContext userContext);
|
Map<String, Object> getFileList(Long userId, Long cId, String proxyPath, UserContext userContext, String customTargetDir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新文件
|
* 更新文件
|
||||||
*/
|
*/
|
||||||
Map<String, Object> filesUpdate(Long userId, Long cId, List<ComputerFileInfo> files, UserContext userContext);
|
Map<String, Object> filesUpdate(Long userId, Long cId, List<ComputerFileInfo> files, UserContext userContext, String customTargetDir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传文件
|
* 上传文件
|
||||||
*/
|
*/
|
||||||
Map<String, Object> uploadFile(Long userId, Long cId, String filePath, MultipartFile file, UserContext userContext);
|
Map<String, Object> uploadFile(Long userId, Long cId, String filePath, MultipartFile file, UserContext userContext, String customTargetDir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量上传文件
|
* 批量上传文件
|
||||||
*/
|
*/
|
||||||
Map<String, Object> uploadFiles(Long userId, Long cId, List<String> filePaths, List<MultipartFile> files, UserContext userContext);
|
Map<String, Object> uploadFiles(Long userId, Long cId, List<String> filePaths, List<MultipartFile> files, UserContext userContext, String customTargetDir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入项目(zip 替换工作空间,保留白名单目录)
|
||||||
|
*/
|
||||||
|
Map<String, Object> importProject(Long userId, Long cId, MultipartFile file, UserContext userContext, String customTargetDir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取静态文件
|
* 获取静态文件
|
||||||
*/
|
*/
|
||||||
ResponseEntity<StreamingResponseBody> getStaticFile(Long cId, HttpServletRequest request);
|
ResponseEntity<StreamingResponseBody> getStaticFile(Long cId, HttpServletRequest request, String customTargetDir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下载全部文件(zip)
|
* 下载全部文件(zip)
|
||||||
*/
|
*/
|
||||||
ResponseEntity<StreamingResponseBody> downloadAllFiles(Long userId, Long cId, UserContext userContext);
|
ResponseEntity<StreamingResponseBody> downloadAllFiles(Long userId, Long cId, UserContext userContext, String customTargetDir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取沙盒日志
|
||||||
|
*/
|
||||||
|
Map<String, Object> getLogs(Long userId, Long cId, int tailLines);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.xspaceagi.agent.core.adapter.application;
|
|||||||
|
|
||||||
import com.xspaceagi.agent.core.adapter.dto.CodeCheckResultDto;
|
import com.xspaceagi.agent.core.adapter.dto.CodeCheckResultDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.ModelQueryDto;
|
import com.xspaceagi.agent.core.adapter.dto.ModelQueryDto;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.SortUpdateDTO;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.ModelConfigDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.ModelConfigDto;
|
||||||
import org.springframework.core.ParameterizedTypeReference;
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
|
||||||
@@ -142,4 +143,6 @@ public interface ModelApplicationService {
|
|||||||
String testModelConnectivity(ModelConfigDto modelConfig, String testPrompt);
|
String testModelConnectivity(ModelConfigDto modelConfig, String testPrompt);
|
||||||
|
|
||||||
List<ModelConfigDto> getMySystemModels(Long userId, String tab);
|
List<ModelConfigDto> getMySystemModels(Long userId, String tab);
|
||||||
|
|
||||||
|
void updateModelSort(List<SortUpdateDTO> updateDTOS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.application;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.ProjectCreateDTO;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.ProjectCreateResultDTO;
|
||||||
|
|
||||||
|
public interface ProjectApplicationService {
|
||||||
|
|
||||||
|
ProjectCreateResultDTO createProject(ProjectCreateDTO projectCreateDTO);
|
||||||
|
}
|
||||||
@@ -5,6 +5,8 @@ import com.xspaceagi.agent.core.adapter.dto.*;
|
|||||||
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
||||||
import com.xspaceagi.system.spec.dto.PageQueryVo;
|
import com.xspaceagi.system.spec.dto.PageQueryVo;
|
||||||
import com.xspaceagi.system.spec.page.SuperPage;
|
import com.xspaceagi.system.spec.page.SuperPage;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -15,6 +17,8 @@ public interface PublishApplicationService {
|
|||||||
*/
|
*/
|
||||||
SuperPage<PublishedDto> queryPublishedList(PublishedQueryDto publishedQueryDto);
|
SuperPage<PublishedDto> queryPublishedList(PublishedQueryDto publishedQueryDto);
|
||||||
|
|
||||||
|
List<ResourceGroupDto> queryGroupedPublishedList(PublishedQueryDto publishedQueryDto);
|
||||||
|
|
||||||
SuperPage<PublishedDto> queryPublishedListForAt(PublishedQueryDto publishedQueryDto);
|
SuperPage<PublishedDto> queryPublishedListForAt(PublishedQueryDto publishedQueryDto);
|
||||||
|
|
||||||
List<PublishedDto> queryPublishedList(Published.TargetType targetType, List<Long> targetIds);
|
List<PublishedDto> queryPublishedList(Published.TargetType targetType, List<Long> targetIds);
|
||||||
@@ -23,6 +27,8 @@ public interface PublishApplicationService {
|
|||||||
|
|
||||||
List<PublishedDto> queryPublishedList(Published.TargetType targetType, List<Long> targetIds, String kw);
|
List<PublishedDto> queryPublishedList(Published.TargetType targetType, List<Long> targetIds, String kw);
|
||||||
|
|
||||||
|
List<PublishedDto> queryPublishedList(Published.TargetType targetType, List<Long> targetIds, String kw, boolean returnConfig);
|
||||||
|
|
||||||
IPage<PublishedDto> queryPublishedListForManage(PublishedQueryDto publishedQueryDto);
|
IPage<PublishedDto> queryPublishedListForManage(PublishedQueryDto publishedQueryDto);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,6 +45,8 @@ public interface PublishApplicationService {
|
|||||||
*/
|
*/
|
||||||
Long publishApply(PublishApplyDto publishApplyDto);
|
Long publishApply(PublishApplyDto publishApplyDto);
|
||||||
|
|
||||||
|
String publishOrApply(PublishApplySubmitDto publishApplySubmitDto);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过发布
|
* 通过发布
|
||||||
*/
|
*/
|
||||||
@@ -108,4 +116,6 @@ public interface PublishApplicationService {
|
|||||||
void updateAccessControlStatus(Published.TargetType targetType, Long targetId, Integer status);
|
void updateAccessControlStatus(Published.TargetType targetType, Long targetId, Integer status);
|
||||||
|
|
||||||
void updatePublishName(Published.TargetType targetType, Long targetId, String name);
|
void updatePublishName(Published.TargetType targetType, Long targetId, String name);
|
||||||
|
|
||||||
|
Object checkPermissionAndReturnTargetConfig(Published.TargetType targetType, Long targetId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.application;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.recommend.RecommendHomeResponse;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.recommend.TargetRecommendPageRequest;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.recommend.TargetRecommendResponse;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.recommend.TargetRecommendSaveRequest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface RecommendApplicationService {
|
||||||
|
|
||||||
|
void save(TargetRecommendSaveRequest request);
|
||||||
|
|
||||||
|
void update(TargetRecommendSaveRequest request);
|
||||||
|
|
||||||
|
void delete(Long id);
|
||||||
|
|
||||||
|
TargetRecommendResponse getById(Long id);
|
||||||
|
|
||||||
|
List<TargetRecommendResponse> page(TargetRecommendPageRequest request);
|
||||||
|
|
||||||
|
List<TargetRecommendResponse> list(String recType, String targetType);
|
||||||
|
|
||||||
|
void updateSort(Long id, Integer sort);
|
||||||
|
|
||||||
|
RecommendHomeResponse getRecommendations();
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.application;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.ResourceGroupDto;
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.ResourceGroupRelation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface ResourceGroupApplicationService {
|
||||||
|
|
||||||
|
Long add(ResourceGroupDto dto);
|
||||||
|
|
||||||
|
void update(ResourceGroupDto dto);
|
||||||
|
|
||||||
|
void delete(Long id);
|
||||||
|
|
||||||
|
ResourceGroupDto queryById(Long id);
|
||||||
|
|
||||||
|
ResourceGroupDto queryByName(Long spaceId, String type, String name);
|
||||||
|
|
||||||
|
List<ResourceGroupDto> queryList(String name, List<String> types, Long spaceId);
|
||||||
|
|
||||||
|
List<ResourceGroupDto> queryList(List<Long> groupIds);
|
||||||
|
|
||||||
|
void addResourceToGroup(Long groupId, String targetType, Long targetId);
|
||||||
|
|
||||||
|
void removeResourceFromGroup(Long groupId, String targetType, Long targetId);
|
||||||
|
|
||||||
|
List<ResourceGroupRelation> queryGroupRelations(Long groupId);
|
||||||
|
|
||||||
|
List<ResourceGroupRelation> queryGroupRelations(List<Map<String, Long>> targets);
|
||||||
|
|
||||||
|
ResourceGroupRelation queryResourceGroupRelation(String type, Long targetId);
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.xspaceagi.agent.core.adapter.application;
|
package com.xspaceagi.agent.core.adapter.application;
|
||||||
|
|
||||||
import com.xspaceagi.agent.core.adapter.dto.*;
|
import com.xspaceagi.agent.core.adapter.dto.*;
|
||||||
|
import com.xspaceagi.agent.core.spec.enums.UsageScenarioEnum;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -68,6 +69,18 @@ public interface SkillApplicationService {
|
|||||||
*/
|
*/
|
||||||
Long importSkill(MultipartFile file, SkillConfigDto existSkill, Long targetSpaceId, SkillExtDto ext);
|
Long importSkill(MultipartFile file, SkillConfigDto existSkill, Long targetSpaceId, SkillExtDto ext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入技能(支持文件或URL导入)
|
||||||
|
*
|
||||||
|
* @param url 技能文件URL(与file二选一)
|
||||||
|
* @param file 上传的技能文件(与url二选一)
|
||||||
|
* @param targetSkillId 目标技能ID(导入到已有技能),为null时创建新技能
|
||||||
|
* @param targetSpaceId 目标空间ID(创建新技能时必填)
|
||||||
|
* @param usageScenarios 使用场景列表
|
||||||
|
* @return 技能ID
|
||||||
|
*/
|
||||||
|
Long importSkill(String url, MultipartFile file, Long targetSkillId, Long targetSpaceId, List<UsageScenarioEnum> usageScenarios);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 复制技能
|
* 复制技能
|
||||||
*/
|
*/
|
||||||
@@ -78,6 +91,11 @@ public interface SkillApplicationService {
|
|||||||
*/
|
*/
|
||||||
SkillConfigDto getSkillTemplate(InputStream inputStream);
|
SkillConfigDto getSkillTemplate(InputStream inputStream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取技能模板(从 classpath 自动读取 skill-template.json)
|
||||||
|
*/
|
||||||
|
SkillConfigDto getSkillTemplate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验空间技能权限
|
* 校验空间技能权限
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.application;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.PageAppNewSqlDTO;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.PageAppUpdateSqlDTO;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.PageSqlResultDTO;
|
||||||
|
|
||||||
|
public interface TableWorkflowForPageApplicationService {
|
||||||
|
|
||||||
|
PageSqlResultDTO tableNewSql(PageAppNewSqlDTO pageAppNewSqlDTO);
|
||||||
|
|
||||||
|
PageSqlResultDTO tableUpdateSql(PageAppUpdateSqlDTO pageAppUpdateSqlDTO);
|
||||||
|
}
|
||||||
@@ -88,6 +88,8 @@ public interface WorkflowApplicationService {
|
|||||||
|
|
||||||
WorkflowConfigDto queryPublishedWorkflowConfig(Long workflowId, Long spaceId);
|
WorkflowConfigDto queryPublishedWorkflowConfig(Long workflowId, Long spaceId);
|
||||||
|
|
||||||
|
List<WorkflowConfigDto> queryPublishedWorkflowConfigs(List<Long> workflowIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加节点
|
* 添加节点
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -31,4 +31,7 @@ public class AgentAddDto implements Serializable {
|
|||||||
|
|
||||||
@Schema(description = "类型,ChatBot 对话智能体;TaskAgent 任务型智能体", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "类型,ChatBot 对话智能体;TaskAgent 任务型智能体", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "子类型,ChatBot 问答型、General 通用型、Custom 自定义、Flow 流程协作、Group 群组协作")
|
||||||
|
private String subType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.config.AgentConfigDto;
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AgentConfigCacheStatusVo {
|
||||||
|
|
||||||
|
private AgentConfigDto agentConfig;
|
||||||
|
private List<AgentComponentCacheStatusVo> components;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class AgentComponentCacheStatusVo {
|
||||||
|
private Published.TargetType targetType;
|
||||||
|
private Long targetId;
|
||||||
|
private Long lastUpdated;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -74,4 +74,13 @@ public class AgentConfigUpdateDto implements Serializable {
|
|||||||
|
|
||||||
@Schema(description = "是否隐藏聊天区域,1 隐藏;0 不隐藏")
|
@Schema(description = "是否隐藏聊天区域,1 隐藏;0 不隐藏")
|
||||||
private Integer hideChatArea;
|
private Integer hideChatArea;
|
||||||
|
|
||||||
|
@Schema(description = "是否允许用户在对话框中选择模式, 1 允许,其他不允许")
|
||||||
|
private Integer allowChooseMode;
|
||||||
|
|
||||||
|
@Schema(description = "是否开启询问用户, 1 允许,其他不允许")
|
||||||
|
private Integer enableAskQuestion;
|
||||||
|
|
||||||
|
@Schema(description = "是否开启版本控制, 1 允许,其他不允许")
|
||||||
|
private Integer enableVersionControl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ public class AgentDetailDto implements Serializable {
|
|||||||
@Schema(description = "智能体类型,ChatBot 对话智能体;PageApp 网页应用智能体")
|
@Schema(description = "智能体类型,ChatBot 对话智能体;PageApp 网页应用智能体")
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "子类型,ChatBot->ChatBot、PageApp->PageApp, TaskAgent -> General、Custom、Flow、Group")
|
||||||
|
private String subType;
|
||||||
|
|
||||||
@Schema(description = "智能体名称")
|
@Schema(description = "智能体名称")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@@ -107,6 +110,12 @@ public class AgentDetailDto implements Serializable {
|
|||||||
@Schema(description = "是否允许用户在对话框中选择自己的电脑, 1 允许,其他不允许")
|
@Schema(description = "是否允许用户在对话框中选择自己的电脑, 1 允许,其他不允许")
|
||||||
private Integer allowPrivateSandbox;
|
private Integer allowPrivateSandbox;
|
||||||
|
|
||||||
|
@Schema(description = "是否允许用户在对话框中选择模式, 1 允许,其他不允许")
|
||||||
|
private Integer allowChooseMode;
|
||||||
|
|
||||||
|
@Schema(description = "是否开启版本控制, 1 允许,其他不允许")
|
||||||
|
private Integer enableVersionControl;
|
||||||
|
|
||||||
@Schema(description = "扩展页面首页")
|
@Schema(description = "扩展页面首页")
|
||||||
private String pageHomeIndex;
|
private String pageHomeIndex;
|
||||||
|
|
||||||
@@ -130,4 +139,7 @@ public class AgentDetailDto implements Serializable {
|
|||||||
|
|
||||||
@Schema(description = "超出调用限制提示")
|
@Schema(description = "超出调用限制提示")
|
||||||
private boolean overCallLimit;
|
private boolean overCallLimit;
|
||||||
|
|
||||||
|
@Schema(description = "是否显示发布按钮")
|
||||||
|
private boolean showPublishBtn;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ public class AgentOutputDto implements Serializable {
|
|||||||
PROCESSING_MESSAGE,
|
PROCESSING_MESSAGE,
|
||||||
// 输出消息
|
// 输出消息
|
||||||
MESSAGE,
|
MESSAGE,
|
||||||
|
STATE,
|
||||||
// 最终统计等消息
|
// 最终统计等消息
|
||||||
FINAL_RESULT,
|
FINAL_RESULT,
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AgentPublishVersionDto implements Serializable {
|
||||||
|
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
private String gitCommit;
|
||||||
|
|
||||||
|
@Builder.Default
|
||||||
|
private Boolean latest = true;
|
||||||
|
|
||||||
|
private List<PackageArtifact> packages;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class PackageArtifact implements Serializable {
|
||||||
|
private String platform;
|
||||||
|
private String url;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
package com.xspaceagi.agent.core.adapter.dto;
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
import com.xspaceagi.agent.core.spec.enums.MessageTypeEnum;
|
import com.xspaceagi.agent.core.spec.enums.MessageTypeEnum;
|
||||||
|
import com.xspaceagi.agent.core.spec.utils.TikTokensUtil;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.springframework.ai.chat.messages.Message;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.springframework.ai.chat.messages.MessageType;
|
import org.springframework.ai.chat.messages.*;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
@@ -19,6 +18,8 @@ import java.util.Map;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class ChatMessageDto implements Message {
|
public class ChatMessageDto implements Message {
|
||||||
|
|
||||||
|
private static final int MAX_TOKEN_WINDOW_SIZE = 64 * 1024;
|
||||||
|
|
||||||
private Long index;
|
private Long index;
|
||||||
|
|
||||||
private Long tenantId;
|
private Long tenantId;
|
||||||
@@ -72,7 +73,10 @@ public class ChatMessageDto implements Message {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MessageType getMessageType() {
|
public MessageType getMessageType() {
|
||||||
return MessageType.valueOf(role.name());
|
if (role != null) {
|
||||||
|
return MessageType.valueOf(role.name());
|
||||||
|
}
|
||||||
|
return MessageType.USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Role {
|
public enum Role {
|
||||||
@@ -84,6 +88,74 @@ public class ChatMessageDto implements Message {
|
|||||||
|
|
||||||
public enum SenderType {
|
public enum SenderType {
|
||||||
USER,
|
USER,
|
||||||
AGENT
|
AGENT,
|
||||||
|
REMINDER
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Message> toMessages(List<ChatMessageDto> messages) {
|
||||||
|
List<Message> all = new ArrayList<>();
|
||||||
|
//cachedMessageList转Message
|
||||||
|
for (ChatMessageDto message : messages) {
|
||||||
|
if (message.getRole().name().equals(MessageType.USER.name())) {
|
||||||
|
String text = message.getText();
|
||||||
|
if (text != null) {
|
||||||
|
text = text.replaceAll("<user-memory>[\\s\\S]*?</user-memory>", "").trim();
|
||||||
|
}
|
||||||
|
all.add(new UserMessage(text == null ? "" : text));
|
||||||
|
}
|
||||||
|
if (message.getRole().name().equals(MessageType.ASSISTANT.name())) {
|
||||||
|
String text = removeSystemTagContent(message.getText());
|
||||||
|
if (text != null) {
|
||||||
|
text = text.replaceAll("\n<div><markdown-custom-process[^>]*>.*?</markdown-custom-process></div>\n\n", "");
|
||||||
|
text = text.replaceAll("<markdown-custom-process[^>]*>.*?</markdown-custom-process>", "");
|
||||||
|
}
|
||||||
|
all.add(new AssistantMessage(text));
|
||||||
|
}
|
||||||
|
if (message.getRole().name().equals(MessageType.SYSTEM.name())) {
|
||||||
|
all.add(new SystemMessage(message.getText()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.reverse(all);
|
||||||
|
Iterator<Message> iterator = all.iterator();
|
||||||
|
int tokenCount = 0;
|
||||||
|
MessageType messageType = MessageType.ASSISTANT;
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Message next = iterator.next();
|
||||||
|
if (messageType != next.getMessageType()) {
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
messageType = messageType == MessageType.USER ? MessageType.ASSISTANT : MessageType.USER;
|
||||||
|
if (tokenCount >= MAX_TOKEN_WINDOW_SIZE) {
|
||||||
|
iterator.remove();
|
||||||
|
} else {
|
||||||
|
tokenCount += TikTokensUtil.tikTokensCount(next.getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.reverse(all);
|
||||||
|
removeIfFirstMessageIsAssistant(all);
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String removeSystemTagContent(String text) {
|
||||||
|
if (text == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return text.replaceAll("<think>[\\s\\S]*?</think>", "").trim()
|
||||||
|
.replaceAll("```xml[\\s\\S]*?<tool_.*>[\\s\\S]*?</tool_.*>[\\s\\S]*?```", " ")
|
||||||
|
.replaceAll("<tool_.*>[\\s\\S]*?</tool_.*>", " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//移除第一条消息不是User的内容,避免像deepseek第一条消息不是User消息时,导致无法正常工具调用
|
||||||
|
private static void removeIfFirstMessageIsAssistant(List<Message> all) {
|
||||||
|
if (CollectionUtils.isEmpty(all)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (all.get(0).getMessageType() == MessageType.ASSISTANT) {
|
||||||
|
all.remove(0);
|
||||||
|
removeIfFirstMessageIsAssistant(all);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
package com.xspaceagi.agent.core.adapter.dto;
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
||||||
|
import com.xspaceagi.agent.core.spec.enums.ComponentTypeEnum;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
|
||||||
import com.xspaceagi.agent.core.spec.enums.ComponentTypeEnum;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class ComponentDto implements Serializable {
|
public class ComponentDto implements Serializable {
|
||||||
|
|
||||||
@@ -19,6 +18,9 @@ public class ComponentDto implements Serializable {
|
|||||||
@Schema(description = "空间ID")
|
@Schema(description = "空间ID")
|
||||||
private Long spaceId;
|
private Long spaceId;
|
||||||
|
|
||||||
|
@Schema(description = "分组ID")
|
||||||
|
private Long groupId;
|
||||||
|
|
||||||
@Schema(description = "组件类型")
|
@Schema(description = "组件类型")
|
||||||
private ComponentTypeEnum type;
|
private ComponentTypeEnum type;
|
||||||
|
|
||||||
@@ -54,4 +56,7 @@ public class ComponentDto implements Serializable {
|
|||||||
@Schema(description = "是否启用")
|
@Schema(description = "是否启用")
|
||||||
private Integer enabled;
|
private Integer enabled;
|
||||||
|
|
||||||
|
@Schema(description = "[插件专用]开发时使用的会话ID")
|
||||||
|
private Long devAgentConversationId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ public class ConversationDto {
|
|||||||
@Schema(description = "会话摘要,当开启长期记忆时,会对每次会话进行总结")
|
@Schema(description = "会话摘要,当开启长期记忆时,会对每次会话进行总结")
|
||||||
private String summary;
|
private String summary;
|
||||||
|
|
||||||
|
@Schema(description = "会话图标")
|
||||||
|
private String icon;
|
||||||
|
|
||||||
@Schema(description = "用户填写的会话变量内容")
|
@Schema(description = "用户填写的会话变量内容")
|
||||||
private Map<String, Object> variables;
|
private Map<String, Object> variables;
|
||||||
|
|
||||||
@@ -68,6 +71,13 @@ public class ConversationDto {
|
|||||||
|
|
||||||
private String sandboxSessionId;
|
private String sandboxSessionId;
|
||||||
|
|
||||||
|
@Schema(description = "开发项目所在的空间ID")
|
||||||
|
private Long devSpaceId;
|
||||||
|
@Schema(description = "开发模式目标类型 Agent,PageApp,Skill,Plugin")
|
||||||
|
private String devTargetType;
|
||||||
|
@Schema(description = "开发模式目标ID")
|
||||||
|
private String devTargetId;
|
||||||
|
|
||||||
@Schema(description = "已分享的URI地址,比对上了则不需要认证")
|
@Schema(description = "已分享的URI地址,比对上了则不需要认证")
|
||||||
private List<String> sharedUris;
|
private List<String> sharedUris;
|
||||||
|
|
||||||
|
|||||||
@@ -18,4 +18,7 @@ public class ConversationUpdateDto implements Serializable {
|
|||||||
|
|
||||||
@Schema(description = "会话主题,可以不传,firstMessage与topic二选一")
|
@Schema(description = "会话主题,可以不传,firstMessage与topic二选一")
|
||||||
private String topic;
|
private String topic;
|
||||||
|
|
||||||
|
@Schema(description = "会话图标")
|
||||||
|
private String icon;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import lombok.NoArgsConstructor;
|
|||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@@ -31,4 +32,17 @@ public class CreateWorkspaceDto implements Serializable {
|
|||||||
|
|
||||||
@Schema(description = "子代理列表")
|
@Schema(description = "子代理列表")
|
||||||
private List<SubagentDto> subagents;
|
private List<SubagentDto> subagents;
|
||||||
|
|
||||||
|
@Schema(description = "MCP servers配置,key为server名称,value为server配置")
|
||||||
|
private Map<String, McpServerConfigDto> mcpServersConfig;
|
||||||
|
|
||||||
|
@Schema(description = "工具权限配置")
|
||||||
|
private PermissionsConfigDto permissionsConfig;
|
||||||
|
|
||||||
|
@Schema(description = "Hooks配置,key为事件类型(如PreToolUse),value为Hook规则列表")
|
||||||
|
private Map<String, List<HookEntryDto>> hooksConfig;
|
||||||
|
|
||||||
|
@Schema(description = "Hook外挂脚本列表")
|
||||||
|
private List<HookScriptDto> hookScripts;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.xspaceagi.agent.web.ui.controller.dto;
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
|
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class GenerateInfoAiDto implements Serializable {
|
||||||
|
|
||||||
|
@JsonPropertyDescription("项目名称,简洁有意义,不超过20个字符")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@JsonPropertyDescription("项目描述,一句话概括功能和用途,不超过100个字符")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@JsonPropertyDescription("SVG图标内容,根元素必须为 <svg width=\"200\" height=\"200\" viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">;第一个元素必须是铺满画布的背景 rect(x=0,y=0,width=100,height=100);主图形需占满大部分画布(约10-90坐标范围),不要留大空白边距;不使用外部资源")
|
||||||
|
private String svgIcon;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(description = "AI生成项目信息请求")
|
||||||
|
public class GenerateInfoReqDto implements Serializable {
|
||||||
|
|
||||||
|
@Schema(description = "用户需求描述", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank
|
||||||
|
private String prompt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(description = "AI生成项目信息结果")
|
||||||
|
public class GenerateInfoResultDto implements Serializable {
|
||||||
|
|
||||||
|
@Schema(description = "项目名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "项目描述")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "图标文件访问URL")
|
||||||
|
private String iconUrl;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(description = "Hook规则条目")
|
||||||
|
public class HookEntryDto implements Serializable {
|
||||||
|
|
||||||
|
// 过滤条件(如 "Bash" 仅针对 Bash 工具)
|
||||||
|
@Schema(description = "匹配器,如工具名或正则表达式")
|
||||||
|
private String matcher;
|
||||||
|
|
||||||
|
@Schema(description = "Hook配置列表,每项为解析后的 JSON 对象")
|
||||||
|
private List<Object> hooks;
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(description = "单个Hook脚本配置")
|
||||||
|
public class HookItemDto implements Serializable {
|
||||||
|
|
||||||
|
@Schema(description = "Hook类型," +
|
||||||
|
"command - 运行 shell 脚本、" +
|
||||||
|
"http - 调用 HTTP 端点、" +
|
||||||
|
"mcp_tool - 调用 MCP 工具、" +
|
||||||
|
"prompt - 向 Claude 发送提示、" +
|
||||||
|
"agent - 生成 subagent")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "要执行的命令")
|
||||||
|
private String command;
|
||||||
|
|
||||||
|
@Schema(description = "命令参数列表")
|
||||||
|
private List<String> args;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(description = "Hook外挂脚本DTO")
|
||||||
|
public class HookScriptDto implements Serializable {
|
||||||
|
|
||||||
|
// 比如:传的相对路径:hooks/my-script.sh,实际存放路径是 ${PROJECT_DIR}/.claude/hooks/my-script.sh
|
||||||
|
@Schema(description = "脚本相对路径,如 hooks/my-script.sh")
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@Schema(description = "脚本文件内容")
|
||||||
|
private String content;
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(description = "初始化项目模板请求DTO")
|
||||||
|
public class InitProjectTemplateDto implements Serializable {
|
||||||
|
|
||||||
|
@Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Schema(description = "会话ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@JsonProperty("cId")
|
||||||
|
private Long cId;
|
||||||
|
|
||||||
|
@Schema(description = "项目类型", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private ProjectType projectType;
|
||||||
|
|
||||||
|
@Schema(description = "编程语言(projectType=AGENT时必填)")
|
||||||
|
private ProgrammingLanguage programmingLanguage;
|
||||||
|
|
||||||
|
public enum ProjectType {
|
||||||
|
AGENT("agent"),
|
||||||
|
SKILL("skill");
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
ProjectType(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonValue
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public static ProjectType fromValue(String value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Arrays.stream(values())
|
||||||
|
.filter(e -> e.value.equalsIgnoreCase(value))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("Unknown projectType: " + value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ProgrammingLanguage {
|
||||||
|
TYPESCRIPT("typescript"),
|
||||||
|
PYTHON("python");
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
ProgrammingLanguage(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonValue
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonCreator
|
||||||
|
public static ProgrammingLanguage fromValue(String value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Arrays.stream(values())
|
||||||
|
.filter(e -> e.value.equalsIgnoreCase(value))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("Unknown programmingLanguage: " + value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Schema(description = "安装项目依赖请求DTO")
|
||||||
|
public class InstallProjectDto implements Serializable {
|
||||||
|
|
||||||
|
@Schema(description = "用户ID", hidden = true)
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Schema(description = "会话ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@JsonProperty("cId")
|
||||||
|
private Long cId;
|
||||||
|
|
||||||
|
@Schema(description = "编程语言", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private InitProjectTemplateDto.ProgrammingLanguage programmingLanguage;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(description = "MCP Server配置")
|
||||||
|
public class McpServerConfigDto implements Serializable {
|
||||||
|
|
||||||
|
@Schema(description = "MCP Server类型,stdio、http、streamable-http、sse、ws")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "远程HTTP端点URL")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Schema(description = "启动命令,如 npx、python(type为stdio时使用)")
|
||||||
|
private String command;
|
||||||
|
|
||||||
|
@Schema(description = "命令参数列表(type为stdio时使用)")
|
||||||
|
private List<String> args;
|
||||||
|
|
||||||
|
@Schema(description = "环境变量(type为stdio时使用)")
|
||||||
|
private Map<String, String> env;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PackageAgentDto implements Serializable {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@JsonProperty("cId")
|
||||||
|
private Long cId;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Long agentId;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private InitProjectTemplateDto.ProgrammingLanguage programmingLanguage;
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.config.Arg;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PageAppNewSqlDTO {
|
||||||
|
|
||||||
|
@Schema(description = "空间ID,环境变量中读取 DEV_SPACE_ID", requiredMode = Schema.RequiredMode.REQUIRED, hidden = true)
|
||||||
|
private Long spaceId;
|
||||||
|
|
||||||
|
@Schema(description = "项目ID,环境变量中读取 DEV_PROJECT_ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
@Schema(description = "给接口一个分组名称,便于管理,尽量将所有接口放在一个分组里")
|
||||||
|
private String groupName;
|
||||||
|
|
||||||
|
@Schema(description = "分组描述")
|
||||||
|
private String groupDescription;
|
||||||
|
|
||||||
|
@Schema(description = "参数,使用一级即可")
|
||||||
|
private List<Arg> args;
|
||||||
|
|
||||||
|
@Schema(description = "表ID")
|
||||||
|
private Long tableId;
|
||||||
|
|
||||||
|
@Schema(description = "SQL:Variable placeholders do not need single quotes, e.g., SELECT * FROM custom_table WHERE agent_id = {{agent_id}};For LIKE fuzzy queries, use $+variable, e.g., SELECT * FROM custom_table WHERE agent_name LIKE '%${{agent_name}}%';", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String sql;
|
||||||
|
|
||||||
|
@Schema(description = "API名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String apiName;
|
||||||
|
|
||||||
|
@Schema(description = "API描述", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String description;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.config.Arg;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PageAppUpdateSqlDTO {
|
||||||
|
|
||||||
|
@Schema(description = "项目ID,环境变量中读取 DEV_PROJECT_ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
@Schema(description = "API ID")
|
||||||
|
private Long apiId;
|
||||||
|
|
||||||
|
@Schema(description = "参数,使用一级即可")
|
||||||
|
private List<Arg> args;
|
||||||
|
|
||||||
|
@Schema(description = "SQL:Variable placeholders do not need single quotes, e.g., SELECT * FROM custom_table WHERE agent_id = {{agent_id}};For LIKE fuzzy queries, use $+variable, e.g., SELECT * FROM custom_table WHERE agent_name LIKE '%${{agent_name}}%';", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String sql;
|
||||||
|
|
||||||
|
@Schema(description = "API名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String apiName;
|
||||||
|
|
||||||
|
@Schema(description = "API描述", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String description;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PageSqlResultDTO {
|
||||||
|
|
||||||
|
@Schema(description = "接口ID")
|
||||||
|
private Long apiId;
|
||||||
|
|
||||||
|
@Schema(description = "接口Schema,可用于调试")
|
||||||
|
private String apiSchema;
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(description = "工具权限配置")
|
||||||
|
public class PermissionsConfigDto implements Serializable {
|
||||||
|
|
||||||
|
@Schema(description = "自动允许的工具规则列表,如 [\"Bash(npm run lint)\", \"Read(~/.zshrc)\"]")
|
||||||
|
private List<String> allow;
|
||||||
|
|
||||||
|
@Schema(description = "拒绝的工具规则列表,如 [\"Bash(curl *)\", \"Read(./.env)\"]")
|
||||||
|
private List<String> deny;
|
||||||
|
|
||||||
|
@Schema(description = "需要询问的工具规则列表,如 [\"Bash(git push *)\"]")
|
||||||
|
private List<String> ask;
|
||||||
|
}
|
||||||
@@ -21,4 +21,6 @@ public class PluginExecuteRequestDto implements Serializable {
|
|||||||
private Map<String, Object> params;
|
private Map<String, Object> params;
|
||||||
|
|
||||||
private boolean test;
|
private boolean test;
|
||||||
|
|
||||||
|
private String apiKey;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,4 +24,7 @@ public class PluginUpdateDto<T> implements Serializable {
|
|||||||
|
|
||||||
@Schema(description = "插件配置")
|
@Schema(description = "插件配置")
|
||||||
private T config;
|
private T config;
|
||||||
|
|
||||||
|
@Schema(description = "开发智能体的会话ID")
|
||||||
|
private Long devAgentConversationId;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ProjectCreateDTO {
|
||||||
|
|
||||||
|
@Schema(description = "项目所属空间ID,不传则默认放在个人空间,可选")
|
||||||
|
private Long spaceId;
|
||||||
|
|
||||||
|
@Schema(description = "目标项目类型", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Published.TargetType targetType;
|
||||||
|
|
||||||
|
@Schema(description = "目标项目名称,可选")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "目标项目创建者ID,可选", hidden = true)
|
||||||
|
private Long creatorId;
|
||||||
|
|
||||||
|
@Schema(description = "编程语言选择")
|
||||||
|
private InitProjectTemplateDto.ProgrammingLanguage programmingLanguage;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ProjectCreateResultDTO {
|
||||||
|
|
||||||
|
@Schema(description = "目标项目类型")
|
||||||
|
private Published.TargetType targetType;
|
||||||
|
|
||||||
|
@Schema(description = "目标项目ID")
|
||||||
|
private String targetId;
|
||||||
|
|
||||||
|
@Schema(description = "开发智能体的关联的会话ID")
|
||||||
|
private Long conversationId;
|
||||||
|
}
|
||||||
@@ -1,18 +1,17 @@
|
|||||||
package com.xspaceagi.agent.core.adapter.dto;
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
||||||
import com.xspaceagi.agent.core.spec.enums.PluginTypeEnum;
|
import com.xspaceagi.agent.core.spec.enums.PluginTypeEnum;
|
||||||
import com.xspaceagi.agent.core.spec.enums.UsageScenarioEnum;
|
import com.xspaceagi.agent.core.spec.enums.UsageScenarioEnum;
|
||||||
import com.xspaceagi.custompage.sdk.dto.SourceTypeEnum;
|
import com.xspaceagi.custompage.sdk.dto.SourceTypeEnum;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class PublishedDto implements Serializable {
|
public class PublishedDto implements Serializable {
|
||||||
|
|
||||||
@@ -23,6 +22,8 @@ public class PublishedDto implements Serializable {
|
|||||||
|
|
||||||
private Long spaceId;
|
private Long spaceId;
|
||||||
|
|
||||||
|
private Long groupId;
|
||||||
|
|
||||||
@Schema(description = "目标对象(智能体、工作流、插件)ID")
|
@Schema(description = "目标对象(智能体、工作流、插件)ID")
|
||||||
private Published.TargetType targetType;
|
private Published.TargetType targetType;
|
||||||
|
|
||||||
@@ -102,6 +103,9 @@ public class PublishedDto implements Serializable {
|
|||||||
@Schema(description = "价格")
|
@Schema(description = "价格")
|
||||||
private BigDecimal price;
|
private BigDecimal price;
|
||||||
|
|
||||||
|
@Schema(description = "价格类型, ONE_TIME 次;SECOND 秒;MILLION_TOKEN 百万Token")
|
||||||
|
private String pricingType;
|
||||||
|
|
||||||
@Schema(description = "是否已订阅,对智能体和技能有效")
|
@Schema(description = "是否已订阅,对智能体和技能有效")
|
||||||
private boolean subscribed;
|
private boolean subscribed;
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,15 @@ public class PublishedQueryDto implements Serializable {
|
|||||||
@Schema(description = "子类型")
|
@Schema(description = "子类型")
|
||||||
private Published.TargetSubType targetSubType;
|
private Published.TargetSubType targetSubType;
|
||||||
|
|
||||||
|
@Schema(description = "智能体类型")
|
||||||
|
private List<String> agentTypes;
|
||||||
|
|
||||||
@Schema(description = "页码")
|
@Schema(description = "页码")
|
||||||
private Integer page;
|
private Integer page;
|
||||||
|
|
||||||
|
@Schema(description = "上一页最后一条数据的时间戳,与page二选一")
|
||||||
|
private Long lastTimestamp;
|
||||||
|
|
||||||
@Schema(description = "每页数量")
|
@Schema(description = "每页数量")
|
||||||
private Integer pageSize;
|
private Integer pageSize;
|
||||||
|
|
||||||
@@ -65,12 +71,21 @@ public class PublishedQueryDto implements Serializable {
|
|||||||
@Schema(description = "查询的ID范围,比如只查看推荐、官方标识的组件等", hidden = true)
|
@Schema(description = "查询的ID范围,比如只查看推荐、官方标识的组件等", hidden = true)
|
||||||
private List<Long> targetIds;
|
private List<Long> targetIds;
|
||||||
|
|
||||||
|
@Schema(description = "推荐列表", hidden = true)
|
||||||
|
private List<Long> recommendIds;
|
||||||
|
|
||||||
|
@Schema(description = "排除列表", hidden = true)
|
||||||
|
private List<Long> excludeIds;
|
||||||
|
|
||||||
@Schema(description = "是否只返回官方标识的内容")
|
@Schema(description = "是否只返回官方标识的内容")
|
||||||
private Boolean official;
|
private Boolean official;
|
||||||
|
|
||||||
@Schema(description = "适用场景筛选参数,如 [TaskAgent, PageApp]")
|
@Schema(description = "适用场景筛选参数,如 [TaskAgent, PageApp]")
|
||||||
private List<UsageScenarioEnum> usageScenarios;
|
private List<UsageScenarioEnum> usageScenarios;
|
||||||
|
|
||||||
|
@Schema(description = "是否返回配置信息", hidden = true)
|
||||||
|
private boolean returnConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取页码
|
* 获取页码
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ResourceGroupDto implements Serializable {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private Long spaceId;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
private Integer toolCount;
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "目标对象(智能体、工作流、插件)类型,分组中第一个工具的类型")
|
||||||
|
private Published.TargetType targetType;
|
||||||
|
|
||||||
|
@Schema(description = "目标对象(工作流、插件)ID,分组中第一个工具的ID")
|
||||||
|
private Long targetId;
|
||||||
|
|
||||||
|
private Date created;
|
||||||
|
|
||||||
|
private Date modified;
|
||||||
|
|
||||||
|
@Schema(description = "是否需要付费")
|
||||||
|
private boolean paymentRequired;
|
||||||
|
|
||||||
|
@Schema(description = "发布者信息")
|
||||||
|
private PublishUserDto publishUser;
|
||||||
|
|
||||||
|
@Schema(description = "工具列表,选择使用")
|
||||||
|
private List<PublishedDto> tools;
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.ResourceGroupRelation;
|
||||||
|
|
||||||
|
public class ResourceGroupRelationDto extends ResourceGroupRelation {
|
||||||
|
}
|
||||||
@@ -56,4 +56,7 @@ public class SkillConfigDto implements Serializable {
|
|||||||
|
|
||||||
@Schema(description = "技能发布zip代理下载地址")
|
@Schema(description = "技能发布zip代理下载地址")
|
||||||
private String zipFileUrl;
|
private String zipFileUrl;
|
||||||
|
|
||||||
|
@Schema(description = "技能开发智能体的关联的会话ID")
|
||||||
|
private Long devAgentConversationId;
|
||||||
}
|
}
|
||||||
@@ -23,4 +23,6 @@ public class SkillPublishedConfigDto {
|
|||||||
|
|
||||||
@Schema(description = "技能发布zip代理下载地址")
|
@Schema(description = "技能发布zip代理下载地址")
|
||||||
private String zipFileUrl;
|
private String zipFileUrl;
|
||||||
|
|
||||||
|
private Long devAgentConversationId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class SortUpdateDTO {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private Integer sort;
|
||||||
|
}
|
||||||
@@ -17,4 +17,6 @@ public class TopicGenDto implements Serializable {
|
|||||||
@JsonPropertyDescription("Contextually appropriate titles, ≤50 characters. Do not generate titles unrelated to the topic. For meaningless contexts, such as user input errors or arbitrary content, no summary is needed; return empty. Output language based on the <content>")
|
@JsonPropertyDescription("Contextually appropriate titles, ≤50 characters. Do not generate titles unrelated to the topic. For meaningless contexts, such as user input errors or arbitrary content, no summary is needed; return empty. Output language based on the <content>")
|
||||||
private String topic;
|
private String topic;
|
||||||
|
|
||||||
|
@JsonPropertyDescription("SVG icon, viewBox='0 0 100 100'. Do not generate icons unrelated to the topic. For meaningless contexts, such as user input errors or arbitrary content, no icon is needed; return empty. Output language based on the <content>. \nSVG requirements: \n- Use simple geometric shapes and clean lines \n- Use a modern color palette (gradient or solid colors) \n- Must be a valid, self-contained SVG with no external references \n- Keep it simple and recognizable at small sizes \n- The SVG should be visually appealing and professional")
|
||||||
|
private String svgIcon;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ public class TryReqDto implements Serializable {
|
|||||||
@Schema(description = "请求ID", hidden = true)
|
@Schema(description = "请求ID", hidden = true)
|
||||||
private String requestId;
|
private String requestId;
|
||||||
|
|
||||||
|
@Schema(description = "代理模式")
|
||||||
|
private String agentMode;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class SelectedComponentDto {
|
public static class SelectedComponentDto {
|
||||||
@Schema(description = "组件ID")
|
@Schema(description = "组件ID")
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public class WorkflowExecuteRequestDto implements Serializable {
|
|||||||
|
|
||||||
private boolean test;
|
private boolean test;
|
||||||
|
|
||||||
|
private String apiKey;
|
||||||
|
|
||||||
public Map<String, Object> getParams() {
|
public Map<String, Object> getParams() {
|
||||||
return params == null ? params = new HashMap<>() : params;
|
return params == null ? params = new HashMap<>() : params;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,7 @@ package com.xspaceagi.agent.core.adapter.dto.config;
|
|||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.CreatorDto;
|
import com.xspaceagi.agent.core.adapter.dto.*;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.GuidQuestionDto;
|
|
||||||
import com.xspaceagi.agent.core.adapter.dto.PublishUserDto;
|
|
||||||
import com.xspaceagi.agent.core.adapter.dto.StatisticsDto;
|
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.bind.*;
|
import com.xspaceagi.agent.core.adapter.dto.config.bind.*;
|
||||||
import com.xspaceagi.agent.core.adapter.repository.entity.AgentComponentConfig;
|
import com.xspaceagi.agent.core.adapter.repository.entity.AgentComponentConfig;
|
||||||
import com.xspaceagi.agent.core.adapter.repository.entity.AgentConfig;
|
import com.xspaceagi.agent.core.adapter.repository.entity.AgentConfig;
|
||||||
@@ -36,6 +33,9 @@ public class AgentConfigDto implements Serializable {
|
|||||||
@Schema(description = "类型,ChatBot 对话智能体;PageApp 网页应用智能体, TaskAgent 任务型智能体")
|
@Schema(description = "类型,ChatBot 对话智能体;PageApp 网页应用智能体, TaskAgent 任务型智能体")
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "子类型,ChatBot->ChatBot、PageApp->PageApp, TaskAgent -> General、Custom、Flow、Group")
|
||||||
|
private String subType;
|
||||||
|
|
||||||
@Schema(description = "商户ID")
|
@Schema(description = "商户ID")
|
||||||
private Long tenantId; // 商户ID
|
private Long tenantId; // 商户ID
|
||||||
|
|
||||||
@@ -111,9 +111,12 @@ public class AgentConfigDto implements Serializable {
|
|||||||
@Schema(description = "是否收藏", hidden = true)
|
@Schema(description = "是否收藏", hidden = true)
|
||||||
private boolean isCollected;
|
private boolean isCollected;
|
||||||
|
|
||||||
@Schema(description = "开发会话ID")
|
@Schema(description = "debug调试会话ID")
|
||||||
private Long devConversationId;
|
private Long devConversationId;
|
||||||
|
|
||||||
|
@Schema(description = "开发Agent的会话ID")
|
||||||
|
private Long devAgentConversationId;
|
||||||
|
|
||||||
@Schema(description = "发布时间,如果不为空,与当前modified时间做对比,如果发布时间小于modified,则前端显示:有更新未发布")
|
@Schema(description = "发布时间,如果不为空,与当前modified时间做对比,如果发布时间小于modified,则前端显示:有更新未发布")
|
||||||
private Date publishDate;
|
private Date publishDate;
|
||||||
|
|
||||||
@@ -162,6 +165,23 @@ public class AgentConfigDto implements Serializable {
|
|||||||
@Schema(description = "是否允许用户在对话框中选择自己的电脑, 1 允许,其他不允许")
|
@Schema(description = "是否允许用户在对话框中选择自己的电脑, 1 允许,其他不允许")
|
||||||
private Integer allowPrivateSandbox;
|
private Integer allowPrivateSandbox;
|
||||||
|
|
||||||
|
@Schema(description = "是否允许用户在对话框中选择模式, 1 允许,其他不允许")
|
||||||
|
private Integer allowChooseMode;
|
||||||
|
|
||||||
|
@Schema(description = "是否开启询问用户, 1 允许,其他不允许")
|
||||||
|
private Integer enableAskQuestion;
|
||||||
|
|
||||||
|
@Schema(description = "是否开启版本控制, 1 允许,其他不允许")
|
||||||
|
private Integer enableVersionControl;
|
||||||
|
|
||||||
|
@Schema(description = "发布版本列表")
|
||||||
|
private List<AgentPublishVersionDto> publishVersion;
|
||||||
|
|
||||||
|
@Schema(description = "已发布的空间ID", hidden = true)
|
||||||
|
private List<Long> publishedSpaceIds;
|
||||||
|
|
||||||
|
private List<CustomPageMenu> customPageMenus;
|
||||||
|
|
||||||
public String getPageHomeIndex() {
|
public String getPageHomeIndex() {
|
||||||
//设置默认页面首页
|
//设置默认页面首页
|
||||||
if (getAgentComponentConfigList() != null) {
|
if (getAgentComponentConfigList() != null) {
|
||||||
@@ -249,6 +269,10 @@ public class AgentConfigDto implements Serializable {
|
|||||||
VariableConfigDto variableConfigDto = JSON.parseObject(componentConfig.getBindConfig().toString(), VariableConfigDto.class);
|
VariableConfigDto variableConfigDto = JSON.parseObject(componentConfig.getBindConfig().toString(), VariableConfigDto.class);
|
||||||
componentConfig.setBindConfig(variableConfigDto);
|
componentConfig.setBindConfig(variableConfigDto);
|
||||||
}
|
}
|
||||||
|
case Hook -> {
|
||||||
|
HookConfigDto hookConfigDto = JSON.parseObject(componentConfig.getBindConfig().toString(), HookConfigDto.class);
|
||||||
|
componentConfig.setBindConfig(hookConfigDto);
|
||||||
|
}
|
||||||
case Mcp -> {
|
case Mcp -> {
|
||||||
McpBindConfigDto mcpBindConfigDto = JSON.parseObject(componentConfig.getBindConfig().toString(), McpBindConfigDto.class);
|
McpBindConfigDto mcpBindConfigDto = JSON.parseObject(componentConfig.getBindConfig().toString(), McpBindConfigDto.class);
|
||||||
componentConfig.setBindConfig(mcpBindConfigDto);
|
componentConfig.setBindConfig(mcpBindConfigDto);
|
||||||
@@ -308,6 +332,11 @@ public class AgentConfigDto implements Serializable {
|
|||||||
componentConfig.setBindConfig(new VariableConfigDto());
|
componentConfig.setBindConfig(new VariableConfigDto());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case Hook -> {
|
||||||
|
if (!(componentConfig.getBindConfig() instanceof HookConfigDto)) {
|
||||||
|
componentConfig.setBindConfig(new HookConfigDto());
|
||||||
|
}
|
||||||
|
}
|
||||||
case Mcp -> {
|
case Mcp -> {
|
||||||
if (!(componentConfig.getBindConfig() instanceof McpBindConfigDto)) {
|
if (!(componentConfig.getBindConfig() instanceof McpBindConfigDto)) {
|
||||||
componentConfig.setBindConfig(new McpBindConfigDto());
|
componentConfig.setBindConfig(new McpBindConfigDto());
|
||||||
@@ -350,4 +379,12 @@ public class AgentConfigDto implements Serializable {
|
|||||||
@Schema(description = "是否选中")
|
@Schema(description = "是否选中")
|
||||||
private boolean selected;
|
private boolean selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum AgentType {
|
||||||
|
ChatBot, PageApp, TaskAgent
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum AgentSubType {
|
||||||
|
ChatBot, PageApp, General, Custom, Flow, Group
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,9 @@ public class Arg implements Serializable {
|
|||||||
|
|
||||||
private Long loopId;
|
private Long loopId;
|
||||||
|
|
||||||
|
@Schema(description = "参数更新策略")
|
||||||
|
private UpdateStrategy updateStrategy;
|
||||||
|
|
||||||
public void setSubArgs(List<Arg> subArgs) {
|
public void setSubArgs(List<Arg> subArgs) {
|
||||||
if (this.subArgs != null) {
|
if (this.subArgs != null) {
|
||||||
return;
|
return;
|
||||||
@@ -121,7 +124,14 @@ public class Arg implements Serializable {
|
|||||||
Number,
|
Number,
|
||||||
//自动识别
|
//自动识别
|
||||||
AutoRecognition,
|
AutoRecognition,
|
||||||
|
File,
|
||||||
|
Radio,
|
||||||
|
FixedValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum UpdateStrategy {
|
||||||
|
REPLACE, // Overwrite the existing value entirely
|
||||||
|
APPEND // Append to the existing value (string concatenation, list append, or numeric addition)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Arg> updateBindConfigArgs(String startKey, List<Arg> bindConfigArgs, List<Arg> configInputArgs) {
|
public static List<Arg> updateBindConfigArgs(String startKey, List<Arg> bindConfigArgs, List<Arg> configInputArgs) {
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto.config;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class HookConfigDto implements Serializable {
|
||||||
|
|
||||||
|
@Schema(description = "Hook列表")
|
||||||
|
private List<Hook> hooks;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Hook {
|
||||||
|
@Schema(description = "Hook名称")
|
||||||
|
private String name;
|
||||||
|
@Schema(description = "Hook事件")
|
||||||
|
private String event;
|
||||||
|
@Schema(description = "Hook匹配规则")
|
||||||
|
private String matcher;
|
||||||
|
@Schema(description = "Hook类型")
|
||||||
|
private String type;
|
||||||
|
@Schema(description = "Hook配置")
|
||||||
|
private String config;
|
||||||
|
@Schema(description = "Hook状态,1 启用;0 停用")
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,6 +34,9 @@ public class McpBindConfigDto implements Serializable {
|
|||||||
@Schema(description = "是否默认选中,0-否,1-是")
|
@Schema(description = "是否默认选中,0-否,1-是")
|
||||||
private Integer defaultSelected;
|
private Integer defaultSelected;
|
||||||
|
|
||||||
|
@Schema(description = "是否需要审批,0-否,1-是")
|
||||||
|
private Integer callApproval;
|
||||||
|
|
||||||
public enum McpInvokeTypeEnum {
|
public enum McpInvokeTypeEnum {
|
||||||
//自动调用、按需调用、手动选择、手动选择和按需调用
|
//自动调用、按需调用、手动选择、手动选择和按需调用
|
||||||
AUTO, ON_DEMAND, MANUAL, MANUAL_ON_DEMAND
|
AUTO, ON_DEMAND, MANUAL, MANUAL_ON_DEMAND
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ public class PluginBindConfigDto implements Serializable {
|
|||||||
@Schema(description = "是否默认选中,0-否,1-是")
|
@Schema(description = "是否默认选中,0-否,1-是")
|
||||||
private Integer defaultSelected;
|
private Integer defaultSelected;
|
||||||
|
|
||||||
|
@Schema(description = "是否需要审批,0-否,1-是")
|
||||||
|
private Integer callApproval;
|
||||||
|
|
||||||
public enum PluginInvokeTypeEnum {
|
public enum PluginInvokeTypeEnum {
|
||||||
//自动调用、按需调用、手动选择、手动选择和按需调用
|
//自动调用、按需调用、手动选择、手动选择和按需调用
|
||||||
AUTO, ON_DEMAND, MANUAL, MANUAL_ON_DEMAND
|
AUTO, ON_DEMAND, MANUAL, MANUAL_ON_DEMAND
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ public class WorkflowBindConfigDto implements Serializable {
|
|||||||
// 相同requestId时是否使用缓存的结果,问答场景
|
// 相同requestId时是否使用缓存的结果,问答场景
|
||||||
private boolean useResultCache;
|
private boolean useResultCache;
|
||||||
|
|
||||||
|
@Schema(description = "是否需要审批,0-否,1-是")
|
||||||
|
private Integer callApproval;
|
||||||
|
|
||||||
public enum WorkflowInvokeTypeEnum {
|
public enum WorkflowInvokeTypeEnum {
|
||||||
//自动调用、按需调用
|
//自动调用、按需调用
|
||||||
AUTO, ON_DEMAND, MANUAL, MANUAL_ON_DEMAND
|
AUTO, ON_DEMAND, MANUAL, MANUAL_ON_DEMAND
|
||||||
|
|||||||
@@ -72,6 +72,11 @@ public class PluginDto implements Serializable {
|
|||||||
@Schema(description = "已发布的空间ID", hidden = true)
|
@Schema(description = "已发布的空间ID", hidden = true)
|
||||||
private List<Long> publishedSpaceIds;
|
private List<Long> publishedSpaceIds;
|
||||||
|
|
||||||
|
@Schema(description = "开发时使用的会话ID")
|
||||||
|
private Long devAgentConversationId;
|
||||||
|
|
||||||
|
private String toolId;
|
||||||
|
|
||||||
public static PluginDto convertToPluginDto(String config) {
|
public static PluginDto convertToPluginDto(String config) {
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto.config.workflow;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.config.AgentConfigDto;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AgentNodeConfigDto extends NodeConfigDto {
|
||||||
|
|
||||||
|
@Schema(description = "智能体ID")
|
||||||
|
private Long agentId;
|
||||||
|
|
||||||
|
@Schema(description = "节点名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "节点描述")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "节点图标")
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
@Schema(description = "补充提示词")
|
||||||
|
private String extraPrompt;
|
||||||
|
|
||||||
|
@Schema(description = "自身循环次数")
|
||||||
|
private int selfLoopTimes;
|
||||||
|
|
||||||
|
@Schema(description = "循环提醒提示词")
|
||||||
|
private String reminderPrompt;
|
||||||
|
|
||||||
|
@Schema(description = "智能体配置信息,执行阶段使用")
|
||||||
|
private AgentConfigDto agentConfigDto;
|
||||||
|
}
|
||||||
@@ -35,6 +35,9 @@ public class IntentRecognitionNodeConfigDto extends NodeConfigDto {
|
|||||||
@Schema(description = "token上限")
|
@Schema(description = "token上限")
|
||||||
private Integer maxTokens; // token上限
|
private Integer maxTokens; // token上限
|
||||||
|
|
||||||
|
@Schema(description = "系统提示词")
|
||||||
|
private String systemPrompt;
|
||||||
|
|
||||||
@Schema(description = "补充提示词")
|
@Schema(description = "补充提示词")
|
||||||
private String extraPrompt;
|
private String extraPrompt;
|
||||||
|
|
||||||
@@ -55,12 +58,22 @@ public class IntentRecognitionNodeConfigDto extends NodeConfigDto {
|
|||||||
@Schema(description = "唯一标识")
|
@Schema(description = "唯一标识")
|
||||||
private String uuid;
|
private String uuid;
|
||||||
|
|
||||||
@Schema(description = "意图描述")
|
@Schema(description = "意图名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "意图描述,兜底匹配")
|
||||||
private String intent;
|
private String intent;
|
||||||
|
|
||||||
@Schema(description = "意图类型,NORMAL正常添加配置,OTHER其他意图")
|
@Schema(description = "意图类型,NORMAL正常添加配置,OTHER其他意图")
|
||||||
private IntentTypeEnum intentType;
|
private IntentTypeEnum intentType;
|
||||||
|
|
||||||
|
//条件参数关系
|
||||||
|
@Schema(description = "条件参数之间关系")
|
||||||
|
private ConditionNodeConfigDto.ConditionTypeEnum conditionType;
|
||||||
|
|
||||||
|
//参数列表配置
|
||||||
|
@Schema(description = "参数列表配置")
|
||||||
|
private List<ConditionNodeConfigDto.ConditionArgDto> conditionArgs;
|
||||||
|
|
||||||
@Schema(description = "关联下级节点id列表")
|
@Schema(description = "关联下级节点id列表")
|
||||||
private List<Long> nextNodeIds;
|
private List<Long> nextNodeIds;
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto.config.workflow;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.config.Arg;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.config.InputArg;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.config.OutputArg;
|
||||||
|
import com.xspaceagi.agent.core.spec.enums.DataTypeEnum;
|
||||||
|
import com.xspaceagi.system.spec.utils.I18nUtil;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class KnowledgeInsertNodeConfigDto extends NodeConfigDto {
|
||||||
|
|
||||||
|
@Schema(description = "知识库ID配置", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Long knowledgeBaseId;
|
||||||
|
|
||||||
|
@Schema(description = "节点名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "节点描述")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "节点图标")
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共节点配置转条件节点配置
|
||||||
|
*
|
||||||
|
* @return 条件节点配置
|
||||||
|
*/
|
||||||
|
public static KnowledgeInsertNodeConfigDto addFrom(Long knowledgeBaseId) {
|
||||||
|
KnowledgeInsertNodeConfigDto knowledgeInsertNodeConfigDto = new KnowledgeInsertNodeConfigDto();
|
||||||
|
knowledgeInsertNodeConfigDto.setKnowledgeBaseId(knowledgeBaseId);
|
||||||
|
//设置默认输入参数和输出参数
|
||||||
|
List<Arg> args = new ArrayList<>();
|
||||||
|
InputArg arg = new InputArg();
|
||||||
|
arg.setKey(UUID.randomUUID().toString().replace("-", ""));
|
||||||
|
arg.setName("title");
|
||||||
|
arg.setDescription(I18nUtil.systemMessage("Backend.WorkflowKbArgs.title.description"));
|
||||||
|
arg.setDataType(DataTypeEnum.String);
|
||||||
|
args.add(arg);
|
||||||
|
arg = new InputArg();
|
||||||
|
arg.setKey(UUID.randomUUID().toString().replace("-", ""));
|
||||||
|
arg.setName("content");
|
||||||
|
arg.setDescription(I18nUtil.systemMessage("Backend.WorkflowKbArgs.content.description"));
|
||||||
|
arg.setDataType(DataTypeEnum.String);
|
||||||
|
args.add(arg);
|
||||||
|
arg = new InputArg();
|
||||||
|
arg.setKey(UUID.randomUUID().toString().replace("-", ""));
|
||||||
|
arg.setName("docUrl");
|
||||||
|
arg.setDescription(I18nUtil.systemMessage("Backend.WorkflowKbArgs.docUrl.description"));
|
||||||
|
arg.setDataType(DataTypeEnum.String);
|
||||||
|
args.add(arg);
|
||||||
|
//segment
|
||||||
|
arg = new InputArg();
|
||||||
|
arg.setKey(UUID.randomUUID().toString().replace("-", ""));
|
||||||
|
arg.setName("segment");
|
||||||
|
arg.setDescription(I18nUtil.systemMessage("Backend.WorkflowKbArgs.segment.description"));
|
||||||
|
arg.setDataType(DataTypeEnum.String);
|
||||||
|
arg.setBindValue("WORDS");
|
||||||
|
args.add(arg);
|
||||||
|
arg = new InputArg();
|
||||||
|
arg.setKey(UUID.randomUUID().toString().replace("-", ""));
|
||||||
|
arg.setName("words");
|
||||||
|
arg.setDescription(I18nUtil.systemMessage("Backend.WorkflowKbArgs.words.description"));
|
||||||
|
arg.setDataType(DataTypeEnum.Integer);
|
||||||
|
arg.setBindValue("800");
|
||||||
|
args.add(arg);
|
||||||
|
|
||||||
|
knowledgeInsertNodeConfigDto.setInputArgs(args);
|
||||||
|
|
||||||
|
List<Arg> outputArgs = new ArrayList<>();
|
||||||
|
Arg outArg = new OutputArg();
|
||||||
|
outArg.setName("success");
|
||||||
|
outArg.setDataType(DataTypeEnum.Boolean);
|
||||||
|
outArg.setDescription(I18nUtil.systemMessage("Backend.WorkflowKbArgs.success.description"));
|
||||||
|
outputArgs.add(outArg);
|
||||||
|
outArg = new OutputArg();
|
||||||
|
outArg.setName("message");
|
||||||
|
outArg.setDataType(DataTypeEnum.String);
|
||||||
|
outArg.setDescription(I18nUtil.systemMessage("Backend.WorkflowKbArgs.message.description"));
|
||||||
|
outputArgs.add(outArg);
|
||||||
|
outArg = new OutputArg();
|
||||||
|
outArg.setName("docId");
|
||||||
|
outArg.setDataType(DataTypeEnum.Number);
|
||||||
|
outArg.setDescription(I18nUtil.systemMessage("Backend.WorkflowKbArgs.docId.description"));
|
||||||
|
outputArgs.add(outArg);
|
||||||
|
knowledgeInsertNodeConfigDto.setOutputArgs(outputArgs);
|
||||||
|
return knowledgeInsertNodeConfigDto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,8 @@ import java.util.Map;
|
|||||||
@Data
|
@Data
|
||||||
public class NodeConfigDto implements Serializable {
|
public class NodeConfigDto implements Serializable {
|
||||||
|
|
||||||
|
private ContextPassingType contextPassingType;
|
||||||
|
|
||||||
@Schema(description = "扩展字段,用于前端存储画布位置等相关配置")
|
@Schema(description = "扩展字段,用于前端存储画布位置等相关配置")
|
||||||
private Map<String, Object> extension;
|
private Map<String, Object> extension;
|
||||||
|
|
||||||
@@ -22,4 +24,9 @@ public class NodeConfigDto implements Serializable {
|
|||||||
|
|
||||||
@Schema(description = "异常处理配置")
|
@Schema(description = "异常处理配置")
|
||||||
private ExceptionHandleConfigDto exceptionHandleConfig;
|
private ExceptionHandleConfigDto exceptionHandleConfig;
|
||||||
|
|
||||||
|
public enum ContextPassingType {
|
||||||
|
Auto,
|
||||||
|
Manual
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.xspaceagi.agent.core.adapter.dto.config.workflow;
|
package com.xspaceagi.agent.core.adapter.dto.config.workflow;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.config.Arg;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.ModelConfigDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.ModelConfigDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.bind.ModelBindConfigDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.bind.ModelBindConfigDto;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
@@ -35,6 +36,9 @@ public class QaNodeConfigDto extends NodeConfigDto {
|
|||||||
@NotNull(message = "Answer type is required")
|
@NotNull(message = "Answer type is required")
|
||||||
private AnswerTypeEnum answerType;
|
private AnswerTypeEnum answerType;
|
||||||
|
|
||||||
|
@Schema(description = "表单参数")
|
||||||
|
private List<Arg> formArgs;
|
||||||
|
|
||||||
//从回复中提取字段
|
//从回复中提取字段
|
||||||
@Schema(description = "从回复中提取字段")
|
@Schema(description = "从回复中提取字段")
|
||||||
private Boolean extractField;
|
private Boolean extractField;
|
||||||
@@ -53,7 +57,8 @@ public class QaNodeConfigDto extends NodeConfigDto {
|
|||||||
public enum AnswerTypeEnum {
|
public enum AnswerTypeEnum {
|
||||||
//直接回答、选项回答
|
//直接回答、选项回答
|
||||||
TEXT,
|
TEXT,
|
||||||
SELECT
|
SELECT,
|
||||||
|
FORM
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|||||||
@@ -44,6 +44,12 @@ public class WorkflowConfigDto {
|
|||||||
@Schema(description = "图标地址")
|
@Schema(description = "图标地址")
|
||||||
private String icon;
|
private String icon;
|
||||||
|
|
||||||
|
@Schema(description = "工作流类型: Workflow、AgentFlow")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "AgentFlow时所属AgentID")
|
||||||
|
private Long agentId;
|
||||||
|
|
||||||
@Schema(description = "开始节点", hidden = true)
|
@Schema(description = "开始节点", hidden = true)
|
||||||
private WorkflowNodeDto startNode;
|
private WorkflowNodeDto startNode;
|
||||||
|
|
||||||
@@ -120,6 +126,12 @@ public class WorkflowConfigDto {
|
|||||||
case Knowledge:
|
case Knowledge:
|
||||||
nodeConfigDto = JSON.parseObject(config, KnowledgeNodeConfigDto.class);
|
nodeConfigDto = JSON.parseObject(config, KnowledgeNodeConfigDto.class);
|
||||||
break;
|
break;
|
||||||
|
case KnowledgeInsert:
|
||||||
|
nodeConfigDto = JSON.parseObject(config, KnowledgeInsertNodeConfigDto.class);
|
||||||
|
break;
|
||||||
|
case Agent:
|
||||||
|
nodeConfigDto = JSON.parseObject(config, AgentNodeConfigDto.class);
|
||||||
|
break;
|
||||||
case Loop:
|
case Loop:
|
||||||
nodeConfigDto = JSON.parseObject(config, LoopNodeConfigDto.class);
|
nodeConfigDto = JSON.parseObject(config, LoopNodeConfigDto.class);
|
||||||
break;
|
break;
|
||||||
@@ -216,4 +228,9 @@ public class WorkflowConfigDto {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum Type {
|
||||||
|
Workflow,
|
||||||
|
AgentFlow
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto.recommend;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class RecommendHomeResponse {
|
||||||
|
|
||||||
|
private Map<String, List<TargetRecommendResponse>> recHome;
|
||||||
|
|
||||||
|
private Map<String, List<TargetRecommendResponse>> recChatBoxNav;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto.recommend;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TargetRecommendPageRequest {
|
||||||
|
|
||||||
|
private Integer pageNo = 1;
|
||||||
|
|
||||||
|
private Integer pageSize = 10;
|
||||||
|
|
||||||
|
private String recType;
|
||||||
|
|
||||||
|
private String targetType;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto.recommend;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class TargetRecommendResponse {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private Long tenantId;
|
||||||
|
private String targetType;
|
||||||
|
private Long targetId;
|
||||||
|
private String recType;
|
||||||
|
private String functionType;
|
||||||
|
private String label;
|
||||||
|
private String icon;
|
||||||
|
private String placeholder;
|
||||||
|
private Integer sort;
|
||||||
|
private Date modified;
|
||||||
|
private Date created;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.dto.recommend;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TargetRecommendSaveRequest {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@NotNull(message = "targetType不能为空")
|
||||||
|
private String targetType;
|
||||||
|
|
||||||
|
@NotNull(message = "targetId不能为空")
|
||||||
|
private Long targetId;
|
||||||
|
|
||||||
|
@NotNull(message = "recType不能为空")
|
||||||
|
private String recType;
|
||||||
|
|
||||||
|
@NotNull(message = "functionType不能为空")
|
||||||
|
private String functionType;
|
||||||
|
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
private String placeholder;
|
||||||
|
|
||||||
|
private Integer sort;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.repository;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.ResourceGroupRelation;
|
||||||
|
|
||||||
|
public interface ResourceGroupRelationRepository extends IService<ResourceGroupRelation> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.repository;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.ResourceGroup;
|
||||||
|
|
||||||
|
public interface ResourceGroupRepository extends IService<ResourceGroup> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.repository;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.TargetRecommend;
|
||||||
|
|
||||||
|
public interface TargetRecommendRepository extends IService<TargetRecommend> {
|
||||||
|
}
|
||||||
@@ -49,6 +49,6 @@ public class AgentComponentConfig {
|
|||||||
private Date created; // 创建时间
|
private Date created; // 创建时间
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
Plugin, Workflow, Trigger, Knowledge, Variable, Database, Model, Agent, Table, Mcp, Page, Event, Skill, SubAgent
|
Plugin, Workflow, Trigger, Knowledge, Variable, Database, Model, Agent, Table, Mcp, Page, Event, Skill, SubAgent, Hook
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,17 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.AgentPublishVersionDto;
|
||||||
|
import com.xspaceagi.agent.core.adapter.typehandler.AgentPublishVersionListTypeHandler;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@TableName("agent_config")
|
@TableName(value = "agent_config", autoResultMap = true)
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@@ -25,6 +28,8 @@ public class AgentConfig {
|
|||||||
|
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
private String subType;
|
||||||
|
|
||||||
@TableField(value = "_tenant_id")
|
@TableField(value = "_tenant_id")
|
||||||
private Long tenantId; // 商户ID
|
private Long tenantId; // 商户ID
|
||||||
|
|
||||||
@@ -62,6 +67,8 @@ public class AgentConfig {
|
|||||||
|
|
||||||
private Long devConversationId; // 开发模式对应的会话ID
|
private Long devConversationId; // 开发模式对应的会话ID
|
||||||
|
|
||||||
|
private Long devAgentConversationId; // 开发Agent的会话ID
|
||||||
|
|
||||||
private AgentConfig.OpenStatus openScheduledTask;
|
private AgentConfig.OpenStatus openScheduledTask;
|
||||||
|
|
||||||
private Integer expandPageArea;//是否默认展开扩展页面区域, 1 展开;0 不展开
|
private Integer expandPageArea;//是否默认展开扩展页面区域, 1 展开;0 不展开
|
||||||
@@ -80,6 +87,15 @@ public class AgentConfig {
|
|||||||
|
|
||||||
private Integer allowPrivateSandbox;
|
private Integer allowPrivateSandbox;
|
||||||
|
|
||||||
|
private Integer allowChooseMode;
|
||||||
|
|
||||||
|
private Integer enableAskQuestion;
|
||||||
|
|
||||||
|
private Integer enableVersionControl;
|
||||||
|
|
||||||
|
@TableField(value = "publish_version", typeHandler = AgentPublishVersionListTypeHandler.class)
|
||||||
|
private List<AgentPublishVersionDto> publishVersion;
|
||||||
|
|
||||||
public enum OpenStatus {
|
public enum OpenStatus {
|
||||||
Open, Close;
|
Open, Close;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ public class Conversation {
|
|||||||
|
|
||||||
private String summary;
|
private String summary;
|
||||||
|
|
||||||
|
private String icon;
|
||||||
|
|
||||||
@TableField(value = "variables", typeHandler = JsonTypeHandler.class)
|
@TableField(value = "variables", typeHandler = JsonTypeHandler.class)
|
||||||
private Map<String, Object> variables;
|
private Map<String, Object> variables;
|
||||||
|
|
||||||
@@ -53,6 +55,9 @@ public class Conversation {
|
|||||||
private String sandboxServerId;
|
private String sandboxServerId;
|
||||||
|
|
||||||
private String sandboxSessionId;
|
private String sandboxSessionId;
|
||||||
|
private Long devSpaceId;
|
||||||
|
private String devTargetType;
|
||||||
|
private String devTargetId;
|
||||||
|
|
||||||
private Date modified;
|
private Date modified;
|
||||||
|
|
||||||
@@ -62,7 +67,9 @@ public class Conversation {
|
|||||||
Chat,
|
Chat,
|
||||||
TempChat,
|
TempChat,
|
||||||
TASK,
|
TASK,
|
||||||
TaskCenter
|
TaskCenter,
|
||||||
|
Development,
|
||||||
|
DevDebug
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ConversationTaskStatus {
|
public enum ConversationTaskStatus {
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ public class ModelConfig {
|
|||||||
private Integer enabled; // 是否启用,0-否,1-是
|
private Integer enabled; // 是否启用,0-否,1-是
|
||||||
private Integer accessControl;
|
private Integer accessControl;
|
||||||
private String usageScenario;
|
private String usageScenario;
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
public enum ModelScopeEnum {
|
public enum ModelScopeEnum {
|
||||||
Space,
|
Space,
|
||||||
Tenant,
|
Tenant,
|
||||||
|
|||||||
@@ -39,4 +39,6 @@ public class PluginConfig {
|
|||||||
private Date modified;
|
private Date modified;
|
||||||
|
|
||||||
private Date created;
|
private Date created;
|
||||||
|
|
||||||
|
private Long devAgentConversationId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ public class Published {
|
|||||||
|
|
||||||
private Long spaceId;
|
private Long spaceId;
|
||||||
|
|
||||||
|
private Long groupId;
|
||||||
|
|
||||||
@TableField("user_id")
|
@TableField("user_id")
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|
||||||
@@ -97,7 +99,9 @@ public class Published {
|
|||||||
Knowledge,
|
Knowledge,
|
||||||
Table,
|
Table,
|
||||||
Skill,
|
Skill,
|
||||||
Model
|
Model,
|
||||||
|
PageApp,
|
||||||
|
Mcp
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum TargetSubType {
|
public enum TargetSubType {
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.repository.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@TableName(value = "resource_group")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class ResourceGroup {
|
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@TableField(value = "_tenant_id")
|
||||||
|
private Long tenantId;
|
||||||
|
|
||||||
|
private Long spaceId;
|
||||||
|
|
||||||
|
private Long creatorId;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
private Integer toolCount;
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private Date created;
|
||||||
|
|
||||||
|
private Date modified;
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.repository.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@TableName(value = "resource_group_relation")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class ResourceGroupRelation {
|
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@TableField(value = "_tenant_id")
|
||||||
|
private Long tenantId;
|
||||||
|
|
||||||
|
private String targetType;
|
||||||
|
|
||||||
|
private Long targetId;
|
||||||
|
|
||||||
|
private Long groupId;
|
||||||
|
|
||||||
|
private Date created;
|
||||||
|
|
||||||
|
private Date modified;
|
||||||
|
}
|
||||||
@@ -57,4 +57,6 @@ public class SkillConfig {
|
|||||||
private String modifiedName; // 最后修改人
|
private String modifiedName; // 最后修改人
|
||||||
|
|
||||||
private Integer yn; // 逻辑标记,1:有效;-1:无效
|
private Integer yn; // 逻辑标记,1:有效;-1:无效
|
||||||
|
|
||||||
|
private Long devAgentConversationId;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.repository.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@TableName("target_recommend")
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class TargetRecommend {
|
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@TableField("_tenant_id")
|
||||||
|
private Long tenantId;
|
||||||
|
|
||||||
|
@TableField("target_type")
|
||||||
|
private TargetType targetType;
|
||||||
|
|
||||||
|
@TableField("target_id")
|
||||||
|
private Long targetId;
|
||||||
|
|
||||||
|
@TableField("rec_type")
|
||||||
|
private RecType recType;
|
||||||
|
|
||||||
|
@TableField("function_type")
|
||||||
|
private FunctionType functionType;
|
||||||
|
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
private String placeholder;
|
||||||
|
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
|
private Date modified;
|
||||||
|
|
||||||
|
private Date created;
|
||||||
|
|
||||||
|
public enum TargetType {
|
||||||
|
Agent,
|
||||||
|
PageApp,
|
||||||
|
Skill,
|
||||||
|
Plugin,
|
||||||
|
Workflow
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum RecType {
|
||||||
|
Home,
|
||||||
|
Official,
|
||||||
|
ChatBoxNav
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum FunctionType {
|
||||||
|
AgentDev,
|
||||||
|
PageAppDev,
|
||||||
|
SkillDev,
|
||||||
|
PluginDev,
|
||||||
|
Chat
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,6 +36,10 @@ public class WorkflowConfig {
|
|||||||
|
|
||||||
private String icon;
|
private String icon;
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private Long agentId;
|
||||||
|
|
||||||
@TableField("start_node_id")
|
@TableField("start_node_id")
|
||||||
private Long startNodeId;
|
private Long startNodeId;
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public class WorkflowNodeConfig {
|
|||||||
LoopContinue("继续循环", "用于终止当前循环,执行下次循环"), // 继续循环节点
|
LoopContinue("继续循环", "用于终止当前循环,执行下次循环"), // 继续循环节点
|
||||||
LoopBreak("终止循环", "用于立即终止当前所在的循环,跳出循环体"), // 终止循环节点
|
LoopBreak("终止循环", "用于立即终止当前所在的循环,跳出循环体"), // 终止循环节点
|
||||||
Knowledge("知识库", "在选定的知识中,根据输入变量召回最匹配的信息"), // 知识库节点
|
Knowledge("知识库", "在选定的知识中,根据输入变量召回最匹配的信息"), // 知识库节点
|
||||||
|
KnowledgeInsert("知识库写入", "向选定的知识库中写入新的内容"), // 知识库写入节点
|
||||||
TableSQL("SQL自定义", "可支持对数据表放开读写控制,用户可读写其他用户提交的数据,由开发者控制"),
|
TableSQL("SQL自定义", "可支持对数据表放开读写控制,用户可读写其他用户提交的数据,由开发者控制"),
|
||||||
TableDataAdd("数据新增", "对选定的数据表进行数据写入"),
|
TableDataAdd("数据新增", "对选定的数据表进行数据写入"),
|
||||||
TableDataDelete("数据删除", "对选定的数据表根据指定条件进行数据删除"),
|
TableDataDelete("数据删除", "对选定的数据表根据指定条件进行数据删除"),
|
||||||
@@ -66,6 +67,7 @@ public class WorkflowNodeConfig {
|
|||||||
DocumentExtraction("文档提取", "用于提取文档内容,支持的文件类型: txt、 markdown、pdf、 html、 xlsx、 xls、 docx、 csv、 md、 htm"), // 文档提取节点
|
DocumentExtraction("文档提取", "用于提取文档内容,支持的文件类型: txt、 markdown、pdf、 html、 xlsx、 xls、 docx、 csv、 md、 htm"), // 文档提取节点
|
||||||
HTTPRequest("HTTP 请求", "用于配置http请求调用已有的服务"), // HTTP 请求节点
|
HTTPRequest("HTTP 请求", "用于配置http请求调用已有的服务"), // HTTP 请求节点
|
||||||
Mcp("MCP服务", "用于调用MCP服务"), // MCP服务节点
|
Mcp("MCP服务", "用于调用MCP服务"), // MCP服务节点
|
||||||
|
Agent("Agent", "用于调用Agent服务"),
|
||||||
End("结束", "工作流的最终节点,用于返回工作流运行后的结果信息"); // 结束节点
|
End("结束", "工作流的最终节点,用于返回工作流运行后的结果信息"); // 结束节点
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.xspaceagi.agent.core.adapter.typehandler;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.AgentPublishVersionDto;
|
||||||
|
import com.xspaceagi.system.spec.common.ListJsonTypeHandler;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AgentPublishVersionListTypeHandler extends ListJsonTypeHandler<AgentPublishVersionDto> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TypeReference<List<AgentPublishVersionDto>> getTypeReference() {
|
||||||
|
return new TypeReference<List<AgentPublishVersionDto>>() {};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -620,7 +620,7 @@ public class AgentApiServiceImpl implements IAgentRpcService, TemplateExportOrIm
|
|||||||
return ReqResult.error("Page data source not found");
|
return ReqResult.error("Page data source not found");
|
||||||
}
|
}
|
||||||
Optional<DataSourceDto> first = dataSources.stream().filter(dataSourceDto -> dataSourceDto.getId() != null && dataSourceDto.getId().equals(targetId)).findFirst();
|
Optional<DataSourceDto> first = dataSources.stream().filter(dataSourceDto -> dataSourceDto.getId() != null && dataSourceDto.getId().equals(targetId)).findFirst();
|
||||||
if (!first.isPresent()) {
|
if (first.isEmpty()) {
|
||||||
return ReqResult.error("Data source not found");
|
return ReqResult.error("Data source not found");
|
||||||
}
|
}
|
||||||
String key = first.get().getKey();
|
String key = first.get().getKey();
|
||||||
@@ -638,14 +638,14 @@ public class AgentApiServiceImpl implements IAgentRpcService, TemplateExportOrIm
|
|||||||
|
|
||||||
List<Arg> inputArgs = pluginConfigDto.getInputArgs();
|
List<Arg> inputArgs = pluginConfigDto.getInputArgs();
|
||||||
List<Arg> outputArgs = List.of(
|
List<Arg> outputArgs = List.of(
|
||||||
Arg.builder().require(true).name("success").description("Interface call status, success=true only represents successful interface call, business execution logic please pay attention to data definition").dataType(DataTypeEnum.Boolean).build(),
|
Arg.builder().require(true).name("success").description("Interface call status, business execution logic please pay attention to data definition").dataType(DataTypeEnum.Boolean).build(),
|
||||||
Arg.builder().require(true).name("message").description("Error information when interface call fails, such as server internal error").dataType(DataTypeEnum.String).build(),
|
Arg.builder().require(true).name("message").description("Error information when interface call fails, such as server internal error").dataType(DataTypeEnum.String).build(),
|
||||||
Arg.builder().require(true).name("data").description("Returned specific business data").dataType(DataTypeEnum.Object).subArgs(pluginConfigDto.getOutputArgs()).build()
|
Arg.builder().require(true).name("data").description("Returned specific business data").dataType(DataTypeEnum.Object).subArgs(pluginConfigDto.getOutputArgs()).build()
|
||||||
);
|
);
|
||||||
Map<String, Object> outputSchema = ArgConverter.convertArgsToJsonSchema(outputArgs);
|
Map<String, Object> outputSchema = ArgConverter.convertArgsToJsonSchema(outputArgs);
|
||||||
Map<String, Object> inputSchema = ArgConverter.convertArgsToJsonSchema(inputArgs);
|
Map<String, Object> inputSchema = ArgConverter.convertArgsToJsonSchema(inputArgs);
|
||||||
apiSchema.put("paths", Map.of(
|
apiSchema.put("paths", Map.of(
|
||||||
"/api/page/plugin/" + key + "/execute",
|
"/api/page/p/" + key,
|
||||||
buildPath(pluginDto.getName(), pluginDto.getDescription(), "application/json", inputSchema, outputSchema)
|
buildPath(pluginDto.getName(), pluginDto.getDescription(), "application/json", inputSchema, outputSchema)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -654,28 +654,17 @@ public class AgentApiServiceImpl implements IAgentRpcService, TemplateExportOrIm
|
|||||||
if (workflowConfigDto == null) {
|
if (workflowConfigDto == null) {
|
||||||
return ReqResult.error("Workflow not found");
|
return ReqResult.error("Workflow not found");
|
||||||
}
|
}
|
||||||
String description = workflowConfigDto.getDescription() == null ? "" : workflowConfigDto.getDescription() + "(Note that this interface is a text/event-stream streaming interface, it ends when complete=true appears. When processing data, please note that SSE data starts with data:, and SSE streaming interface is not used by default unless the user explicitly requests to use streaming interface)";
|
|
||||||
List<Arg> inputArgs = workflowConfigDto.getInputArgs();
|
List<Arg> inputArgs = workflowConfigDto.getInputArgs();
|
||||||
Map<String, Object> inputSchema = ArgConverter.convertArgsToJsonSchema(inputArgs, true);
|
Map<String, Object> inputSchema = ArgConverter.convertArgsToJsonSchema(inputArgs, true);
|
||||||
List<Arg> outputArgs = List.of(
|
List<Arg> outputArgs = List.of(
|
||||||
Arg.builder().require(true).name("success").description("Interface call status, success=true only represents successful interface call, business execution logic please pay attention to data definition").dataType(DataTypeEnum.Boolean).build(),
|
Arg.builder().require(true).name("success").description("Interface call status, business execution logic please pay attention to data definition").dataType(DataTypeEnum.Boolean).build(),
|
||||||
Arg.builder().require(true).name("message").description("Error information when interface call fails, such as server internal error").dataType(DataTypeEnum.String).build(),
|
|
||||||
Arg.builder().require(true).name("data").description("Returned specific business data").dataType(DataTypeEnum.Object).subArgs(workflowConfigDto.getOutputArgs()).build(),
|
|
||||||
Arg.builder().require(true).name("complete").description("Whether workflow execution is completed, just need to pay attention to results when complete=true if no special requirements").dataType(DataTypeEnum.Boolean).build()
|
|
||||||
);
|
|
||||||
Map<String, Object> streamOutputSchema = ArgConverter.convertArgsToJsonSchema(outputArgs);
|
|
||||||
|
|
||||||
outputArgs = List.of(
|
|
||||||
Arg.builder().require(true).name("success").description("Interface call status, success=true only represents successful interface call, business execution logic please pay attention to data definition").dataType(DataTypeEnum.Boolean).build(),
|
|
||||||
Arg.builder().require(true).name("message").description("Error information when interface call fails, such as server internal error").dataType(DataTypeEnum.String).build(),
|
Arg.builder().require(true).name("message").description("Error information when interface call fails, such as server internal error").dataType(DataTypeEnum.String).build(),
|
||||||
Arg.builder().require(true).name("data").description("Returned specific business data").dataType(DataTypeEnum.Object).subArgs(workflowConfigDto.getOutputArgs()).build()
|
Arg.builder().require(true).name("data").description("Returned specific business data").dataType(DataTypeEnum.Object).subArgs(workflowConfigDto.getOutputArgs()).build()
|
||||||
);
|
);
|
||||||
Map<String, Object> outputSchema = ArgConverter.convertArgsToJsonSchema(outputArgs);
|
Map<String, Object> outputSchema = ArgConverter.convertArgsToJsonSchema(outputArgs);
|
||||||
|
|
||||||
apiSchema.put("paths", Map.of(
|
apiSchema.put("paths", Map.of(
|
||||||
"/api/page/workflow/" + key + "/streamExecute",
|
"/api/page/w/" + key,
|
||||||
buildPath(workflowConfigDto.getName(), description, "text/event-stream", inputSchema, streamOutputSchema),
|
|
||||||
"/api/page/workflow/" + key + "/execute",
|
|
||||||
buildPath(workflowConfigDto.getName(), workflowConfigDto.getDescription() == null ? "" : workflowConfigDto.getDescription(), "application/json", inputSchema, outputSchema)
|
buildPath(workflowConfigDto.getName(), workflowConfigDto.getDescription() == null ? "" : workflowConfigDto.getDescription(), "application/json", inputSchema, outputSchema)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -848,6 +837,21 @@ public class AgentApiServiceImpl implements IAgentRpcService, TemplateExportOrIm
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (workflowNodeDto.getType() == WorkflowNodeConfig.NodeType.KnowledgeInsert) {
|
||||||
|
KnowledgeInsertNodeConfigDto knowledgeNodeConfigDto = (KnowledgeInsertNodeConfigDto) workflowNodeDto.getNodeConfig();
|
||||||
|
if (knowledgeNodeConfigDto.getKnowledgeBaseId() != null) {
|
||||||
|
KnowledgeCreateRequestVo knowledgeCreateRequestVo = KnowledgeCreateRequestVo.builder()
|
||||||
|
.dataType(1)
|
||||||
|
.name(knowledgeNodeConfigDto.getName())
|
||||||
|
.description(knowledgeNodeConfigDto.getDescription())
|
||||||
|
.icon(knowledgeNodeConfigDto.getIcon())
|
||||||
|
.userId(user.getId())
|
||||||
|
.spaceId(spaceId)
|
||||||
|
.build();
|
||||||
|
Long knowledgeConfigId = knowledgeRpcService.createKnowledgeConfig(knowledgeCreateRequestVo, knowledgeNodeConfigDto.getKnowledgeBaseId());
|
||||||
|
knowledgeNodeConfigDto.setKnowledgeBaseId(knowledgeConfigId);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (workflowNodeDto.getType().name().startsWith("Table")) {
|
if (workflowNodeDto.getType().name().startsWith("Table")) {
|
||||||
TableNodeConfigDto tableNodeConfigDto = (TableNodeConfigDto) workflowNodeDto.getNodeConfig();
|
TableNodeConfigDto tableNodeConfigDto = (TableNodeConfigDto) workflowNodeDto.getNodeConfig();
|
||||||
if (StringUtils.isNotBlank(tableNodeConfigDto.getOriginalTableConfig())) {
|
if (StringUtils.isNotBlank(tableNodeConfigDto.getOriginalTableConfig())) {
|
||||||
@@ -1148,7 +1152,8 @@ public class AgentApiServiceImpl implements IAgentRpcService, TemplateExportOrIm
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Object> executePlugin(PluginExecuteRequestDto pluginExecuteRequest) {
|
public Mono<Object> executePlugin(PluginExecuteRequestDto pluginExecuteRequest) {
|
||||||
PluginDto pluginDto = (PluginDto) JsonSerializeUtil.parseObjectGeneric(pluginExecuteRequest.getConfig());
|
PluginDto pluginDto = pluginExecuteRequest.getConfig() instanceof PluginDto ?
|
||||||
|
(PluginDto) pluginExecuteRequest.getConfig() : (PluginDto) JsonSerializeUtil.parseObjectGeneric(pluginExecuteRequest.getConfig().toString());
|
||||||
if (pluginDto == null) {
|
if (pluginDto == null) {
|
||||||
return Mono.error(new IllegalArgumentException("Invalid plugin configuration"));
|
return Mono.error(new IllegalArgumentException("Invalid plugin configuration"));
|
||||||
}
|
}
|
||||||
@@ -1165,11 +1170,16 @@ public class AgentApiServiceImpl implements IAgentRpcService, TemplateExportOrIm
|
|||||||
|
|
||||||
//For common agent, when user uses workflow, plugin, set parameter reference (temporarily only support system variables, user custom variables in agent cannot be passed)
|
//For common agent, when user uses workflow, plugin, set parameter reference (temporarily only support system variables, user custom variables in agent cannot be passed)
|
||||||
if (pluginExecuteRequest.getBindConfig() != null) {
|
if (pluginExecuteRequest.getBindConfig() != null) {
|
||||||
PluginBindConfigDto pluginBindConfigDto = (PluginBindConfigDto) JsonSerializeUtil.parseObjectGeneric(pluginExecuteRequest.getBindConfig());
|
PluginBindConfigDto pluginBindConfigDto = pluginExecuteRequest.getBindConfig() instanceof PluginBindConfigDto ?
|
||||||
|
(PluginBindConfigDto) pluginExecuteRequest.getBindConfig() : (PluginBindConfigDto) JsonSerializeUtil.parseObjectGeneric(pluginExecuteRequest.getBindConfig().toString());
|
||||||
if (pluginBindConfigDto != null) {
|
if (pluginBindConfigDto != null) {
|
||||||
completeArgReferenceBindValue(agentContext, pluginBindConfigDto.getInputArgBindConfigs(), pluginExecuteRequest.getParams());
|
completeArgReferenceBindValue(agentContext, pluginBindConfigDto.getInputArgBindConfigs(), pluginExecuteRequest.getParams());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (pluginExecuteRequest.getTraceContext() != null && pluginExecuteRequest.getTraceContext().getConversationId() != null) {
|
||||||
|
completeAgentContextVariable(agentContext, pluginExecuteRequest.getTraceContext().getConversationId());
|
||||||
|
}
|
||||||
|
|
||||||
PluginContext pluginContext = PluginContext.builder()
|
PluginContext pluginContext = PluginContext.builder()
|
||||||
.requestId(pluginExecuteRequest.getRequestId())
|
.requestId(pluginExecuteRequest.getRequestId())
|
||||||
.pluginConfig((PluginConfigDto) pluginDto.getConfig())
|
.pluginConfig((PluginConfigDto) pluginDto.getConfig())
|
||||||
@@ -1190,6 +1200,22 @@ public class AgentApiServiceImpl implements IAgentRpcService, TemplateExportOrIm
|
|||||||
}).doOnError(emitter::error).subscribe());
|
}).doOnError(emitter::error).subscribe());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void completeAgentContextVariable(AgentContext agentContext, String conversationId) {
|
||||||
|
try {
|
||||||
|
ConversationDto conversation = conversationApplicationService.getConversationByCid(Long.parseLong(conversationId));
|
||||||
|
if (conversation != null && conversation.getVariables() != null) {
|
||||||
|
conversation.getVariables().forEach((key, value) -> {
|
||||||
|
if (!agentContext.getVariableParams().containsKey(key)) {
|
||||||
|
agentContext.getVariableParams().put(key, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
log.debug("completeAgentContextVariable conversationId: {}, variables: {}", conversationId, agentContext.getVariableParams());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("completeAgentContextVariable error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void completeArgReferenceBindValue(AgentContext agentContext, List<Arg> inputArgs, Map<String, Object> params) {
|
private void completeArgReferenceBindValue(AgentContext agentContext, List<Arg> inputArgs, Map<String, Object> params) {
|
||||||
if (inputArgs == null || params == null) {
|
if (inputArgs == null || params == null) {
|
||||||
return;
|
return;
|
||||||
@@ -1223,7 +1249,8 @@ public class AgentApiServiceImpl implements IAgentRpcService, TemplateExportOrIm
|
|||||||
public Flux<WorkflowExecuteResultDto> executeWorkflow(WorkflowExecuteRequestDto workflowExecuteRequest) {
|
public Flux<WorkflowExecuteResultDto> executeWorkflow(WorkflowExecuteRequestDto workflowExecuteRequest) {
|
||||||
AtomicReference<Disposable> disposable = new AtomicReference<>();
|
AtomicReference<Disposable> disposable = new AtomicReference<>();
|
||||||
Flux<WorkflowExecuteResultDto> flux = Flux.create(emitter -> {
|
Flux<WorkflowExecuteResultDto> flux = Flux.create(emitter -> {
|
||||||
WorkflowConfigDto workflowConfigDto = (WorkflowConfigDto) JsonSerializeUtil.parseObjectGeneric(workflowExecuteRequest.getConfig());
|
WorkflowConfigDto workflowConfigDto = (workflowExecuteRequest.getConfig() instanceof WorkflowConfigDto) ?
|
||||||
|
(WorkflowConfigDto) workflowExecuteRequest.getConfig() : (WorkflowConfigDto) JsonSerializeUtil.parseObjectGeneric(workflowExecuteRequest.getConfig().toString());
|
||||||
if (workflowConfigDto == null) {
|
if (workflowConfigDto == null) {
|
||||||
emitter.error(BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.agentWorkflowNotFoundSimple));
|
emitter.error(BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.agentWorkflowNotFoundSimple));
|
||||||
return;
|
return;
|
||||||
@@ -1246,9 +1273,14 @@ public class AgentApiServiceImpl implements IAgentRpcService, TemplateExportOrIm
|
|||||||
emitter.next(workflowExecutingDto);
|
emitter.next(workflowExecutingDto);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (workflowExecuteRequest.getTraceContext() != null && workflowExecuteRequest.getTraceContext().getConversationId() != null) {
|
||||||
|
completeAgentContextVariable(agentContext, workflowExecuteRequest.getTraceContext().getConversationId());
|
||||||
|
}
|
||||||
|
|
||||||
//For common agent, when user uses workflow, plugin, set parameter reference (temporarily only support system variables, user custom variables in agent cannot be passed)
|
//For common agent, when user uses workflow, plugin, set parameter reference (temporarily only support system variables, user custom variables in agent cannot be passed)
|
||||||
if (workflowExecuteRequest.getBindConfig() != null) {
|
if (workflowExecuteRequest.getBindConfig() != null) {
|
||||||
WorkflowBindConfigDto workflowBindConfigDto = (WorkflowBindConfigDto) JsonSerializeUtil.parseObjectGeneric(workflowExecuteRequest.getBindConfig());
|
WorkflowBindConfigDto workflowBindConfigDto = workflowExecuteRequest.getBindConfig() instanceof WorkflowBindConfigDto ?
|
||||||
|
(WorkflowBindConfigDto) workflowExecuteRequest.getBindConfig() : (WorkflowBindConfigDto) JsonSerializeUtil.parseObjectGeneric(workflowExecuteRequest.getBindConfig().toString());
|
||||||
if (workflowBindConfigDto != null) {
|
if (workflowBindConfigDto != null) {
|
||||||
completeArgReferenceBindValue(agentContext, workflowBindConfigDto.getInputArgBindConfigs(), workflowExecuteRequest.getParams());
|
completeArgReferenceBindValue(agentContext, workflowBindConfigDto.getInputArgBindConfigs(), workflowExecuteRequest.getParams());
|
||||||
}
|
}
|
||||||
@@ -1360,7 +1392,8 @@ public class AgentApiServiceImpl implements IAgentRpcService, TemplateExportOrIm
|
|||||||
agentConfigDto.setName(pageAppAgentCreateDto.getName());
|
agentConfigDto.setName(pageAppAgentCreateDto.getName());
|
||||||
agentConfigDto.setDescription(pageAppAgentCreateDto.getDescription());
|
agentConfigDto.setDescription(pageAppAgentCreateDto.getDescription());
|
||||||
agentConfigDto.setIcon(pageAppAgentCreateDto.getIcon());
|
agentConfigDto.setIcon(pageAppAgentCreateDto.getIcon());
|
||||||
agentConfigDto.setType("PageApp");
|
agentConfigDto.setType(AgentConfigDto.AgentType.PageApp.name());
|
||||||
|
agentConfigDto.setSubType(AgentConfigDto.AgentSubType.PageApp.name());
|
||||||
Long agentId = agentApplicationService.add(agentConfigDto);
|
Long agentId = agentApplicationService.add(agentConfigDto);
|
||||||
AgentComponentConfigDto agentComponentConfigDto = new AgentComponentConfigDto();
|
AgentComponentConfigDto agentComponentConfigDto = new AgentComponentConfigDto();
|
||||||
agentComponentConfigDto.setAgentId(agentId);
|
agentComponentConfigDto.setAgentId(agentId);
|
||||||
@@ -1456,7 +1489,8 @@ public class AgentApiServiceImpl implements IAgentRpcService, TemplateExportOrIm
|
|||||||
agentConfigDto.setSpaceId(spaceDto.getId());
|
agentConfigDto.setSpaceId(spaceDto.getId());
|
||||||
agentConfigDto.setName(StringUtils.isNotBlank(name) ? "Agent@" + name : I18nUtil.systemMessage("Backend.Agent.PrivateAgent.DefaultName", sandboxId.toString()));
|
agentConfigDto.setName(StringUtils.isNotBlank(name) ? "Agent@" + name : I18nUtil.systemMessage("Backend.Agent.PrivateAgent.DefaultName", sandboxId.toString()));
|
||||||
agentConfigDto.setDescription(I18nUtil.systemMessage("Backend.Agent.PrivateAgent.Description"));
|
agentConfigDto.setDescription(I18nUtil.systemMessage("Backend.Agent.PrivateAgent.Description"));
|
||||||
agentConfigDto.setType("TaskAgent");
|
agentConfigDto.setType(AgentConfigDto.AgentType.TaskAgent.name());
|
||||||
|
agentConfigDto.setSubType(AgentConfigDto.AgentSubType.General.name());
|
||||||
agentConfigDto.setOpenLongMemory(AgentConfig.OpenStatus.Open);
|
agentConfigDto.setOpenLongMemory(AgentConfig.OpenStatus.Open);
|
||||||
agentConfigDto.setAllowOtherModel(YesOrNoEnum.Y.getKey());
|
agentConfigDto.setAllowOtherModel(YesOrNoEnum.Y.getKey());
|
||||||
Map<String, Object> extra = new HashMap<>();
|
Map<String, Object> extra = new HashMap<>();
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.xspaceagi.agent.core.application.api;
|
||||||
|
|
||||||
|
import com.xspaceagi.agent.core.adapter.application.SkillApplicationService;
|
||||||
|
import com.xspaceagi.agent.core.sdk.ISkillRpcService;
|
||||||
|
import com.xspaceagi.agent.core.spec.enums.UsageScenarioEnum;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SkillRpcServiceImpl implements ISkillRpcService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SkillApplicationService skillApplicationService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long importSkill(String url, MultipartFile file, Long targetSkillId, Long targetSpaceId, List<UsageScenarioEnum> usageScenarios) {
|
||||||
|
return skillApplicationService.importSkill(url, file, targetSkillId, targetSpaceId, usageScenarios);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ import com.xspaceagi.agent.core.adapter.dto.config.plugin.CodePluginConfigDto;
|
|||||||
import com.xspaceagi.agent.core.adapter.dto.config.plugin.HttpPluginConfigDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.plugin.HttpPluginConfigDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.plugin.PluginConfigDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.plugin.PluginConfigDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.plugin.PluginDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.plugin.PluginDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.workflow.WorkflowConfigDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.workflow.*;
|
||||||
import com.xspaceagi.agent.core.adapter.repository.CopyIndexRecordRepository;
|
import com.xspaceagi.agent.core.adapter.repository.CopyIndexRecordRepository;
|
||||||
import com.xspaceagi.agent.core.adapter.repository.entity.*;
|
import com.xspaceagi.agent.core.adapter.repository.entity.*;
|
||||||
import com.xspaceagi.agent.core.domain.service.AgentDomainService;
|
import com.xspaceagi.agent.core.domain.service.AgentDomainService;
|
||||||
@@ -30,9 +30,13 @@ import com.xspaceagi.agent.core.infra.rpc.*;
|
|||||||
import com.xspaceagi.agent.core.infra.rpc.dto.PageDto;
|
import com.xspaceagi.agent.core.infra.rpc.dto.PageDto;
|
||||||
import com.xspaceagi.agent.core.spec.enums.*;
|
import com.xspaceagi.agent.core.spec.enums.*;
|
||||||
import com.xspaceagi.agent.core.spec.utils.PlaceholderParser;
|
import com.xspaceagi.agent.core.spec.utils.PlaceholderParser;
|
||||||
|
import com.xspaceagi.agent.core.spec.utils.SvgIconUtil;
|
||||||
|
import com.xspaceagi.agent.core.spec.utils.ZipStringUtils;
|
||||||
import com.xspaceagi.compose.sdk.request.DorisTableDefineRequest;
|
import com.xspaceagi.compose.sdk.request.DorisTableDefineRequest;
|
||||||
import com.xspaceagi.compose.sdk.service.IComposeDbTableRpcService;
|
import com.xspaceagi.compose.sdk.service.IComposeDbTableRpcService;
|
||||||
import com.xspaceagi.compose.sdk.vo.define.TableDefineVo;
|
import com.xspaceagi.compose.sdk.vo.define.TableDefineVo;
|
||||||
|
import com.xspaceagi.file.application.service.FileManagementService;
|
||||||
|
import com.xspaceagi.file.domain.model.FileRecordDomain;
|
||||||
import com.xspaceagi.knowledge.sdk.request.KnowledgeCreateRequestVo;
|
import com.xspaceagi.knowledge.sdk.request.KnowledgeCreateRequestVo;
|
||||||
import com.xspaceagi.knowledge.sdk.response.KnowledgeConfigVo;
|
import com.xspaceagi.knowledge.sdk.response.KnowledgeConfigVo;
|
||||||
import com.xspaceagi.mcp.sdk.dto.McpComponentDto;
|
import com.xspaceagi.mcp.sdk.dto.McpComponentDto;
|
||||||
@@ -67,6 +71,7 @@ import com.xspaceagi.system.spec.enums.PermissionSubjectTypeEnum;
|
|||||||
import com.xspaceagi.system.spec.enums.YesOrNoEnum;
|
import com.xspaceagi.system.spec.enums.YesOrNoEnum;
|
||||||
import com.xspaceagi.system.spec.exception.BizException;
|
import com.xspaceagi.system.spec.exception.BizException;
|
||||||
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
|
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
|
||||||
|
import com.xspaceagi.system.spec.file.InMemoryMultipartFile;
|
||||||
import com.xspaceagi.system.spec.jackson.JsonSerializeUtil;
|
import com.xspaceagi.system.spec.jackson.JsonSerializeUtil;
|
||||||
import com.xspaceagi.system.spec.utils.I18nUtil;
|
import com.xspaceagi.system.spec.utils.I18nUtil;
|
||||||
import com.xspaceagi.system.spec.utils.RedisUtil;
|
import com.xspaceagi.system.spec.utils.RedisUtil;
|
||||||
@@ -75,9 +80,11 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -162,6 +169,9 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
@Resource
|
@Resource
|
||||||
private ResourcePricingRpcService resourcePricingRpcService;
|
private ResourcePricingRpcService resourcePricingRpcService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private FileManagementService fileManagementService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@DSTransactional
|
@DSTransactional
|
||||||
public Long add(AgentConfigDto agent) {
|
public Long add(AgentConfigDto agent) {
|
||||||
@@ -210,6 +220,23 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
.bindConfig(modelBindConfigDto).build();
|
.bindConfig(modelBindConfigDto).build();
|
||||||
agentDomainService.addAgentComponentConfig(agentComponentConfig);
|
agentDomainService.addAgentComponentConfig(agentComponentConfig);
|
||||||
|
|
||||||
|
//AgentFlow初始化工作流
|
||||||
|
if (agent.getSubType() != null && agent.getSubType().equals(AgentConfigDto.AgentSubType.Flow.name())) {
|
||||||
|
WorkflowConfigDto workflowConfigDto = new WorkflowConfigDto();
|
||||||
|
workflowConfigDto.setName(agent.getName());
|
||||||
|
workflowConfigDto.setDescription(agent.getDescription());
|
||||||
|
workflowConfigDto.setCreatorId(agentConfig.getCreatorId());
|
||||||
|
workflowConfigDto.setSpaceId(agent.getSpaceId());
|
||||||
|
workflowConfigDto.setType(WorkflowConfigDto.Type.AgentFlow.name());
|
||||||
|
workflowConfigDto.setAgentId(agentConfig.getId());
|
||||||
|
Long workflowId = workflowApplicationService.add(workflowConfigDto);
|
||||||
|
AgentComponentConfig workflowComponentConfig = AgentComponentConfig.builder().agentId(agentConfig.getId())
|
||||||
|
.type(AgentComponentConfig.Type.Workflow).targetId(workflowId)
|
||||||
|
.name(workflowConfigDto.getName()).description(workflowConfigDto.getDescription())
|
||||||
|
.bindConfig(new WorkflowBindConfigDto()).build();
|
||||||
|
agentDomainService.addAgentComponentConfig(workflowComponentConfig);
|
||||||
|
}
|
||||||
|
|
||||||
// 添加智能体新增历史记录
|
// 添加智能体新增历史记录
|
||||||
addConfigHistory(agentConfig.getId(), ConfigHistory.Type.Add, I18nUtil.systemMessage("Agent.ConfigHistory.Add"));
|
addConfigHistory(agentConfig.getId(), ConfigHistory.Type.Add, I18nUtil.systemMessage("Agent.ConfigHistory.Add"));
|
||||||
|
|
||||||
@@ -512,6 +539,21 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
if (agentConfig.getExtra() == null) {
|
if (agentConfig.getExtra() == null) {
|
||||||
agentConfigDto.setExtra(new HashMap<>());
|
agentConfigDto.setExtra(new HashMap<>());
|
||||||
}
|
}
|
||||||
|
if (agentConfigDto.getSubType() == null) {
|
||||||
|
if (AgentConfigDto.AgentType.ChatBot.name().equals(agentConfigDto.getType())) {
|
||||||
|
agentConfigDto.setSubType(AgentConfigDto.AgentSubType.ChatBot.name());
|
||||||
|
}
|
||||||
|
if (AgentConfigDto.AgentType.PageApp.name().equals(agentConfigDto.getType())) {
|
||||||
|
agentConfigDto.setSubType(AgentConfigDto.AgentSubType.PageApp.name());
|
||||||
|
}
|
||||||
|
if (AgentConfigDto.AgentType.TaskAgent.name().equals(agentConfigDto.getType())) {
|
||||||
|
if (agentConfigDto.getDevAgentConversationId() != null) {
|
||||||
|
agentConfigDto.setSubType(AgentConfigDto.AgentSubType.Custom.name());
|
||||||
|
} else {
|
||||||
|
agentConfigDto.setSubType(AgentConfigDto.AgentSubType.General.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return agentConfigDto;
|
return agentConfigDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,6 +608,41 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
if (!modelComponentConfigList.isEmpty()) {
|
if (!modelComponentConfigList.isEmpty()) {
|
||||||
agentConfigDto.setModelComponentConfig(modelComponentConfigList.get(0));
|
agentConfigDto.setModelComponentConfig(modelComponentConfigList.get(0));
|
||||||
}
|
}
|
||||||
|
if (AgentConfigDto.AgentSubType.Flow.name().equals(agentConfigDto.getSubType())) {
|
||||||
|
AgentComponentConfigDto componentConfigDto = agentConfigDto.getAgentComponentConfigList().stream().filter(agentComponentConfigDto -> agentComponentConfigDto.getType() == AgentComponentConfig.Type.Workflow).findFirst().orElse(null);
|
||||||
|
if (componentConfigDto != null) {
|
||||||
|
WorkflowConfigDto workflowConfigDto = workflowApplicationService.queryById(componentConfigDto.getTargetId());
|
||||||
|
Assert.notNull(workflowConfigDto, "AgentFlow configuration is incomplete");
|
||||||
|
List<WorkflowNodeDto> workflowNodes = forExecute ? workflowApplicationService.queryWorkflowNodeListForTestExecute(workflowConfigDto.getId()) : workflowApplicationService.queryWorkflowNodeList(workflowConfigDto.getId());
|
||||||
|
workflowConfigDto.setNodes(workflowNodes);
|
||||||
|
componentConfigDto.setTargetConfig(workflowConfigDto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
completeCreatorAndSpaceInfo(List.of(agentConfigDto));
|
||||||
|
PublishedDto published = publishApplicationService.queryPublished(Published.TargetType.Agent, agentId);
|
||||||
|
if (published != null) {
|
||||||
|
agentConfigDto.setPublishDate(published.getModified());
|
||||||
|
agentConfigDto.setCategory(published.getCategory());
|
||||||
|
}
|
||||||
|
return agentConfigDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AgentConfigDto queryByIdForDetail(Long agentId) {
|
||||||
|
AgentConfig agentConfig = agentDomainService.queryById(agentId);
|
||||||
|
if (agentConfig != null) {
|
||||||
|
AgentConfigDto agentConfigDto = convertToDto(agentConfig);
|
||||||
|
agentConfigDto.setAgentComponentConfigList(queryComponentConfigList(agentId, false));
|
||||||
|
// 从agentConfigDto.getAgentComponentConfigList()中获取类型为Model的组件列表
|
||||||
|
List<AgentComponentConfigDto> modelComponentConfigList = agentConfigDto.getAgentComponentConfigList()
|
||||||
|
.stream()
|
||||||
|
.filter(agentComponentConfigDto -> agentComponentConfigDto.getType() == AgentComponentConfig.Type.Model)
|
||||||
|
.toList();
|
||||||
|
if (!modelComponentConfigList.isEmpty()) {
|
||||||
|
agentConfigDto.setModelComponentConfig(modelComponentConfigList.get(0));
|
||||||
|
}
|
||||||
completeCreatorAndSpaceInfo(List.of(agentConfigDto));
|
completeCreatorAndSpaceInfo(List.of(agentConfigDto));
|
||||||
PublishedDto published = publishApplicationService.queryPublished(Published.TargetType.Agent, agentId);
|
PublishedDto published = publishApplicationService.queryPublished(Published.TargetType.Agent, agentId);
|
||||||
if (published != null) {
|
if (published != null) {
|
||||||
@@ -749,6 +826,12 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
return queryComponentConfigList(agentId, false);
|
return queryComponentConfigList(agentId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AgentComponentConfigDto> queryComponentConfigListByAgentIdAndType(Long agentId, AgentComponentConfig.Type type) {
|
||||||
|
List<AgentComponentConfig> agentComponentConfigs = agentDomainService.queryComponentConfigsByAgentIdAndType(agentId, type);
|
||||||
|
return convertComponentConfigList(agentId, agentComponentConfigs, false);
|
||||||
|
}
|
||||||
|
|
||||||
private List<AgentComponentConfigDto> queryComponentConfigList(Long agentId, boolean forExecute) {
|
private List<AgentComponentConfigDto> queryComponentConfigList(Long agentId, boolean forExecute) {
|
||||||
List<AgentComponentConfig> agentComponentConfigList = agentDomainService.queryAgentComponentConfigList(agentId);
|
List<AgentComponentConfig> agentComponentConfigList = agentDomainService.queryAgentComponentConfigList(agentId);
|
||||||
AgentComponentConfig varConfig = agentComponentConfigList.stream().filter(agentComponentConfig -> agentComponentConfig.getType() == AgentComponentConfig.Type.Variable).findFirst().orElse(null);
|
AgentComponentConfig varConfig = agentComponentConfigList.stream().filter(agentComponentConfig -> agentComponentConfig.getType() == AgentComponentConfig.Type.Variable).findFirst().orElse(null);
|
||||||
@@ -763,6 +846,21 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
agentComponentConfigList.add(varConfig);
|
agentComponentConfigList.add(varConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AgentComponentConfig hookConfig = agentComponentConfigList.stream().filter(agentComponentConfig -> agentComponentConfig.getType() == AgentComponentConfig.Type.Hook).findFirst().orElse(null);
|
||||||
|
if (hookConfig == null) {
|
||||||
|
//初始化Hook配置
|
||||||
|
HookConfigDto hookBindConfigDto = new HookConfigDto();
|
||||||
|
hookBindConfigDto.setHooks(new ArrayList<>());
|
||||||
|
AgentComponentConfig hookComponentConfig = AgentComponentConfig.builder().agentId(agentId)
|
||||||
|
.type(AgentComponentConfig.Type.Hook)
|
||||||
|
.targetId(-1L)
|
||||||
|
.name("Hook").description("Hook Binding")
|
||||||
|
.bindConfig(hookBindConfigDto).build();
|
||||||
|
agentComponentConfigList.add(hookComponentConfig);
|
||||||
|
agentDomainService.addAgentComponentConfig(hookComponentConfig);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
AgentComponentConfig eventConfig = agentComponentConfigList.stream().filter(agentComponentConfig -> agentComponentConfig.getType() == AgentComponentConfig.Type.Event).findFirst().orElse(null);
|
AgentComponentConfig eventConfig = agentComponentConfigList.stream().filter(agentComponentConfig -> agentComponentConfig.getType() == AgentComponentConfig.Type.Event).findFirst().orElse(null);
|
||||||
if (eventConfig == null) {
|
if (eventConfig == null) {
|
||||||
//初始化事件配置
|
//初始化事件配置
|
||||||
@@ -788,7 +886,10 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
.bindConfig(subAgentBindConfigDto).build();
|
.bindConfig(subAgentBindConfigDto).build();
|
||||||
agentDomainService.addAgentComponentConfig(subAgentConfig);
|
agentDomainService.addAgentComponentConfig(subAgentConfig);
|
||||||
}
|
}
|
||||||
|
return convertComponentConfigList(agentId, agentComponentConfigList, forExecute);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AgentComponentConfigDto> convertComponentConfigList(Long agentId, List<AgentComponentConfig> agentComponentConfigList, boolean forExecute) {
|
||||||
AgentConfig agentConfig = agentDomainService.queryById(agentId);
|
AgentConfig agentConfig = agentDomainService.queryById(agentId);
|
||||||
List<AgentComponentConfigDto> agentComponentConfigDtoList = agentComponentConfigList.stream().map(agentComponentConfig -> {
|
List<AgentComponentConfigDto> agentComponentConfigDtoList = agentComponentConfigList.stream().map(agentComponentConfig -> {
|
||||||
AgentComponentConfigDto agentComponentConfigDto = AgentComponentConfigDto.builder().build();
|
AgentComponentConfigDto agentComponentConfigDto = AgentComponentConfigDto.builder().build();
|
||||||
@@ -808,6 +909,19 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public AgentConfigDto queryPublishedConfig(Long agentId, boolean execute) {
|
public AgentConfigDto queryPublishedConfig(Long agentId, boolean execute) {
|
||||||
|
String cacheKey = "agent_config:" + (execute ? "execute_" : "") + agentId;
|
||||||
|
Object val = redisUtil.get(cacheKey);
|
||||||
|
try {
|
||||||
|
if (val != null) {
|
||||||
|
String config = ZipStringUtils.decompressFromBase64(val.toString());
|
||||||
|
AgentConfigCacheStatusVo agentConfigCacheStatusVo = (AgentConfigCacheStatusVo) JsonSerializeUtil.parseObjectGeneric(config);
|
||||||
|
if (!checkIfCacheExpired(agentConfigCacheStatusVo)) {
|
||||||
|
return agentConfigCacheStatusVo.getAgentConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("读取Agent缓存失败:{}", cacheKey, e);
|
||||||
|
}
|
||||||
PublishedDto agentPublished = publishApplicationService.queryPublished(Published.TargetType.Agent, agentId);
|
PublishedDto agentPublished = publishApplicationService.queryPublished(Published.TargetType.Agent, agentId);
|
||||||
if (agentPublished == null) {
|
if (agentPublished == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -816,6 +930,7 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
AgentConfig agentConfig = new AgentConfig();
|
AgentConfig agentConfig = new AgentConfig();
|
||||||
BeanUtils.copyProperties(agentConfigDto, agentConfig);
|
BeanUtils.copyProperties(agentConfigDto, agentConfig);
|
||||||
convertComponentConfig(agentConfigDto.getModelComponentConfig());
|
convertComponentConfig(agentConfigDto.getModelComponentConfig());
|
||||||
|
agentConfigDto.setPublishedSpaceIds(agentPublished.getPublishedSpaceIds());
|
||||||
agentConfigDto.getAgentComponentConfigList().forEach(componentConfigDto -> componentConfigDto.setSpaceId(agentConfigDto.getSpaceId()));
|
agentConfigDto.getAgentComponentConfigList().forEach(componentConfigDto -> componentConfigDto.setSpaceId(agentConfigDto.getSpaceId()));
|
||||||
agentConfigDto.setAgentComponentConfigList(completeAgentComponentConfig(agentConfig, agentConfigDto.getAgentComponentConfigList(), execute));
|
agentConfigDto.setAgentComponentConfigList(completeAgentComponentConfig(agentConfig, agentConfigDto.getAgentComponentConfigList(), execute));
|
||||||
AgentComponentConfigDto modelComponentConfig = agentConfigDto.getAgentComponentConfigList()
|
AgentComponentConfigDto modelComponentConfig = agentConfigDto.getAgentComponentConfigList()
|
||||||
@@ -830,22 +945,184 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
if (tenantConfig.getDefaultAgentId() != null && agentId.longValue() == tenantConfig.getDefaultAgentId() && CollectionUtils.isNotEmpty(tenantConfig.getDefaultAgentIds())) {
|
if (tenantConfig.getDefaultAgentId() != null && agentId.longValue() == tenantConfig.getDefaultAgentId() && CollectionUtils.isNotEmpty(tenantConfig.getDefaultAgentIds())) {
|
||||||
//排除自身
|
//排除自身
|
||||||
tenantConfig.getDefaultAgentIds().remove(agentId);
|
tenantConfig.getDefaultAgentIds().remove(agentId);
|
||||||
List<PublishedDto> publishedList = publishApplicationService.queryPublishedList(Published.TargetType.Agent, tenantConfig.getDefaultAgentIds());
|
for (Long defaultAgentId : tenantConfig.getDefaultAgentIds()) {
|
||||||
publishedList.forEach(publishedDto -> {
|
AgentConfigDto defaultAgentConfigDto = queryPublishedConfig(defaultAgentId, execute);
|
||||||
AgentComponentConfigDto agentComponentConfigDto = new AgentComponentConfigDto();
|
AgentComponentConfigDto agentComponentConfigDto = new AgentComponentConfigDto();
|
||||||
agentComponentConfigDto.setAgentId(agentId);
|
|
||||||
agentComponentConfigDto.setTargetId(publishedDto.getTargetId());
|
|
||||||
agentComponentConfigDto.setName(publishedDto.getName());
|
|
||||||
agentComponentConfigDto.setDescription(publishedDto.getDescription());
|
|
||||||
agentComponentConfigDto.setType(AgentComponentConfig.Type.Agent);
|
|
||||||
agentConfigDto.getAgentComponentConfigList().add(agentComponentConfigDto);
|
agentConfigDto.getAgentComponentConfigList().add(agentComponentConfigDto);
|
||||||
});
|
agentComponentConfigDto.setAgentId(agentId);
|
||||||
|
agentComponentConfigDto.setTargetId(defaultAgentId);
|
||||||
|
agentComponentConfigDto.setName(defaultAgentConfigDto.getName());
|
||||||
|
agentComponentConfigDto.setDescription(defaultAgentConfigDto.getDescription());
|
||||||
|
agentComponentConfigDto.setType(AgentComponentConfig.Type.Agent);
|
||||||
|
agentComponentConfigDto.setTargetConfig(defaultAgentConfigDto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
agentConfigDto.setPublishDate(agentPublished.getModified());
|
agentConfigDto.setPublishDate(agentPublished.getModified());
|
||||||
agentConfigDto.setAccessControl(agentPublished.getAccessControl());
|
agentConfigDto.setAccessControl(agentPublished.getAccessControl());
|
||||||
|
|
||||||
|
// 缓存
|
||||||
|
try {
|
||||||
|
AgentConfigCacheStatusVo agentConfigCacheStatusVo = new AgentConfigCacheStatusVo();
|
||||||
|
agentConfigCacheStatusVo.setAgentConfig(agentConfigDto);
|
||||||
|
agentConfigCacheStatusVo.setComponents(new ArrayList<>());
|
||||||
|
AgentConfigCacheStatusVo.AgentComponentCacheStatusVo agentComponentCacheStatusVo = new AgentConfigCacheStatusVo.AgentComponentCacheStatusVo();
|
||||||
|
agentComponentCacheStatusVo.setTargetType(Published.TargetType.Agent);
|
||||||
|
agentComponentCacheStatusVo.setTargetId(agentId);
|
||||||
|
agentComponentCacheStatusVo.setLastUpdated(agentPublished.getModified().getTime());
|
||||||
|
agentConfigCacheStatusVo.getComponents().add(agentComponentCacheStatusVo);
|
||||||
|
writeAgentConfigToCache(agentConfigDto, agentConfigCacheStatusVo);
|
||||||
|
String jsonStringGeneric = JsonSerializeUtil.toJSONStringGeneric(agentConfigCacheStatusVo);
|
||||||
|
redisUtil.set(cacheKey, ZipStringUtils.compressToBase64(jsonStringGeneric));
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 忽略
|
||||||
|
log.warn("cache agent_config error", e);
|
||||||
|
}
|
||||||
return agentConfigDto;
|
return agentConfigDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkIfCacheExpired(AgentConfigCacheStatusVo agentConfigCacheStatusVo) {
|
||||||
|
//按照type分组
|
||||||
|
List<Long> agentIds = agentConfigCacheStatusVo.getComponents().stream().filter(agentComponentCacheStatusVo -> agentComponentCacheStatusVo.getTargetType() == Published.TargetType.Agent).map(AgentConfigCacheStatusVo.AgentComponentCacheStatusVo::getTargetId).toList();
|
||||||
|
List<PublishedDto> publishedDtos = publishApplicationService.queryPublishedListWithoutConfig(Published.TargetType.Agent, agentIds, null);
|
||||||
|
Map<Long, PublishedDto> agentMap = publishedDtos.stream().collect(Collectors.toMap(PublishedDto::getTargetId, publishedDto -> publishedDto, (p, p1) -> p));
|
||||||
|
|
||||||
|
List<Long> pluginIds = agentConfigCacheStatusVo.getComponents().stream().filter(agentComponentCacheStatusVo -> agentComponentCacheStatusVo.getTargetType() == Published.TargetType.Plugin).map(AgentConfigCacheStatusVo.AgentComponentCacheStatusVo::getTargetId).toList();
|
||||||
|
publishedDtos = publishApplicationService.queryPublishedListWithoutConfig(Published.TargetType.Plugin, pluginIds, null);
|
||||||
|
Map<Long, PublishedDto> pluginMap = publishedDtos.stream().collect(Collectors.toMap(PublishedDto::getTargetId, publishedDto -> publishedDto, (p, p1) -> p));
|
||||||
|
|
||||||
|
List<Long> workflowIds = agentConfigCacheStatusVo.getComponents().stream().filter(agentComponentCacheStatusVo -> agentComponentCacheStatusVo.getTargetType() == Published.TargetType.Workflow).map(AgentConfigCacheStatusVo.AgentComponentCacheStatusVo::getTargetId).toList();
|
||||||
|
publishedDtos = publishApplicationService.queryPublishedListWithoutConfig(Published.TargetType.Workflow, workflowIds, null);
|
||||||
|
Map<Long, PublishedDto> workflowMap = publishedDtos.stream().collect(Collectors.toMap(PublishedDto::getTargetId, publishedDto -> publishedDto, (p, p1) -> p));
|
||||||
|
|
||||||
|
List<Long> skillIds = agentConfigCacheStatusVo.getComponents().stream().filter(agentComponentCacheStatusVo -> agentComponentCacheStatusVo.getTargetType() == Published.TargetType.Skill).map(AgentConfigCacheStatusVo.AgentComponentCacheStatusVo::getTargetId).toList();
|
||||||
|
publishedDtos = publishApplicationService.queryPublishedListWithoutConfig(Published.TargetType.Skill, skillIds, null);
|
||||||
|
Map<Long, PublishedDto> skillMap = publishedDtos.stream().collect(Collectors.toMap(PublishedDto::getTargetId, publishedDto -> publishedDto, (p, p1) -> p));
|
||||||
|
|
||||||
|
List<Long> modelIds = agentConfigCacheStatusVo.getComponents().stream().filter(agentComponentCacheStatusVo -> agentComponentCacheStatusVo.getTargetType() == Published.TargetType.Model).map(AgentConfigCacheStatusVo.AgentComponentCacheStatusVo::getTargetId).toList();
|
||||||
|
List<ModelConfigDto> modelConfigDtos = modelApplicationService.queryModelConfigListByIds(modelIds);
|
||||||
|
Map<Long, ModelConfigDto> modelConfigDtoMap = modelConfigDtos.stream().collect(Collectors.toMap(ModelConfigDto::getId, modelConfigDto -> modelConfigDto, (modelConfigDto1, modelConfigDto2) -> modelConfigDto1));
|
||||||
|
|
||||||
|
for (AgentConfigCacheStatusVo.AgentComponentCacheStatusVo agentComponentCacheStatusVo : agentConfigCacheStatusVo.getComponents()) {
|
||||||
|
if (agentComponentCacheStatusVo.getTargetType() == Published.TargetType.Agent && (!agentMap.containsKey(agentComponentCacheStatusVo.getTargetId()) || agentMap.get(agentComponentCacheStatusVo.getTargetId()).getModified().getTime() > agentComponentCacheStatusVo.getLastUpdated())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (agentComponentCacheStatusVo.getTargetType() == Published.TargetType.Plugin && (!pluginMap.containsKey(agentComponentCacheStatusVo.getTargetId()) || pluginMap.get(agentComponentCacheStatusVo.getTargetId()).getModified().getTime() > agentComponentCacheStatusVo.getLastUpdated())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (agentComponentCacheStatusVo.getTargetType() == Published.TargetType.Workflow && (!workflowMap.containsKey(agentComponentCacheStatusVo.getTargetId()) || workflowMap.get(agentComponentCacheStatusVo.getTargetId()).getModified().getTime() > agentComponentCacheStatusVo.getLastUpdated())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (agentComponentCacheStatusVo.getTargetType() == Published.TargetType.Skill && (!skillMap.containsKey(agentComponentCacheStatusVo.getTargetId()) || skillMap.get(agentComponentCacheStatusVo.getTargetId()).getModified().getTime() > agentComponentCacheStatusVo.getLastUpdated())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (agentComponentCacheStatusVo.getTargetType() == Published.TargetType.Model && (!modelConfigDtoMap.containsKey(agentComponentCacheStatusVo.getTargetId()) || modelConfigDtoMap.get(agentComponentCacheStatusVo.getTargetId()).getModified().getTime() > agentComponentCacheStatusVo.getLastUpdated())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeAgentConfigToCache(AgentConfigDto agentConfigDto, AgentConfigCacheStatusVo agentConfigCacheStatusVo) {
|
||||||
|
agentConfigDto.getAgentComponentConfigList().forEach(agentComponentConfigDto -> {
|
||||||
|
AgentConfigCacheStatusVo.AgentComponentCacheStatusVo agentComponentCacheStatusVo = new AgentConfigCacheStatusVo.AgentComponentCacheStatusVo();
|
||||||
|
if (agentComponentConfigDto.getType() == AgentComponentConfig.Type.Agent) {
|
||||||
|
agentComponentCacheStatusVo.setTargetType(Published.TargetType.Agent);
|
||||||
|
agentComponentCacheStatusVo.setTargetId(agentComponentConfigDto.getTargetId());
|
||||||
|
if (agentComponentConfigDto.getTargetConfig() instanceof AgentConfigDto agentConfigDto1 && agentConfigDto1.getPublishDate() != null) {
|
||||||
|
agentComponentCacheStatusVo.setLastUpdated(agentConfigDto1.getPublishDate().getTime());
|
||||||
|
agentConfigCacheStatusVo.getComponents().add(agentComponentCacheStatusVo);
|
||||||
|
writeAgentConfigToCache(agentConfigDto1, agentConfigCacheStatusVo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (agentComponentConfigDto.getType() == AgentComponentConfig.Type.Plugin) {
|
||||||
|
agentComponentCacheStatusVo.setTargetType(Published.TargetType.Plugin);
|
||||||
|
agentComponentCacheStatusVo.setTargetId(agentComponentConfigDto.getTargetId());
|
||||||
|
if (agentComponentConfigDto.getTargetConfig() instanceof PluginDto pluginDto && pluginDto.getPublishDate() != null) {
|
||||||
|
agentComponentCacheStatusVo.setLastUpdated(pluginDto.getPublishDate().getTime());
|
||||||
|
agentConfigCacheStatusVo.getComponents().add(agentComponentCacheStatusVo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (agentComponentConfigDto.getType() == AgentComponentConfig.Type.Workflow) {
|
||||||
|
if (agentComponentConfigDto.getTargetConfig() instanceof WorkflowConfigDto workflowConfigDto && workflowConfigDto.getPublishDate() != null) {
|
||||||
|
agentComponentCacheStatusVo.setTargetType(Published.TargetType.Workflow);
|
||||||
|
agentComponentCacheStatusVo.setTargetId(agentComponentConfigDto.getTargetId());
|
||||||
|
agentComponentCacheStatusVo.setLastUpdated(workflowConfigDto.getPublishDate().getTime());
|
||||||
|
agentConfigCacheStatusVo.getComponents().add(agentComponentCacheStatusVo);
|
||||||
|
writeWorkflowConfigToCache(workflowConfigDto, agentConfigCacheStatusVo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (agentComponentConfigDto.getType() == AgentComponentConfig.Type.Skill) {
|
||||||
|
agentComponentCacheStatusVo.setTargetType(Published.TargetType.Skill);
|
||||||
|
agentComponentCacheStatusVo.setTargetId(agentComponentConfigDto.getTargetId());
|
||||||
|
if (agentComponentConfigDto.getTargetConfig() instanceof SkillConfigDto skillDto && skillDto.getPublishDate() != null) {
|
||||||
|
agentComponentCacheStatusVo.setLastUpdated(skillDto.getPublishDate().getTime());
|
||||||
|
agentConfigCacheStatusVo.getComponents().add(agentComponentCacheStatusVo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模型有可能配置发生变化
|
||||||
|
if (agentComponentConfigDto.getType() == AgentComponentConfig.Type.Model) {
|
||||||
|
agentComponentCacheStatusVo.setTargetType(Published.TargetType.Model);
|
||||||
|
agentComponentCacheStatusVo.setTargetId(agentComponentConfigDto.getTargetId());
|
||||||
|
if (agentComponentConfigDto.getTargetConfig() instanceof ModelConfigDto modelDto && modelDto.getModified() != null) {
|
||||||
|
agentComponentCacheStatusVo.setLastUpdated(modelDto.getModified().getTime());
|
||||||
|
agentConfigCacheStatusVo.getComponents().add(agentComponentCacheStatusVo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeWorkflowConfigToCache(WorkflowConfigDto workflowConfigDto, AgentConfigCacheStatusVo agentConfigCacheStatusVo) {
|
||||||
|
if (CollectionUtils.isEmpty(workflowConfigDto.getNodes())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
workflowConfigDto.getNodes().forEach(workflowNodeDto -> {
|
||||||
|
AgentConfigCacheStatusVo.AgentComponentCacheStatusVo agentComponentCacheStatusVo = new AgentConfigCacheStatusVo.AgentComponentCacheStatusVo();
|
||||||
|
if (workflowNodeDto.getType() == WorkflowNodeConfig.NodeType.Workflow && workflowNodeDto.getNodeConfig() instanceof WorkflowAsNodeConfigDto workflowAsNodeConfigDto) {
|
||||||
|
agentComponentCacheStatusVo.setTargetType(Published.TargetType.Workflow);
|
||||||
|
agentComponentCacheStatusVo.setTargetId(workflowAsNodeConfigDto.getWorkflowId());
|
||||||
|
if (workflowAsNodeConfigDto.getWorkflowConfig() != null && workflowAsNodeConfigDto.getWorkflowConfig().getPublishDate() != null) {
|
||||||
|
agentComponentCacheStatusVo.setLastUpdated(workflowAsNodeConfigDto.getWorkflowConfig().getPublishDate().getTime());
|
||||||
|
agentConfigCacheStatusVo.getComponents().add(agentComponentCacheStatusVo);
|
||||||
|
writeWorkflowConfigToCache(workflowAsNodeConfigDto.getWorkflowConfig(), agentConfigCacheStatusVo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (workflowNodeDto.getType() == WorkflowNodeConfig.NodeType.Plugin && workflowNodeDto.getNodeConfig() instanceof PluginNodeConfigDto pluginNodeConfigDto) {
|
||||||
|
agentComponentCacheStatusVo.setTargetType(Published.TargetType.Plugin);
|
||||||
|
agentComponentCacheStatusVo.setTargetId(pluginNodeConfigDto.getPluginId());
|
||||||
|
if (pluginNodeConfigDto.getPluginConfig() != null && pluginNodeConfigDto.getPluginConfig().getPublishDate() != null) {
|
||||||
|
agentComponentCacheStatusVo.setLastUpdated(pluginNodeConfigDto.getPluginConfig().getPublishDate().getTime());
|
||||||
|
agentConfigCacheStatusVo.getComponents().add(agentComponentCacheStatusVo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (workflowNodeDto.getType() == WorkflowNodeConfig.NodeType.Mcp && workflowNodeDto.getNodeConfig() instanceof McpNodeConfigDto mcpNodeConfigDto) {
|
||||||
|
agentComponentCacheStatusVo.setTargetType(Published.TargetType.Mcp);
|
||||||
|
agentComponentCacheStatusVo.setTargetId(mcpNodeConfigDto.getMcpId());
|
||||||
|
if (mcpNodeConfigDto.getMcp() != null && mcpNodeConfigDto.getMcp() instanceof McpDto mcpDto) {
|
||||||
|
agentComponentCacheStatusVo.setLastUpdated(mcpDto.getModified().getTime());
|
||||||
|
agentConfigCacheStatusVo.getComponents().add(agentComponentCacheStatusVo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (workflowNodeDto.getType() == WorkflowNodeConfig.NodeType.Agent && workflowNodeDto.getNodeConfig() instanceof AgentNodeConfigDto agentNodeConfigDto) {
|
||||||
|
agentComponentCacheStatusVo.setTargetType(Published.TargetType.Agent);
|
||||||
|
agentComponentCacheStatusVo.setTargetId(agentNodeConfigDto.getAgentId());
|
||||||
|
if (agentNodeConfigDto.getAgentConfigDto() != null && agentNodeConfigDto.getAgentConfigDto().getPublishDate() != null) {
|
||||||
|
agentComponentCacheStatusVo.setLastUpdated(agentNodeConfigDto.getAgentConfigDto().getPublishDate().getTime());
|
||||||
|
agentConfigCacheStatusVo.getComponents().add(agentComponentCacheStatusVo);
|
||||||
|
writeAgentConfigToCache(agentNodeConfigDto.getAgentConfigDto(), agentConfigCacheStatusVo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (workflowNodeDto.getType() == WorkflowNodeConfig.NodeType.LLM && workflowNodeDto.getNodeConfig() instanceof LLMNodeConfigDto llmNodeConfigDto) {
|
||||||
|
agentComponentCacheStatusVo.setTargetType(Published.TargetType.Model);
|
||||||
|
agentComponentCacheStatusVo.setTargetId(llmNodeConfigDto.getModelId());
|
||||||
|
if (llmNodeConfigDto.getModelConfig() != null && llmNodeConfigDto.getModelConfig().getModified() != null) {
|
||||||
|
agentComponentCacheStatusVo.setLastUpdated(llmNodeConfigDto.getModelConfig().getModified().getTime());
|
||||||
|
agentConfigCacheStatusVo.getComponents().add(agentComponentCacheStatusVo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private AgentConfigDto queryPublishedConfig(Long agentId) {
|
private AgentConfigDto queryPublishedConfig(Long agentId) {
|
||||||
PublishedDto agentPublished = publishApplicationService.queryPublished(Published.TargetType.Agent, agentId);
|
PublishedDto agentPublished = publishApplicationService.queryPublished(Published.TargetType.Agent, agentId);
|
||||||
if (agentPublished == null) {
|
if (agentPublished == null) {
|
||||||
@@ -889,7 +1166,7 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
agentDetailDto.setAllowCopy(agentConfigDto.getAllowCopy());
|
agentDetailDto.setAllowCopy(agentConfigDto.getAllowCopy());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
agentConfigDto = queryById(agentId);
|
agentConfigDto = queryByIdForDetail(agentId);
|
||||||
}
|
}
|
||||||
if (agentConfigDto == null) {
|
if (agentConfigDto == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -904,6 +1181,9 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
variables.addAll(bindConfig.getVariables().stream().filter(var -> !var.isSystemVariable() && var.getInputType() != null && var.getInputType() != Arg.InputTypeEnum.AutoRecognition).collect(Collectors.toList()));
|
variables.addAll(bindConfig.getVariables().stream().filter(var -> !var.isSystemVariable() && var.getInputType() != null && var.getInputType() != Arg.InputTypeEnum.AutoRecognition).collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (agentComponentConfigDto.getType() == AgentComponentConfig.Type.Agent) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (agentComponentConfigDto.getBindConfig() != null) {
|
if (agentComponentConfigDto.getBindConfig() != null) {
|
||||||
if (agentComponentConfigDto.getBindConfig() instanceof PluginBindConfigDto pluginBindConfigDto) {
|
if (agentComponentConfigDto.getBindConfig() instanceof PluginBindConfigDto pluginBindConfigDto) {
|
||||||
return pluginBindConfigDto.getInvokeType() == PluginBindConfigDto.PluginInvokeTypeEnum.MANUAL ||
|
return pluginBindConfigDto.getInvokeType() == PluginBindConfigDto.PluginInvokeTypeEnum.MANUAL ||
|
||||||
@@ -940,9 +1220,17 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
agentManualComponentDto.setName(skillBindConfigDto.getAlias());
|
agentManualComponentDto.setName(skillBindConfigDto.getAlias());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (agentComponentConfigDto.getType() == AgentComponentConfig.Type.Agent) {
|
||||||
|
agentManualComponentDto.setDefaultSelected(0);
|
||||||
|
}
|
||||||
return agentManualComponentDto;
|
return agentManualComponentDto;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
boolean isAgentGroup = agentConfigDto.getAgentComponentConfigList().stream().anyMatch(agentComponentConfigDto -> agentComponentConfigDto.getType() == AgentComponentConfig.Type.Agent);
|
||||||
|
if (isAgentGroup) {
|
||||||
|
agentConfigDto.setType(AgentConfigDto.AgentType.TaskAgent.name());
|
||||||
|
agentConfigDto.setSubType(AgentConfigDto.AgentSubType.Group.name());
|
||||||
|
}
|
||||||
if (agentConfigDto.getModelComponentConfig() != null) {
|
if (agentConfigDto.getModelComponentConfig() != null) {
|
||||||
ModelBindConfigDto bindConfig = (ModelBindConfigDto) agentConfigDto.getModelComponentConfig().getBindConfig();
|
ModelBindConfigDto bindConfig = (ModelBindConfigDto) agentConfigDto.getModelComponentConfig().getBindConfig();
|
||||||
if (bindConfig.getReasoningModelId() != null) {
|
if (bindConfig.getReasoningModelId() != null) {
|
||||||
@@ -985,6 +1273,7 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
agentDetailDto.setPageHomeIndex(agentConfigDto.getPageHomeIndex());
|
agentDetailDto.setPageHomeIndex(agentConfigDto.getPageHomeIndex());
|
||||||
agentDetailDto.setCustomPageMenus(agentConfigDto.getCustomPageMenus());
|
agentDetailDto.setCustomPageMenus(agentConfigDto.getCustomPageMenus());
|
||||||
agentDetailDto.setType(agentConfigDto.getType());
|
agentDetailDto.setType(agentConfigDto.getType());
|
||||||
|
agentDetailDto.setSubType(agentConfigDto.getSubType());
|
||||||
Map<String, Object> variablesMap = new HashMap<>();
|
Map<String, Object> variablesMap = new HashMap<>();
|
||||||
if (RequestContext.get() != null && RequestContext.get().getUser() != null) {
|
if (RequestContext.get() != null && RequestContext.get().getUser() != null) {
|
||||||
UserDto userDto = (UserDto) RequestContext.get().getUser();
|
UserDto userDto = (UserDto) RequestContext.get().getUser();
|
||||||
@@ -1002,10 +1291,7 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
Map<Long, AgentComponentConfigDto> pageComponentConfigMap = agentConfigDto.getAgentComponentConfigList().stream().filter(agentComponentConfigDto -> agentComponentConfigDto.getType() == AgentComponentConfig.Type.Page)
|
Map<Long, AgentComponentConfigDto> pageComponentConfigMap = agentConfigDto.getAgentComponentConfigList().stream().filter(agentComponentConfigDto -> agentComponentConfigDto.getType() == AgentComponentConfig.Type.Page)
|
||||||
.collect(Collectors.toMap(AgentComponentConfigDto::getTargetId, componentConfigDto -> componentConfigDto, (old, newConfig) -> newConfig));
|
.collect(Collectors.toMap(AgentComponentConfigDto::getTargetId, componentConfigDto -> componentConfigDto, (old, newConfig) -> newConfig));
|
||||||
if (CollectionUtils.isNotEmpty(agentConfigDto.getOpeningGuidQuestions())) {
|
if (CollectionUtils.isNotEmpty(agentConfigDto.getOpeningGuidQuestions())) {
|
||||||
agentDetailDto.setOpeningGuidQuestions(agentConfigDto.getOpeningGuidQuestions().stream().map(question -> {
|
agentDetailDto.setOpeningGuidQuestions(agentConfigDto.getOpeningGuidQuestions().stream().map(question -> PlaceholderParser.resoleAndReplacePlaceholder(variablesMap, question)).collect(Collectors.toList()));
|
||||||
String questionText = PlaceholderParser.resoleAndReplacePlaceholder(variablesMap, question);
|
|
||||||
return questionText;
|
|
||||||
}).collect(Collectors.toList()));
|
|
||||||
List<String> newOpeningGuidQuestions = new ArrayList<>();
|
List<String> newOpeningGuidQuestions = new ArrayList<>();
|
||||||
agentDetailDto.setGuidQuestionDtos(agentDetailDto.getOpeningGuidQuestions().stream().map(question -> {
|
agentDetailDto.setGuidQuestionDtos(agentDetailDto.getOpeningGuidQuestions().stream().map(question -> {
|
||||||
GuidQuestionDto guidQuestionDto;
|
GuidQuestionDto guidQuestionDto;
|
||||||
@@ -1089,6 +1375,8 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
agentDetailDto.setAllowAtSkill(agentConfigDto.getAllowAtSkill() == null ? YesOrNoEnum.Y.getKey() : agentConfigDto.getAllowAtSkill());
|
agentDetailDto.setAllowAtSkill(agentConfigDto.getAllowAtSkill() == null ? YesOrNoEnum.Y.getKey() : agentConfigDto.getAllowAtSkill());
|
||||||
agentDetailDto.setAllowOtherModel(agentConfigDto.getAllowOtherModel() == null ? YesOrNoEnum.Y.getKey() : agentConfigDto.getAllowOtherModel());
|
agentDetailDto.setAllowOtherModel(agentConfigDto.getAllowOtherModel() == null ? YesOrNoEnum.Y.getKey() : agentConfigDto.getAllowOtherModel());
|
||||||
agentDetailDto.setAllowPrivateSandbox(agentConfigDto.getAllowPrivateSandbox() == null ? YesOrNoEnum.Y.getKey() : agentConfigDto.getAllowPrivateSandbox());
|
agentDetailDto.setAllowPrivateSandbox(agentConfigDto.getAllowPrivateSandbox() == null ? YesOrNoEnum.Y.getKey() : agentConfigDto.getAllowPrivateSandbox());
|
||||||
|
agentDetailDto.setAllowChooseMode(agentConfigDto.getAllowChooseMode() == null ? YesOrNoEnum.N.getKey() : agentConfigDto.getAllowChooseMode());
|
||||||
|
agentDetailDto.setEnableVersionControl(agentConfigDto.getEnableVersionControl() == null ? YesOrNoEnum.N.getKey() : agentConfigDto.getEnableVersionControl());
|
||||||
|
|
||||||
// 是否有权限
|
// 是否有权限
|
||||||
agentDetailDto.setHasPermission(true);
|
agentDetailDto.setHasPermission(true);
|
||||||
@@ -1145,6 +1433,10 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (agentConfigDto.getDevAgentConversationId() != null) {
|
||||||
|
agentDetailDto.setShowPublishBtn(true);
|
||||||
|
}
|
||||||
|
|
||||||
return agentDetailDto;
|
return agentDetailDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1316,6 +1608,7 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
agentComponentConfigDto.setDeleted(true);
|
agentComponentConfigDto.setDeleted(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
pluginDto.setPublishDate(publishedDto.getModified());
|
||||||
agentComponentConfigDto.setName(pluginDto.getName());
|
agentComponentConfigDto.setName(pluginDto.getName());
|
||||||
agentComponentConfigDto.setDescription(pluginDto.getDescription());
|
agentComponentConfigDto.setDescription(pluginDto.getDescription());
|
||||||
agentComponentConfigDto.setIcon(pluginDto.getIcon());
|
agentComponentConfigDto.setIcon(pluginDto.getIcon());
|
||||||
@@ -1491,6 +1784,14 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
}
|
}
|
||||||
if (agentComponentConfigDto.getType() == AgentComponentConfig.Type.Workflow) {
|
if (agentComponentConfigDto.getType() == AgentComponentConfig.Type.Workflow) {
|
||||||
WorkflowConfigDto workflowConfigDto = workflowApplicationService.queryPublishedWorkflowConfig(agentComponentConfigDto.getTargetId(), agentComponentConfigDto.getSpaceId(), forExecute);
|
WorkflowConfigDto workflowConfigDto = workflowApplicationService.queryPublishedWorkflowConfig(agentComponentConfigDto.getTargetId(), agentComponentConfigDto.getSpaceId(), forExecute);
|
||||||
|
if (workflowConfigDto == null && AgentConfigDto.AgentSubType.Flow.name().equals(agentConfig.getSubType())) {
|
||||||
|
workflowConfigDto = workflowApplicationService.queryByIdWithoutNodes(agentComponentConfigDto.getTargetId());
|
||||||
|
Assert.notNull(workflowConfigDto, "AgentFlow configuration is incomplete");
|
||||||
|
if (forExecute) {
|
||||||
|
List<WorkflowNodeDto> workflowNodes = workflowApplicationService.queryWorkflowNodeListForTestExecute(workflowConfigDto.getId());
|
||||||
|
workflowConfigDto.setNodes(workflowNodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
agentComponentConfigDto.setDeleted(workflowConfigDto == null);
|
agentComponentConfigDto.setDeleted(workflowConfigDto == null);
|
||||||
if (workflowConfigDto != null) {
|
if (workflowConfigDto != null) {
|
||||||
agentComponentConfigDto.setName(workflowConfigDto.getName());
|
agentComponentConfigDto.setName(workflowConfigDto.getName());
|
||||||
@@ -1659,6 +1960,19 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
if (agentComponentConfigDto.getType() != AgentComponentConfig.Type.Model && agentComponentConfigDto.getType() != AgentComponentConfig.Type.Variable) {
|
if (agentComponentConfigDto.getType() != AgentComponentConfig.Type.Model && agentComponentConfigDto.getType() != AgentComponentConfig.Type.Variable) {
|
||||||
agentComponentConfigDto.setIcon(DefaultIconUrlUtil.setDefaultIconUrl(agentComponentConfigDto.getIcon(), agentComponentConfigDto.getName(), agentComponentConfigDto.getType().name()));
|
agentComponentConfigDto.setIcon(DefaultIconUrlUtil.setDefaultIconUrl(agentComponentConfigDto.getIcon(), agentComponentConfigDto.getName(), agentComponentConfigDto.getType().name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Agent
|
||||||
|
if (agentComponentConfigDto.getType() == AgentComponentConfig.Type.Agent) {
|
||||||
|
AgentConfigDto agentConfigDto = queryPublishedConfig(agentComponentConfigDto.getTargetId(), forExecute);
|
||||||
|
if (agentConfigDto != null) {
|
||||||
|
agentComponentConfigDto.setTargetConfig(agentConfigDto);
|
||||||
|
agentComponentConfigDto.setName(agentConfigDto.getName());
|
||||||
|
agentComponentConfigDto.setDescription(agentConfigDto.getDescription());
|
||||||
|
agentComponentConfigDto.setIcon(DefaultIconUrlUtil.setDefaultIconUrl(agentConfigDto.getIcon(), agentConfigDto.getName(), agentComponentConfigDto.getType().name()));
|
||||||
|
} else {
|
||||||
|
agentComponentConfigDto.setDeleted(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return agentComponentConfigList.stream().filter(agentComponentConfigDto -> !agentComponentConfigDto.isDeleted()).collect(Collectors.toList());
|
return agentComponentConfigList.stream().filter(agentComponentConfigDto -> !agentComponentConfigDto.isDeleted()).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
@@ -2129,6 +2443,57 @@ public class AgentApplicationServiceImpl implements AgentApplicationService {
|
|||||||
return modelConfigDtos;
|
return modelConfigDtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GenerateInfoResultDto generateInfo(GenerateInfoReqDto req) {
|
||||||
|
String sysPrompt = """
|
||||||
|
You are a professional project branding assistant. Based on the user's requirement description, generate:
|
||||||
|
1. A concise project name (no more than 20 characters)
|
||||||
|
2. A one-line project description (no more than 100 characters)
|
||||||
|
3. A minimal SVG icon that visually represents the project
|
||||||
|
|
||||||
|
SVG requirements (must match the platform default logo size of 200x200 pixels):
|
||||||
|
- Root element must be: <svg width="200" height="200" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
- The icon must be full-bleed: the first element MUST be a background rect covering the entire canvas: <rect x="0" y="0" width="100" height="100" rx="12" fill="..."/>
|
||||||
|
- The main icon shape (not background) must be large: roughly span x from 15 to 85 and y from 12 to 88
|
||||||
|
- Do NOT add low-opacity decorative lines/bars that shrink the perceived icon area
|
||||||
|
- Main graphic elements must occupy most of the canvas; do NOT leave large empty margins
|
||||||
|
- Draw all shapes within the 0-100 coordinate space; do not use width/height/viewBox values other than above
|
||||||
|
- Use simple geometric shapes and clean lines
|
||||||
|
- Use a modern color palette (gradient or solid colors)
|
||||||
|
- Must be a valid, self-contained SVG with no external references
|
||||||
|
- Keep it simple and recognizable at small sizes
|
||||||
|
- The SVG should be visually appealing and professional
|
||||||
|
|
||||||
|
Identify the language based on the user's description and respond in the same language for name and description.
|
||||||
|
""";
|
||||||
|
|
||||||
|
GenerateInfoAiDto aiResult = modelApplicationService.call(
|
||||||
|
sysPrompt, req.getPrompt(), new ParameterizedTypeReference<GenerateInfoAiDto>() {
|
||||||
|
});
|
||||||
|
|
||||||
|
String iconUrl = null;
|
||||||
|
if (StringUtils.isNotBlank(aiResult.getSvgIcon())) {
|
||||||
|
iconUrl = uploadSvgIcon(aiResult.getSvgIcon(), aiResult.getName() + ".svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
return GenerateInfoResultDto.builder()
|
||||||
|
.name(aiResult.getName())
|
||||||
|
.description(aiResult.getDescription())
|
||||||
|
.iconUrl(iconUrl)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String uploadSvgIcon(String svgIcon, String fileName) {
|
||||||
|
byte[] svgBytes = SvgIconUtil.normalize(svgIcon).getBytes(StandardCharsets.UTF_8);
|
||||||
|
InMemoryMultipartFile multipartFile = new InMemoryMultipartFile(
|
||||||
|
"file", fileName, "image/svg+xml", svgBytes);
|
||||||
|
Long tenantId = RequestContext.get().getTenantId();
|
||||||
|
Long userId = RequestContext.get().getUserId();
|
||||||
|
FileRecordDomain fileRecord = fileManagementService.uploadFile(
|
||||||
|
multipartFile, tenantId, userId, "icon", -1L, null, true);
|
||||||
|
return fileRecord.getFileUrl();
|
||||||
|
}
|
||||||
|
|
||||||
private Map<Long, StatisticsDto> getAgentStatisticsMapByAgentIds(List<Long> agentIds) {
|
private Map<Long, StatisticsDto> getAgentStatisticsMapByAgentIds(List<Long> agentIds) {
|
||||||
List<StatisticsDto> agentStatisticsList = publishDomainService
|
List<StatisticsDto> agentStatisticsList = publishDomainService
|
||||||
.queryStatisticsCountList(Published.TargetType.Agent, agentIds);
|
.queryStatisticsCountList(Published.TargetType.Agent, agentIds);
|
||||||
|
|||||||
@@ -2,18 +2,33 @@ package com.xspaceagi.agent.core.application.service;
|
|||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.xspaceagi.agent.core.adapter.application.AgentWorkspaceApplicationService;
|
import com.xspaceagi.agent.core.adapter.application.AgentWorkspaceApplicationService;
|
||||||
|
import com.xspaceagi.agent.core.adapter.application.AgentApplicationService;
|
||||||
import com.xspaceagi.agent.core.adapter.application.PublishApplicationService;
|
import com.xspaceagi.agent.core.adapter.application.PublishApplicationService;
|
||||||
|
import com.xspaceagi.agent.core.adapter.application.SkillApplicationService;
|
||||||
import com.xspaceagi.agent.core.adapter.constant.SkillFileFormatConstants;
|
import com.xspaceagi.agent.core.adapter.constant.SkillFileFormatConstants;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.*;
|
import com.xspaceagi.agent.core.adapter.dto.*;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.config.AgentConfigDto;
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.AgentConfig;
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.Conversation;
|
||||||
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
||||||
import com.xspaceagi.agent.core.adapter.repository.entity.SkillConfig;
|
import com.xspaceagi.agent.core.adapter.repository.entity.SkillConfig;
|
||||||
|
import com.xspaceagi.agent.core.domain.service.AgentDomainService;
|
||||||
|
import com.xspaceagi.agent.core.domain.service.ConversationDomainService;
|
||||||
|
import com.xspaceagi.agent.core.domain.service.PublishDomainService;
|
||||||
import com.xspaceagi.agent.core.domain.service.SkillDomainService;
|
import com.xspaceagi.agent.core.domain.service.SkillDomainService;
|
||||||
import com.xspaceagi.agent.core.infra.rpc.SkillFileClient;
|
import com.xspaceagi.agent.core.infra.rpc.ComputerFileClient;
|
||||||
|
import com.xspaceagi.agent.core.infra.rpc.GitRpcClient;
|
||||||
|
import com.xspaceagi.agent.core.infra.rpc.WorkspaceRpcClient;
|
||||||
import com.xspaceagi.agent.core.adapter.util.SkillNameUtil;
|
import com.xspaceagi.agent.core.adapter.util.SkillNameUtil;
|
||||||
import com.xspaceagi.agent.core.spec.utils.FileTypeUtils;
|
import com.xspaceagi.agent.core.spec.utils.FileTypeUtils;
|
||||||
import com.xspaceagi.agent.core.spec.utils.MarkdownExtractUtil;
|
import com.xspaceagi.agent.core.spec.utils.MarkdownExtractUtil;
|
||||||
|
import com.xspaceagi.agent.core.spec.utils.UrlFile;
|
||||||
|
import com.xspaceagi.file.application.service.FileManagementService;
|
||||||
|
import com.xspaceagi.file.domain.model.FileRecordDomain;
|
||||||
import com.xspaceagi.file.sdk.IFileAccessService;
|
import com.xspaceagi.file.sdk.IFileAccessService;
|
||||||
|
import com.xspaceagi.system.spec.common.RequestContext;
|
||||||
import com.xspaceagi.system.spec.enums.ErrorCodeEnum;
|
import com.xspaceagi.system.spec.enums.ErrorCodeEnum;
|
||||||
|
import com.xspaceagi.system.spec.enums.YesOrNoEnum;
|
||||||
import com.xspaceagi.system.spec.exception.BizException;
|
import com.xspaceagi.system.spec.exception.BizException;
|
||||||
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
|
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
|
||||||
import com.xspaceagi.system.spec.file.InMemoryMultipartFile;
|
import com.xspaceagi.system.spec.file.InMemoryMultipartFile;
|
||||||
@@ -24,6 +39,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -34,17 +50,35 @@ import java.util.zip.ZipEntry;
|
|||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class AgentWorkspaceApplicationServiceImpl implements AgentWorkspaceApplicationService {
|
public class AgentWorkspaceApplicationServiceImpl implements AgentWorkspaceApplicationService {
|
||||||
@Resource
|
@Resource
|
||||||
private SkillFileClient skillFileClient;
|
private WorkspaceRpcClient workspaceRpcClient;
|
||||||
@Resource
|
@Resource
|
||||||
private SkillDomainService skillDomainService;
|
private SkillDomainService skillDomainService;
|
||||||
@Resource
|
@Resource
|
||||||
private PublishApplicationService publishApplicationService;
|
private PublishApplicationService publishApplicationService;
|
||||||
@Resource
|
@Resource
|
||||||
|
private PublishDomainService publishDomainService;
|
||||||
|
@Resource
|
||||||
private IFileAccessService iFileAccessService;
|
private IFileAccessService iFileAccessService;
|
||||||
|
@Resource
|
||||||
|
private ComputerFileClient computerFileClient;
|
||||||
|
@Resource
|
||||||
|
private FileManagementService fileManagementService;
|
||||||
|
@Resource
|
||||||
|
private AgentDomainService agentDomainService;
|
||||||
|
@Resource
|
||||||
|
private AgentApplicationService agentApplicationService;
|
||||||
|
@Resource
|
||||||
|
private ConversationDomainService conversationDomainService;
|
||||||
|
@Resource
|
||||||
|
private SkillApplicationService skillApplicationService;
|
||||||
|
@Resource
|
||||||
|
private GitRpcClient gitRpcClient;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createWorkspace(CreateWorkspaceDto createWorkspaceDto) {
|
public void createWorkspace(CreateWorkspaceDto createWorkspaceDto) {
|
||||||
@@ -103,9 +137,18 @@ public class AgentWorkspaceApplicationServiceImpl implements AgentWorkspaceAppli
|
|||||||
zipFile = buildZip(toPushSkills, subagents);
|
zipFile = buildZip(toPushSkills, subagents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String mcpServersConfig = createWorkspaceDto.getMcpServersConfig() != null ? JSON.toJSONString(createWorkspaceDto.getMcpServersConfig()) : null;
|
||||||
|
String permissionsConfig = createWorkspaceDto.getPermissionsConfig() != null ? JSON.toJSONString(createWorkspaceDto.getPermissionsConfig()) : null;
|
||||||
|
String hooksConfig = createWorkspaceDto.getHooksConfig() != null ? JSON.toJSONString(createWorkspaceDto.getHooksConfig()) : null;
|
||||||
|
List<HookScriptDto> hookScripts = createWorkspaceDto.getHookScripts();
|
||||||
|
String hookScriptsJson = null;
|
||||||
|
if (CollectionUtils.isNotEmpty(hookScripts)) {
|
||||||
|
hookScriptsJson = JSON.toJSONString(hookScripts);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, Object> result = null;
|
Map<String, Object> result = null;
|
||||||
try {
|
try {
|
||||||
result = skillFileClient.createWorkSpaceV2(userId, cId, zipFile, skillUrls);
|
result = workspaceRpcClient.createWorkSpaceV2(userId, cId, zipFile, skillUrls, mcpServersConfig, permissionsConfig, hooksConfig, hookScriptsJson);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("[createWorkspace] userId={} cId={} 调用 createWorkSpaceV2 异常,准备回退到 createWorkSpace", userId, cId, e);
|
log.warn("[createWorkspace] userId={} cId={} 调用 createWorkSpaceV2 异常,准备回退到 createWorkSpace", userId, cId, e);
|
||||||
}
|
}
|
||||||
@@ -116,7 +159,7 @@ public class AgentWorkspaceApplicationServiceImpl implements AgentWorkspaceAppli
|
|||||||
log.warn("[createWorkspace] userId={} cId={} createWorkSpaceV2失败,准备回退。message={}", userId, cId, message);
|
log.warn("[createWorkspace] userId={} cId={} createWorkSpaceV2失败,准备回退。message={}", userId, cId, message);
|
||||||
|
|
||||||
MultipartFile fallbackZipFile = buildZipWithSkillUrls(zipFile, skillUrls, false);
|
MultipartFile fallbackZipFile = buildZipWithSkillUrls(zipFile, skillUrls, false);
|
||||||
result = skillFileClient.createWorkSpace(userId, cId, fallbackZipFile);
|
result = workspaceRpcClient.createWorkSpace(userId, cId, fallbackZipFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
@@ -155,7 +198,7 @@ public class AgentWorkspaceApplicationServiceImpl implements AgentWorkspaceAppli
|
|||||||
|
|
||||||
Map<String, Object> result = null;
|
Map<String, Object> result = null;
|
||||||
try {
|
try {
|
||||||
result = skillFileClient.pushSkillsToWorkspaceV2(userId, cId, baseZipFile, skillUrls);
|
result = workspaceRpcClient.pushSkillsToWorkspaceV2(userId, cId, baseZipFile, skillUrls);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("[addSkills] userId={} cId={} 调用 pushSkillsToWorkspaceV2 异常,准备回退到 pushSkillsToWorkspace", userId, cId, e);
|
log.warn("[addSkills] userId={} cId={} 调用 pushSkillsToWorkspaceV2 异常,准备回退到 pushSkillsToWorkspace", userId, cId, e);
|
||||||
}
|
}
|
||||||
@@ -168,7 +211,7 @@ public class AgentWorkspaceApplicationServiceImpl implements AgentWorkspaceAppli
|
|||||||
if (zipFile == null) {
|
if (zipFile == null) {
|
||||||
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.agentSkillZipPackFailed);
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.agentSkillZipPackFailed);
|
||||||
}
|
}
|
||||||
result = skillFileClient.pushSkillsToWorkspace(userId, cId, zipFile);
|
result = workspaceRpcClient.pushSkillsToWorkspace(userId, cId, zipFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
@@ -185,6 +228,622 @@ public class AgentWorkspaceApplicationServiceImpl implements AgentWorkspaceAppli
|
|||||||
log.info("[addSkills] userId={} cId={} 动态增加技能完成", userId, cId);
|
log.info("[addSkills] userId={} cId={} 动态增加技能完成", userId, cId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initProjectTemplate(InitProjectTemplateDto dto) {
|
||||||
|
Long userId = dto.getUserId();
|
||||||
|
Long cId = dto.getCId();
|
||||||
|
InitProjectTemplateDto.ProjectType projectType = dto.getProjectType();
|
||||||
|
InitProjectTemplateDto.ProgrammingLanguage programmingLanguage = dto.getProgrammingLanguage();
|
||||||
|
|
||||||
|
log.info("[initProjectTemplate] userId={} cId={} projectType={} programmingLanguage={} 开始初始化项目模板", userId, cId, projectType, programmingLanguage);
|
||||||
|
|
||||||
|
if (userId == null || cId == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.fieldRequiredButEmpty, "userId/cId");
|
||||||
|
}
|
||||||
|
if (projectType == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.fieldRequiredButEmpty, "projectType");
|
||||||
|
}
|
||||||
|
if (projectType == InitProjectTemplateDto.ProjectType.AGENT && programmingLanguage == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.fieldRequiredButEmpty, "programmingLanguage");
|
||||||
|
}
|
||||||
|
|
||||||
|
MultipartFile templateFile = null;
|
||||||
|
|
||||||
|
if (projectType == InitProjectTemplateDto.ProjectType.AGENT) {
|
||||||
|
String templateFileName;
|
||||||
|
switch (programmingLanguage) {
|
||||||
|
case PYTHON:
|
||||||
|
templateFileName = "deepagent-app-py.zip";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
templateFileName = "deepagents-flow-ts.zip";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从 classpath 读取模板 zip 文件
|
||||||
|
String classpathLocation = "templates/" + templateFileName;
|
||||||
|
byte[] zipBytes;
|
||||||
|
try {
|
||||||
|
ClassPathResource resource = new ClassPathResource(classpathLocation);
|
||||||
|
try (InputStream is = resource.getInputStream()) {
|
||||||
|
zipBytes = is.readAllBytes();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("[initProjectTemplate] userId={} cId={} 读取模板文件失败, classpathLocation={}", userId, cId, classpathLocation, e);
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.validationFailedWithDetail,
|
||||||
|
"Template file not found: " + templateFileName);
|
||||||
|
}
|
||||||
|
templateFile = new InMemoryMultipartFile("file", templateFileName, "application/zip", zipBytes);
|
||||||
|
} else if (projectType == InitProjectTemplateDto.ProjectType.SKILL) {
|
||||||
|
templateFile = buildSkillTemplateZip();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean enableGit = resolveEnableGit(cId);
|
||||||
|
log.info("[initProjectTemplate] userId={} cId={} enableGit={}", userId, cId, enableGit);
|
||||||
|
|
||||||
|
// 调用 file-server 接口
|
||||||
|
Map<String, Object> result = workspaceRpcClient.initProjectTemplate(userId, cId, templateFile, enableGit);
|
||||||
|
|
||||||
|
// 结果校验
|
||||||
|
if (result == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.agentTemplateInitFailed, "result is null");
|
||||||
|
}
|
||||||
|
Object successObj = result.get("success");
|
||||||
|
if (successObj instanceof Boolean && !(Boolean) successObj) {
|
||||||
|
String message = result.getOrDefault("message", "初始化项目模板失败").toString();
|
||||||
|
log.error("[initProjectTemplate] userId={} cId={} 初始化项目模板失败, message={}", userId, cId, message);
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.agentTemplateInitFailed, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("[initProjectTemplate] userId={} cId={} 初始化项目模板成功", userId, cId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean resolveEnableGit(Long cId) {
|
||||||
|
Conversation conversation = conversationDomainService.getConversation(cId);
|
||||||
|
if (conversation == null || conversation.getAgentId() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
AgentConfigDto executingAgent;
|
||||||
|
if (YesOrNoEnum.Y.getKey().equals(conversation.getDevMode())) {
|
||||||
|
executingAgent = agentApplicationService.queryConfigForTestExecute(conversation.getAgentId());
|
||||||
|
} else {
|
||||||
|
executingAgent = agentApplicationService.queryPublishedConfigForExecute(conversation.getAgentId());
|
||||||
|
}
|
||||||
|
if (executingAgent == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return YesOrNoEnum.Y.getKey().equals(executingAgent.getEnableVersionControl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void installProject(InstallProjectDto dto) {
|
||||||
|
Long userId = dto.getUserId();
|
||||||
|
Long cId = dto.getCId();
|
||||||
|
InitProjectTemplateDto.ProgrammingLanguage programmingLanguage = dto.getProgrammingLanguage();
|
||||||
|
|
||||||
|
log.info("[installProject] userId={} cId={} programmingLanguage={} 开始安装项目依赖", userId, cId, programmingLanguage);
|
||||||
|
|
||||||
|
if (userId == null || cId == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.fieldRequiredButEmpty, "userId/cId");
|
||||||
|
}
|
||||||
|
if (programmingLanguage == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.fieldRequiredButEmpty, "programmingLanguage");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> result = workspaceRpcClient.installProject(userId, cId, programmingLanguage.getValue());
|
||||||
|
if (result == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.workspaceExecuteCommandFailed, "installProject result is null");
|
||||||
|
}
|
||||||
|
Object successObj = result.get("success");
|
||||||
|
if (successObj instanceof Boolean && !(Boolean) successObj) {
|
||||||
|
String message = String.valueOf(result.getOrDefault("message", "安装项目依赖失败"));
|
||||||
|
log.error("[installProject] userId={} cId={} 安装项目依赖失败, message={}", userId, cId, message);
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.workspaceExecuteCommandFailed, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("[installProject] userId={} cId={} 安装项目依赖成功", userId, cId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AgentPublishVersionDto> packageAgent(PackageAgentDto dto) {
|
||||||
|
Long userId = dto.getUserId();
|
||||||
|
Long cId = dto.getCId();
|
||||||
|
Long agentId = dto.getAgentId();
|
||||||
|
|
||||||
|
log.info("[packageAgent] userId={} cId={} agentId={} programmingLanguage={} 开始打包Agent", userId, cId, agentId, dto.getProgrammingLanguage());
|
||||||
|
|
||||||
|
if (userId == null || cId == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.fieldRequiredButEmpty, "userId/cId");
|
||||||
|
}
|
||||||
|
if (agentId == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.fieldRequiredButEmpty, "agentId");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 先 git add + commit 确保工作区改动已提交(仅版本控制开启时)
|
||||||
|
boolean enableGit = resolveEnableGit(cId);
|
||||||
|
if (enableGit) {
|
||||||
|
gitCommitAndPush(userId, cId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 获取 git commit hash
|
||||||
|
String gitCommit = enableGit ? getGitCommitHash(userId, cId) : null;
|
||||||
|
log.info("[packageAgent] userId={} cId={} agentId={} gitCommit={}", userId, cId, agentId, gitCommit);
|
||||||
|
|
||||||
|
// 3. 查询 agent_config 中的已有版本记录,检查是否需要重新打包
|
||||||
|
AgentConfig agentConfig = agentDomainService.queryById(agentId);
|
||||||
|
List<AgentPublishVersionDto> existingVersions = agentConfig != null ? agentConfig.getPublishVersion() : null;
|
||||||
|
if (CollectionUtils.isNotEmpty(existingVersions)) {
|
||||||
|
AgentPublishVersionDto latestVersion = existingVersions.stream()
|
||||||
|
.filter(v -> Boolean.TRUE.equals(v.getLatest()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
if (latestVersion != null && gitCommit != null && gitCommit.equals(latestVersion.getGitCommit())) {
|
||||||
|
// git commit 没有变化,不需要重新打包
|
||||||
|
log.info("[packageAgent] userId={} cId={} agentId={} git commit未变化, 跳过打包, version={}", userId, cId, agentId, latestVersion.getVersion());
|
||||||
|
return existingVersions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 生成递增版本号
|
||||||
|
String version = getNextVersion(existingVersions);
|
||||||
|
log.info("[packageAgent] userId={} cId={} agentId={} newVersion={}", userId, cId, agentId, version);
|
||||||
|
|
||||||
|
// 5. 调用 file-server 构建 agent 产物
|
||||||
|
Map<String, Object> buildResult = workspaceRpcClient.buildAgentPackage(userId, cId, agentId, version);
|
||||||
|
if (buildResult == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.workspaceExecuteCommandFailed, "buildAgentPackage result is null");
|
||||||
|
}
|
||||||
|
Object buildSuccessObj = buildResult.get("success");
|
||||||
|
if (buildSuccessObj instanceof Boolean && !(Boolean) buildSuccessObj) {
|
||||||
|
String message = String.valueOf(buildResult.getOrDefault("message", "buildAgentPackage failed"));
|
||||||
|
log.error("[packageAgent] userId={} cId={} 构建产物失败, message={}", userId, cId, message);
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.workspaceExecuteCommandFailed, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 遍历产物列表,下载并上传
|
||||||
|
Object artifactsObj = buildResult.get("artifacts");
|
||||||
|
List<AgentPublishVersionDto.PackageArtifact> packages = new ArrayList<>();
|
||||||
|
|
||||||
|
if (artifactsObj instanceof List) {
|
||||||
|
for (Object artifactObj : (List<?>) artifactsObj) {
|
||||||
|
if (!(artifactObj instanceof Map)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<String, Object> artifact = (Map<String, Object>) artifactObj;
|
||||||
|
|
||||||
|
String artifactPath = String.valueOf(artifact.getOrDefault("path", ""));
|
||||||
|
String fileName = String.valueOf(artifact.getOrDefault("fileName", ""));
|
||||||
|
String platform = String.valueOf(artifact.getOrDefault("platform", ""));
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(artifactPath) || StringUtils.isBlank(fileName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(platform)) {
|
||||||
|
log.warn("[packageAgent] userId={} cId={} 无法从文件名提取platform, fileName={}", userId, cId, fileName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String staticPrefix = "computer/static/" + userId + "/" + cId;
|
||||||
|
byte[] fileBytes = computerFileClient.getStaticFileAsBytes(cId, staticPrefix, artifactPath, "packageAgent:" + userId + ":" + cId);
|
||||||
|
|
||||||
|
String lowerFileName = fileName.toLowerCase();
|
||||||
|
String contentType = lowerFileName.endsWith(".zip") ? "application/zip" : "application/gzip";
|
||||||
|
InMemoryMultipartFile multipartFile = new InMemoryMultipartFile("file", fileName, contentType, fileBytes);
|
||||||
|
Long tenantId = RequestContext.get() != null ? RequestContext.get().getTenantId() : null;
|
||||||
|
Long uploadUserId = RequestContext.get() != null ? RequestContext.get().getUserId() : null;
|
||||||
|
FileRecordDomain fileRecord = fileManagementService.uploadFile(multipartFile, tenantId, uploadUserId, "agent_package", agentId, artifactPath, true);
|
||||||
|
|
||||||
|
String fileUrl = fileRecord.getFileUrl();
|
||||||
|
packages.add(AgentPublishVersionDto.PackageArtifact.builder()
|
||||||
|
.platform(platform)
|
||||||
|
.url(fileUrl)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
log.info("[packageAgent] userId={} cId={} 上传产物成功, fileName={}, platform={}, fileUrl={}", userId, cId, fileName, platform, fileUrl);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[packageAgent] userId={} cId={} 处理产物失败, artifactPath={}", userId, cId, artifactPath, e);
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.agentPackageFailed, "Failed to process artifact: " + artifactPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packages.isEmpty()) {
|
||||||
|
log.error("[packageAgent] userId={} cId={} 打包产物处理失败,无有效产物", userId, cId);
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.agentPackageFailed, "No valid package artifacts found");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. 清理沙箱打包产物
|
||||||
|
try {
|
||||||
|
workspaceRpcClient.cleanupBuildArtifacts(userId, cId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("[packageAgent] userId={} cId={} 清理打包产物目录失败, 不影响发布流程", userId, cId, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. 保存版本记录到 agent_config.publishVersion
|
||||||
|
List<AgentPublishVersionDto> updatedVersions = saveVersionToAgentConfig(agentId, existingVersions, version, gitCommit, packages);
|
||||||
|
|
||||||
|
log.info("[packageAgent] userId={} cId={} agentId={} 打包完成, version={}, gitCommit={}, packages={}", userId, cId, agentId, version, gitCommit, packages.size());
|
||||||
|
return updatedVersions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SkillFileDto> snapshotSkillFilesFromSandbox(Long userId, Long cId, String targetType, Long skillId) {
|
||||||
|
if (userId == null || cId == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.fieldRequiredButEmpty, "userId/cId");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 获取技能
|
||||||
|
byte[] zipBytes = zipAndDownloadFromSandbox(userId, cId);
|
||||||
|
|
||||||
|
// 2. 解析 zip,逐个文件上传到文件服务
|
||||||
|
List<SkillFileDto> results = new ArrayList<>();
|
||||||
|
try (ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zipBytes))) {
|
||||||
|
ZipEntry entry;
|
||||||
|
while ((entry = zis.getNextEntry()) != null) {
|
||||||
|
String entryName = entry.getName();
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
SkillFileDto dirDto = new SkillFileDto();
|
||||||
|
dirDto.setName(entryName);
|
||||||
|
dirDto.setIsDir(true);
|
||||||
|
results.add(dirDto);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 跳过隐藏文件和无关文件
|
||||||
|
if (entryName.startsWith(".") || entryName.contains("/__pycache__/") || entryName.contains("/node_modules/")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] fileBytes = zis.readAllBytes();
|
||||||
|
String fileName = entryName;
|
||||||
|
int lastSlash = entryName.lastIndexOf('/');
|
||||||
|
if (lastSlash >= 0 && lastSlash < entryName.length() - 1) {
|
||||||
|
fileName = entryName.substring(lastSlash + 1);
|
||||||
|
}
|
||||||
|
String contentType = FileTypeUtils.getContentTypeByFileName(fileName).toString();
|
||||||
|
InMemoryMultipartFile multipartFile = new InMemoryMultipartFile("file", fileName, contentType, fileBytes);
|
||||||
|
Long tenantId = RequestContext.get() != null ? RequestContext.get().getTenantId() : null;
|
||||||
|
Long uploadUserId = RequestContext.get() != null ? RequestContext.get().getUserId() : null;
|
||||||
|
FileRecordDomain fileRecord = fileManagementService.uploadFile(multipartFile, tenantId, uploadUserId, targetType, skillId, entryName, true);
|
||||||
|
|
||||||
|
SkillFileDto fileDto = new SkillFileDto();
|
||||||
|
fileDto.setName(entryName);
|
||||||
|
fileDto.setFileProxyUrl(fileRecord.getFileUrl());
|
||||||
|
results.add(fileDto);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("[snapshotSkillFilesFromSandbox] 解析zip失败, userId={}, cId={}", userId, cId, e);
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.agentSkillZipPackFailed,
|
||||||
|
"Failed to parse skill zip");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("[snapshotSkillFilesFromSandbox] userId={} cId={} skillId={} 从沙箱取回技能文件完成, fileCount={}", userId, cId, skillId, results.size());
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteWorkspace(Long userId, Long cId) {
|
||||||
|
if (userId == null || cId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Map<String, Object> result = workspaceRpcClient.deleteWorkspace(userId, cId);
|
||||||
|
if (result != null) {
|
||||||
|
Object successObj = result.get("success");
|
||||||
|
if (successObj instanceof Boolean && !(Boolean) successObj) {
|
||||||
|
log.warn("[deleteWorkspace] userId={} cId={} 删除工作空间失败, result={}", userId, cId, result);
|
||||||
|
} else {
|
||||||
|
log.info("[deleteWorkspace] userId={} cId={} 删除工作空间成功", userId, cId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("[deleteWorkspace] userId={} cId={} 删除工作空间异常", userId, cId, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SkillExportResultDto exportSkillFromSandbox(Long userId, Long cId, String skillName) {
|
||||||
|
if (userId == null || cId == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.fieldRequiredButEmpty, "userId/cId");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 获取技能
|
||||||
|
byte[] zipBytes = zipAndDownloadFromSandbox(userId, cId);
|
||||||
|
|
||||||
|
// 2. 构建返回结果
|
||||||
|
String exportFileName = (StringUtils.isNotBlank(skillName) ? skillName : "skill") + ".zip";
|
||||||
|
SkillExportResultDto resultDto = new SkillExportResultDto();
|
||||||
|
resultDto.setFileName(exportFileName);
|
||||||
|
resultDto.setData(zipBytes);
|
||||||
|
resultDto.setContentType("application/zip");
|
||||||
|
|
||||||
|
log.info("[exportSkillFromSandbox] userId={} cId={} skillName={} 导出完成, zipSize={}", userId, cId, skillName, zipBytes.length);
|
||||||
|
return resultDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void copySandboxWorkspace(Long srcUserId, Long srcCId, Long destUserId, Long destCId) {
|
||||||
|
if (srcUserId == null || srcCId == null || destUserId == null || destCId == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.fieldRequiredButEmpty, "srcUserId/srcCId/destUserId/destCId");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("[copySandboxWorkspace] srcUserId={} srcCId={} destUserId={} destCId={} 开始复制工作空间", srcUserId, srcCId, destUserId, destCId);
|
||||||
|
|
||||||
|
// 1. 打包下载
|
||||||
|
byte[] zipBytes = zipAndDownloadFromSandbox(srcUserId, srcCId);
|
||||||
|
|
||||||
|
// 2. 使用 initProjectTemplate 将 zip 推送到新工作空间,按版本开关决定是否初始化 git
|
||||||
|
InMemoryMultipartFile zipFile = new InMemoryMultipartFile("file", "skill-copy.zip", "application/zip", zipBytes);
|
||||||
|
boolean enableGit = resolveEnableGit(destCId);
|
||||||
|
Map<String, Object> initResult = workspaceRpcClient.initProjectTemplate(destUserId, destCId, zipFile, enableGit);
|
||||||
|
|
||||||
|
if (initResult == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.agentTemplateInitFailed, "initProjectTemplate result is null");
|
||||||
|
}
|
||||||
|
Object successObj = initResult.get("success");
|
||||||
|
if (successObj instanceof Boolean && !(Boolean) successObj) {
|
||||||
|
String message = String.valueOf(initResult.getOrDefault("message", "initProjectTemplate failed"));
|
||||||
|
log.error("[copySandboxWorkspace] destUserId={} destCId={} initProjectTemplate失败, message={}", destUserId, destCId, message);
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.agentTemplateInitFailed, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("[copySandboxWorkspace] srcUserId={} srcCId={} destUserId={} destCId={} 复制工作空间完成", srcUserId, srcCId, destUserId, destCId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uploadZipToWorkspace(Long userId, Long cId, String zipFileUrl) {
|
||||||
|
if (userId == null || cId == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.fieldRequiredButEmpty, "userId/cId");
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(zipFileUrl)) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.fieldRequiredButEmpty, "zipFileUrl");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("[uploadZipToWorkspace] userId={} cId={} 开始上传 zip 到工作空间", userId, cId);
|
||||||
|
|
||||||
|
// 1. 下载 zip 字节(UrlFile 内部会生成签名下载地址,并兼容 S3 presigned URL)
|
||||||
|
byte[] zipBytes;
|
||||||
|
try {
|
||||||
|
zipBytes = UrlFile.urlToBytes(zipFileUrl);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[uploadZipToWorkspace] userId={} cId={} 下载 zip 失败, zipFileUrl={}", userId, cId, zipFileUrl, e);
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.agentTemplateInitFailed, "Failed to download zip: " + e.getMessage());
|
||||||
|
}
|
||||||
|
if (zipBytes == null || zipBytes.length == 0) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.agentTemplateInitFailed, "Downloaded zip is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 如果压缩包只有一个顶层目录,去掉顶层目录后再上传
|
||||||
|
zipBytes = stripTopLevelDirIfNeeded(zipBytes);
|
||||||
|
|
||||||
|
// 3. 包装为 MultipartFile 并推送到工作空间,按版本开关决定是否初始化 git
|
||||||
|
InMemoryMultipartFile zipFile = new InMemoryMultipartFile("file", "skill.zip", "application/zip", zipBytes);
|
||||||
|
boolean enableGit = resolveEnableGit(cId);
|
||||||
|
Map<String, Object> initResult = workspaceRpcClient.initProjectTemplate(userId, cId, zipFile, enableGit);
|
||||||
|
|
||||||
|
if (initResult == null) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.agentTemplateInitFailed, "initProjectTemplate result is null");
|
||||||
|
}
|
||||||
|
Object successObj = initResult.get("success");
|
||||||
|
if (successObj instanceof Boolean && !(Boolean) successObj) {
|
||||||
|
String message = String.valueOf(initResult.getOrDefault("message", "initProjectTemplate failed"));
|
||||||
|
log.error("[uploadZipToWorkspace] userId={} cId={} initProjectTemplate失败, message={}", userId, cId, message);
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.agentTemplateInitFailed, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("[uploadZipToWorkspace] userId={} cId={} 上传 zip 到工作空间完成", userId, cId);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ------------------ 以下是private方法 -----------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用 file-server 的 zip-workspace 接口打包工作空间文件并下载 zip 字节
|
||||||
|
*
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @param cId 会话ID
|
||||||
|
* @return zip 文件的字节数组
|
||||||
|
*/
|
||||||
|
private byte[] zipAndDownloadFromSandbox(Long userId, Long cId) {
|
||||||
|
byte[] zipBytes = workspaceRpcClient.zipWorkspace(userId, cId, null);
|
||||||
|
if (zipBytes == null || zipBytes.length == 0) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.workspaceExecuteCommandFailed,
|
||||||
|
"Failed to zip files in sandbox: empty response");
|
||||||
|
}
|
||||||
|
log.info("userId={} cId={} 沙箱打包完成, zipSize={}", userId, cId, zipBytes.length);
|
||||||
|
return zipBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果 zip 只有一个顶层目录,去掉该顶层目录前缀后重新打包;否则原样返回。
|
||||||
|
* 例如 entry 为 "my-skill/SKILL.md" 时会去掉 "my-skill/" 前缀。
|
||||||
|
*/
|
||||||
|
private byte[] stripTopLevelDirIfNeeded(byte[] zipBytes) {
|
||||||
|
// 第一次扫描:判断是否所有 entry 都在同一个顶层目录下
|
||||||
|
String topLevelDir = null;
|
||||||
|
boolean singleTopLevel = true;
|
||||||
|
try (ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zipBytes), StandardCharsets.UTF_8)) {
|
||||||
|
ZipEntry entry;
|
||||||
|
while ((entry = zis.getNextEntry()) != null) {
|
||||||
|
String name = normalizeZipPath(entry.getName());
|
||||||
|
int slash = name.indexOf('/');
|
||||||
|
if (slash < 0) {
|
||||||
|
// 根目录下存在文件,不存在单一顶层目录
|
||||||
|
singleTopLevel = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
String top = name.substring(0, slash);
|
||||||
|
if (topLevelDir == null) {
|
||||||
|
topLevelDir = top;
|
||||||
|
} else if (!topLevelDir.equals(top)) {
|
||||||
|
singleTopLevel = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
zis.closeEntry();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("[stripTopLevelDir] 解析zip判断顶层目录失败, 原样返回", e);
|
||||||
|
return zipBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!singleTopLevel || topLevelDir == null) {
|
||||||
|
return zipBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String prefix = topLevelDir + "/";
|
||||||
|
// 第二次扫描:去掉顶层目录前缀后重新打包
|
||||||
|
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
ZipOutputStream zos = new ZipOutputStream(baos, StandardCharsets.UTF_8)) {
|
||||||
|
try (ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zipBytes), StandardCharsets.UTF_8)) {
|
||||||
|
ZipEntry entry;
|
||||||
|
while ((entry = zis.getNextEntry()) != null) {
|
||||||
|
String name = normalizeZipPath(entry.getName());
|
||||||
|
if (name.startsWith(prefix)) {
|
||||||
|
name = name.substring(prefix.length());
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(name)) {
|
||||||
|
// 去掉前缀后为空(即顶层目录 entry 本身),跳过
|
||||||
|
zis.closeEntry();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ZipEntry newEntry = new ZipEntry(name);
|
||||||
|
zos.putNextEntry(newEntry);
|
||||||
|
if (!entry.isDirectory()) {
|
||||||
|
zos.write(zis.readAllBytes());
|
||||||
|
}
|
||||||
|
zos.closeEntry();
|
||||||
|
zis.closeEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zos.finish();
|
||||||
|
log.info("[stripTopLevelDir] 去掉顶层目录 '{}' 后重新打包完成", topLevelDir);
|
||||||
|
return baos.toByteArray();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("[stripTopLevelDir] 重新打包失败, 原样返回", e);
|
||||||
|
return zipBytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行 git add + commit,确保所有改动已提交
|
||||||
|
*/
|
||||||
|
private void gitCommitAndPush(Long userId, Long cId) {
|
||||||
|
try {
|
||||||
|
gitRpcClient.commitTaskAgent(cId, userId, "auto commit before package", null, null, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("[packageAgent] git commit失败, userId={}, cId={}", userId, cId, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取沙箱工作空间中的 git commit hash(HEAD)
|
||||||
|
*/
|
||||||
|
private String getGitCommitHash(Long userId, Long cId) {
|
||||||
|
try {
|
||||||
|
Map<String, Object> result = gitRpcClient.logTaskAgent(cId, userId, 1, 1, null, null);
|
||||||
|
if (result != null) {
|
||||||
|
Object successObj = result.get("success");
|
||||||
|
if (successObj instanceof Boolean && (Boolean) successObj) {
|
||||||
|
Object commitsObj = result.get("commits");
|
||||||
|
if (commitsObj instanceof List && !((List<?>) commitsObj).isEmpty()) {
|
||||||
|
Object firstCommit = ((List<?>) commitsObj).get(0);
|
||||||
|
if (firstCommit instanceof Map) {
|
||||||
|
String hash = String.valueOf(((Map<?, ?>) firstCommit).get("hash"));
|
||||||
|
if (hash.length() >= 7) {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("[packageAgent] 获取git commit hash失败, userId={}, cId={}", userId, cId, e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 agent_config 中的已有版本记录获取下一个版本号
|
||||||
|
*/
|
||||||
|
private String getNextVersion(List<AgentPublishVersionDto> existingVersions) {
|
||||||
|
if (CollectionUtils.isNotEmpty(existingVersions)) {
|
||||||
|
String latest = existingVersions.stream()
|
||||||
|
.filter(v -> Boolean.TRUE.equals(v.getLatest()))
|
||||||
|
.findFirst()
|
||||||
|
.map(AgentPublishVersionDto::getVersion)
|
||||||
|
.orElse(null);
|
||||||
|
if (latest != null) {
|
||||||
|
return incrementVersion(latest);
|
||||||
|
}
|
||||||
|
// 没有 latest 标记,取最后一个版本
|
||||||
|
String last = existingVersions.get(existingVersions.size() - 1).getVersion();
|
||||||
|
if (last != null) {
|
||||||
|
return incrementVersion(last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "1.0.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存版本记录到 agent_config:将所有旧版本 latest=false,追加新版本 latest=true
|
||||||
|
* @return 最新的完整版本列表
|
||||||
|
*/
|
||||||
|
private List<AgentPublishVersionDto> saveVersionToAgentConfig(Long agentId, List<AgentPublishVersionDto> existingVersions,
|
||||||
|
String version, String gitCommit, List<AgentPublishVersionDto.PackageArtifact> packages) {
|
||||||
|
try {
|
||||||
|
List<AgentPublishVersionDto> updatedVersions = new ArrayList<>();
|
||||||
|
if (CollectionUtils.isNotEmpty(existingVersions)) {
|
||||||
|
// 所有旧版本标记为 latest=false
|
||||||
|
existingVersions.forEach(v -> v.setLatest(false));
|
||||||
|
updatedVersions.addAll(existingVersions);
|
||||||
|
}
|
||||||
|
// 追加新版本
|
||||||
|
updatedVersions.add(AgentPublishVersionDto.builder()
|
||||||
|
.version(version)
|
||||||
|
.gitCommit(gitCommit)
|
||||||
|
.latest(true)
|
||||||
|
.packages(packages)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
AgentConfig updateConfig = new AgentConfig();
|
||||||
|
updateConfig.setId(agentId);
|
||||||
|
updateConfig.setPublishVersion(updatedVersions);
|
||||||
|
agentDomainService.update(updateConfig);
|
||||||
|
return updatedVersions;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[packageAgent] 保存版本记录到agent_config失败, agentId={}, version={}", agentId, version, e);
|
||||||
|
throw BizException.of(ErrorCodeEnum.ERROR_REQUEST, BizExceptionCodeEnum.agentPackageFailed, "Failed to save version to agent config");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 十进制递增版本号:x.y.z 每位 0-9,满十进一
|
||||||
|
* 1.0.9 → 1.1.0, 1.9.9 → 2.0.0
|
||||||
|
*/
|
||||||
|
private String incrementVersion(String version) {
|
||||||
|
try {
|
||||||
|
String[] parts = version.split("\\.");
|
||||||
|
if (parts.length == 3) {
|
||||||
|
int major = Integer.parseInt(parts[0]);
|
||||||
|
int minor = Integer.parseInt(parts[1]);
|
||||||
|
int patch = Integer.parseInt(parts[2]) + 1;
|
||||||
|
if (patch >= 10) {
|
||||||
|
patch = 0;
|
||||||
|
minor++;
|
||||||
|
}
|
||||||
|
if (minor >= 10) {
|
||||||
|
minor = 0;
|
||||||
|
major++;
|
||||||
|
}
|
||||||
|
return major + "." + minor + "." + patch;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
}
|
||||||
|
return "1.0.0";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建动态增加技能的锁标志文件
|
* 构建动态增加技能的锁标志文件
|
||||||
* 写入技能文件夹根目录下,用于标识该技能为动态增加
|
* 写入技能文件夹根目录下,用于标识该技能为动态增加
|
||||||
@@ -219,9 +878,47 @@ public class AgentWorkspaceApplicationServiceImpl implements AgentWorkspaceAppli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/**
|
||||||
// ------------------ 以下是private方法 -----------------------
|
* 构建技能模板 zip:从 skill-template.json 读取模板文件列表,打包成 zip
|
||||||
//
|
*/
|
||||||
|
private MultipartFile buildSkillTemplateZip() {
|
||||||
|
SkillConfigDto skillConfigDto = skillApplicationService.getSkillTemplate();
|
||||||
|
List<SkillFileDto> files = skillConfigDto.getFiles();
|
||||||
|
if (CollectionUtils.isEmpty(files)) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.agentSkillTemplateReadFailed,
|
||||||
|
"skill template has no files");
|
||||||
|
}
|
||||||
|
return buildSkillFilesZip(files, "skill-template.zip");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 SkillFileDto 列表打包成 zip 文件
|
||||||
|
*/
|
||||||
|
private MultipartFile buildSkillFilesZip(List<SkillFileDto> files, String zipFileName) {
|
||||||
|
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
ZipOutputStream zos = new ZipOutputStream(baos, StandardCharsets.UTF_8)) {
|
||||||
|
for (SkillFileDto file : files) {
|
||||||
|
if (file == null || StringUtils.isBlank(file.getName())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (Boolean.TRUE.equals(file.getIsDir())) {
|
||||||
|
String dirPath = file.getName().endsWith("/") ? file.getName() : file.getName() + "/";
|
||||||
|
zos.putNextEntry(new ZipEntry(dirPath));
|
||||||
|
zos.closeEntry();
|
||||||
|
} else {
|
||||||
|
zos.putNextEntry(new ZipEntry(file.getName()));
|
||||||
|
if (file.getContents() != null) {
|
||||||
|
zos.write(file.getContents().getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
zos.closeEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zos.finish();
|
||||||
|
return new InMemoryMultipartFile("file", zipFileName, "application/zip", baos.toByteArray());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.agentSkillZipPackFailed, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将skills和subagents打包成 zip
|
* 将skills和subagents打包成 zip
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
package com.xspaceagi.agent.core.application.service;
|
package com.xspaceagi.agent.core.application.service;
|
||||||
|
|
||||||
import com.xspaceagi.agent.core.adapter.application.ComponentApplicationService;
|
import com.xspaceagi.agent.core.adapter.application.*;
|
||||||
import com.xspaceagi.agent.core.adapter.application.ModelApplicationService;
|
|
||||||
import com.xspaceagi.agent.core.adapter.application.PluginApplicationService;
|
|
||||||
import com.xspaceagi.agent.core.adapter.application.WorkflowApplicationService;
|
|
||||||
import com.xspaceagi.agent.core.adapter.dto.ComponentDto;
|
import com.xspaceagi.agent.core.adapter.dto.ComponentDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.CreatorDto;
|
import com.xspaceagi.agent.core.adapter.dto.CreatorDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.ModelConfigDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.ModelConfigDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.plugin.PluginDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.plugin.PluginDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.workflow.WorkflowConfigDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.workflow.WorkflowConfigDto;
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
||||||
|
import com.xspaceagi.agent.core.adapter.repository.entity.ResourceGroupRelation;
|
||||||
import com.xspaceagi.agent.core.spec.enums.ComponentTypeEnum;
|
import com.xspaceagi.agent.core.spec.enums.ComponentTypeEnum;
|
||||||
import com.xspaceagi.compose.sdk.service.IComposeDbTableRpcService;
|
import com.xspaceagi.compose.sdk.service.IComposeDbTableRpcService;
|
||||||
import com.xspaceagi.compose.sdk.vo.define.TableDefineVo;
|
import com.xspaceagi.compose.sdk.vo.define.TableDefineVo;
|
||||||
@@ -47,92 +46,119 @@ public class ComponentApplicationServiceImpl implements ComponentApplicationServ
|
|||||||
@Resource
|
@Resource
|
||||||
private UserApplicationService userApplicationService;
|
private UserApplicationService userApplicationService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ResourceGroupApplicationService resourceGroupApplicationService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ComponentDto> getComponentListBySpaceId(Long spaceId) {
|
public List<ComponentDto> getComponentListBySpaceId(Long spaceId, Long groupId, List<Published.TargetType> types) {
|
||||||
List<ComponentDto> componentDtos = new java.util.ArrayList<>();
|
List<ComponentDto> componentDtos = new java.util.ArrayList<>();
|
||||||
|
if (types == null || types.contains(Published.TargetType.Workflow)) {
|
||||||
|
// 查询工作流配置
|
||||||
|
List<WorkflowConfigDto> workflowConfigDtos = workflowApplicationService.queryListBySpaceId(spaceId);
|
||||||
|
workflowConfigDtos.forEach(workflowConfigDto -> {
|
||||||
|
ComponentDto componentDto = new ComponentDto();
|
||||||
|
BeanUtils.copyProperties(workflowConfigDto, componentDto);
|
||||||
|
componentDto.setType(ComponentTypeEnum.Workflow);
|
||||||
|
componentDtos.add(componentDto);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 查询工作流配置
|
if (types == null || types.contains(Published.TargetType.Model)) {
|
||||||
List<WorkflowConfigDto> workflowConfigDtos = workflowApplicationService.queryListBySpaceId(spaceId);
|
// 查询模型配置
|
||||||
workflowConfigDtos.forEach(workflowConfigDto -> {
|
List<ModelConfigDto> modelConfigDtos = modelApplicationService.queryModelConfigLisBySpaceId(spaceId);
|
||||||
ComponentDto componentDto = new ComponentDto();
|
modelConfigDtos.forEach(modelConfigDto -> {
|
||||||
BeanUtils.copyProperties(workflowConfigDto, componentDto);
|
ComponentDto componentDto = new ComponentDto();
|
||||||
componentDto.setType(ComponentTypeEnum.Workflow);
|
BeanUtils.copyProperties(modelConfigDto, componentDto);
|
||||||
componentDtos.add(componentDto);
|
componentDto.setName(modelConfigDto.getName());
|
||||||
});
|
componentDto.setType(ComponentTypeEnum.Model);
|
||||||
|
componentDtos.add(componentDto);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 查询模型配置
|
if (types == null || types.contains(Published.TargetType.Plugin)) {
|
||||||
List<ModelConfigDto> modelConfigDtos = modelApplicationService.queryModelConfigLisBySpaceId(spaceId);
|
List<PluginDto> pluginDtos = pluginApplicationService.queryListBySpaceId(spaceId);
|
||||||
modelConfigDtos.forEach(modelConfigDto -> {
|
pluginDtos.forEach(pluginDto -> {
|
||||||
ComponentDto componentDto = new ComponentDto();
|
ComponentDto componentDto = new ComponentDto();
|
||||||
BeanUtils.copyProperties(modelConfigDto, componentDto);
|
BeanUtils.copyProperties(pluginDto, componentDto);
|
||||||
componentDto.setName(modelConfigDto.getName());
|
componentDto.setType(ComponentTypeEnum.Plugin);
|
||||||
componentDto.setType(ComponentTypeEnum.Model);
|
componentDto.setExt(pluginDto.getType());
|
||||||
componentDtos.add(componentDto);
|
componentDto.setDevAgentConversationId(pluginDto.getDevAgentConversationId());
|
||||||
});
|
componentDtos.add(componentDto);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
List<PluginDto> pluginDtos = pluginApplicationService.queryListBySpaceId(spaceId);
|
if (types == null || types.contains(Published.TargetType.Knowledge)) {
|
||||||
pluginDtos.forEach(pluginDto -> {
|
List<KnowledgeConfigModel> knowledgeConfigModels = iKnowledgeConfigApplicationService.queryListBySpaceId(spaceId);
|
||||||
ComponentDto componentDto = new ComponentDto();
|
//给知识库补充用户信息
|
||||||
BeanUtils.copyProperties(pluginDto, componentDto);
|
List<UserDto> userDtoList = userApplicationService.queryUserListByIds(knowledgeConfigModels.stream().map(KnowledgeConfigModel::getCreatorId).distinct().collect(Collectors.toList()));
|
||||||
componentDto.setType(ComponentTypeEnum.Plugin);
|
//userDtoList转map
|
||||||
componentDto.setExt(pluginDto.getType());
|
Map<Long, UserDto> userDtoMap = userDtoList.stream().collect(Collectors.toMap(UserDto::getId, userDto -> userDto));
|
||||||
componentDtos.add(componentDto);
|
knowledgeConfigModels.forEach(knowledgeConfigModel -> {
|
||||||
});
|
ComponentDto componentDto = new ComponentDto();
|
||||||
|
componentDto.setName(knowledgeConfigModel.getName());
|
||||||
|
componentDto.setId(knowledgeConfigModel.getId());
|
||||||
|
componentDto.setSpaceId(knowledgeConfigModel.getSpaceId());
|
||||||
|
//LocalDateTime转Date
|
||||||
|
componentDto.setCreated(Date.from(knowledgeConfigModel.getCreated().atZone(ZoneId.systemDefault()).toInstant()));
|
||||||
|
componentDto.setModified(Date.from(knowledgeConfigModel.getModified().atZone(ZoneId.systemDefault()).toInstant()));
|
||||||
|
componentDto.setDescription(knowledgeConfigModel.getDescription());
|
||||||
|
componentDto.setType(ComponentTypeEnum.Knowledge);
|
||||||
|
componentDto.setExt(knowledgeConfigModel.getDataType());
|
||||||
|
componentDto.setIcon(knowledgeConfigModel.getIcon());
|
||||||
|
componentDto.setCreatorId(knowledgeConfigModel.getCreatorId());
|
||||||
|
UserDto userDto = userDtoMap.get(knowledgeConfigModel.getCreatorId());
|
||||||
|
if (userDto != null) {
|
||||||
|
componentDto.setCreator(new CreatorDto(userDto.getId(), userDto.getUserName(), userDto.getNickName(), userDto.getAvatar()));
|
||||||
|
}
|
||||||
|
componentDtos.add(componentDto);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
List<KnowledgeConfigModel> knowledgeConfigModels = iKnowledgeConfigApplicationService.queryListBySpaceId(spaceId);
|
if (types == null || types.contains(Published.TargetType.Table)) {
|
||||||
//给知识库补充用户信息
|
//数据表
|
||||||
List<UserDto> userDtoList = userApplicationService.queryUserListByIds(knowledgeConfigModels.stream().map(KnowledgeConfigModel::getCreatorId).distinct().collect(Collectors.toList()));
|
List<TableDefineVo> tableDefineVoDorisDataPage = iComposeDbTableRpcService.queryListBySpaceId(spaceId);
|
||||||
//userDtoList转map
|
//给知识库补充用户信息
|
||||||
Map<Long, UserDto> userDtoMap = userDtoList.stream().collect(Collectors.toMap(UserDto::getId, userDto -> userDto));
|
List<UserDto> tableUserDtoList = userApplicationService.queryUserListByIds(tableDefineVoDorisDataPage.stream()
|
||||||
knowledgeConfigModels.forEach(knowledgeConfigModel -> {
|
.map(TableDefineVo::getCreatorId)
|
||||||
ComponentDto componentDto = new ComponentDto();
|
.distinct()
|
||||||
componentDto.setName(knowledgeConfigModel.getName());
|
.toList());
|
||||||
componentDto.setId(knowledgeConfigModel.getId());
|
Map<Long, UserDto> tableUserDtoMap = tableUserDtoList.stream().collect(Collectors.toMap(UserDto::getId, userDto -> userDto));
|
||||||
componentDto.setSpaceId(knowledgeConfigModel.getSpaceId());
|
|
||||||
//LocalDateTime转Date
|
|
||||||
componentDto.setCreated(Date.from(knowledgeConfigModel.getCreated().atZone(ZoneId.systemDefault()).toInstant()));
|
|
||||||
componentDto.setModified(Date.from(knowledgeConfigModel.getModified().atZone(ZoneId.systemDefault()).toInstant()));
|
|
||||||
componentDto.setDescription(knowledgeConfigModel.getDescription());
|
|
||||||
componentDto.setType(ComponentTypeEnum.Knowledge);
|
|
||||||
componentDto.setExt(knowledgeConfigModel.getDataType());
|
|
||||||
componentDto.setIcon(knowledgeConfigModel.getIcon());
|
|
||||||
componentDto.setCreatorId(knowledgeConfigModel.getCreatorId());
|
|
||||||
UserDto userDto = userDtoMap.get(knowledgeConfigModel.getCreatorId());
|
|
||||||
if (userDto != null) {
|
|
||||||
componentDto.setCreator(new CreatorDto(userDto.getId(), userDto.getUserName(), userDto.getNickName(), userDto.getAvatar()));
|
|
||||||
}
|
|
||||||
componentDtos.add(componentDto);
|
|
||||||
});
|
|
||||||
|
|
||||||
//数据表
|
tableDefineVoDorisDataPage.forEach(tableDefineVo -> {
|
||||||
List<TableDefineVo> tableDefineVoDorisDataPage = iComposeDbTableRpcService.queryListBySpaceId(spaceId);
|
ComponentDto componentDto = new ComponentDto();
|
||||||
//给知识库补充用户信息
|
componentDto.setName(tableDefineVo.getTableName());
|
||||||
List<UserDto> tableUserDtoList = userApplicationService.queryUserListByIds(tableDefineVoDorisDataPage.stream()
|
componentDto.setDescription(tableDefineVo.getTableDescription());
|
||||||
.map(TableDefineVo::getCreatorId)
|
componentDto.setIcon(tableDefineVo.getIcon());
|
||||||
.distinct()
|
componentDto.setId(tableDefineVo.getId());
|
||||||
.toList());
|
componentDto.setSpaceId(tableDefineVo.getSpaceId());
|
||||||
Map<Long, UserDto> tableUserDtoMap = tableUserDtoList.stream().collect(Collectors.toMap(UserDto::getId, userDto -> userDto));
|
componentDto.setCreated(Date.from(tableDefineVo.getCreated().atZone(ZoneId.systemDefault()).toInstant()));
|
||||||
|
componentDto.setModified(Date.from(tableDefineVo.getModified().atZone(ZoneId.systemDefault()).toInstant()));
|
||||||
tableDefineVoDorisDataPage.forEach(tableDefineVo -> {
|
componentDto.setType(ComponentTypeEnum.Table);
|
||||||
ComponentDto componentDto = new ComponentDto();
|
componentDto.setExt(tableDefineVo.getDorisDatabase() + "." + tableDefineVo.getDorisTable());
|
||||||
componentDto.setName(tableDefineVo.getTableName());
|
UserDto userDto = tableUserDtoMap.get(tableDefineVo.getCreatorId());
|
||||||
componentDto.setDescription(tableDefineVo.getTableDescription());
|
if (userDto != null) {
|
||||||
componentDto.setIcon(tableDefineVo.getIcon());
|
componentDto.setCreator(new CreatorDto(userDto.getId(), userDto.getUserName(), userDto.getNickName(), userDto.getAvatar()));
|
||||||
componentDto.setId(tableDefineVo.getId());
|
}
|
||||||
componentDto.setSpaceId(tableDefineVo.getSpaceId());
|
componentDto.setCreatorId(tableDefineVo.getCreatorId());
|
||||||
componentDto.setCreated(Date.from(tableDefineVo.getCreated().atZone(ZoneId.systemDefault()).toInstant()));
|
componentDtos.add(componentDto);
|
||||||
componentDto.setModified(Date.from(tableDefineVo.getModified().atZone(ZoneId.systemDefault()).toInstant()));
|
});
|
||||||
componentDto.setType(ComponentTypeEnum.Table);
|
}
|
||||||
componentDto.setExt(tableDefineVo.getDorisDatabase() + "." + tableDefineVo.getDorisTable());
|
|
||||||
UserDto userDto = tableUserDtoMap.get(tableDefineVo.getCreatorId());
|
|
||||||
if (userDto != null) {
|
|
||||||
componentDto.setCreator(new CreatorDto(userDto.getId(), userDto.getUserName(), userDto.getNickName(), userDto.getAvatar()));
|
|
||||||
}
|
|
||||||
componentDto.setCreatorId(tableDefineVo.getCreatorId());
|
|
||||||
componentDtos.add(componentDto);
|
|
||||||
});
|
|
||||||
//componentDtos按照编辑时间从大到小排序
|
//componentDtos按照编辑时间从大到小排序
|
||||||
componentDtos.sort((o1, o2) -> o2.getModified().compareTo(o1.getModified()));
|
componentDtos.sort((o1, o2) -> o2.getModified().compareTo(o1.getModified()));
|
||||||
|
|
||||||
|
if (groupId != null) {
|
||||||
|
Map<String, ResourceGroupRelation> relationMap = resourceGroupApplicationService.queryGroupRelations(groupId).stream()
|
||||||
|
.collect(Collectors.toMap(resourceGroupRelation -> resourceGroupRelation.getTargetType() + "-" + resourceGroupRelation.getTargetId(),
|
||||||
|
resourceGroupRelation -> resourceGroupRelation, (a, b) -> a));
|
||||||
|
componentDtos.removeIf(componentDto -> !relationMap.containsKey(componentDto.getType().name() + "-" + componentDto.getId()));
|
||||||
|
componentDtos.forEach(componentDto -> componentDto.setGroupId(groupId));
|
||||||
|
} else {
|
||||||
|
List<Map<String, Long>> list = componentDtos.stream().map(componentDto -> Map.of(componentDto.getType().name(), componentDto.getId())).collect(Collectors.toList());
|
||||||
|
Map<String, ResourceGroupRelation> relationMap = resourceGroupApplicationService.queryGroupRelations(list).stream()
|
||||||
|
.collect(Collectors.toMap(resourceGroupRelation -> resourceGroupRelation.getTargetType() + "-" + resourceGroupRelation.getTargetId(),
|
||||||
|
resourceGroupRelation -> resourceGroupRelation, (a, b) -> a));
|
||||||
|
componentDtos.forEach(componentDto -> componentDto.setGroupId(relationMap.get(componentDto.getType().name() + "-" + componentDto.getId()) != null ? relationMap.get(componentDto.getType().name() + "-" + componentDto.getId()).getGroupId() : null));
|
||||||
|
}
|
||||||
return componentDtos;
|
return componentDtos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.xspaceagi.agent.core.infra.rpc.dto.SandboxServerConfig;
|
|||||||
import com.xspaceagi.agent.core.spec.utils.FileTypeUtils;
|
import com.xspaceagi.agent.core.spec.utils.FileTypeUtils;
|
||||||
import com.xspaceagi.system.application.dto.UserDto;
|
import com.xspaceagi.system.application.dto.UserDto;
|
||||||
import com.xspaceagi.system.application.service.AuthService;
|
import com.xspaceagi.system.application.service.AuthService;
|
||||||
|
import com.xspaceagi.system.sdk.permission.SpacePermissionService;
|
||||||
import com.xspaceagi.system.sdk.service.dto.UserShareDto;
|
import com.xspaceagi.system.sdk.service.dto.UserShareDto;
|
||||||
import com.xspaceagi.system.spec.common.RequestContext;
|
import com.xspaceagi.system.spec.common.RequestContext;
|
||||||
import com.xspaceagi.system.spec.common.UserContext;
|
import com.xspaceagi.system.spec.common.UserContext;
|
||||||
@@ -59,9 +60,11 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
private UserShareRpcService userShareRpcService;
|
private UserShareRpcService userShareRpcService;
|
||||||
@Resource
|
@Resource
|
||||||
private AuthService authService;
|
private AuthService authService;
|
||||||
|
@Resource
|
||||||
|
private SpacePermissionService spacePermissionService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> getFileList(Long userId, Long cId, String proxyPath, UserContext userContext) {
|
public Map<String, Object> getFileList(Long userId, Long cId, String proxyPath, UserContext userContext, String customTargetDir) {
|
||||||
if (userId == null || userId <= 0) {
|
if (userId == null || userId <= 0) {
|
||||||
log.error("[Web] Invalid userId, userId={}", userId);
|
log.error("[Web] Invalid userId, userId={}", userId);
|
||||||
return buildError("userId is invalid");
|
return buildError("userId is invalid");
|
||||||
@@ -71,7 +74,7 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
return buildError("cId is invalid");
|
return buildError("cId is invalid");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return computerFileDomainService.getFileList(userId, cId, proxyPath, userContext);
|
return computerFileDomainService.getFileList(userId, cId, proxyPath, userContext, customTargetDir);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("[Web] Exception querying file list, userId={}, cId={}", userId, cId, e);
|
log.error("[Web] Exception querying file list, userId={}, cId={}", userId, cId, e);
|
||||||
return buildError("Failed to query file list");
|
return buildError("Failed to query file list");
|
||||||
@@ -79,7 +82,26 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> filesUpdate(Long userId, Long cId, List<ComputerFileInfo> files, UserContext userContext) {
|
public Map<String, Object> getLogs(Long userId, Long cId, int tailLines) {
|
||||||
|
if (userId == null || userId <= 0) {
|
||||||
|
log.error("[Web] Invalid userId, userId={}", userId);
|
||||||
|
return buildError("userId is invalid");
|
||||||
|
}
|
||||||
|
if (cId == null || cId <= 0) {
|
||||||
|
log.error("[Web] Invalid cId, cId={}", cId);
|
||||||
|
return buildError("cId is invalid");
|
||||||
|
}
|
||||||
|
int safeTailLines = Math.max(1, tailLines);
|
||||||
|
try {
|
||||||
|
return computerFileDomainService.getLogs(userId, cId, safeTailLines, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[Web] Exception querying logs, userId={}, cId={}", userId, cId, e);
|
||||||
|
return buildError("Failed to query logs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> filesUpdate(Long userId, Long cId, List<ComputerFileInfo> files, UserContext userContext, String customTargetDir) {
|
||||||
if (userId == null || userId <= 0) {
|
if (userId == null || userId <= 0) {
|
||||||
log.error("[Web] Invalid userId, userId={}", userId);
|
log.error("[Web] Invalid userId, userId={}", userId);
|
||||||
return buildError("userId is invalid");
|
return buildError("userId is invalid");
|
||||||
@@ -93,7 +115,7 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
return buildError("files is invalid");
|
return buildError("files is invalid");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return computerFileDomainService.filesUpdate(userId, cId, files, userContext);
|
return computerFileDomainService.filesUpdate(userId, cId, files, userContext, customTargetDir);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("[Web] Exception updating user file list, userId={}, cId={}", userId, cId, e);
|
log.error("[Web] Exception updating user file list, userId={}, cId={}", userId, cId, e);
|
||||||
return buildError("Failed to update user file list, please check if filename is duplicated");
|
return buildError("Failed to update user file list, please check if filename is duplicated");
|
||||||
@@ -101,7 +123,7 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> uploadFile(Long userId, Long cId, String filePath, MultipartFile file, UserContext userContext) {
|
public Map<String, Object> uploadFile(Long userId, Long cId, String filePath, MultipartFile file, UserContext userContext, String customTargetDir) {
|
||||||
if (userId == null || userId <= 0) {
|
if (userId == null || userId <= 0) {
|
||||||
log.error("[Web] Invalid userId, userId={}", userId);
|
log.error("[Web] Invalid userId, userId={}", userId);
|
||||||
return buildError("userId is invalid");
|
return buildError("userId is invalid");
|
||||||
@@ -119,7 +141,7 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
return buildError("file is invalid");
|
return buildError("file is invalid");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return computerFileDomainService.uploadFile(userId, cId, filePath, file, userContext);
|
return computerFileDomainService.uploadFile(userId, cId, filePath, file, userContext, customTargetDir);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("[Web] Exception uploading user file, userId={}, cId={}, filePath={}", userId, cId, filePath, e);
|
log.error("[Web] Exception uploading user file, userId={}, cId={}, filePath={}", userId, cId, filePath, e);
|
||||||
return buildError("Failed to upload user file");
|
return buildError("Failed to upload user file");
|
||||||
@@ -127,7 +149,7 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> uploadFiles(Long userId, Long cId, List<String> filePaths, List<MultipartFile> files, UserContext userContext) {
|
public Map<String, Object> uploadFiles(Long userId, Long cId, List<String> filePaths, List<MultipartFile> files, UserContext userContext, String customTargetDir) {
|
||||||
if (userId == null || userId <= 0) {
|
if (userId == null || userId <= 0) {
|
||||||
log.error("[Web] Invalid userId, userId={}", userId);
|
log.error("[Web] Invalid userId, userId={}", userId);
|
||||||
return buildError("userId is invalid");
|
return buildError("userId is invalid");
|
||||||
@@ -149,7 +171,7 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
return buildError("filePaths and files count mismatch");
|
return buildError("filePaths and files count mismatch");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return computerFileDomainService.uploadFiles(userId, cId, filePaths, files, userContext);
|
return computerFileDomainService.uploadFiles(userId, cId, filePaths, files, userContext, customTargetDir);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("[Web] Exception batch uploading user files, userId={}, cId={}", userId, cId, e);
|
log.error("[Web] Exception batch uploading user files, userId={}, cId={}", userId, cId, e);
|
||||||
return buildError("Failed to batch upload user files");
|
return buildError("Failed to batch upload user files");
|
||||||
@@ -157,7 +179,34 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<StreamingResponseBody> downloadAllFiles(Long userId, Long cId, UserContext userContext) {
|
public Map<String, Object> importProject(Long userId, Long cId, MultipartFile file, UserContext userContext, String customTargetDir) {
|
||||||
|
if (userId == null || userId <= 0) {
|
||||||
|
log.error("[Web] Invalid userId, userId={}", userId);
|
||||||
|
return buildError("userId is invalid");
|
||||||
|
}
|
||||||
|
if (cId == null || cId <= 0) {
|
||||||
|
log.error("[Web] Invalid cId, cId={}", cId);
|
||||||
|
return buildError("cId is invalid");
|
||||||
|
}
|
||||||
|
if (file == null || file.isEmpty()) {
|
||||||
|
log.error("[Web] file is invalid, file is empty");
|
||||||
|
return buildError("file is invalid");
|
||||||
|
}
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
if (originalFilename == null || !originalFilename.toLowerCase().endsWith(".zip")) {
|
||||||
|
log.error("[Web] file is invalid, only zip is supported, fileName={}", originalFilename);
|
||||||
|
return buildError("Only zip files are supported");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return computerFileDomainService.importProject(userId, cId, file, userContext, customTargetDir);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[Web] Exception importing project, userId={}, cId={}, fileName={}", userId, cId, originalFilename, e);
|
||||||
|
return buildError("Failed to import project");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<StreamingResponseBody> downloadAllFiles(Long userId, Long cId, UserContext userContext, String customTargetDir) {
|
||||||
if (userId == null || userId <= 0) {
|
if (userId == null || userId <= 0) {
|
||||||
log.error("[Web] Invalid userId, userId={}", userId);
|
log.error("[Web] Invalid userId, userId={}", userId);
|
||||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
|
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
|
||||||
@@ -171,7 +220,7 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
log.info("[Web] Download all files, logId={}, userId={}, cId={}", logId, userId, cId);
|
log.info("[Web] Download all files, logId={}, userId={}, cId={}", logId, userId, cId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Flux<DataBuffer> fileFlux = computerFileDomainService.downloadAllFiles(userId, cId, logId, userContext);
|
Flux<DataBuffer> fileFlux = computerFileDomainService.downloadAllFiles(userId, cId, logId, userContext, customTargetDir);
|
||||||
|
|
||||||
// Check the first signal before starting to write to detect errors early
|
// Check the first signal before starting to write to detect errors early
|
||||||
// Use share() to share Flux, then use materialize() to check the first signal
|
// Use share() to share Flux, then use materialize() to check the first signal
|
||||||
@@ -273,7 +322,7 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<StreamingResponseBody> getStaticFile(Long cId, HttpServletRequest request) {
|
public ResponseEntity<StreamingResponseBody> getStaticFile(Long cId, HttpServletRequest request, String customTargetDir) {
|
||||||
ConversationDto currentConversation = getConversation(cId);
|
ConversationDto currentConversation = getConversation(cId);
|
||||||
AuthResult authResult = staticFileAuth(currentConversation, cId, request);
|
AuthResult authResult = staticFileAuth(currentConversation, cId, request);
|
||||||
if (authResult.getRedirectUrl() != null) {
|
if (authResult.getRedirectUrl() != null) {
|
||||||
@@ -321,7 +370,7 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
log.info("[Web] Client range request, logId={}, range={}", logId, rangeHeader);
|
log.info("[Web] Client range request, logId={}, range={}", logId, rangeHeader);
|
||||||
}
|
}
|
||||||
ResponseEntity<Flux<DataBuffer>> downstreamResponse = computerFileDomainService.getStaticFileResponse(
|
ResponseEntity<Flux<DataBuffer>> downstreamResponse = computerFileDomainService.getStaticFileResponse(
|
||||||
cId, targetPrefix, finalRelativePath, logId, rangeHeader
|
cId, targetPrefix, finalRelativePath, logId, rangeHeader, customTargetDir
|
||||||
);
|
);
|
||||||
if (downstreamResponse == null || downstreamResponse.getBody() == null) {
|
if (downstreamResponse == null || downstreamResponse.getBody() == null) {
|
||||||
log.error("[Web] Downstream static file response is empty, logId={}", logId);
|
log.error("[Web] Downstream static file response is empty, logId={}", logId);
|
||||||
@@ -545,8 +594,14 @@ public class ComputerFileApplicationServiceImpl implements IComputerFileApplicat
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!currentUserId.equals(conversationUserId)) {
|
if (!currentUserId.equals(conversationUserId)) {
|
||||||
throw BizException.of(ErrorCodeEnum.PERMISSION_DENIED, BizExceptionCodeEnum.permissionDenied);
|
Long devSpaceId = currentConversation.getDevSpaceId();
|
||||||
|
if (devSpaceId != null) {
|
||||||
|
spacePermissionService.checkSpaceUserPermission(devSpaceId, RequestContext.get().getUserId());
|
||||||
|
} else {
|
||||||
|
throw BizException.of(ErrorCodeEnum.PERMISSION_DENIED, BizExceptionCodeEnum.permissionDenied);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AuthResult(conversationUserId, null, null, null);
|
return new AuthResult(conversationUserId, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,10 +8,12 @@ import com.xspaceagi.agent.core.adapter.application.ModelApplicationService;
|
|||||||
import com.xspaceagi.agent.core.adapter.dto.CodeCheckResultDto;
|
import com.xspaceagi.agent.core.adapter.dto.CodeCheckResultDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.CreatorDto;
|
import com.xspaceagi.agent.core.adapter.dto.CreatorDto;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.ModelQueryDto;
|
import com.xspaceagi.agent.core.adapter.dto.ModelQueryDto;
|
||||||
|
import com.xspaceagi.agent.core.adapter.dto.SortUpdateDTO;
|
||||||
import com.xspaceagi.agent.core.adapter.dto.config.ModelConfigDto;
|
import com.xspaceagi.agent.core.adapter.dto.config.ModelConfigDto;
|
||||||
import com.xspaceagi.agent.core.adapter.repository.ModelConfigRepository;
|
import com.xspaceagi.agent.core.adapter.repository.ModelConfigRepository;
|
||||||
import com.xspaceagi.agent.core.adapter.repository.entity.ModelConfig;
|
import com.xspaceagi.agent.core.adapter.repository.entity.ModelConfig;
|
||||||
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
import com.xspaceagi.agent.core.adapter.repository.entity.Published;
|
||||||
|
import com.xspaceagi.agent.core.infra.component.model.FunctionToolCallback;
|
||||||
import com.xspaceagi.agent.core.infra.component.model.ModelClientFactory;
|
import com.xspaceagi.agent.core.infra.component.model.ModelClientFactory;
|
||||||
import com.xspaceagi.agent.core.infra.component.model.ModelInvoker;
|
import com.xspaceagi.agent.core.infra.component.model.ModelInvoker;
|
||||||
import com.xspaceagi.agent.core.infra.rpc.ResourcePricingRpcService;
|
import com.xspaceagi.agent.core.infra.rpc.ResourcePricingRpcService;
|
||||||
@@ -57,16 +59,15 @@ import org.springframework.ai.chat.model.Generation;
|
|||||||
import org.springframework.ai.chat.prompt.Prompt;
|
import org.springframework.ai.chat.prompt.Prompt;
|
||||||
import org.springframework.ai.converter.BeanOutputConverter;
|
import org.springframework.ai.converter.BeanOutputConverter;
|
||||||
import org.springframework.ai.embedding.EmbeddingModel;
|
import org.springframework.ai.embedding.EmbeddingModel;
|
||||||
|
import org.springframework.ai.tool.ToolCallback;
|
||||||
|
import org.springframework.ai.tool.metadata.DefaultToolMetadata;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.core.ParameterizedTypeReference;
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -240,7 +241,7 @@ public class ModelApplicationServiceImpl implements ModelApplicationService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ModelConfigDto> queryTenantModelConfigList(Integer accessControlStatus) {
|
public List<ModelConfigDto> queryTenantModelConfigList(Integer accessControlStatus) {
|
||||||
return queryModelConfigList(new LambdaQueryWrapper<ModelConfig>().eq(ModelConfig::getScope, ModelConfig.ModelScopeEnum.Tenant).eq(accessControlStatus != null, ModelConfig::getAccessControl, accessControlStatus).orderByDesc(ModelConfig::getId));
|
return queryModelConfigList(new LambdaQueryWrapper<ModelConfig>().eq(ModelConfig::getScope, ModelConfig.ModelScopeEnum.Tenant).eq(accessControlStatus != null, ModelConfig::getAccessControl, accessControlStatus).orderByAsc(ModelConfig::getSort).orderByDesc(ModelConfig::getCreated));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -360,6 +361,7 @@ public class ModelApplicationServiceImpl implements ModelApplicationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<ModelConfigDto> queryModelConfigList(LambdaQueryWrapper<ModelConfig> queryWrapper) {
|
private List<ModelConfigDto> queryModelConfigList(LambdaQueryWrapper<ModelConfig> queryWrapper) {
|
||||||
|
queryWrapper.orderByAsc(ModelConfig::getSort).orderByDesc(ModelConfig::getCreated);
|
||||||
List<ModelConfigDto> modelDtos = new ArrayList<>();
|
List<ModelConfigDto> modelDtos = new ArrayList<>();
|
||||||
modelRepository.list(queryWrapper).forEach(model1 -> modelDtos.add(convertToModelDto(model1)));
|
modelRepository.list(queryWrapper).forEach(model1 -> modelDtos.add(convertToModelDto(model1)));
|
||||||
// creatorIdList in modelDtos
|
// creatorIdList in modelDtos
|
||||||
@@ -454,38 +456,53 @@ public class ModelApplicationServiceImpl implements ModelApplicationService {
|
|||||||
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.agentModelJsonInvalid);
|
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.agentModelJsonInvalid);
|
||||||
}
|
}
|
||||||
modelConfig.setIsReasonModel(0);
|
modelConfig.setIsReasonModel(0);
|
||||||
ChatClient.StreamResponseSpec stream = modelClientFactory.createChatClient(modelConfig)
|
ToolCallback jsonOutputToolCallback = FunctionToolCallback
|
||||||
|
.builder("json_output", (input, context) -> JSON.toJSONString(input))
|
||||||
|
.description("Generate JSON based on the context. When this tool appears, it indicates that the user intends to invoke it to extract JSON content; please invoke it finally")
|
||||||
|
.inputSchema(jsonSchema)
|
||||||
|
.inputType(HashMap.class)
|
||||||
|
.toolMetadata(DefaultToolMetadata.builder().returnDirect(true).build())
|
||||||
|
.toolCallResultConverter((res, returnType) -> (res instanceof String) ? (String) res : JSON.toJSONString(res))
|
||||||
|
.build();
|
||||||
|
ChatClient.StreamResponseSpec stream = modelClientFactory.createChatClient(modelConfig, List.of(jsonOutputToolCallback))
|
||||||
.prompt(new Prompt(new SystemMessage(sysPrompt), new UserMessage(prompt))).stream();
|
.prompt(new Prompt(new SystemMessage(sysPrompt), new UserMessage(prompt))).stream();
|
||||||
StringBuilder responseStr = new StringBuilder();
|
StringBuilder responseStr = new StringBuilder();
|
||||||
Mono.create(sink -> stream.chatResponse().onErrorResume(throwable -> {
|
try {
|
||||||
log.warn("call error", throwable);
|
Mono.create(sink -> stream.chatResponse().onErrorResume(throwable -> {
|
||||||
if (throwable instanceof TimeoutException) {
|
log.warn("call error", throwable);
|
||||||
return Mono.error(new TimeoutException("Large model execution timeout"));
|
if (throwable instanceof TimeoutException) {
|
||||||
}
|
return Mono.error(new TimeoutException("Large model execution timeout"));
|
||||||
return Mono.error(throwable);
|
|
||||||
})
|
|
||||||
.doOnComplete(sink::success).doOnError(sink::error)
|
|
||||||
.subscribe(chatResponse -> {
|
|
||||||
Generation result = chatResponse.getResult();
|
|
||||||
if (result == null || result.getOutput() == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
AssistantMessage assistantMessage = result.getOutput();
|
|
||||||
if (assistantMessage != null && assistantMessage.getText() != null) {
|
|
||||||
responseStr.append(assistantMessage.getText());
|
|
||||||
}
|
|
||||||
if (assistantMessage != null && assistantMessage.getMetadata() != null) {
|
|
||||||
Object finishReason = assistantMessage.getMetadata().get("finishReason");
|
|
||||||
if (finishReason != null && finishReason.toString().equals("STOP")) {
|
|
||||||
sink.success();
|
|
||||||
}
|
}
|
||||||
}
|
return Mono.error(throwable);
|
||||||
}))
|
})
|
||||||
.block();
|
.doOnComplete(sink::success).doOnError(sink::error)
|
||||||
|
.subscribe(chatResponse -> {
|
||||||
|
Generation result = chatResponse.getResult();
|
||||||
|
if (result == null || result.getOutput() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AssistantMessage assistantMessage = result.getOutput();
|
||||||
|
if (assistantMessage != null && assistantMessage.getText() != null) {
|
||||||
|
responseStr.append(assistantMessage.getText());
|
||||||
|
}
|
||||||
|
if (assistantMessage != null && assistantMessage.getMetadata() != null) {
|
||||||
|
Object finishReason = assistantMessage.getMetadata().get("finishReason");
|
||||||
|
if (finishReason != null && finishReason.toString().equals("STOP")) {
|
||||||
|
sink.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.block();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Model call error", e);
|
||||||
|
return call(modelConfig, sysPrompt, responseStr.toString(), type, retry + 1);
|
||||||
|
}
|
||||||
String jsonText = ModelInvoker.getJSONText(responseStr.toString());
|
String jsonText = ModelInvoker.getJSONText(responseStr.toString());
|
||||||
if (!JSON.isValid(jsonText)) {
|
if (!JSON.isValid(jsonText)) {
|
||||||
|
log.warn("Model returned JSON format is incorrect, please check prompt\nOriginal content {}\nReturned content:{}", prompt, responseStr);
|
||||||
return call(modelConfig, sysPrompt, jsonText, type, retry + 1);
|
return call(modelConfig, sysPrompt, jsonText, type, retry + 1);
|
||||||
}
|
}
|
||||||
|
log.debug("Model call Original content {}, jsonText: {}", prompt, jsonText);
|
||||||
Object object = JSON.parseObject(jsonText, type.getType());
|
Object object = JSON.parseObject(jsonText, type.getType());
|
||||||
if (object == null) {
|
if (object == null) {
|
||||||
log.warn("Model returned JSON format is incorrect, please check prompt\nOriginal content {}\nReturned content:{}", prompt, responseStr);
|
log.warn("Model returned JSON format is incorrect, please check prompt\nOriginal content {}\nReturned content:{}", prompt, responseStr);
|
||||||
@@ -501,7 +518,7 @@ public class ModelApplicationServiceImpl implements ModelApplicationService {
|
|||||||
|
|
||||||
public String call(String userPrompt) {
|
public String call(String userPrompt) {
|
||||||
ModelConfigDto modelConfig = queryDefaultModelConfig();
|
ModelConfigDto modelConfig = queryDefaultModelConfig();
|
||||||
return modelClientFactory.createChatClient(modelConfig).prompt()
|
return modelClientFactory.createChatClient(modelConfig, List.of()).prompt()
|
||||||
.user(userPrompt)
|
.user(userPrompt)
|
||||||
.call().content();
|
.call().content();
|
||||||
}
|
}
|
||||||
@@ -596,7 +613,7 @@ public class ModelApplicationServiceImpl implements ModelApplicationService {
|
|||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
// Non-vector model, use chat interface for testing
|
// Non-vector model, use chat interface for testing
|
||||||
ChatClient chatClient = modelClientFactory.createChatClient(modelConfig);
|
ChatClient chatClient = modelClientFactory.createChatClient(modelConfig, List.of());
|
||||||
Flux<ChatResponse> chatResponseFlux = chatClient.prompt()
|
Flux<ChatResponse> chatResponseFlux = chatClient.prompt()
|
||||||
.user(testPrompt)
|
.user(testPrompt)
|
||||||
.stream().chatResponse();
|
.stream().chatResponse();
|
||||||
@@ -656,4 +673,15 @@ public class ModelApplicationServiceImpl implements ModelApplicationService {
|
|||||||
});
|
});
|
||||||
return modelConfigs;
|
return modelConfigs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateModelSort(List<SortUpdateDTO> updateDTOS) {
|
||||||
|
List<ModelConfig> modelConfigs = updateDTOS.stream().map(updateDTO -> {
|
||||||
|
ModelConfig model = new ModelConfig();
|
||||||
|
model.setId(updateDTO.getId());
|
||||||
|
model.setSort(updateDTO.getSort());
|
||||||
|
return model;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
modelRepository.updateBatchById(modelConfigs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ public class PluginApplicationServiceImpl implements PluginApplicationService {
|
|||||||
pluginConfig.setIcon(pluginUpdateDto.getIcon());
|
pluginConfig.setIcon(pluginUpdateDto.getIcon());
|
||||||
pluginConfig.setDescription(pluginUpdateDto.getDescription());
|
pluginConfig.setDescription(pluginUpdateDto.getDescription());
|
||||||
pluginConfig.setName(pluginUpdateDto.getName());
|
pluginConfig.setName(pluginUpdateDto.getName());
|
||||||
|
pluginConfig.setDevAgentConversationId(pluginUpdateDto.getDevAgentConversationId());
|
||||||
if (pluginUpdateDto.getConfig() != null) {
|
if (pluginUpdateDto.getConfig() != null) {
|
||||||
pluginConfig.setConfig(JSON.toJSONString(pluginUpdateDto.getConfig()));
|
pluginConfig.setConfig(JSON.toJSONString(pluginUpdateDto.getConfig()));
|
||||||
}
|
}
|
||||||
@@ -380,6 +381,7 @@ public class PluginApplicationServiceImpl implements PluginApplicationService {
|
|||||||
.enableSubscription(tenantConfigDto.getEnableSubscription() != null && tenantConfigDto.getEnableSubscription() == 1)
|
.enableSubscription(tenantConfigDto.getEnableSubscription() != null && tenantConfigDto.getEnableSubscription() == 1)
|
||||||
.billUserId(RequestContext.get().getUserId())
|
.billUserId(RequestContext.get().getUserId())
|
||||||
.devTest(pluginExecuteRequestDto.isTest())
|
.devTest(pluginExecuteRequestDto.isTest())
|
||||||
|
.apiKey(pluginExecuteRequestDto.getApiKey())
|
||||||
.traceTargets(Lists.newArrayList(TraceContext.TraceTarget.builder()
|
.traceTargets(Lists.newArrayList(TraceContext.TraceTarget.builder()
|
||||||
.targetType(TraceContext.TraceTargetType.Plugin)
|
.targetType(TraceContext.TraceTargetType.Plugin)
|
||||||
.name(pluginDto.getName())
|
.name(pluginDto.getName())
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user