Bläddra i källkod

Merge branch 'main' of https://git.shalu.com/Shalu/shalu-agent-workflow into feature-0123-Ai-workFlow

# Conflicts:
#	apps/web/package.json
lj1559651600@163.com 2 veckor sedan
förälder
incheckning
c66f574f61
43 ändrade filer med 3277 tillägg och 2484 borttagningar
  1. 1 0
      apps/web/package.json
  2. 3 0
      apps/web/src/assets/icons/efficiency.svg
  3. 4 0
      apps/web/src/assets/icons/growth.svg
  4. 6 0
      apps/web/src/assets/icons/legal.svg
  5. 4 0
      apps/web/src/assets/icons/lock.svg
  6. 6 0
      apps/web/src/assets/icons/service.svg
  7. 4 0
      apps/web/src/assets/icons/smartphone.svg
  8. 21 4
      apps/web/src/components/Sidebar/index.vue
  9. 4 4
      apps/web/src/components/TemplateModal/index.vue
  10. 14 1
      apps/web/src/router/index.ts
  11. 4 4
      apps/web/src/style.css
  12. 2 6
      apps/web/src/views/About.vue
  13. 631 709
      apps/web/src/views/Dashboard.vue
  14. 6 6
      apps/web/src/views/Docs.vue
  15. 9 0
      apps/web/src/views/Editor.vue
  16. 1 1
      apps/web/src/views/LogStream.vue
  17. 1 1
      apps/web/src/views/ModelLog.vue
  18. 5 6
      apps/web/src/views/QuickStart.vue
  19. 3 3
      apps/web/src/views/Statistics.vue
  20. 7 7
      apps/web/src/views/UserCenter.vue
  21. 341 0
      apps/web/src/views/WorkflowExecution.vue
  22. 541 0
      apps/web/src/views/WorkflowOrchestration.vue
  23. 11 1
      apps/web/vite.config.ts
  24. 2 2
      packages/api-client/index.ts
  25. 4 1
      packages/api-client/package.json
  26. 333 316
      packages/api-client/request.ts
  27. 990 0
      packages/api-service/agent.openapi.json
  28. 5 1
      packages/api-service/index.ts
  29. 4 4
      packages/api-service/openapi2ts.config.ts
  30. 153 0
      packages/api-service/servers/api/agent.ts
  31. 0 23
      packages/api-service/servers/api/audit.ts
  32. 0 84
      packages/api-service/servers/api/credential.ts
  33. 0 72
      packages/api-service/servers/api/execution.ts
  34. 2 18
      packages/api-service/servers/api/index.ts
  35. 0 123
      packages/api-service/servers/api/projects.ts
  36. 0 15
      packages/api-service/servers/api/sourceControl.ts
  37. 0 79
      packages/api-service/servers/api/tags.ts
  38. 61 637
      packages/api-service/servers/api/typings.d.ts
  39. 0 90
      packages/api-service/servers/api/user.ts
  40. 0 66
      packages/api-service/servers/api/variables.ts
  41. 0 190
      packages/api-service/servers/api/workflow.ts
  42. 8 0
      packages/workflow/src/components/elements/node-temp/HttpNode1.vue
  43. 86 10
      pnpm-lock.yaml

+ 1 - 0
apps/web/package.json

@@ -27,6 +27,7 @@
     "@repo/nodes": "workspace:*",
     "@repo/ui": "workspace:*",
     "@repo/workflow": "workspace:*",
+    "@repo/api-service": "workspace:*",
     "@types/lodash-es": "^4.17.12",
     "@vitejs/plugin-vue": "^6.0.1",
     "@vue/tsconfig": "^0.8.1",

+ 3 - 0
apps/web/src/assets/icons/efficiency.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+  <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2m-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
+</svg>

+ 4 - 0
apps/web/src/assets/icons/growth.svg

@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+  <circle cx="12" cy="12" r="10"/>
+  <path d="M12 6v6l4 2"/>
+</svg>

+ 6 - 0
apps/web/src/assets/icons/legal.svg

@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+  <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
+  <polyline points="14 2 14 8 20 8"/>
+  <line x1="12" y1="11" x2="12" y2="17"/>
+  <line x1="9" y1="14" x2="15" y2="14"/>
+</svg>

+ 4 - 0
apps/web/src/assets/icons/lock.svg

@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+  <rect width="18" height="11" x="3" y="11" rx="2" ry="2"/>
+  <path d="M7 11V7a5 5 0 0 1 10 0v4"/>
+</svg>

+ 6 - 0
apps/web/src/assets/icons/service.svg

@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+  <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
+  <circle cx="9" cy="7" r="4"/>
+  <path d="M23 21v-2a4 4 0 0 0-3-3.87"/>
+  <path d="M16 3.13a4 4 0 0 1 0 7.75"/>
+</svg>

+ 4 - 0
apps/web/src/assets/icons/smartphone.svg

@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+  <rect width="14" height="20" x="5" y="2" rx="2" ry="2"/>
+  <path d="M12 18h.01"/>
+</svg>

+ 21 - 4
apps/web/src/components/Sidebar/index.vue

@@ -19,7 +19,6 @@
 						<el-dropdown-menu>
 							<el-dropdown-item @click="createWorkflow">工作流程</el-dropdown-item>
 							<el-dropdown-item @click="createCertificate">凭证</el-dropdown-item>
-							<el-dropdown-item @click="createTable">数据表</el-dropdown-item>
 						</el-dropdown-menu>
 					</template>
 				</el-dropdown>
@@ -59,6 +58,22 @@
 				<span v-if="!collapsed" class="label">概览</span>
 			</el-menu-item>
 
+			<el-menu-item index="/orchestration">
+				<el-tooltip v-if="collapsed" content="流程设计" placement="right">
+					<span><SvgIcon name="workflow" /></span>
+				</el-tooltip>
+				<SvgIcon v-else name="workflow" />
+				<span v-if="!collapsed" class="label">流程设计</span>
+			</el-menu-item>
+
+			<el-menu-item index="/execution">
+				<el-tooltip v-if="collapsed" content="执行" placement="right">
+					<span><SvgIcon name="play" /></span>
+				</el-tooltip>
+				<SvgIcon v-else name="play" />
+				<span v-if="!collapsed" class="label">执行</span>
+			</el-menu-item>
+
 			<el-menu-item index="/chat">
 				<el-tooltip v-if="collapsed" content="聊天" placement="right">
 					<span><SvgIcon name="chatMessage" /></span>
@@ -141,6 +156,7 @@
 <script setup lang="ts">
 import { ref, computed, onMounted, onUnmounted } from 'vue'
 import { useRouter } from 'vue-router'
+import { ElMessage } from 'element-plus'
 import SearchDialog from '../SearchDialog/index.vue'
 import { v4 } from 'uuid'
 import TemplateModal from '../TemplateModal/index.vue'
@@ -166,9 +182,10 @@ const createWorkflow = () => {
 	router.push(`/workflow/${id}`)
 }
 
-const createCertificate = () => {}
-
-const createTable = () => {}
+const createCertificate = () => {
+	// TODO: 实现凭证创建功能
+	ElMessage.info('凭证功能开发中')
+}
 
 const handleTemplateClick = () => {
 	showTemplateModal.value = true

+ 4 - 4
apps/web/src/components/TemplateModal/index.vue

@@ -13,7 +13,7 @@
 							class="use-btn"
 							@click="selectTemplate(template)"
 						>
-							使用模板
+							查看模板
 						</el-button>
 					</div>
 				</el-col>
@@ -178,12 +178,12 @@ const selectTemplate = (template: Template) => {
 		margin-bottom: 24px;
 
 		&:hover {
-			border-color: #0076ff;
-			box-shadow: 0 4px 12px rgba(0, 118, 255, 0.15);
+			border-color: var(--el-color-primary);
+			box-shadow: 0 4px 12px var(--el-color-primary-light-7);
 			transform: translateY(-2px);
 
 			.template-title {
-				color: #0076ff;
+				color: var(--el-color-primary);
 			}
 		}
 

+ 14 - 1
apps/web/src/router/index.ts

@@ -12,6 +12,8 @@ const About = () => import('@/views/About.vue')
 const UserCenter = () => import('@/views/UserCenter.vue')
 const LogStream = () => import('@/views/LogStream.vue')
 const ModelLog = () => import('@/views/ModelLog.vue')
+const WorkflowOrchestration = () => import('@/views/WorkflowOrchestration.vue')
+const WorkflowExecution = () => import('@/views/WorkflowExecution.vue')
 
 const routes = [
 	{
@@ -21,13 +23,24 @@ const routes = [
 			{
 				path: '',
 				name: 'Dashboard',
-				component: Dashboard
+				component: Dashboard,
+				alias: 'overview'
 			},
 			{
 				path: 'statistics',
 				name: 'Statistics',
 				component: Statistics
 			},
+			{
+				path: 'orchestration',
+				name: 'WorkflowOrchestration',
+				component: WorkflowOrchestration
+			},
+			{
+				path: 'execution',
+				name: 'WorkflowExecution',
+				component: WorkflowExecution
+			},
 			{
 				path: 'chat',
 				name: 'Chat',

+ 4 - 4
apps/web/src/style.css

@@ -18,11 +18,11 @@
 
 a {
 	font-weight: 500;
-	color: #646cff;
+	color: var(--el-color-primary);
 	text-decoration: inherit;
 }
 a:hover {
-	color: #535bf2;
+	color: var(--el-color-primary);
 }
 
 body {
@@ -49,7 +49,7 @@ button {
 	transition: border-color 0.25s;
 }
 button:hover {
-	border-color: #646cff;
+	border-color: var(--el-color-primary);
 }
 button:focus,
 button:focus-visible {
@@ -73,7 +73,7 @@ button:focus-visible {
 		background-color: #ffffff;
 	}
 	a:hover {
-		color: #747bff;
+		color: var(--el-color-primary);
 	}
 	button {
 		background-color: #f9f9f9;

+ 2 - 6
apps/web/src/views/About.vue

@@ -60,7 +60,7 @@
 	.hero-section {
 		text-align: center;
 		padding: 60px 0;
-		background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+		background: linear-gradient(135deg, var(--el-color-primary) 0%, #764ba2 100%);
 		border-radius: 20px;
 		margin-bottom: 40px;
 		color: #fff;
@@ -143,11 +143,7 @@
 
 				.feature-icon {
 					font-size: 40px;
-					color: #667eea;
-					margin-bottom: 16px;
-				}
-
-				h3 {
+				color: var(--el-color-primary);
 					font-size: 18px;
 					font-weight: 600;
 					color: #333;

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 631 - 709
apps/web/src/views/Dashboard.vue


+ 6 - 6
apps/web/src/views/Docs.vue

@@ -195,9 +195,9 @@ const docDescription = computed(() => {
 						}
 
 						&.active {
-							color: #667eea;
+							color: var(--el-color-primary);
 							background: #f0f3ff;
-							border-right: 3px solid #667eea;
+							border-right: 3px solid var(--el-color-primary);
 							font-weight: 500;
 						}
 					}
@@ -268,7 +268,7 @@ const docDescription = computed(() => {
 								content: '✓';
 								position: absolute;
 								left: 0;
-								color: #667eea;
+								color: var(--el-color-primary);
 								font-weight: 700;
 							}
 
@@ -317,13 +317,13 @@ const docDescription = computed(() => {
 
 							&:hover {
 								background: #fff;
-								border-color: #667eea;
-								box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
+								border-color: var(--el-color-primary);
+								box-shadow: 0 4px 12px var(--el-color-primary-light-9);
 							}
 
 							svg {
 								font-size: 24px;
-								color: #667eea;
+								color: var(--el-color-primary);
 							}
 
 							span {

+ 9 - 0
apps/web/src/views/Editor.vue

@@ -81,6 +81,7 @@ import { startNode, endNode, httpNode, conditionNode, databaseNode, codeNode } f
 import { Workflow, type IWorkflow, type XYPosition, type Connection } from '@repo/workflow'
 import { v4 as uuid } from 'uuid'
 import { useRoute, useRouter } from 'vue-router'
+import { agent } from '@repo/api-service'
 
 import Setter from '@/components/setter/index.vue'
 import RunWorkflow from '@/components/RunWorkflow/index.vue'
@@ -97,6 +98,14 @@ layout?.setMainStyle({
 	padding: '0px'
 })
 
+agent
+	.postGetAgentInfo({
+		id: 'b3a4aabb-a6b8-47f3-8a32-f45930f7d7b8'
+	})
+	.then((res) => {
+		console.log('在线请求结果:', res.result.nodes)
+	})
+
 const footerHeight = ref(32)
 const route = useRoute()
 const router = useRouter()

+ 1 - 1
apps/web/src/views/LogStream.vue

@@ -213,7 +213,7 @@ const refreshLogs = () => {
 
 				.log-workflow {
 					font-size: 13px;
-					color: #667eea;
+					color: var(--el-color-primary);
 					font-weight: 500;
 				}
 			}

+ 1 - 1
apps/web/src/views/ModelLog.vue

@@ -260,7 +260,7 @@ const viewDetails = (log: any) => {
 				width: 56px;
 				height: 56px;
 				border-radius: 12px;
-				background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+				background: linear-gradient(135deg, var(--el-color-primary) 0%, #764ba2 100%);
 				display: flex;
 				align-items: center;
 				justify-content: center;

+ 5 - 6
apps/web/src/views/QuickStart.vue

@@ -108,7 +108,7 @@
 				max-width: 800px;
 				margin: 0 auto;
 				aspect-ratio: 16/9;
-				background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+				background: linear-gradient(135deg, var(--el-color-primary) 0%, #764ba2 100%);
 				border-radius: 12px;
 				display: flex;
 				flex-direction: column;
@@ -160,7 +160,7 @@
 					.step-number {
 						width: 40px;
 						height: 40px;
-						background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+						background: linear-gradient(135deg, var(--el-color-primary) 0%, #764ba2 100%);
 						color: #fff;
 						border-radius: 50%;
 						display: flex;
@@ -212,15 +212,14 @@
 					transition: all 0.3s ease;
 
 					&:hover {
-						border-color: #667eea;
-						box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
+						border-color: var(--el-color-primary);
+						box-shadow: 0 4px 12px var(--el-color-primary-light-7);
 						transform: translateY(-4px);
 					}
 
 					svg {
 						font-size: 48px;
-						color: #667eea;
-						margin-bottom: 16px;
+						color: var(--el-color-primary);
 					}
 
 					h3 {

+ 3 - 3
apps/web/src/views/Statistics.vue

@@ -38,15 +38,15 @@
 						:style="{
 							background:
 								selectedCardIdx === idx
-									? 'linear-gradient(135deg, #e6f7ff 0%, #f0f5ff 100%)'
+									? 'linear-gradient(135deg, var(--el-color-primary-light-9) 0%, var(--el-color-primary-light-8) 100%)'
 									: 'linear-gradient(135deg, #fff 0%, #fafafa 100%)',
 							padding: '20px 16px',
 							borderRadius: '8px',
 							boxShadow:
 								selectedCardIdx === idx
-									? '0 4px 12px rgba(0, 118, 255, 0.15)'
+									? '0 4px 12px var(--el-color-primary-light-7)'
 									: '0 2px 8px rgba(0, 0, 0, 0.08)',
-							border: selectedCardIdx === idx ? '1px solid #0076ff' : '1px solid #f0f0f0',
+							border: selectedCardIdx === idx ? '1px solid var(--el-color-primary)' : '1px solid #f0f0f0',
 							textAlign: 'center',
 							cursor: 'pointer',
 							transition: 'all 0.3s ease'

+ 7 - 7
apps/web/src/views/UserCenter.vue

@@ -8,7 +8,7 @@
 			<div class="profile-card">
 				<div class="avatar-section">
 					<div class="avatar">
-						<SvgIcon name="user-round" size="60"/>
+						<SvgIcon name="user-round" size="60" />
 					</div>
 					<el-button type="primary" size="small">更换头像</el-button>
 				</div>
@@ -70,7 +70,7 @@
 				<div class="security-items">
 					<div class="security-item">
 						<div class="security-left">
-							<SvgIcon name="lock" />
+							<SvgIcon name="lock" size="30" />
 							<div class="security-text">
 								<div class="security-title">登录密码</div>
 								<div class="security-desc">定期更换密码可以提高账号安全性</div>
@@ -80,7 +80,7 @@
 					</div>
 					<div class="security-item">
 						<div class="security-left">
-							<SvgIcon name="shield" />
+							<SvgIcon name="shield" size="30" />
 							<div class="security-text">
 								<div class="security-title">双因素认证</div>
 								<div class="security-desc">未开启</div>
@@ -90,7 +90,7 @@
 					</div>
 					<div class="security-item">
 						<div class="security-left">
-							<SvgIcon name="smartphone" />
+							<SvgIcon name="smartphone" size="30" />
 							<div class="security-text">
 								<div class="security-title">绑定手机</div>
 								<div class="security-desc">131****1111</div>
@@ -151,7 +151,7 @@ const userInfo = ref({
 					width: 120px;
 					height: 120px;
 					border-radius: 50%;
-					background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+					background: linear-gradient(135deg, var(--el-color-primary) 0%, #764ba2 100%);
 					display: flex;
 					align-items: center;
 					justify-content: center;
@@ -191,7 +191,7 @@ const userInfo = ref({
 					width: 60px;
 					height: 60px;
 					border-radius: 12px;
-					background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+					background: linear-gradient(135deg, var(--el-color-primary) 0%, #764ba2 100%);
 					display: flex;
 					align-items: center;
 					justify-content: center;
@@ -249,7 +249,7 @@ const userInfo = ref({
 
 						svg {
 							font-size: 32px;
-							color: #667eea;
+							color: var(--el-color-primary);
 						}
 
 						.security-text {

+ 341 - 0
apps/web/src/views/WorkflowExecution.vue

@@ -0,0 +1,341 @@
+<template>
+	<div class="execution-container">
+		<div class="header">
+			<div>
+				<h1>执行</h1>
+				<p class="subtitle">聚合监控执行状态、耗时与失败原因</p>
+			</div>
+			<el-button type="primary" @click="refresh">
+				<el-icon><RefreshRight /></el-icon>
+				刷新
+			</el-button>
+		</div>
+
+		<div class="stats-grid">
+			<div class="stat-card">
+				<div class="stat-icon">
+					<SvgIcon name="play" size="20" />
+				</div>
+				<div>
+					<div class="stat-value">186</div>
+					<div class="stat-label">今日执行</div>
+				</div>
+			</div>
+			<div class="stat-card">
+				<div class="stat-icon success">
+					<SvgIcon name="check-circle" size="20" />
+				</div>
+				<div>
+					<div class="stat-value">96.8%</div>
+					<div class="stat-label">成功率</div>
+				</div>
+			</div>
+			<div class="stat-card">
+				<div class="stat-icon warning">
+					<SvgIcon name="clock" size="20" />
+				</div>
+				<div>
+					<div class="stat-value">2.4s</div>
+					<div class="stat-label">平均耗时</div>
+				</div>
+			</div>
+			<div class="stat-card">
+				<div class="stat-icon danger">
+					<SvgIcon name="x-circle" size="20" />
+				</div>
+				<div>
+					<div class="stat-value">6</div>
+					<div class="stat-label">失败数</div>
+				</div>
+			</div>
+		</div>
+
+		<div class="filters">
+			<el-input v-model="keyword" placeholder="搜索工作流或执行 ID" clearable class="filter-item">
+				<template #prefix>
+					<el-icon><Search /></el-icon>
+				</template>
+			</el-input>
+			<el-select v-model="status" placeholder="状态" class="filter-item" clearable>
+				<el-option label="全部" value="" />
+				<el-option label="成功" value="success" />
+				<el-option label="失败" value="failed" />
+				<el-option label="运行中" value="running" />
+			</el-select>
+			<el-date-picker
+				v-model="dateRange"
+				type="daterange"
+				range-separator="至"
+				start-placeholder="开始"
+				end-placeholder="结束"
+				class="filter-item"
+			/>
+			<el-button @click="resetFilters">重置</el-button>
+		</div>
+
+		<div class="panel">
+			<el-table :data="filteredExecutions" stripe style="width: 100%">
+				<el-table-column prop="workflow" label="工作流" />
+				<el-table-column prop="executionId" label="执行 ID" />
+				<el-table-column prop="startedAt" label="开始时间" />
+				<el-table-column prop="duration" label="耗时" />
+				<el-table-column prop="trigger" label="触发方式" />
+				<el-table-column label="状态">
+					<template #default="scope">
+						<el-tag :type="statusType(scope.row.status)">
+							{{ statusText(scope.row.status) }}
+						</el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column label="操作">
+					<template #default>
+						<el-button text size="small">详情</el-button>
+						<el-button text size="small">重试</el-button>
+					</template>
+				</el-table-column>
+			</el-table>
+		</div>
+
+		<div class="side-panels">
+			<div class="panel">
+				<div class="panel-title">执行概览</div>
+				<div class="summary-item" v-for="item in summary" :key="item.label">
+					<span class="label">{{ item.label }}</span>
+					<span class="value">{{ item.value }}</span>
+				</div>
+			</div>
+			<div class="panel">
+				<div class="panel-title">告警与建议</div>
+				<ul class="tips">
+					<li>失败率高的工作流建议开启重试与超时策略</li>
+					<li>高耗时节点建议拆分为异步执行</li>
+					<li>关键流程可接入通知节点提高可观测性</li>
+				</ul>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { RefreshRight, Search } from '@element-plus/icons-vue'
+
+const keyword = ref('')
+const status = ref('')
+const dateRange = ref<[Date, Date] | null>(null)
+
+const executions = ref([
+	{
+		workflow: '客户支持自动分派',
+		executionId: 'EXE-20260129001',
+		startedAt: '2026-01-29 09:12:03',
+		duration: '2.1s',
+		trigger: '定时',
+		status: 'success'
+	},
+	{
+		workflow: '内容生成与审核',
+		executionId: 'EXE-20260129002',
+		startedAt: '2026-01-29 09:15:45',
+		duration: '4.3s',
+		trigger: '手动',
+		status: 'running'
+	},
+	{
+		workflow: 'RAG 知识库同步',
+		executionId: 'EXE-20260129003',
+		startedAt: '2026-01-29 08:58:12',
+		duration: '3.9s',
+		trigger: 'Webhook',
+		status: 'failed'
+	},
+	{
+		workflow: '财务报表汇总',
+		executionId: 'EXE-20260129004',
+		startedAt: '2026-01-29 08:40:30',
+		duration: '1.6s',
+		trigger: '定时',
+		status: 'success'
+	}
+])
+
+const summary = ref([
+	{ label: '正在运行', value: '3' },
+	{ label: '队列中', value: '8' },
+	{ label: '近 24h 执行量', value: '412' },
+	{ label: 'P95 耗时', value: '5.9s' }
+])
+
+const filteredExecutions = computed(() => {
+	const q = keyword.value.trim().toLowerCase()
+	return executions.value.filter((item) => {
+		const matchKeyword =
+			!q || item.workflow.toLowerCase().includes(q) || item.executionId.toLowerCase().includes(q)
+		const matchStatus = !status.value || item.status === status.value
+		return matchKeyword && matchStatus
+	})
+})
+
+const statusType = (value: string) => {
+	if (value === 'success') return 'success'
+	if (value === 'failed') return 'danger'
+	if (value === 'running') return 'warning'
+	return 'info'
+}
+
+const statusText = (value: string) => {
+	if (value === 'success') return '成功'
+	if (value === 'failed') return '失败'
+	if (value === 'running') return '运行中'
+	return '未知'
+}
+
+const refresh = () => {
+	console.log('refresh executions')
+}
+
+const resetFilters = () => {
+	keyword.value = ''
+	status.value = ''
+	dateRange.value = null
+}
+</script>
+
+<style lang="less" scoped>
+.execution-container {
+	max-width: 1200px;
+	margin: 0 auto;
+	padding: 24px;
+
+	.header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 24px;
+
+		h1 {
+			font-size: 28px;
+			margin: 0;
+			color: #222;
+		}
+
+		.subtitle {
+			margin: 6px 0 0;
+			color: #666;
+			font-size: 14px;
+		}
+	}
+
+	.stats-grid {
+		display: grid;
+		grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+		gap: 16px;
+		margin-bottom: 20px;
+
+		.stat-card {
+			background: #fff;
+			border-radius: 12px;
+			padding: 18px;
+			box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+			display: flex;
+			gap: 12px;
+			align-items: center;
+
+			.stat-icon {
+				width: 40px;
+				height: 40px;
+				border-radius: 10px;
+				background: #eef2ff;
+				color: #4f46e5;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+
+				&.success {
+					background: #ecfdf3;
+					color: #10b981;
+				}
+
+				&.warning {
+					background: #fff7ed;
+					color: #f97316;
+				}
+
+				&.danger {
+					background: #fef2f2;
+					color: #ef4444;
+				}
+			}
+
+			.stat-value {
+				font-size: 22px;
+				font-weight: 700;
+				color: #1f2937;
+			}
+
+			.stat-label {
+				font-size: 13px;
+				color: #6b7280;
+			}
+		}
+	}
+
+	.filters {
+		display: flex;
+		flex-wrap: wrap;
+		gap: 12px;
+		margin-bottom: 16px;
+		align-items: center;
+
+		.filter-item {
+			width: 220px;
+		}
+	}
+
+	.panel {
+		background: #fff;
+		border-radius: 12px;
+		padding: 20px;
+		box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+	}
+
+	.side-panels {
+		display: grid;
+		grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+		gap: 16px;
+		margin-top: 16px;
+
+		.panel-title {
+			font-size: 16px;
+			font-weight: 600;
+			margin-bottom: 12px;
+			color: #1f2937;
+		}
+
+		.summary-item {
+			display: flex;
+			justify-content: space-between;
+			padding: 10px 0;
+			border-bottom: 1px solid #f1f5f9;
+
+			.label {
+				color: #6b7280;
+				font-size: 13px;
+			}
+
+			.value {
+				font-weight: 600;
+				color: #111827;
+			}
+		}
+
+		.tips {
+			margin: 0;
+			padding-left: 16px;
+			color: #6b7280;
+			line-height: 1.6;
+			font-size: 13px;
+		}
+	}
+}
+</style>

+ 541 - 0
apps/web/src/views/WorkflowOrchestration.vue

@@ -0,0 +1,541 @@
+<template>
+	<div class="orchestration-container">
+		<div class="header">
+			<div>
+				<h1>流程设计</h1>
+				<p class="subtitle">把一堆"要做的事",按顺序、条件、规则,自动地串起来执行</p>
+			</div>
+			<div class="header-actions">
+				<el-button type="primary" @click="createWorkflow">
+					<SvgIcon name="workflow" size="16" />
+					创建工作流
+				</el-button>
+				<el-button @click="openTemplateModal">
+					<SvgIcon name="box" size="16" />
+					导入模板
+				</el-button>
+			</div>
+		</div>
+
+		<!-- 编排核心概念 -->
+		<div class="core-concepts">
+			<div class="concept-card sequence">
+				<div class="concept-icon">🔗</div>
+				<div class="concept-info">
+					<div class="concept-title">按顺序</div>
+					<div class="concept-desc">节点A → 节点B → 节点C,串联执行</div>
+				</div>
+				<div class="concept-example">开始 → HTTP请求 → 数据处理 → 发送通知</div>
+			</div>
+			<div class="concept-card condition">
+				<div class="concept-icon">🔀</div>
+				<div class="concept-info">
+					<div class="concept-title">按条件</div>
+					<div class="concept-desc">判断结果,走不同的分支路径</div>
+				</div>
+				<div class="concept-example">if (状态=成功) → 路径A else → 路径B</div>
+			</div>
+			<div class="concept-card rule">
+				<div class="concept-icon">⚙️</div>
+				<div class="concept-info">
+					<div class="concept-title">按规则</div>
+					<div class="concept-desc">触发器、定时任务、事件驱动自动执行</div>
+				</div>
+				<div class="concept-example">每天9点 | Webhook触发 | 数据变化时</div>
+			</div>
+		</div>
+
+		<div class="stats-grid">
+			<div class="stat-card">
+				<div class="stat-icon">
+					<SvgIcon name="workflow" size="22" />
+				</div>
+				<div class="stat-info">
+					<div class="stat-value">28</div>
+					<div class="stat-label">工作流总数</div>
+				</div>
+			</div>
+			<div class="stat-card">
+				<div class="stat-icon green">
+					<SvgIcon name="clock" size="22" />
+				</div>
+				<div class="stat-info">
+					<div class="stat-value">6</div>
+					<div class="stat-label">近 7 天更新</div>
+				</div>
+			</div>
+			<div class="stat-card">
+				<div class="stat-icon purple">
+					<SvgIcon name="box" size="22" />
+				</div>
+				<div class="stat-info">
+					<div class="stat-value">12</div>
+					<div class="stat-label">模板可用</div>
+				</div>
+			</div>
+			<div class="stat-card">
+				<div class="stat-icon orange">
+					<SvgIcon name="sparkle" size="22" />
+				</div>
+				<div class="stat-info">
+					<div class="stat-value">18</div>
+					<div class="stat-label">节点类型</div>
+				</div>
+			</div>
+		</div>
+
+		<div class="content-grid">
+			<div class="panel">
+				<div class="panel-title">最近编排</div>
+				<div class="workflow-list">
+					<div class="workflow-item" v-for="item in recentWorkflows" :key="item.id">
+						<div class="workflow-main">
+							<div class="workflow-title">{{ item.name }}</div>
+							<div class="workflow-meta">{{ item.updatedAt }} · {{ item.owner }}</div>
+						</div>
+						<div class="workflow-tags">
+							<el-tag size="small" type="info">{{ item.tag }}</el-tag>
+							<el-button text size="small" @click="openWorkflow(item.id)">打开</el-button>
+						</div>
+					</div>
+				</div>
+			</div>
+
+			<div class="panel">
+				<div class="panel-title">可用节点类型</div>
+				<div class="node-types">
+					<div class="node-type-group">
+						<div class="node-type-label">流程控制</div>
+						<div class="node-type-tags">
+							<el-tag size="small" type="info">开始节点</el-tag>
+							<el-tag size="small" type="warning">条件分支</el-tag>
+							<el-tag size="small" type="danger">循环节点</el-tag>
+							<el-tag size="small" type="success">结束节点</el-tag>
+						</div>
+					</div>
+					<div class="node-type-group">
+						<div class="node-type-label">数据操作</div>
+						<div class="node-type-tags">
+							<el-tag size="small">HTTP请求</el-tag>
+							<el-tag size="small">数据库查询</el-tag>
+							<el-tag size="small">代码执行</el-tag>
+							<el-tag size="small">数据转换</el-tag>
+						</div>
+					</div>
+					<div class="node-type-group">
+						<div class="node-type-label">触发规则</div>
+						<div class="node-type-tags">
+							<el-tag size="small" type="info">定时触发</el-tag>
+							<el-tag size="small" type="info">Webhook</el-tag>
+							<el-tag size="small" type="info">事件监听</el-tag>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+
+		<div class="panel full">
+			<div class="panel-title">推荐模板</div>
+			<div class="template-grid">
+				<div class="template-card" v-for="item in templates" :key="item.id">
+					<div class="template-title">{{ item.name }}</div>
+					<div class="template-desc">{{ item.desc }}</div>
+					<div class="template-footer">
+						<el-tag size="small">{{ item.category }}</el-tag>
+						<el-button text size="small" @click="useTemplate(item.id)">查看模板</el-button>
+					</div>
+				</div>
+			</div>
+		</div>
+
+		<!-- 模板弹窗 -->
+		<TemplateModal
+			:visible="templateModalVisible"
+			@close="closeTemplateModal"
+			@select="selectTemplate"
+		/>
+	</div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import { useRouter } from 'vue-router'
+import SvgIcon from '@/components/SvgIcon/index.vue'
+import TemplateModal from '@/components/TemplateModal/index.vue'
+import { v4 } from 'uuid'
+
+const router = useRouter()
+
+const templateModalVisible = ref(false)
+
+const recentWorkflows = ref([
+	{ id: '1', name: '客户支持自动分派', updatedAt: '今天 10:12', owner: '张伟', tag: '客服' },
+	{ id: '2', name: '内容生成与审核', updatedAt: '昨天 18:20', owner: '李娜', tag: '内容' },
+	{ id: '3', name: 'RAG 知识库同步', updatedAt: '1 月 27 日', owner: '王强', tag: '知识库' },
+	{ id: '4', name: '财务报表汇总', updatedAt: '1 月 26 日', owner: '赵敏', tag: '财务' }
+])
+
+const templates = ref([
+	{
+		id: 't1',
+		name: '客户意图识别',
+		desc: '接收消息 → AI分析意图 → 条件判断 → 自动分派客服/机器人',
+		category: '客服'
+	},
+	{
+		id: 't2',
+		name: '日报自动汇总',
+		desc: '定时触发 → 查询数据表 → 汇总计算 → 生成报告 → 通知团队',
+		category: '运营'
+	},
+	{
+		id: 't3',
+		name: '合同审查助手',
+		desc: '上传合同 → OCR识别 → AI审查 → 风险分类 → 生成报告',
+		category: '法务'
+	},
+	{
+		id: 't4',
+		name: '线索打标',
+		desc: 'Webhook接收 → 数据清洗 → 规则匹配 → 打标签 → 写入CRM',
+		category: '增长'
+	}
+])
+
+const createWorkflow = () => {
+	const id = v4()
+	router.push(`/workflow/${id}`)
+}
+
+const openTemplateModal = () => {
+	templateModalVisible.value = true
+}
+
+const closeTemplateModal = () => {
+	templateModalVisible.value = false
+}
+
+const selectTemplate = () => {
+	templateModalVisible.value = false
+	// 根据模板ID创建新工作流
+	const id = v4()
+	router.push(`/templates/${id}`)
+}
+
+const openWorkflow = (id: string) => {
+	router.push(`/workflow/${id}`)
+}
+
+const useTemplate = (id: string) => {
+	router.push(`/templates/${id}`)
+}
+</script>
+
+<style lang="less" scoped>
+.orchestration-container {
+	max-width: 1200px;
+	margin: 0 auto;
+	padding: 24px;
+
+	.header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 24px;
+
+		h1 {
+			font-size: 28px;
+			margin: 0;
+			color: #222;
+		}
+
+		.subtitle {
+			margin: 6px 0 0;
+			color: #666;
+			font-size: 14px;
+		}
+
+		.header-actions {
+			display: flex;
+			gap: 12px;
+
+			:deep(.el-button) {
+				&:not(:last-child) {
+					margin-right: 0;
+				}
+			}
+		}
+	}
+
+	.core-concepts {
+		display: grid;
+		grid-template-columns: repeat(3, 1fr);
+		gap: 16px;
+		margin-bottom: 24px;
+
+		@media (max-width: 900px) {
+			grid-template-columns: 1fr;
+		}
+
+		.concept-card {
+			background: #fff;
+			border-radius: 12px;
+			padding: 20px;
+			box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+			border-left: 4px solid #3b82f6;
+
+			&.sequence {
+				border-left-color: #3b82f6;
+			}
+
+			&.condition {
+				border-left-color: #f59e0b;
+			}
+
+			&.rule {
+				border-left-color: #10b981;
+			}
+
+			.concept-icon {
+				font-size: 32px;
+				margin-bottom: 12px;
+			}
+
+			.concept-info {
+				margin-bottom: 12px;
+
+				.concept-title {
+					font-size: 18px;
+					font-weight: 700;
+					color: #1f2937;
+					margin-bottom: 6px;
+				}
+
+				.concept-desc {
+					font-size: 13px;
+					color: #6b7280;
+					line-height: 1.6;
+				}
+			}
+
+			.concept-example {
+				font-size: 12px;
+				padding: 10px 12px;
+				background: #f9fafb;
+				border-radius: 8px;
+				color: #374151;
+				font-family: 'Consolas', 'Monaco', monospace;
+			}
+		}
+	}
+
+	.stats-grid {
+		display: grid;
+		grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+		gap: 16px;
+		margin-bottom: 24px;
+
+		.stat-card {
+			background: #fff;
+			border-radius: 12px;
+			padding: 18px;
+			display: flex;
+			align-items: center;
+			gap: 12px;
+			box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+
+			.stat-icon {
+				width: 40px;
+				height: 40px;
+				border-radius: 10px;
+				background: #eef2ff;
+				color: #4f46e5;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+
+				&.green {
+					background: #ecfdf3;
+					color: #10b981;
+				}
+
+				&.purple {
+					background: #f5f3ff;
+					color: #7c3aed;
+				}
+
+				&.orange {
+					background: #fff7ed;
+					color: #f97316;
+				}
+			}
+
+			.stat-info {
+				.stat-value {
+					font-size: 22px;
+					font-weight: 700;
+					color: #1f2937;
+				}
+
+				.stat-label {
+					font-size: 13px;
+					color: #6b7280;
+				}
+			}
+		}
+	}
+
+	.content-grid {
+		display: grid;
+		grid-template-columns: 2fr 1fr;
+		gap: 16px;
+		margin-bottom: 16px;
+
+		@media (max-width: 900px) {
+			grid-template-columns: 1fr;
+		}
+	}
+
+	.panel {
+		background: #fff;
+		border-radius: 12px;
+		padding: 20px;
+		box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+
+		&.full {
+			margin-top: 8px;
+		}
+
+		.panel-title {
+			font-size: 16px;
+			font-weight: 600;
+			margin-bottom: 16px;
+			color: #1f2937;
+		}
+	}
+
+	.workflow-list {
+		display: flex;
+		flex-direction: column;
+		gap: 12px;
+
+		.workflow-item {
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			padding: 12px;
+			border-radius: 10px;
+			border: 1px solid #f0f0f0;
+
+			.workflow-title {
+				font-weight: 600;
+				color: #111827;
+			}
+
+			.workflow-meta {
+				font-size: 12px;
+				color: #6b7280;
+				margin-top: 4px;
+			}
+
+			.workflow-tags {
+				display: flex;
+				gap: 8px;
+				align-items: center;
+			}
+		}
+	}
+
+	.feature-list {
+		display: flex;
+		flex-direction: column;
+		gap: 16px;
+
+		.feature-item {
+			display: flex;
+			gap: 12px;
+			align-items: flex-start;
+
+			.feature-icon {
+				width: 36px;
+				height: 36px;
+				border-radius: 10px;
+				background: #f3f4f6;
+				color: #374151;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+			}
+
+			.feature-title {
+				font-weight: 600;
+				color: #111827;
+			}
+
+			.feature-desc {
+				font-size: 13px;
+				color: #6b7280;
+				margin-top: 4px;
+			}
+		}
+	}
+
+	.node-types {
+		display: flex;
+		flex-direction: column;
+		gap: 16px;
+
+		.node-type-group {
+			.node-type-label {
+				font-size: 13px;
+				color: #6b7280;
+				margin-bottom: 8px;
+				font-weight: 600;
+			}
+
+			.node-type-tags {
+				display: flex;
+				flex-wrap: wrap;
+				gap: 8px;
+			}
+		}
+	}
+
+	.template-grid {
+		display: grid;
+		grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
+		gap: 16px;
+
+		.template-card {
+			border: 1px solid #f0f0f0;
+			border-radius: 12px;
+			padding: 16px;
+			background: #fcfcff;
+
+			.template-title {
+				font-weight: 600;
+				color: #111827;
+				margin-bottom: 8px;
+			}
+
+			.template-desc {
+				font-size: 12px;
+				color: #6b7280;
+				line-height: 1.6;
+				min-height: 54px;
+				font-family: 'Consolas', 'Monaco', monospace;
+				background: #f9fafb;
+				padding: 8px;
+				border-radius: 6px;
+				margin-bottom: 10px;
+			}
+
+			.template-footer {
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+			}
+		}
+	}
+}
+</style>

+ 11 - 1
apps/web/vite.config.ts

@@ -1,4 +1,3 @@
-
 import { defineConfig } from 'vite'
 import vue from '@vitejs/plugin-vue'
 import path from 'path'
@@ -50,5 +49,16 @@ export default defineConfig({
 		alias: {
 			'@': path.resolve(__dirname, 'src')
 		}
+	},
+	server: {
+		host: true,
+		port: 5174,
+		proxy: {
+			'/api': {
+				target: 'http://shalu-componenttesting-admin-dev.shalu.com',
+				changeOrigin: true,
+				rewrite: (path) => path.replace(/^\/api/, '/api')
+			}
+		}
 	}
 })

+ 2 - 2
packages/api-client/index.ts

@@ -1,3 +1,3 @@
-import { request } from './request';
+import { request } from './request'
 
-export default request;
+export default request

+ 4 - 1
packages/api-client/package.json

@@ -10,10 +10,13 @@
   },
   "devDependencies": {
     "@repo/typescript-config": "workspace:*",
+    "@types/node": "^25.1.0",
+    "@types/qs": "^6.14.0",
     "@umijs/openapi": "^1.14.1"
   },
   "license": "MIT",
   "dependencies": {
-    "axios": "^1.13.2"
+    "axios": "^1.13.2",
+    "qs": "^6.14.1"
   }
 }

+ 333 - 316
packages/api-client/request.ts

@@ -1,332 +1,349 @@
-import type { AxiosRequestConfig, Method, RawAxiosRequestHeaders } from 'axios'
-import axios from 'axios'
-import { IRestApiContext } from './types'
-
-export const NO_NETWORK_ERROR_CODE = 999
-export const STREAM_SEPARATOR = '⧉⇋⇋➽⌑⧉§§\n'
+import Axios, {
+	type AxiosInstance,
+	type AxiosRequestConfig,
+	type CustomParamsSerializer,
+	type AxiosResponse,
+	type InternalAxiosRequestConfig,
+	type AxiosError
+} from 'axios'
+import { stringify } from 'qs'
+
+// 基础配置
+const defaultConfig: AxiosRequestConfig = {
+	timeout: 6000,
+	headers: {
+		'Content-Type': 'application/json;charset=utf-8'
+	},
+	paramsSerializer: {
+		serialize: stringify as unknown as CustomParamsSerializer
+	}
+}
 
-type GenericValue = string | number | boolean | object | null | undefined
-export interface IDataObject {
-  [key: string]: GenericValue | IDataObject | GenericValue[] | IDataObject[]
+// 响应数据基础结构
+export interface BaseResponse {
+	code: number
+	error?: string
+	isAuthorized?: boolean
+	isSuccess?: boolean
 }
 
-const BROWSER_ID_STORAGE_KEY = 'n8n-browserId'
+type OmitBaseResponse<T> = Omit<T, keyof BaseResponse>
 
-const baseURL = 'dev-n8n.shalu.com'
-const getBrowserId = () => {
-  let browserId = localStorage.getItem(BROWSER_ID_STORAGE_KEY)
-  if (!browserId) {
-    browserId = crypto.randomUUID()
-    localStorage.setItem(BROWSER_ID_STORAGE_KEY, browserId)
-  }
-  return browserId
-}
+export type ResponseData<T = any> = BaseResponse & OmitBaseResponse<T>
 
-export class ResponseError {
-  name?: string
-  // The HTTP status code of response
-  httpStatusCode?: number
-
-  // The error code in the response
-  errorCode?: number
-
-  // The stack trace of the server
-  serverStackTrace?: string
-
-  // Additional metadata from the server (e.g., EULA URL)
-  meta?: Record<string, unknown>
-
-  /**
-   * Creates an instance of ResponseError.
-   * @param {string} message The error message
-   * @param {number} [errorCode] The error code which can be used by frontend to identify the actual error
-   * @param {number} [httpStatusCode] The HTTP status code the response should have
-   * @param {string} [stack] The stack trace
-   * @param {Record<string, unknown>} [meta] Additional metadata from the server
-   */
-  constructor(
-    message: string,
-    options: {
-      errorCode?: number
-      httpStatusCode?: number
-      stack?: string
-      meta?: Record<string, unknown>
-    } = {}
-  ) {
-    // super(message);
-    this.name = 'ResponseError'
-
-    const { errorCode, httpStatusCode, stack, meta } = options
-    if (errorCode) {
-      this.errorCode = errorCode
-    }
-    if (httpStatusCode) {
-      this.httpStatusCode = httpStatusCode
-    }
-    if (stack) {
-      this.serverStackTrace = stack
-    }
-    if (meta) {
-      this.meta = meta
-    }
-  }
-}
+export type ResponseValidator<T = any> = (data: ResponseData<T>) => boolean
 
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-const legacyParamSerializer = (params: Record<string, any>) =>
-  Object.keys(params)
-    .filter((key) => params[key] !== undefined)
-    .map((key) => {
-      if (Array.isArray(params[key])) {
-        return params[key].map((v: string) => `${key}[]=${encodeURIComponent(v)}`).join('&')
-      }
-      if (typeof params[key] === 'object') {
-        params[key] = JSON.stringify(params[key])
-      }
-      return `${key}=${encodeURIComponent(params[key])}`
-    })
-    .join('&')
-
-export async function request(
-  endpoint: string,
-  config: {
-    method: Method
-    // baseURL: string
-    // endpoint: string
-    headers?: RawAxiosRequestHeaders
-    data?: GenericValue | GenericValue[]
-    withCredentials?: boolean
-  }
-) {
-  const { method, headers, data } = config
-  const options: AxiosRequestConfig = {
-    method,
-    url: endpoint,
-    baseURL,
-    headers: headers ?? {}
-  }
-  if (baseURL.startsWith('/')) {
-    options.headers!['browser-id'] = getBrowserId()
-  }
-  if (
-    import.meta.env.NODE_ENV !== 'production' &&
-    !baseURL.includes('api.n8n.io') &&
-    !baseURL.includes('n8n.cloud')
-  ) {
-    options.withCredentials = options.withCredentials ?? true
-  }
-  if (['POST', 'PATCH', 'PUT'].includes(method)) {
-    options.data = data
-  } else if (data) {
-    options.params = data
-    options.paramsSerializer = legacyParamSerializer
-  }
-
-  try {
-    const response = await axios.request(options)
-    return response.data
-  } catch (error) {
-    if (error.message === 'Network Error') {
-      throw new ResponseError("Can't connect to n8n.", {
-        errorCode: NO_NETWORK_ERROR_CODE
-      })
-    }
-
-    const errorResponseData = error.response?.data
-    if (errorResponseData?.mfaRequired === true) {
-      // throw new MfaRequiredError();
-      throw errorResponseData
-    }
-    if (errorResponseData?.message !== undefined) {
-      if (errorResponseData.name === 'NodeApiError') {
-        errorResponseData.httpStatusCode = error.response.status
-        throw errorResponseData
-      }
-
-      throw new ResponseError(errorResponseData.message, {
-        errorCode: errorResponseData.code,
-        httpStatusCode: error.response.status,
-        stack: errorResponseData.stack,
-        meta: errorResponseData.meta
-      })
-    }
-
-    throw error
-  }
+// 重试配置
+export interface RetryConfig {
+	retries?: number
+	retryDelay?: number
+	retryCondition?: (error: AxiosError) => boolean
 }
 
-/**
- * Sends a request to the API and returns the response without extracting the data key.
- * @param context Rest API context
- * @param method HTTP method
- * @param endpoint relative path to the API endpoint
- * @param data request data
- * @returns data and total count
- */
-export async function getFullApiResponse<T>(
-  context: IRestApiContext,
-  method: Method,
-  endpoint: string,
-  data?: GenericValue | GenericValue[]
-) {
-  const response = await request({
-    method,
-    baseURL: context.baseUrl,
-    endpoint,
-    headers: { 'push-ref': context.pushRef },
-    data
-  })
-
-  return response as { count: number; data: T }
+// 拦截器配置类型
+interface InterceptorsConfig {
+	requestInterceptor?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig
+	requestErrorInterceptor?: (error: AxiosError) => Promise<any>
+	responseInterceptor?: (response: AxiosResponse<ResponseData<any>>) => any
+	responseErrorInterceptor?: (error: AxiosError) => Promise<any>
 }
 
-export async function makeRestApiRequest<T>(
-  context: IRestApiContext,
-  method: Method,
-  endpoint: string,
-  data?: GenericValue | GenericValue[]
-) {
-  const response = await request({
-    method,
-    baseURL: context.baseUrl,
-    endpoint,
-    headers: { 'push-ref': context.pushRef },
-    data
-  })
-
-  // All cli rest api endpoints return data wrapped in `data` key
-  return response.data as T
-}
+// 请求唯一键
+type RequestKey = string | symbol
 
-export async function get(
-  baseURL: string,
-  endpoint: string,
-  params?: IDataObject,
-  headers?: RawAxiosRequestHeaders
-) {
-  return await request({ method: 'GET', baseURL, endpoint, headers, data: params })
+/**
+ * 获取url参数
+ * @param url
+ * @returns
+ */
+export function getParams(url: string) {
+	const paramsString = url.split('?')[1]
+	const searchParams = new URLSearchParams(paramsString)
+	return Object.fromEntries(searchParams.entries())
 }
 
-export async function post(
-  baseURL: string,
-  endpoint: string,
-  params?: IDataObject,
-  headers?: RawAxiosRequestHeaders
-) {
-  return await request({ method: 'POST', baseURL, endpoint, headers, data: params })
+class HttpClient {
+	private instance: AxiosInstance
+	private requestInterceptorId?: number
+	private responseInterceptorId?: number
+	private abortControllers: Map<RequestKey, AbortController> = new Map()
+
+	constructor(customConfig?: AxiosRequestConfig, interceptors?: InterceptorsConfig) {
+		this.instance = Axios.create({ ...defaultConfig, ...customConfig })
+		this.initInterceptors(interceptors)
+	}
+
+	private initInterceptors(interceptors?: InterceptorsConfig): void {
+		this.initRequestInterceptor(
+			interceptors?.requestInterceptor,
+			interceptors?.requestErrorInterceptor
+		)
+		this.initResponseInterceptor(
+			interceptors?.responseInterceptor,
+			interceptors?.responseErrorInterceptor
+		)
+	}
+
+	private initRequestInterceptor(
+		customInterceptor?: InterceptorsConfig['requestInterceptor'],
+		customErrorInterceptor?: InterceptorsConfig['requestErrorInterceptor']
+	): void {
+		const defaultInterceptor = (config: InternalAxiosRequestConfig): InternalAxiosRequestConfig => {
+			const search = getParams(window.location.href)
+			const enterpriseCode = search?.['enterpriseCode']
+			const token =
+				localStorage.getItem('token_' + enterpriseCode) ||
+				document.cookie.match(new RegExp('(^| )' + 'x-sessionId_b' + '=([^;]*)(;|$)'))?.[2]
+
+			// 添加token
+			if (token) {
+				if (!config.headers) {
+					config.headers = {} as InternalAxiosRequestConfig['headers']
+				}
+				config.headers.Authorization = token
+			}
+
+			return config
+		}
+
+		// 默认请求错误拦截器
+		const defaultErrorInterceptor = (error: AxiosError): Promise<any> => {
+			// todo 错误处理
+
+			return Promise.reject(error)
+		}
+
+		this.requestInterceptorId = this.instance.interceptors.request.use(
+			customInterceptor || defaultInterceptor,
+			customErrorInterceptor || defaultErrorInterceptor
+		)
+	}
+
+	private initResponseInterceptor(
+		customInterceptor?: InterceptorsConfig['responseInterceptor'],
+		customErrorInterceptor?: InterceptorsConfig['responseErrorInterceptor']
+	): void {
+		this.responseInterceptorId = this.instance.interceptors.response.use(
+			customInterceptor,
+			customErrorInterceptor
+		)
+	}
+
+	private getRequestKey(config: AxiosRequestConfig): RequestKey | undefined {
+		if (!config.url) return undefined
+		return `${config.method?.toUpperCase()}-${config.url}`
+	}
+
+	private setupCancelController(
+		config: AxiosRequestConfig,
+		requestKey?: RequestKey
+	): AxiosRequestConfig {
+		const key = requestKey || this.getRequestKey(config)
+		if (!key) return config
+
+		// 如果已有相同key的请求,先取消它
+		this.cancelRequest(key)
+
+		const controller = new AbortController()
+		this.abortControllers.set(key, controller)
+
+		return {
+			...config,
+			signal: controller.signal
+		}
+	}
+
+	public removeRequestInterceptor(): void {
+		if (this.requestInterceptorId !== undefined) {
+			this.instance.interceptors.request.eject(this.requestInterceptorId)
+			this.requestInterceptorId = undefined // 重置ID,避免重复移除
+		}
+	}
+
+	public removeResponseInterceptor(): void {
+		if (this.responseInterceptorId !== undefined) {
+			this.instance.interceptors.response.eject(this.responseInterceptorId)
+			this.responseInterceptorId = undefined // 重置ID,避免重复移除
+		}
+	}
+
+	public setRequestInterceptor(
+		customInterceptor?: InterceptorsConfig['requestInterceptor'],
+		customErrorInterceptor?: InterceptorsConfig['requestErrorInterceptor']
+	): void {
+		this.removeRequestInterceptor()
+		this.initRequestInterceptor(customInterceptor, customErrorInterceptor)
+	}
+
+	public setResponseInterceptor(
+		customInterceptor?: InterceptorsConfig['responseInterceptor'],
+		customErrorInterceptor?: InterceptorsConfig['responseErrorInterceptor']
+	): void {
+		this.removeResponseInterceptor()
+		this.initResponseInterceptor(customInterceptor, customErrorInterceptor)
+	}
+
+	public getInstance(): AxiosInstance {
+		return this.instance
+	}
+
+	public cancelRequest(key: RequestKey, message?: string): boolean {
+		const controller = this.abortControllers.get(key)
+		if (controller) {
+			controller.abort(message || `取消请求: ${String(key)}`)
+			this.abortControllers.delete(key)
+			return true
+		}
+		return false
+	}
+
+	public cancelAllRequests(message?: string): void {
+		this.abortControllers.forEach((controller, key) => {
+			controller.abort(message || `取消所有请求: ${String(key)}`)
+		})
+		this.abortControllers.clear()
+	}
+
+	public static isCancel(error: unknown): boolean {
+		return Axios.isCancel(error)
+	}
+
+	private sleep(ms: number): Promise<void> {
+		return new Promise((resolve) => setTimeout(resolve, ms))
+	}
+
+	/**
+	 * 通用请求方法
+	 * @param url 请求地址
+	 * @param config 请求配置
+	 * @returns 响应数据
+	 */
+	public async request<T = any>(
+		url: string,
+		config?: AxiosRequestConfig & { requestKey?: RequestKey; retry?: RetryConfig }
+	): Promise<ResponseData<T>> {
+		const { requestKey, retry, method, ...restConfig } = config || {}
+
+		const defaultRetryCondition = (error: AxiosError) => {
+			// 默认只重试网络错误或5xx服务器错误
+			return !error.response || (error.response.status >= 500 && error.response.status < 600)
+		}
+
+		const retryConfig = {
+			retries: 0,
+			retryDelay: 1000,
+			retryCondition: defaultRetryCondition,
+			...retry
+		}
+
+		let lastError: any
+		const key = requestKey || this.getRequestKey({ ...restConfig, method, url })
+
+		for (let attempt = 0; attempt <= retryConfig.retries; attempt++) {
+			try {
+				if (attempt > 0 && key) {
+					this.abortControllers.delete(key)
+				}
+
+				const requestConfig = this.setupCancelController({ ...restConfig, method, url }, requestKey)
+
+				const response = await this.instance.request<ResponseData<T>>(requestConfig)
+
+				return response.data
+			} catch (error) {
+				lastError = error
+				if (
+					attempt === retryConfig.retries ||
+					!retryConfig.retryCondition(error as AxiosError) ||
+					HttpClient.isCancel(error)
+				) {
+					break
+				}
+
+				// 延迟后重试
+				if (retryConfig.retryDelay > 0) {
+					await this.sleep(retryConfig.retryDelay)
+				}
+			}
+		}
+
+		return Promise.reject(lastError)
+	}
+
+	/**
+	 * GET 请求
+	 * @param url 请求地址
+	 * @param config 请求配置
+	 * @returns 响应数据
+	 */
+	public get<T = any>(
+		url: string,
+		config?: AxiosRequestConfig & { requestKey?: RequestKey; retry?: RetryConfig }
+	): Promise<ResponseData<T>> {
+		return this.request<T>(url, { ...config, method: 'GET' })
+	}
+
+	/**
+	 * POST 请求
+	 * @param url 请求地址
+	 * @param data 请求数据
+	 * @param config 请求配置
+	 * @returns 响应数据
+	 */
+	public post<T = any>(
+		url: string,
+		data?: any,
+		config?: AxiosRequestConfig & { requestKey?: RequestKey; retry?: RetryConfig }
+	): Promise<ResponseData<T>> {
+		return this.request<T>(url, { ...config, data, method: 'POST' })
+	}
+
+	/**
+	 * PUT 请求
+	 * @param url 请求地址
+	 * @param data 请求数据
+	 * @param config 请求配置
+	 * @returns 响应数据
+	 */
+	public put<T = any>(
+		url: string,
+		data?: any,
+		config?: AxiosRequestConfig & { requestKey?: RequestKey; retry?: RetryConfig }
+	): Promise<ResponseData<T>> {
+		return this.request<T>(url, { ...config, data, method: 'PUT' })
+	}
+
+	/**
+	 * DELETE 请求
+	 * @param url 请求地址
+	 * @param config 请求配置
+	 * @returns 响应数据
+	 */
+	public delete<T = any>(
+		url: string,
+		config?: AxiosRequestConfig & { requestKey?: RequestKey; retry?: RetryConfig }
+	): Promise<ResponseData<T>> {
+		return this.request<T>(url, { ...config, method: 'DELETE' })
+	}
+
+	/**
+	 * PATCH 请求
+	 * @param url 请求地址
+	 * @param data 请求数据
+	 * @param config 请求配置
+	 * @returns 响应数据
+	 */
+	public patch<T = any>(
+		url: string,
+		data?: any,
+		config?: AxiosRequestConfig & { requestKey?: RequestKey; retry?: RetryConfig }
+	): Promise<ResponseData<T>> {
+		return this.request<T>(url, { ...config, data, method: 'PATCH' })
+	}
 }
 
-export async function patch(
-  baseURL: string,
-  endpoint: string,
-  params?: IDataObject,
-  headers?: RawAxiosRequestHeaders
-) {
-  return await request({ method: 'PATCH', baseURL, endpoint, headers, data: params })
-}
+const http = new HttpClient()
+// 导出request供api-service使用
+export const request = http.request.bind(http)
 
-export async function streamRequest<T extends object>(
-  context: IRestApiContext,
-  apiEndpoint: string,
-  payload: object,
-  onChunk?: (chunk: T) => void,
-  onDone?: () => void,
-  onError?: (e: Error) => void,
-  separator = STREAM_SEPARATOR,
-  abortSignal?: AbortSignal
-): Promise<void> {
-  let onErrorOnce: ((e: Error) => void) | undefined = (e: Error) => {
-    onErrorOnce = undefined
-    onError?.(e)
-  }
-  const headers: Record<string, string> = {
-    'browser-id': getBrowserId(),
-    'Content-Type': 'application/json'
-  }
-  const assistantRequest: RequestInit = {
-    headers,
-    method: 'POST',
-    credentials: 'include',
-    body: JSON.stringify(payload),
-    signal: abortSignal
-  }
-  try {
-    const response = await fetch(`${context.baseUrl}${apiEndpoint}`, assistantRequest)
-
-    if (response.body) {
-      // Handle the streaming response
-      const reader = response.body.getReader()
-      const decoder = new TextDecoder('utf-8')
-
-      let buffer = ''
-
-      async function readStream() {
-        const { done, value } = await reader.read()
-        if (done) {
-          if (response.ok) {
-            onDone?.()
-          } else {
-            onErrorOnce?.(
-              new ResponseError(response.statusText, {
-                httpStatusCode: response.status
-              })
-            )
-          }
-          return
-        }
-        const chunk = decoder.decode(value)
-        buffer += chunk
-
-        const splitChunks = buffer.split(separator)
-
-        buffer = ''
-        for (const splitChunk of splitChunks) {
-          if (splitChunk) {
-            let data: T
-            try {
-              // data = jsonParse<T>(splitChunk, { errorMessage: 'Invalid json' });
-              data = JSON.parse(splitChunk) as T
-            } catch (e) {
-              // incomplete json. append to buffer to complete
-              buffer += splitChunk
-
-              continue
-            }
-
-            try {
-              if (response.ok) {
-                // Call chunk callback if request was successful
-                onChunk?.(data)
-              } else {
-                // Otherwise, call error callback
-                const message = 'message' in data ? data.message : response.statusText
-                onErrorOnce?.(
-                  new ResponseError(String(message), {
-                    httpStatusCode: response.status
-                  })
-                )
-              }
-            } catch (e: unknown) {
-              if (e instanceof Error) {
-                onErrorOnce?.(e)
-              }
-            }
-          }
-        }
-        await readStream()
-      }
-
-      // Start reading the stream
-      await readStream()
-    } else if (onErrorOnce) {
-      onErrorOnce(new Error(response.statusText))
-    }
-  } catch (e: unknown) {
-    const condition = e instanceof Error
-    if (!condition) {
-      // eslint-disable-next-line n8n-local-rules/no-plain-errors
-      throw new Error('Assertion failed')
-    }
-    onErrorOnce?.(e)
-  }
-}
+export default http

+ 990 - 0
packages/api-service/agent.openapi.json

@@ -0,0 +1,990 @@
+{
+	"openapi": "3.0.3",
+	"info": {
+		"title": "默认模块",
+		"description": "",
+		"version": "1.0.0"
+	},
+	"servers": [
+		{
+			"url": "/",
+			"description": "默认服务器"
+		}
+	],
+	"tags": [
+		{
+			"name": "Agent",
+			"description": "智能体相关接口"
+		}
+	],
+	"paths": {
+		"/api/agent/doEditAgent": {
+			"post": {
+				"summary": "智能体编辑",
+				"description": "",
+				"tags": ["Agent"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "认证令牌",
+						"required": false,
+						"schema": {
+							"type": "string",
+							"default": "bpm_client_1473687766939209728",
+							"example": "bpm_client_1473687766939209728"
+						}
+					}
+				],
+				"responses": {
+					"200": {
+						"description": "成功响应",
+						"content": {
+							"application/json": {
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"result": "20d31522-66e7-463e-81d7-7fb7fd5864f7",
+									"isAuthorized": true
+								},
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer",
+											"format": "int32"
+										},
+										"result": {
+											"type": "string",
+											"format": "uuid"
+										},
+										"isAuthorized": {
+											"type": "boolean"
+										}
+									},
+									"required": ["isSuccess", "code", "result", "isAuthorized"]
+								}
+							}
+						}
+					}
+				}
+			}
+		},
+		"/api/agent/doSaveAgentVariables": {
+			"post": {
+				"summary": "保存智能体变量",
+				"description": "",
+				"tags": ["Agent"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "认证令牌",
+						"required": false,
+						"schema": {
+							"type": "string",
+							"default": "bpm_client_1473687766939209728",
+							"example": "bpm_client_1473687766939209728"
+						}
+					}
+				],
+				"requestBody": {
+					"required": true,
+					"content": {
+						"application/json": {
+							"schema": {
+								"type": "object",
+								"properties": {
+									"appAgentId": {
+										"type": "string",
+										"format": "uuid"
+									},
+									"conversation_variables": {
+										"type": "array",
+										"items": {
+											"type": "string"
+										}
+									},
+									"env_variables": {
+										"type": "array",
+										"items": {
+											"type": "object",
+											"properties": {
+												"name": {
+													"type": "string"
+												},
+												"value": {
+													"type": "string"
+												},
+												"type": {
+													"type": "string",
+													"enum": ["string", "number", "boolean", "object", "array"]
+												}
+											},
+											"required": ["name", "value", "type"]
+										}
+									}
+								},
+								"required": ["appAgentId", "conversation_variables", "env_variables"]
+							}
+						}
+					}
+				},
+				"responses": {
+					"200": {
+						"description": "成功响应",
+						"content": {
+							"application/json": {
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"isAuthorized": true
+								},
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer",
+											"format": "int32"
+										},
+										"result": {
+											"type": "string"
+										},
+										"isAuthorized": {
+											"type": "boolean"
+										}
+									},
+									"required": ["isSuccess", "code", "result", "isAuthorized"]
+								}
+							}
+						}
+					}
+				}
+			}
+		},
+		"/api/agent/getAgentInfo": {
+			"post": {
+				"summary": "获取智能体信息",
+				"description": "",
+				"tags": ["Agent"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "认证令牌",
+						"required": false,
+						"schema": {
+							"type": "string",
+							"default": "bpm_client_1473687766939209728",
+							"example": "bpm_client_1473687766939209728"
+						}
+					}
+				],
+				"requestBody": {
+					"required": true,
+					"content": {
+						"application/json": {
+							"schema": {
+								"type": "object",
+								"properties": {
+									"id": {
+										"type": "string",
+										"format": "uuid"
+									}
+								},
+								"required": ["id"]
+							}
+						}
+					}
+				},
+				"responses": {
+					"200": {
+						"description": "成功响应",
+						"content": {
+							"application/json": {
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"result": {
+										"conversation_variables": [],
+										"edges": [],
+										"env_variables": [
+											{
+												"is_require": false,
+												"name": "api_address",
+												"type": "string",
+												"value": "http://shalu-componenttesting-admin-dev.shalu.com"
+											}
+										],
+										"id": "b3a4aabb-a6b8-47f3-8a32-f45930f7d7b8",
+										"name": "测试智能体",
+										"nodes": [
+											{
+												"appAgentId": "b3a4aabb-a6b8-47f3-8a32-f45930f7d7b8",
+												"creationTime": "2026-01-28 10:24:45",
+												"creatorUserId": "7F8A2BFE-402D-4499-9BB8-2EF7FFC7B993",
+												"data": {
+													"outputs": [
+														{
+															"name": "body",
+															"describe": "响应内容",
+															"type": "string"
+														},
+														{
+															"name": "status_code",
+															"describe": "响应状态码",
+															"type": "number"
+														},
+														{
+															"name": "headers",
+															"describe": "响应头列表 JSON",
+															"type": "object"
+														}
+													],
+													"output_can_alter": false,
+													"variables": [],
+													"method": "post",
+													"ssl_verify": false,
+													"isInIteration": false,
+													"default_value": [],
+													"body": {
+														"data": [
+															{
+																"type": "text",
+																"value": "{\"name\":\"测试智能体\",\"profilePhoto\":\"1111\",\"remark\":\"描述\",\"viewPort\":{\"x\":10,\"y\":\"10\",\"zoom\":1}}",
+																"key": ""
+															}
+														],
+														"type": "json"
+													},
+													"params": [],
+													"title": "HTTP 请求",
+													"type": "http-request",
+													"error_strategy": "none",
+													"retry_config": {
+														"max_retries": 3,
+														"retry_enabled": false,
+														"retry_interval": 100
+													},
+													"url": "http://shalu-componenttesting-admin-dev.shalu.com/api/agent/doEditAgent",
+													"authorization": {
+														"type": "none",
+														"config": {
+															"api_key": "",
+															"header": "",
+															"type": ""
+														}
+													},
+													"timeout_config": {
+														"max_write_timeout": 0,
+														"max_read_timeout": 0,
+														"max_connect_timeout": 0
+													},
+													"heads": [
+														{
+															"name": "Authorization",
+															"value": "bpm_client_1473108597171818496"
+														}
+													],
+													"selected": true,
+													"desc": "",
+													"isInLoop": false
+												},
+												"height": 40,
+												"id": "492048da-6f33-4a36-adc5-cff4b973b053",
+												"isDeleted": false,
+												"position": {
+													"x": 20,
+													"y": 30
+												},
+												"selected": true,
+												"type": "custom",
+												"updateTime": "2026-01-28 11:00:09",
+												"width": 20,
+												"zIndex": 1
+											}
+										],
+										"profilePhoto": "1111",
+										"viewPort": {
+											"x": 10,
+											"y": 10,
+											"zoom": 1
+										}
+									},
+									"isAuthorized": true
+								},
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer",
+											"format": "int32"
+										},
+										"result": {
+											"type": "object",
+											"properties": {
+												"conversation_variables": {
+													"type": "array",
+													"items": {
+														"type": "string"
+													}
+												},
+												"edges": {
+													"type": "array",
+													"items": {
+														"type": "string"
+													}
+												},
+												"env_variables": {
+													"type": "array",
+													"items": {
+														"type": "object",
+														"properties": {
+															"is_require": {
+																"type": "boolean"
+															},
+															"name": {
+																"type": "string"
+															},
+															"type": {
+																"type": "string",
+																"enum": ["string", "number", "boolean", "object", "array"]
+															},
+															"value": {
+																"type": "string"
+															}
+														},
+														"required": ["name", "type", "value"]
+													}
+												},
+												"id": {
+													"type": "string",
+													"format": "uuid"
+												},
+												"name": {
+													"type": "string"
+												},
+												"nodes": {
+													"type": "array",
+													"items": {
+														"$ref": "#/components/schemas/AgentNode"
+													}
+												},
+												"profilePhoto": {
+													"type": "string"
+												},
+												"viewPort": {
+													"type": "object",
+													"properties": {
+														"x": {
+															"type": "integer"
+														},
+														"y": {
+															"type": "integer"
+														},
+														"zoom": {
+															"type": "integer"
+														}
+													},
+													"required": ["x", "y", "zoom"]
+												}
+											},
+											"required": ["id", "name", "nodes", "profilePhoto", "viewPort"]
+										},
+										"isAuthorized": {
+											"type": "boolean"
+										}
+									},
+									"required": ["isSuccess", "code", "result", "isAuthorized"]
+								}
+							}
+						}
+					}
+				}
+			}
+		},
+		"/api/agent/doNewAgentNode": {
+			"post": {
+				"summary": "智能体添加节点",
+				"description": "",
+				"tags": ["Agent"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "认证令牌",
+						"required": false,
+						"schema": {
+							"type": "string",
+							"default": "bpm_client_1473687766939209728",
+							"example": "bpm_client_1473687766939209728"
+						}
+					}
+				],
+				"requestBody": {
+					"required": true,
+					"content": {
+						"application/json": {
+							"schema": {
+								"type": "object",
+								"properties": {
+									"appAgentId": {
+										"type": "string",
+										"format": "uuid"
+									},
+									"position": {
+										"type": "object",
+										"properties": {
+											"x": {
+												"type": "integer"
+											},
+											"y": {
+												"type": "integer"
+											}
+										},
+										"required": ["x", "y"]
+									},
+									"width": {
+										"type": "integer"
+									},
+									"height": {
+										"type": "integer"
+									},
+									"selected": {
+										"type": "boolean"
+									},
+									"nodeType": {
+										"type": "string",
+										"enum": ["custom", "start", "end", "condition", "task", "http-request"]
+									},
+									"zIndex": {
+										"type": "integer"
+									},
+									"parentId": {
+										"type": "string",
+										"format": "uuid"
+									}
+								},
+								"required": [
+									"appAgentId",
+									"parentId",
+									"position",
+									"width",
+									"height",
+									"selected",
+									"nodeType",
+									"zIndex"
+								]
+							}
+						}
+					}
+				},
+				"responses": {
+					"200": {
+						"description": "成功响应",
+						"content": {
+							"application/json": {
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"isAuthorized": true
+								},
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer",
+											"format": "int32"
+										},
+										"isAuthorized": {
+											"type": "boolean"
+										}
+									},
+									"required": ["isSuccess", "code", "isAuthorized"]
+								}
+							}
+						}
+					}
+				}
+			}
+		},
+		"/api/agent/doUpdateAgentNode": {
+			"post": {
+				"summary": "更新智能体节点",
+				"description": "",
+				"tags": ["Agent"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "认证令牌",
+						"required": false,
+						"schema": {
+							"type": "string",
+							"default": "bpm_client_1473687766939209728",
+							"example": "bpm_client_1473687766939209728"
+						}
+					}
+				],
+				"requestBody": {
+					"required": true,
+					"content": {
+						"application/json": {
+							"schema": {
+								"type": "object",
+								"properties": {
+									"id": {
+										"type": "string",
+										"format": "uuid"
+									},
+									"appAgentId": {
+										"type": "string",
+										"format": "uuid"
+									},
+									"parentId": {
+										"type": "string",
+										"format": "uuid"
+									},
+									"position": {
+										"type": "object",
+										"properties": {
+											"x": {
+												"type": "integer"
+											},
+											"y": {
+												"type": "integer"
+											}
+										},
+										"required": ["x", "y"]
+									},
+									"width": {
+										"type": "integer"
+									},
+									"height": {
+										"type": "integer"
+									},
+									"selected": {
+										"type": "boolean"
+									},
+									"nodeType": {
+										"type": "string",
+										"enum": ["custom", "start", "end", "condition", "task", "http-request"]
+									},
+									"zIndex": {
+										"type": "integer"
+									},
+									"data": {
+										"type": "object"
+									}
+								},
+								"required": [
+									"id",
+									"appAgentId",
+									"parentId",
+									"position",
+									"width",
+									"height",
+									"selected",
+									"nodeType",
+									"zIndex",
+									"data"
+								]
+							}
+						}
+					}
+				},
+				"responses": {
+					"200": {
+						"description": "成功响应",
+						"content": {
+							"application/json": {
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"isAuthorized": true
+								},
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer",
+											"format": "int32"
+										},
+										"isAuthorized": {
+											"type": "boolean"
+										}
+									},
+									"required": ["isSuccess", "code", "isAuthorized"]
+								}
+							}
+						}
+					}
+				}
+			}
+		},
+		"/api/agent/doTestNodeRunner": {
+			"post": {
+				"summary": "测试运行智能体节点",
+				"description": "",
+				"tags": ["Agent"],
+				"parameters": [
+					{
+						"name": "Authorization",
+						"in": "header",
+						"description": "认证令牌",
+						"required": false,
+						"schema": {
+							"type": "string",
+							"default": "bpm_client_1473687766939209728",
+							"example": "bpm_client_1473687766939209728"
+						}
+					}
+				],
+				"requestBody": {
+					"required": true,
+					"content": {
+						"application/json": {
+							"schema": {
+								"type": "object",
+								"properties": {
+									"id": {
+										"type": "string",
+										"format": "uuid"
+									},
+									"appAgentId": {
+										"type": "string",
+										"format": "uuid"
+									}
+								},
+								"required": ["id", "appAgentId"]
+							}
+						}
+					}
+				},
+				"responses": {
+					"200": {
+						"description": "成功响应",
+						"content": {
+							"application/json": {
+								"example": {
+									"isSuccess": true,
+									"code": 1,
+									"isAuthorized": true
+								},
+								"schema": {
+									"type": "object",
+									"properties": {
+										"isSuccess": {
+											"type": "boolean"
+										},
+										"code": {
+											"type": "integer",
+											"format": "int32"
+										},
+										"isAuthorized": {
+											"type": "boolean"
+										}
+									},
+									"required": ["isSuccess", "code", "isAuthorized"]
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	},
+	"components": {
+		"schemas": {
+			"AgentNode": {
+				"type": "object",
+				"properties": {
+					"appAgentId": {
+						"type": "string",
+						"format": "uuid"
+					},
+					"creationTime": {
+						"type": "string",
+						"format": "date-time"
+					},
+					"creatorUserId": {
+						"type": "string",
+						"format": "uuid"
+					},
+					"data": {
+						"$ref": "#/components/schemas/NodeData"
+					},
+					"height": {
+						"type": "integer"
+					},
+					"id": {
+						"type": "string",
+						"format": "uuid"
+					},
+					"isDeleted": {
+						"type": "boolean"
+					},
+					"position": {
+						"type": "object",
+						"properties": {
+							"x": {
+								"type": "integer"
+							},
+							"y": {
+								"type": "integer"
+							}
+						},
+						"required": ["x", "y"]
+					},
+					"selected": {
+						"type": "boolean"
+					},
+					"type": {
+						"type": "string",
+						"enum": ["custom", "start", "end", "condition", "task", "http-request"]
+					},
+					"updateTime": {
+						"type": "string",
+						"format": "date-time"
+					},
+					"width": {
+						"type": "integer"
+					},
+					"zIndex": {
+						"type": "integer"
+					}
+				},
+				"required": [
+					"appAgentId",
+					"creationTime",
+					"creatorUserId",
+					"data",
+					"id",
+					"position",
+					"type"
+				]
+			},
+			"NodeData": {
+				"type": "object",
+				"properties": {
+					"outputs": {
+						"type": "array",
+						"items": {
+							"type": "object",
+							"properties": {
+								"name": {
+									"type": "string"
+								},
+								"describe": {
+									"type": "string"
+								},
+								"type": {
+									"type": "string",
+									"enum": ["string", "number", "boolean", "object", "array"]
+								}
+							},
+							"required": ["name", "describe", "type"]
+						}
+					},
+					"output_can_alter": {
+						"type": "boolean"
+					},
+					"variables": {
+						"type": "array",
+						"items": {
+							"type": "string"
+						}
+					},
+					"method": {
+						"type": "string",
+						"enum": ["get", "post", "put", "delete", "patch", "head", "options"]
+					},
+					"ssl_verify": {
+						"type": "boolean"
+					},
+					"isInIteration": {
+						"type": "boolean"
+					},
+					"default_value": {
+						"type": "array",
+						"items": {
+							"type": "string"
+						}
+					},
+					"body": {
+						"$ref": "#/components/schemas/RequestBody"
+					},
+					"params": {
+						"type": "array",
+						"items": {
+							"type": "string"
+						}
+					},
+					"title": {
+						"type": "string"
+					},
+					"type": {
+						"type": "string",
+						"enum": ["http-request", "condition", "task"]
+					},
+					"error_strategy": {
+						"type": "string",
+						"enum": ["none", "retry", "abort", "continue"]
+					},
+					"retry_config": {
+						"type": "object",
+						"properties": {
+							"max_retries": {
+								"type": "integer",
+								"minimum": 0,
+								"maximum": 10
+							},
+							"retry_enabled": {
+								"type": "boolean"
+							},
+							"retry_interval": {
+								"type": "integer",
+								"minimum": 0,
+								"maximum": 5000
+							}
+						},
+						"required": ["max_retries", "retry_enabled", "retry_interval"]
+					},
+					"url": {
+						"type": "string",
+						"format": "uri"
+					},
+					"authorization": {
+						"type": "object",
+						"properties": {
+							"type": {
+								"type": "string",
+								"enum": ["none", "bearer", "basic", "api-key"]
+							},
+							"config": {
+								"type": "object",
+								"properties": {
+									"api_key": {
+										"type": "string"
+									},
+									"header": {
+										"type": "string"
+									},
+									"type": {
+										"type": "string"
+									}
+								}
+							}
+						},
+						"required": ["type", "config"]
+					},
+					"timeout_config": {
+						"type": "object",
+						"properties": {
+							"max_write_timeout": {
+								"type": "integer",
+								"minimum": 0
+							},
+							"max_read_timeout": {
+								"type": "integer",
+								"minimum": 0
+							},
+							"max_connect_timeout": {
+								"type": "integer",
+								"minimum": 0
+							}
+						},
+						"required": ["max_write_timeout", "max_read_timeout", "max_connect_timeout"]
+					},
+					"heads": {
+						"type": "array",
+						"items": {
+							"$ref": "#/components/schemas/HttpHeader"
+						}
+					},
+					"selected": {
+						"type": "boolean"
+					},
+					"desc": {
+						"type": "string"
+					},
+					"isInLoop": {
+						"type": "boolean"
+					}
+				},
+				"required": ["outputs", "method", "title", "type", "url"]
+			},
+			"RequestBody": {
+				"type": "object",
+				"properties": {
+					"data": {
+						"type": "array",
+						"items": {
+							"$ref": "#/components/schemas/RequestDataItem"
+						}
+					},
+					"type": {
+						"type": "string",
+						"enum": ["json", "form-data", "x-www-form-urlencoded", "raw", "binary"]
+					}
+				},
+				"required": ["data", "type"]
+			},
+			"RequestDataItem": {
+				"type": "object",
+				"properties": {
+					"type": {
+						"type": "string",
+						"enum": ["text", "file", "json"]
+					},
+					"value": {
+						"type": "string"
+					},
+					"key": {
+						"type": "string"
+					}
+				},
+				"required": ["type", "value"]
+			},
+			"HttpHeader": {
+				"type": "object",
+				"properties": {
+					"name": {
+						"type": "string"
+					},
+					"value": {
+						"type": "string"
+					}
+				},
+				"required": ["name", "value"]
+			}
+		},
+		"securitySchemes": {
+			"ApiKeyAuth": {
+				"type": "apiKey",
+				"in": "header",
+				"name": "Authorization"
+			}
+		}
+	},
+	"security": [
+		{
+			"ApiKeyAuth": []
+		}
+	]
+}

+ 5 - 1
packages/api-service/index.ts

@@ -1 +1,5 @@
-export * from './servers/api'
+import api from './servers/api'
+
+const agent = api.agent
+
+export { agent }

+ 4 - 4
packages/api-service/openapi2ts.config.ts

@@ -1,7 +1,7 @@
 import path from 'path'
 
 export default {
-  schemaPath: path.resolve(__dirname, './schema.json'),
-  serversPath: './servers',
-  requestLibPath: "import request from '@repo/api-client'",
-}
+	schemaPath: path.resolve(__dirname, './agent.openapi.json'),
+	serversPath: './servers',
+	requestLibPath: "import request from '@repo/api-client'"
+}

+ 153 - 0
packages/api-service/servers/api/agent.ts

@@ -0,0 +1,153 @@
+// @ts-ignore
+/* eslint-disable */
+import request from '@repo/api-client'
+
+/** 智能体编辑 POST /api/agent/doEditAgent */
+export async function postDoEditAgent(options?: { [key: string]: any }) {
+	return request<{ isSuccess: boolean; code: number; result: string; isAuthorized: boolean }>(
+		'/api/agent/doEditAgent',
+		{
+			method: 'POST',
+			...(options || {})
+		}
+	)
+}
+
+/** 智能体添加节点 POST /api/agent/doNewAgentNode */
+export async function postDoNewAgentNode(
+	body: {
+		appAgentId: string
+		position: { x: number; y: number }
+		width: number
+		height: number
+		selected: boolean
+		nodeType: 'custom' | 'start' | 'end' | 'condition' | 'task' | 'http-request'
+		zIndex: number
+		parentId: string
+	},
+	options?: { [key: string]: any }
+) {
+	return request<{ isSuccess: boolean; code: number; isAuthorized: boolean }>(
+		'/api/agent/doNewAgentNode',
+		{
+			method: 'POST',
+			headers: {
+				'Content-Type': 'application/json'
+			},
+			data: body,
+			...(options || {})
+		}
+	)
+}
+
+/** 保存智能体变量 POST /api/agent/doSaveAgentVariables */
+export async function postDoSaveAgentVariables(
+	body: {
+		appAgentId: string
+		conversation_variables: string[]
+		env_variables: {
+			name: string
+			value: string
+			type: 'string' | 'number' | 'boolean' | 'object' | 'array'
+		}[]
+	},
+	options?: { [key: string]: any }
+) {
+	return request<{ isSuccess: boolean; code: number; result: string; isAuthorized: boolean }>(
+		'/api/agent/doSaveAgentVariables',
+		{
+			method: 'POST',
+			headers: {
+				'Content-Type': 'application/json'
+			},
+			data: body,
+			...(options || {})
+		}
+	)
+}
+
+/** 测试运行智能体节点 POST /api/agent/doTestNodeRunner */
+export async function postDoTestNodeRunner(
+	body: {
+		id: string
+		appAgentId: string
+	},
+	options?: { [key: string]: any }
+) {
+	return request<{ isSuccess: boolean; code: number; isAuthorized: boolean }>(
+		'/api/agent/doTestNodeRunner',
+		{
+			method: 'POST',
+			headers: {
+				'Content-Type': 'application/json'
+			},
+			data: body,
+			...(options || {})
+		}
+	)
+}
+
+/** 更新智能体节点 POST /api/agent/doUpdateAgentNode */
+export async function postDoUpdateAgentNode(
+	body: {
+		id: string
+		appAgentId: string
+		parentId: string
+		position: { x: number; y: number }
+		width: number
+		height: number
+		selected: boolean
+		nodeType: 'custom' | 'start' | 'end' | 'condition' | 'task' | 'http-request'
+		zIndex: number
+		data: Record<string, any>
+	},
+	options?: { [key: string]: any }
+) {
+	return request<{ isSuccess: boolean; code: number; isAuthorized: boolean }>(
+		'/api/agent/doUpdateAgentNode',
+		{
+			method: 'POST',
+			headers: {
+				'Content-Type': 'application/json'
+			},
+			data: body,
+			...(options || {})
+		}
+	)
+}
+
+/** 获取智能体信息 POST /api/agent/getAgentInfo */
+export async function postGetAgentInfo(
+	body: {
+		id: string
+	},
+	options?: { [key: string]: any }
+) {
+	return request<{
+		isSuccess: boolean
+		code: number
+		result: {
+			conversation_variables: string[]
+			edges: string[]
+			env_variables: {
+				is_require?: boolean
+				name: string
+				type: 'string' | 'number' | 'boolean' | 'object' | 'array'
+				value: string
+			}[]
+			id: string
+			name: string
+			nodes: API.AgentNode[]
+			profilePhoto: string
+			viewPort: { x: number; y: number; zoom: number }
+		}
+		isAuthorized: boolean
+	}>('/api/agent/getAgentInfo', {
+		method: 'POST',
+		headers: {
+			'Content-Type': 'application/json'
+		},
+		data: body,
+		...(options || {})
+	})
+}

+ 0 - 23
packages/api-service/servers/api/audit.ts

@@ -1,23 +0,0 @@
-// @ts-ignore
-/* eslint-disable */
-import request from '@repo/api-client'
-
-/** Generate an audit Generate a security audit for your n8n instance. POST /audit */
-export async function postAudit(
-  body: {
-    additionalOptions?: {
-      daysAbandonedWorkflow?: number
-      categories?: ('credentials' | 'database' | 'nodes' | 'filesystem' | 'instance')[]
-    }
-  },
-  options?: { [key: string]: any }
-) {
-  return request<API.audit>('/audit', {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    data: body,
-    ...(options || {})
-  })
-}

+ 0 - 84
packages/api-service/servers/api/credential.ts

@@ -1,84 +0,0 @@
-// @ts-ignore
-/* eslint-disable */
-import request from '@repo/api-client'
-
-/** Create a credential Creates a credential that can be used by nodes of the specified type. POST /credentials */
-export async function postCredentials(body: API.credential, options?: { [key: string]: any }) {
-  return request<API.createCredentialResponse>('/credentials', {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Delete credential by ID Deletes a credential from your instance. You must be the owner of the credentials DELETE /credentials/${param0} */
-export async function deleteCredential(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.deleteCredentialParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.credential>(`/credentials/${param0}`, {
-    method: 'DELETE',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}
-
-/** Update credential by ID Updates an existing credential. You must be the owner of the credential. PATCH /credentials/${param0} */
-export async function updateCredential(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.updateCredentialParams,
-  body: API.updateCredentialRequest,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.createCredentialResponse>(`/credentials/${param0}`, {
-    method: 'PATCH',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Transfer a credential to another project. Transfer a credential to another project. PUT /credentials/${param0}/transfer */
-export async function putCredentialsIdTransfer(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.putCredentialsIdTransferParams,
-  body: {
-    /** The ID of the project to transfer the credential to. */
-    destinationProjectId: string
-  },
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<any>(`/credentials/${param0}/transfer`, {
-    method: 'PUT',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Show credential data schema GET /credentials/schema/${param0} */
-export async function getCredentialsSchemaCredentialTypeName(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getCredentialsSchemaCredentialTypeNameParams,
-  options?: { [key: string]: any }
-) {
-  const { credentialTypeName: param0, ...queryParams } = params
-  return request<Record<string, any>>(`/credentials/schema/${param0}`, {
-    method: 'GET',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}

+ 0 - 72
packages/api-service/servers/api/execution.ts

@@ -1,72 +0,0 @@
-// @ts-ignore
-/* eslint-disable */
-import request from '@repo/api-client'
-
-/** Retrieve all executions Retrieve all executions from your instance. GET /executions */
-export async function getExecutions(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getExecutionsParams,
-  options?: { [key: string]: any }
-) {
-  return request<API.executionList>('/executions', {
-    method: 'GET',
-    params: {
-      // limit has a default value: 100
-      limit: '100',
-      ...params
-    },
-    ...(options || {})
-  })
-}
-
-/** Retrieve an execution Retrieve an execution from your instance. GET /executions/${param0} */
-export async function getExecutionsId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getExecutionsIdParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.execution>(`/executions/${param0}`, {
-    method: 'GET',
-    params: {
-      ...queryParams
-    },
-    ...(options || {})
-  })
-}
-
-/** Delete an execution Deletes an execution from your instance. DELETE /executions/${param0} */
-export async function deleteExecutionsId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.deleteExecutionsIdParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.execution>(`/executions/${param0}`, {
-    method: 'DELETE',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}
-
-/** Retry an execution Retry an execution from your instance. POST /executions/${param0}/retry */
-export async function postExecutionsIdRetry(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.postExecutionsIdRetryParams,
-  body: {
-    /** Whether to load the currently saved workflow to execute instead of the one saved at the time of the execution. If set to true, it will retry with the latest version of the workflow. */
-    loadWorkflow?: boolean
-  },
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.execution>(`/executions/${param0}/retry`, {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}

+ 2 - 18
packages/api-service/servers/api/index.ts

@@ -2,23 +2,7 @@
 /* eslint-disable */
 // API 更新时间:
 // API 唯一标识:
-import * as audit from './audit'
-import * as credential from './credential'
-import * as execution from './execution'
-import * as tags from './tags'
-import * as workflow from './workflow'
-import * as user from './user'
-import * as sourceControl from './sourceControl'
-import * as variables from './variables'
-import * as projects from './projects'
+import * as agent from './agent'
 export default {
-  audit,
-  credential,
-  execution,
-  tags,
-  workflow,
-  user,
-  sourceControl,
-  variables,
-  projects
+  agent
 }

+ 0 - 123
packages/api-service/servers/api/projects.ts

@@ -1,123 +0,0 @@
-// @ts-ignore
-/* eslint-disable */
-import request from '@repo/api-client'
-
-/** Retrieve projects Retrieve projects from your instance. GET /projects */
-export async function getProjects(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getProjectsParams,
-  options?: { [key: string]: any }
-) {
-  return request<API.projectList>('/projects', {
-    method: 'GET',
-    params: {
-      // limit has a default value: 100
-      limit: '100',
-      ...params
-    },
-    ...(options || {})
-  })
-}
-
-/** Create a project Create a project on your instance. POST /projects */
-export async function postProjects(body: API.project, options?: { [key: string]: any }) {
-  return request<any>('/projects', {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Update a project Update a project on your instance. PUT /projects/${param0} */
-export async function putProjectsProjectId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.putProjectsProjectIdParams,
-  body: API.project,
-  options?: { [key: string]: any }
-) {
-  const { projectId: param0, ...queryParams } = params
-  return request<any>(`/projects/${param0}`, {
-    method: 'PUT',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Delete a project Delete a project from your instance. DELETE /projects/${param0} */
-export async function deleteProjectsProjectId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.deleteProjectsProjectIdParams,
-  options?: { [key: string]: any }
-) {
-  const { projectId: param0, ...queryParams } = params
-  return request<any>(`/projects/${param0}`, {
-    method: 'DELETE',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}
-
-/** Add one or more users to a project Add one or more users to a project on your instance. POST /projects/${param0}/users */
-export async function postProjectsProjectIdUsers(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.postProjectsProjectIdUsersParams,
-  body: {
-    /** A list of userIds and roles to add to the project. */
-    relations: { userId: string; role: string }[]
-  },
-  options?: { [key: string]: any }
-) {
-  const { projectId: param0, ...queryParams } = params
-  return request<any>(`/projects/${param0}/users`, {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Delete a user from a project Delete a user from a project on your instance. DELETE /projects/${param0}/users/${param1} */
-export async function deleteProjectsProjectIdUsersUserId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.deleteProjectsProjectIdUsersUserIdParams,
-  options?: { [key: string]: any }
-) {
-  const { projectId: param0, userId: param1, ...queryParams } = params
-  return request<any>(`/projects/${param0}/users/${param1}`, {
-    method: 'DELETE',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}
-
-/** Change a user's role in a project Change a user's role in a project. PATCH /projects/${param0}/users/${param1} */
-export async function patchProjectsProjectIdUsersUserId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.patchProjectsProjectIdUsersUserIdParams,
-  body: {
-    /** The role assigned to the user in the project. */
-    role: string
-  },
-  options?: { [key: string]: any }
-) {
-  const { projectId: param0, userId: param1, ...queryParams } = params
-  return request<any>(`/projects/${param0}/users/${param1}`, {
-    method: 'PATCH',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}

+ 0 - 15
packages/api-service/servers/api/sourceControl.ts

@@ -1,15 +0,0 @@
-// @ts-ignore
-/* eslint-disable */
-import request from '@repo/api-client'
-
-/** Pull changes from the remote repository Requires the Source Control feature to be licensed and connected to a repository. POST /source-control/pull */
-export async function postSourceControlPull(body: API.pull, options?: { [key: string]: any }) {
-  return request<API.importResult>('/source-control/pull', {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    data: body,
-    ...(options || {})
-  })
-}

+ 0 - 79
packages/api-service/servers/api/tags.ts

@@ -1,79 +0,0 @@
-// @ts-ignore
-/* eslint-disable */
-import request from '@repo/api-client'
-
-/** Retrieve all tags Retrieve all tags from your instance. GET /tags */
-export async function getTags(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getTagsParams,
-  options?: { [key: string]: any }
-) {
-  return request<API.tagList>('/tags', {
-    method: 'GET',
-    params: {
-      // limit has a default value: 100
-      limit: '100',
-      ...params
-    },
-    ...(options || {})
-  })
-}
-
-/** Create a tag Create a tag in your instance. POST /tags */
-export async function postTags(body: API.tag, options?: { [key: string]: any }) {
-  return request<API.tag>('/tags', {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Retrieves a tag Retrieves a tag. GET /tags/${param0} */
-export async function getTagsId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getTagsIdParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.tag>(`/tags/${param0}`, {
-    method: 'GET',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}
-
-/** Update a tag Update a tag. PUT /tags/${param0} */
-export async function putTagsId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.putTagsIdParams,
-  body: API.tag,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.tag>(`/tags/${param0}`, {
-    method: 'PUT',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Delete a tag Deletes a tag. DELETE /tags/${param0} */
-export async function deleteTagsId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.deleteTagsIdParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.tag>(`/tags/${param0}`, {
-    method: 'DELETE',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}

+ 61 - 637
packages/api-service/servers/api/typings.d.ts

@@ -1,643 +1,67 @@
 declare namespace API {
-  
-        type activeVersion =
-          {
-              /** Unique identifier for this workflow version */
-                'versionId'?: string;
-              /** The workflow this version belongs to */
-                'workflowId'?: string;
-                'nodes'?: node[];
-                'connections'?: Record<string, any>;
-              /** Comma-separated list of author IDs who contributed to this version */
-                'authors'?: string;
-                'createdAt'?: string;
-                'updatedAt'?: string;
-          }
-        
-  
-        type audit =
-          {
-                'Credentials Risk Report'?: Record<string, any>;
-                'Database Risk Report'?: Record<string, any>;
-                'Filesystem Risk Report'?: Record<string, any>;
-                'Nodes Risk Report'?: Record<string, any>;
-                'Instance Risk Report'?: Record<string, any>;
-          }
-        
-  
-        type Audit = [object Object];
-  
-        type create =
-          {
-                'id'?: string;
-                'key': string;
-                'value': string;
-                'type'?: string;
-                'projectId'?: string;
-          }
-        
-  
-        type createCredentialResponse =
-          {
-                'id': string;
-                'name': string;
-                'type': string;
-                'createdAt': string;
-                'updatedAt': string;
-          }
-        
-  
-        type credential =
-          {
-                'id'?: string;
-                'name': string;
-                'type': string;
-                'data': Record<string, any>;
-              /** Whether this credential has resolvable fields */
-                'isResolvable'?: boolean;
-                'createdAt'?: string;
-                'updatedAt'?: string;
-          }
-        
-  
-        type Credential = [object Object];
-  
-        type credentialType =
-          {
-                'displayName'?: string;
-                'name'?: string;
-                'type'?: string;
-                'default'?: string;
-          }
-        
-  
-        type CredentialType = [object Object];
-  
-        type deleteCredentialParams =
-          {
-              /** The credential ID that needs to be deleted */
-                'id': string;
-          }
-        
-  
-        type deleteExecutionsIdParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type deleteProjectsProjectIdParams =
-          {
-              /** The ID of the project. */
-                'projectId': string;
-          }
-        
-  
-        type deleteProjectsProjectIdUsersUserIdParams =
-          {
-              /** The ID of the project. */
-                'projectId': string;
-              /** The ID of the user. */
-                'userId': string;
-          }
-        
-  
-        type deleteTagsIdParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type deleteUsersIdParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type deleteVariablesIdParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type deleteWorkflowsIdParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type error =
-          {
-                'code'?: string;
-                'message': string;
-                'description'?: string;
-          }
-        
-  
-        type Error = [object Object];
-  
-        type execution =
-          {
-                'id'?: number;
-                'data'?: Record<string, any>;
-                'finished'?: boolean;
-                'mode'?: "cli" | "error" | "integrated" | "internal" | "manual" | "retry" | "trigger" | "webhook" | "evaluation" | "chat";
-                'retryOf'?: number;
-                'retrySuccessId'?: number;
-                'startedAt'?: string;
-              /** The time at which the execution stopped. Will only be null for executions that still have the status 'running'. */
-                'stoppedAt'?: string;
-                'workflowId'?: number;
-                'waitTill'?: string;
-                'customData'?: Record<string, any>;
-                'status'?: "canceled" | "crashed" | "error" | "new" | "running" | "success" | "unknown" | "waiting";
-          }
-        
-  
-        type Execution = [object Object];
-  
-        type executionList =
-          {
-                'data'?: execution[];
-              /** Paginate through executions by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection. */
-                'nextCursor'?: string;
-          }
-        
-  
-        type ExecutionList = [object Object];
-  
-        type getCredentialsSchemaCredentialTypeNameParams =
-          {
-              /** The credential type name that you want to get the schema for */
-                'credentialTypeName': string;
-          }
-        
-  
-        type getExecutionsIdParams =
-          {
-                ''?: any;
-                ''?: any;
-          }
-        
-  
-        type getExecutionsParams =
-          {
-                ''?: any;
-              /** Status to filter the executions by. */
-                'status'?: "canceled" | "error" | "running" | "success" | "waiting";
-              /** Workflow to filter the executions by. */
-                'workflowId'?: string;
-                'projectId'?: string;
-                ''?: any;
-                ''?: any;
-          }
-        
-  
-        type getProjectsParams =
-          {
-                ''?: any;
-                ''?: any;
-          }
-        
-  
-        type getTagsIdParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type getTagsParams =
-          {
-                ''?: any;
-                ''?: any;
-          }
-        
-  
-        type getUsersIdParams =
-          {
-                ''?: any;
-                ''?: any;
-          }
-        
-  
-        type getUsersParams =
-          {
-                ''?: any;
-                ''?: any;
-                ''?: any;
-                'projectId'?: string;
-          }
-        
-  
-        type getVariablesParams =
-          {
-                ''?: any;
-                ''?: any;
-                'projectId'?: string;
-                'state'?: "empty";
-          }
-        
-  
-        type getWorkflowsIdParams =
-          {
-              /** Set this to avoid retrieving pinned data */
-                'excludePinnedData'?: boolean;
-                ''?: any;
-          }
-        
-  
-        type getWorkflowsIdTagsParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type getWorkflowsIdVersionIdParams =
-          {
-                ''?: any;
-              /** The version ID to retrieve */
-                'versionId': string;
-          }
-        
-  
-        type getWorkflowsParams =
-          {
-                'active'?: boolean;
-                'tags'?: string;
-                'name'?: string;
-                'projectId'?: string;
-              /** Set this to avoid retrieving pinned data */
-                'excludePinnedData'?: boolean;
-                ''?: any;
-                ''?: any;
-          }
-        
-  
-        type importResult =
-          {
-                'variables'?: { 'added'?: string[]; 'changed'?: string[]; };
-                'credentials'?: { 'id'?: string; 'name'?: string; 'type'?: string; }[];
-                'workflows'?: { 'id'?: string; 'name'?: string; }[];
-                'tags'?: { 'tags'?: { 'id'?: string; 'name'?: string; }[]; 'mappings'?: { 'workflowId'?: string; 'tagId'?: string; }[]; };
-          }
-        
-  
-        type ImportResult = [object Object];
-  
-        type node =
-          {
-                'id'?: string;
-                'name'?: string;
-                'webhookId'?: string;
-                'disabled'?: boolean;
-                'notesInFlow'?: boolean;
-                'notes'?: string;
-                'type'?: string;
-                'typeVersion'?: number;
-                'executeOnce'?: boolean;
-                'alwaysOutputData'?: boolean;
-                'retryOnFail'?: boolean;
-                'maxTries'?: number;
-                'waitBetweenTries'?: number;
-              /** use onError instead */
-                'continueOnFail'?: boolean;
-                'onError'?: string;
-                'position'?: number[];
-                'parameters'?: Record<string, any>;
-                'credentials'?: Record<string, any>;
-                'createdAt'?: string;
-                'updatedAt'?: string;
-          }
-        
-  
-        type Node = [object Object];
-  
-        type patchProjectsProjectIdUsersUserIdParams =
-          {
-              /** The ID of the project. */
-                'projectId': string;
-              /** The ID of the user. */
-                'userId': string;
-          }
-        
-  
-        type patchUsersIdRoleParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type postExecutionsIdRetryParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type postProjectsProjectIdUsersParams =
-          {
-              /** The ID of the project. */
-                'projectId': string;
-          }
-        
-  
-        type postWorkflowsIdActivateParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type postWorkflowsIdDeactivateParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type project =
-          {
-                'id'?: string;
-                'name': string;
-                'type'?: string;
-          }
-        
-  
-        type projectList =
-          {
-                'data'?: project[];
-              /** Paginate through projects by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection. */
-                'nextCursor'?: string;
-          }
-        
-  
-        type pull =
-          {
-                'force'?: boolean;
-                'variables'?: Record<string, any>;
-          }
-        
-  
-        type Pull = [object Object];
-  
-        type putCredentialsIdTransferParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type putProjectsProjectIdParams =
-          {
-              /** The ID of the project. */
-                'projectId': string;
-          }
-        
-  
-        type putTagsIdParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type putVariablesIdParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type putWorkflowsIdParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type putWorkflowsIdTagsParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type putWorkflowsIdTransferParams =
-          {
-                ''?: any;
-          }
-        
-  
-        type role =
-          {
-                'id'?: number;
-                'name'?: string;
-                'scope'?: string;
-              /** Time the role was created. */
-                'createdAt'?: string;
-              /** Last time the role was updated. */
-                'updatedAt'?: string;
-          }
-        
-  
-        type Role = [object Object];
-  
-        type sharedWorkflow =
-          {
-                'role'?: string;
-                'workflowId'?: string;
-                'projectId'?: string;
-                'project'?: { 'id'?: string; 'name'?: string; 'type'?: string; };
-                'createdAt'?: string;
-                'updatedAt'?: string;
-          }
-        
-  
-        type tag =
-          {
-                'id'?: string;
-                'name': string;
-                'createdAt'?: string;
-                'updatedAt'?: string;
-          }
-        
-  
-        type Tag = [object Object];
-  
-        type tagIds = Record<string, any>;
-  
-        type tagList =
-          {
-                'data'?: tag[];
-              /** Paginate through tags by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection. */
-                'nextCursor'?: string;
-          }
-        
-  
-        type updateCredentialParams =
-          {
-              /** The credential ID that needs to be updated */
-                'id': string;
-          }
-        
-  
-        type updateCredentialRequest =
-          {
-              /** The name of the credential */
-                'name'?: string;
-              /** The credential type. If changing type, data must also be provided. */
-                'type'?: string;
-              /** The credential data. Required when changing credential type. */
-                'data'?: Record<string, any>;
-              /** Whether this credential is available globally */
-                'isGlobal'?: boolean;
-              /** Whether this credential has resolvable fields */
-                'isResolvable'?: boolean;
-              /** If true, unredacts and merges existing credential data with the provided data. If false, replaces the entire data object. */
-                'isPartialData'?: boolean;
-          }
-        
-  
-        type user =
-          {
-                'id'?: string;
-                'email': string;
-              /** User's first name */
-                'firstName'?: string;
-              /** User's last name */
-                'lastName'?: string;
-              /** Whether the user finished setting up their account in response to the invitation (true) or not (false). */
-                'isPending'?: boolean;
-              /** Time the user was created. */
-                'createdAt'?: string;
-              /** Last time the user was updated. */
-                'updatedAt'?: string;
-                'role'?: string;
-          }
-        
-  
-        type User = [object Object];
-  
-        type userList =
-          {
-                'data'?: user[];
-              /** Paginate through users by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection. */
-                'nextCursor'?: string;
-          }
-        
-  
-        type UserList = [object Object];
-  
-        type variable =
-          {
-                'id'?: string;
-                'key': string;
-                'value': string;
-                'type'?: string;
-                'project'?: project;
-          }
-        
-  
-        type variableList =
-          {
-                'data'?: variable[];
-              /** Paginate through variables by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection. */
-                'nextCursor'?: string;
-          }
-        
-  
-        type workflow =
-          {
-                'id'?: string;
-                'name': string;
-                'active'?: boolean;
-                'createdAt'?: string;
-                'updatedAt'?: string;
-                'nodes': node[];
-                'connections': Record<string, any>;
-                'settings': workflowSettings;
-                'staticData'?: string | Record<string, any>;
-                'tags'?: tag[];
-                'shared'?: sharedWorkflow[];
-                'activeVersion'?: activeVersion;
-          }
-        
-  
-        type Workflow = [object Object];
-  
-        type workflowList =
-          {
-                'data'?: workflow[];
-              /** Paginate through workflows by setting the cursor parameter to a nextCursor attribute returned by a previous request. Default value fetches the first "page" of the collection. */
-                'nextCursor'?: string;
-          }
-        
-  
-        type WorkflowList = [object Object];
-  
-        type workflowSettings =
-          {
-                'saveExecutionProgress'?: boolean;
-                'saveManualExecutions'?: boolean;
-                'saveDataErrorExecution'?: "all" | "none";
-                'saveDataSuccessExecution'?: "all" | "none";
-                'executionTimeout'?: number;
-              /** The ID of the workflow that contains the error trigger node. */
-                'errorWorkflow'?: string;
-                'timezone'?: string;
-                'executionOrder'?: string;
-              /** Controls which workflows are allowed to call this workflow using the Execute Workflow node.
+  type AgentNode = {
+    appAgentId: string
+    creationTime: string
+    creatorUserId: string
+    data: NodeData
+    height?: number
+    id: string
+    isDeleted?: boolean
+    position: { x: number; y: number }
+    selected?: boolean
+    type: 'custom' | 'start' | 'end' | 'condition' | 'task' | 'http-request'
+    updateTime?: string
+    width?: number
+    zIndex?: number
+  }
 
-Available options:
-- `any`: Any workflow can call this workflow (no restrictions)
-- `none`: No other workflows can call this workflow (completely blocked)
-- `workflowsFromSameOwner` (default): Only workflows owned by the same project can call this workflow
-  * For personal projects: Only workflows created by the same user
-  * For team projects: Only workflows within the same team project
-- `workflowsFromAList`: Only specific workflows listed in the `callerIds` field can call this workflow
-  * Requires the `callerIds` field to specify which workflow IDs are allowed
-  * See `callerIds` field documentation for usage
- */
-                'callerPolicy'?: "any" | "none" | "workflowsFromAList" | "workflowsFromSameOwner";
-              /** Comma-separated list of workflow IDs allowed to call this workflow (only used with workflowsFromAList policy) */
-                'callerIds'?: string;
-              /** Estimated time saved per execution in minutes */
-                'timeSavedPerExecution'?: number;
-              /** Controls whether this workflow is accessible via the Model Context Protocol (MCP).
+  type HttpHeader = {
+    name: string
+    value: string
+  }
 
-When enabled, this workflow can be called by MCP clients (AI assistants and other tools
-that support MCP). This allows external AI tools to discover and execute this workflow
-as part of their capabilities.
+  type NodeData = {
+    outputs: {
+      name: string
+      describe: string
+      type: 'string' | 'number' | 'boolean' | 'object' | 'array'
+    }[]
+    output_can_alter?: boolean
+    variables?: string[]
+    method: 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head' | 'options'
+    ssl_verify?: boolean
+    isInIteration?: boolean
+    default_value?: string[]
+    body?: RequestBody
+    params?: string[]
+    title: string
+    type: 'http-request' | 'condition' | 'task'
+    error_strategy?: 'none' | 'retry' | 'abort' | 'continue'
+    retry_config?: { max_retries: number; retry_enabled: boolean; retry_interval: number }
+    url: string
+    authorization?: {
+      type: 'none' | 'bearer' | 'basic' | 'api-key'
+      config: { api_key?: string; header?: string; type?: string }
+    }
+    timeout_config?: {
+      max_write_timeout: number
+      max_read_timeout: number
+      max_connect_timeout: number
+    }
+    heads?: HttpHeader[]
+    selected?: boolean
+    desc?: string
+    isInLoop?: boolean
+  }
 
-Requirements for enabling MCP access:
-- The workflow must be active (not deactivated)
-- The workflow must contain at least one active Webhook node
-- Only webhook-triggered workflows can be exposed via MCP
+  type RequestBody = {
+    data: RequestDataItem[]
+    type: 'json' | 'form-data' | 'x-www-form-urlencoded' | 'raw' | 'binary'
+  }
 
-Security note: When a workflow is available in MCP, it can be discovered and executed
-by any MCP client that has the appropriate API credentials for your n8n instance.
- */
-                'availableInMCP'?: boolean;
-          }
-        
-  
-        type WorkflowSettings = [object Object];
-  
-        type workflowTags = tag[];
-  
-        type workflowVersion =
-          {
-              /** The version ID of this workflow snapshot */
-                'versionId': string;
-              /** The workflow ID this version belongs to */
-                'workflowId': string;
-              /** Nodes as they were in this version */
-                'nodes': node[];
-              /** Connections as they were in this version */
-                'connections': Record<string, any>;
-              /** Authors who created this version */
-                'authors': string;
-              /** Workflow name at this version */
-                'name'?: string;
-              /** Workflow description at this version */
-                'description'?: string;
-              /** When this version was created */
-                'createdAt'?: string;
-              /** When this version was last updated */
-                'updatedAt'?: string;
-          }
-        
-  
+  type RequestDataItem = {
+    type: 'text' | 'file' | 'json'
+    value: string
+    key?: string
+  }
 }

+ 0 - 90
packages/api-service/servers/api/user.ts

@@ -1,90 +0,0 @@
-// @ts-ignore
-/* eslint-disable */
-import request from '@repo/api-client'
-
-/** Retrieve all users Retrieve all users from your instance. Only available for the instance owner. GET /users */
-export async function getUsers(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getUsersParams,
-  options?: { [key: string]: any }
-) {
-  return request<API.userList>('/users', {
-    method: 'GET',
-    params: {
-      // limit has a default value: 100
-      limit: '100',
-
-      ...params
-    },
-    ...(options || {})
-  })
-}
-
-/** Create multiple users Create one or more users. POST /users */
-export async function postUsers(
-  body: { email: string; role?: string }[],
-  options?: { [key: string]: any }
-) {
-  return request<{
-    user?: { id?: string; email?: string; inviteAcceptUrl?: string; emailSent?: boolean }
-    error?: string
-  }>('/users', {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Get user by ID/Email Retrieve a user from your instance. Only available for the instance owner. GET /users/${param0} */
-export async function getUsersId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getUsersIdParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.user>(`/users/${param0}`, {
-    method: 'GET',
-    params: {
-      ...queryParams
-    },
-    ...(options || {})
-  })
-}
-
-/** Delete a user Delete a user from your instance. DELETE /users/${param0} */
-export async function deleteUsersId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.deleteUsersIdParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<any>(`/users/${param0}`, {
-    method: 'DELETE',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}
-
-/** Change a user's global role Change a user's global role PATCH /users/${param0}/role */
-export async function patchUsersIdRole(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.patchUsersIdRoleParams,
-  body: {
-    newRoleName: string
-  },
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<any>(`/users/${param0}/role`, {
-    method: 'PATCH',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}

+ 0 - 66
packages/api-service/servers/api/variables.ts

@@ -1,66 +0,0 @@
-// @ts-ignore
-/* eslint-disable */
-import request from '@repo/api-client'
-
-/** Retrieve variables Retrieve variables from your instance. GET /variables */
-export async function getVariables(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getVariablesParams,
-  options?: { [key: string]: any }
-) {
-  return request<API.variableList>('/variables', {
-    method: 'GET',
-    params: {
-      // limit has a default value: 100
-      limit: '100',
-
-      ...params
-    },
-    ...(options || {})
-  })
-}
-
-/** Create a variable Create a variable in your instance. POST /variables */
-export async function postVariables(body: API.create, options?: { [key: string]: any }) {
-  return request<any>('/variables', {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Update a variable Update a variable from your instance. PUT /variables/${param0} */
-export async function putVariablesId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.putVariablesIdParams,
-  body: API.create,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<any>(`/variables/${param0}`, {
-    method: 'PUT',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Delete a variable Delete a variable from your instance. DELETE /variables/${param0} */
-export async function deleteVariablesId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.deleteVariablesIdParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<any>(`/variables/${param0}`, {
-    method: 'DELETE',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}

+ 0 - 190
packages/api-service/servers/api/workflow.ts

@@ -1,190 +0,0 @@
-// @ts-ignore
-/* eslint-disable */
-import request from '@repo/api-client'
-
-/** Retrieve all workflows Retrieve all workflows from your instance. GET /workflows */
-export async function getWorkflows(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getWorkflowsParams,
-  options?: { [key: string]: any }
-) {
-  return request<API.workflowList>('/workflows', {
-    method: 'GET',
-    params: {
-      // limit has a default value: 100
-      limit: '100',
-      ...params
-    },
-    ...(options || {})
-  })
-}
-
-/** Create a workflow Create a workflow in your instance. POST /workflows */
-export async function postWorkflows(body: API.workflow, options?: { [key: string]: any }) {
-  return request<API.workflow>('/workflows', {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Retrieve a workflow Retrieve a workflow. GET /workflows/${param0} */
-export async function getWorkflowsId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getWorkflowsIdParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.workflow>(`/workflows/${param0}`, {
-    method: 'GET',
-    params: {
-      ...queryParams
-    },
-    ...(options || {})
-  })
-}
-
-/** Update a workflow Update a workflow. If the workflow is published, the updated version will be automatically re-published. PUT /workflows/${param0} */
-export async function putWorkflowsId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.putWorkflowsIdParams,
-  body: API.workflow,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.workflow>(`/workflows/${param0}`, {
-    method: 'PUT',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Delete a workflow Delete a workflow. DELETE /workflows/${param0} */
-export async function deleteWorkflowsId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.deleteWorkflowsIdParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.workflow>(`/workflows/${param0}`, {
-    method: 'DELETE',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}
-
-/** Retrieves a specific version of a workflow Retrieves a specific version of a workflow from workflow history. GET /workflows/${param0}/${param1} */
-export async function getWorkflowsIdVersionId(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getWorkflowsIdVersionIdParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, versionId: param1, ...queryParams } = params
-  return request<API.workflowVersion>(`/workflows/${param0}/${param1}`, {
-    method: 'GET',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}
-
-/** Publish a workflow Publish a workflow. In n8n v1, this action was termed activating a workflow. POST /workflows/${param0}/activate */
-export async function postWorkflowsIdActivate(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.postWorkflowsIdActivateParams,
-  body: {
-    /** The specific version ID to activate or publish. If not provided, the latest version is used. */
-    versionId?: string
-    /** Optional name for the workflow version during activation. */
-    name?: string
-    /** Optional description for the workflow version during activation. */
-    description?: string
-  },
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.workflow>(`/workflows/${param0}/activate`, {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Deactivate a workflow Deactivate a workflow. POST /workflows/${param0}/deactivate */
-export async function postWorkflowsIdDeactivate(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.postWorkflowsIdDeactivateParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.workflow>(`/workflows/${param0}/deactivate`, {
-    method: 'POST',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}
-
-/** Get workflow tags Get workflow tags. GET /workflows/${param0}/tags */
-export async function getWorkflowsIdTags(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.getWorkflowsIdTagsParams,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.workflowTags>(`/workflows/${param0}/tags`, {
-    method: 'GET',
-    params: { ...queryParams },
-    ...(options || {})
-  })
-}
-
-/** Update tags of a workflow Update tags of a workflow. PUT /workflows/${param0}/tags */
-export async function putWorkflowsIdTags(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.putWorkflowsIdTagsParams,
-  body: API.tagIds,
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<API.workflowTags>(`/workflows/${param0}/tags`, {
-    method: 'PUT',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}
-
-/** Transfer a workflow to another project Transfer a workflow to another project PUT /workflows/${param0}/transfer */
-export async function putWorkflowsIdTransfer(
-  // 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
-  params: API.putWorkflowsIdTransferParams,
-  body: {
-    /** The ID of the project to transfer the workflow to. */
-    destinationProjectId: string
-  },
-  options?: { [key: string]: any }
-) {
-  const { id: param0, ...queryParams } = params
-  return request<any>(`/workflows/${param0}/transfer`, {
-    method: 'PUT',
-    headers: {
-      'Content-Type': 'application/json'
-    },
-    params: { ...queryParams },
-    data: body,
-    ...(options || {})
-  })
-}

+ 8 - 0
packages/workflow/src/components/elements/node-temp/HttpNode1.vue

@@ -120,6 +120,14 @@ const methodColors: Record<string, string> = {
 			</div>
 		</div>
 
+		<!-- 输入连接点 -->
+		<CanvasHandle
+			handle-id="http-node-input"
+			type="target"
+			:connections-count="1"
+			:position="Position.Left"
+		/>
+
 		<!-- 输出连接点 - 成功 -->
 		<CanvasHandle
 			handle-id="http-node-output1"

+ 86 - 10
pnpm-lock.yaml

@@ -176,6 +176,9 @@ importers:
         specifier: '4'
         version: 4.6.4(vue@3.5.27(typescript@5.9.3))
     devDependencies:
+      '@repo/api-service':
+        specifier: workspace:*
+        version: link:../../packages/api-service
       '@repo/ui':
         specifier: workspace:*
         version: link:../../packages/ui
@@ -187,7 +190,7 @@ importers:
         version: 4.17.12
       '@vitejs/plugin-vue':
         specifier: ^6.0.1
-        version: 6.0.3(rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))(vue@3.5.27(typescript@5.9.3))
+        version: 6.0.3(rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))(vue@3.5.27(typescript@5.9.3))
       '@vue/tsconfig':
         specifier: ^0.8.1
         version: 0.8.1(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3))
@@ -202,7 +205,7 @@ importers:
         version: 5.9.3
       unocss:
         specifier: ^66.6.0
-        version: 66.6.0(postcss@5.2.18)(rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))
+        version: 66.6.0(postcss@5.2.18)(rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))
       unplugin-auto-import:
         specifier: ^21.0.0
         version: 21.0.0(@vueuse/core@13.9.0(vue@3.5.27(typescript@5.9.3)))
@@ -214,13 +217,13 @@ importers:
         version: 31.0.0(vue@3.5.27(typescript@5.9.3))
       vite:
         specifier: npm:rolldown-vite@7.2.5
-        version: rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)
+        version: rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)
       vite-plugin-monaco-editor:
         specifier: ^1.1.0
         version: 1.1.0(monaco-editor@0.55.1)
       vite-plugin-svg-icons:
         specifier: ^2.0.1
-        version: 2.0.1(rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))
+        version: 2.0.1(rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))
       vue-tsc:
         specifier: ^3.1.4
         version: 3.2.2(typescript@5.9.3)
@@ -230,10 +233,19 @@ importers:
       axios:
         specifier: ^1.13.2
         version: 1.13.2
+      qs:
+        specifier: ^6.14.1
+        version: 6.14.1
     devDependencies:
       '@repo/typescript-config':
         specifier: workspace:*
         version: link:../typescript-config
+      '@types/node':
+        specifier: ^25.1.0
+        version: 25.1.0
+      '@types/qs':
+        specifier: ^6.14.0
+        version: 6.14.0
       '@umijs/openapi':
         specifier: ^1.14.1
         version: 1.14.1(chokidar@5.0.0)(typescript@5.9.3)
@@ -2603,9 +2615,15 @@ packages:
   '@types/node@24.10.9':
     resolution: {integrity: sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==}
 
+  '@types/node@25.1.0':
+    resolution: {integrity: sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==}
+
   '@types/prop-types@15.7.15':
     resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==}
 
+  '@types/qs@6.14.0':
+    resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==}
+
   '@types/react-dom@18.3.7':
     resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==}
     peerDependencies:
@@ -5931,6 +5949,10 @@ packages:
     resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
     engines: {node: '>=6'}
 
+  qs@6.14.1:
+    resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==}
+    engines: {node: '>=0.6'}
+
   quansync@0.2.11:
     resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
 
@@ -10129,8 +10151,14 @@ snapshots:
     dependencies:
       undici-types: 7.16.0
 
+  '@types/node@25.1.0':
+    dependencies:
+      undici-types: 7.16.0
+
   '@types/prop-types@15.7.15': {}
 
+  '@types/qs@6.14.0': {}
+
   '@types/react-dom@18.3.7(@types/react@18.3.27)':
     dependencies:
       '@types/react': 18.3.27
@@ -10378,6 +10406,14 @@ snapshots:
     optionalDependencies:
       vite: rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)
 
+  '@unocss/astro@66.6.0(rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))':
+    dependencies:
+      '@unocss/core': 66.6.0
+      '@unocss/reset': 66.6.0
+      '@unocss/vite': 66.6.0(rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))
+    optionalDependencies:
+      vite: rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)
+
   '@unocss/cli@66.6.0':
     dependencies:
       '@jridgewell/remapping': 2.3.5
@@ -10528,6 +10564,19 @@ snapshots:
       unplugin-utils: 0.3.1
       vite: rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)
 
+  '@unocss/vite@66.6.0(rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))':
+    dependencies:
+      '@jridgewell/remapping': 2.3.5
+      '@unocss/config': 66.6.0
+      '@unocss/core': 66.6.0
+      '@unocss/inspector': 66.6.0
+      chokidar: 5.0.0
+      magic-string: 0.30.21
+      pathe: 2.0.3
+      tinyglobby: 0.2.15
+      unplugin-utils: 0.3.1
+      vite: rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)
+
   '@unrs/resolver-binding-android-arm-eabi@1.11.1':
     optional: true
 
@@ -10593,6 +10642,12 @@ snapshots:
       vite: rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)
       vue: 3.5.27(typescript@5.9.3)
 
+  '@vitejs/plugin-vue@6.0.3(rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))(vue@3.5.27(typescript@5.9.3))':
+    dependencies:
+      '@rolldown/pluginutils': 1.0.0-beta.53
+      vite: rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)
+      vue: 3.5.27(typescript@5.9.3)
+
   '@volar/language-core@2.4.27':
     dependencies:
       '@volar/source-map': 2.4.27
@@ -14334,6 +14389,10 @@ snapshots:
 
   punycode@2.3.1: {}
 
+  qs@6.14.1:
+    dependencies:
+      side-channel: 1.1.0
+
   quansync@0.2.11: {}
 
   quansync@1.0.0: {}
@@ -14628,6 +14687,23 @@ snapshots:
       less: 4.5.1
       yaml: 1.10.2
 
+  rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2):
+    dependencies:
+      '@oxc-project/runtime': 0.97.0
+      fdir: 6.5.0(picomatch@4.0.3)
+      lightningcss: 1.31.1
+      picomatch: 4.0.3
+      postcss: 8.5.6
+      rolldown: 1.0.0-beta.50
+      tinyglobby: 0.2.15
+    optionalDependencies:
+      '@types/node': 25.1.0
+      esbuild: 0.27.2
+      fsevents: 2.3.3
+      jiti: 2.6.1
+      less: 4.5.1
+      yaml: 1.10.2
+
   rolldown@1.0.0-beta.50:
     dependencies:
       '@oxc-project/types': 0.97.0
@@ -15392,9 +15468,9 @@ snapshots:
 
   universalify@2.0.1: {}
 
-  unocss@66.6.0(postcss@5.2.18)(rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)):
+  unocss@66.6.0(postcss@5.2.18)(rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)):
     dependencies:
-      '@unocss/astro': 66.6.0(rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))
+      '@unocss/astro': 66.6.0(rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))
       '@unocss/cli': 66.6.0
       '@unocss/core': 66.6.0
       '@unocss/postcss': 66.6.0(postcss@5.2.18)
@@ -15412,9 +15488,9 @@ snapshots:
       '@unocss/transformer-compile-class': 66.6.0
       '@unocss/transformer-directives': 66.6.0
       '@unocss/transformer-variant-group': 66.6.0
-      '@unocss/vite': 66.6.0(rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))
+      '@unocss/vite': 66.6.0(rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2))
     optionalDependencies:
-      vite: rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)
+      vite: rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)
     transitivePeerDependencies:
       - postcss
       - supports-color
@@ -15574,7 +15650,7 @@ snapshots:
     dependencies:
       monaco-editor: 0.55.1
 
-  vite-plugin-svg-icons@2.0.1(rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)):
+  vite-plugin-svg-icons@2.0.1(rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)):
     dependencies:
       '@types/svgo': 2.6.4
       cors: 2.8.6
@@ -15584,7 +15660,7 @@ snapshots:
       pathe: 0.2.0
       svg-baker: 1.7.0
       svgo: 2.8.0
-      vite: rolldown-vite@7.2.5(@types/node@24.10.9)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)
+      vite: rolldown-vite@7.2.5(@types/node@25.1.0)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(yaml@1.10.2)
     transitivePeerDependencies:
       - supports-color