Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d954279c9c | |||
| 9515a4d121 |
@@ -225,11 +225,10 @@ class TextToSqlNode(BaseNode):
|
|||||||
error='请输入要查询的问题',
|
error='请输入要查询的问题',
|
||||||
)
|
)
|
||||||
|
|
||||||
if not model_id:
|
from ai_platform.services.llm_service import LLMService
|
||||||
return NodeResult(
|
|
||||||
success=False,
|
llm_service = LLMService(context.db_session)
|
||||||
error='请选择 LLM 模型',
|
model_id = await llm_service.resolve_chat_model_id(model_id)
|
||||||
)
|
|
||||||
|
|
||||||
# Step 1: 获取数据库 Schema
|
# Step 1: 获取数据库 Schema
|
||||||
|
|
||||||
@@ -248,10 +247,7 @@ class TextToSqlNode(BaseNode):
|
|||||||
|
|
||||||
# Step 2: 调用 LLM 生成 SQL
|
# Step 2: 调用 LLM 生成 SQL
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from ai_platform.services.llm_service import LLMService
|
|
||||||
|
|
||||||
db_type = await self._get_db_type(db_connection)
|
db_type = await self._get_db_type(db_connection)
|
||||||
llm_service = LLMService(context.db_session)
|
|
||||||
llm_result = None
|
llm_result = None
|
||||||
use_function_calling = self.config.get('use_function_calling', True)
|
use_function_calling = self.config.get('use_function_calling', True)
|
||||||
|
|
||||||
@@ -354,6 +350,7 @@ class TextToSqlNode(BaseNode):
|
|||||||
tokens_used=response.total_tokens,
|
tokens_used=response.total_tokens,
|
||||||
elapsed_time=elapsed_time,
|
elapsed_time=elapsed_time,
|
||||||
metadata={
|
metadata={
|
||||||
|
'model_id': str(model_id),
|
||||||
'model': response.model,
|
'model': response.model,
|
||||||
'thought': thought,
|
'thought': thought,
|
||||||
'suggested_next_node': 'db_sql',
|
'suggested_next_node': 'db_sql',
|
||||||
@@ -404,13 +401,22 @@ class TextToSqlNode(BaseNode):
|
|||||||
)
|
)
|
||||||
return NodeResult(success=False, error='请输入要查询的问题')
|
return NodeResult(success=False, error='请输入要查询的问题')
|
||||||
|
|
||||||
if not model_id:
|
import asyncio
|
||||||
|
from ai_platform.services.llm_service import LLMService
|
||||||
|
|
||||||
|
llm_service = LLMService(context.db_session)
|
||||||
|
try:
|
||||||
|
model_id = asyncio.get_event_loop().run_until_complete(
|
||||||
|
llm_service.resolve_chat_model_id(model_id)
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
error_message = str(e)
|
||||||
yield TextToSqlStreamEvent(
|
yield TextToSqlStreamEvent(
|
||||||
event_type='error',
|
event_type='error',
|
||||||
content='请选择 LLM 模型',
|
content=error_message,
|
||||||
is_finished=True,
|
is_finished=True,
|
||||||
)
|
)
|
||||||
return NodeResult(success=False, error='请选择 LLM 模型')
|
return NodeResult(success=False, error=error_message)
|
||||||
|
|
||||||
# Step 1: 获取数据库 Schema
|
# Step 1: 获取数据库 Schema
|
||||||
yield TextToSqlStreamEvent(
|
yield TextToSqlStreamEvent(
|
||||||
@@ -420,7 +426,6 @@ class TextToSqlNode(BaseNode):
|
|||||||
|
|
||||||
table_relations = self.config.get('table_relations', []) # 手动指定的表关系
|
table_relations = self.config.get('table_relations', []) # 手动指定的表关系
|
||||||
|
|
||||||
import asyncio
|
|
||||||
schema_context = asyncio.get_event_loop().run_until_complete(
|
schema_context = asyncio.get_event_loop().run_until_complete(
|
||||||
self._get_schema_context(
|
self._get_schema_context(
|
||||||
db_connection,
|
db_connection,
|
||||||
@@ -449,13 +454,10 @@ class TextToSqlNode(BaseNode):
|
|||||||
)
|
)
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from ai_platform.services.llm_service import LLMService
|
|
||||||
|
|
||||||
db_type = asyncio.get_event_loop().run_until_complete(
|
db_type = asyncio.get_event_loop().run_until_complete(
|
||||||
self._get_db_type(db_connection)
|
self._get_db_type(db_connection)
|
||||||
)
|
)
|
||||||
|
|
||||||
llm_service = LLMService()
|
|
||||||
accumulated_content = ''
|
accumulated_content = ''
|
||||||
total_tokens = 0
|
total_tokens = 0
|
||||||
llm_result = None
|
llm_result = None
|
||||||
@@ -566,6 +568,7 @@ class TextToSqlNode(BaseNode):
|
|||||||
tokens_used=total_tokens,
|
tokens_used=total_tokens,
|
||||||
elapsed_time=elapsed_time,
|
elapsed_time=elapsed_time,
|
||||||
metadata={
|
metadata={
|
||||||
|
'model_id': str(model_id),
|
||||||
'thought': thought,
|
'thought': thought,
|
||||||
'suggested_next_node': 'db_sql',
|
'suggested_next_node': 'db_sql',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -35,6 +35,24 @@ import { ChatBox } from '#/components/ChatBox';
|
|||||||
import { useChatApi } from './composables/useChatApi';
|
import { useChatApi } from './composables/useChatApi';
|
||||||
import { useEventHandler } from './composables/useEventHandler';
|
import { useEventHandler } from './composables/useEventHandler';
|
||||||
|
|
||||||
|
const AppDesignPanel = defineAsyncComponent(() =>
|
||||||
|
import('#/components/form-editor/AppDesignPanel.vue'),
|
||||||
|
);
|
||||||
|
const AppSettingsPanel = defineAsyncComponent(() =>
|
||||||
|
import('#/components/form-editor/AppSettingsPanel.vue'),
|
||||||
|
);
|
||||||
|
const DashboardBasicInfoConfirmPanel = defineAsyncComponent(() =>
|
||||||
|
import('#/components/form-editor/DashboardBasicInfoConfirmPanel.vue'),
|
||||||
|
);
|
||||||
|
const DashboardDesignConfirmPanel = defineAsyncComponent(() =>
|
||||||
|
import('#/components/form-editor/DashboardDesignConfirmPanel.vue'),
|
||||||
|
);
|
||||||
|
const DashboardPublishConfirmPanel = defineAsyncComponent(() =>
|
||||||
|
import('#/components/form-editor/DashboardPublishConfirmPanel.vue'),
|
||||||
|
);
|
||||||
|
const DesignEditorPanel = defineAsyncComponent(() =>
|
||||||
|
import('#/components/form-editor/DesignEditorPanel.vue'),
|
||||||
|
);
|
||||||
const SystemSummaryConfirmPanel = defineAsyncComponent(() =>
|
const SystemSummaryConfirmPanel = defineAsyncComponent(() =>
|
||||||
import('#/components/form-editor/SystemSummaryConfirmPanel.vue'),
|
import('#/components/form-editor/SystemSummaryConfirmPanel.vue'),
|
||||||
);
|
);
|
||||||
@@ -188,7 +206,25 @@ const variablesDialogVisible = ref(false);
|
|||||||
const variablesForm = ref<Record<string, any>>({});
|
const variablesForm = ref<Record<string, any>>({});
|
||||||
const pendingMessage = ref('');
|
const pendingMessage = ref('');
|
||||||
|
|
||||||
// ==================== 轻量版设计预览面板状态 ====================
|
// ==================== 设计预览面板状态 ====================
|
||||||
|
const showDesignPanel = ref(false);
|
||||||
|
const currentDesign = ref<DesignPreviewData | undefined>(undefined);
|
||||||
|
|
||||||
|
const showAppDesignPanel = ref(false);
|
||||||
|
const currentAppDesign = ref<DesignPreviewData | undefined>(undefined);
|
||||||
|
|
||||||
|
const showAppSettingsPanel = ref(false);
|
||||||
|
const currentAppSettings = ref<DesignPreviewData | undefined>(undefined);
|
||||||
|
|
||||||
|
const showDashboardBasicInfoPanel = ref(false);
|
||||||
|
const currentDashboardBasicInfo = ref<DesignPreviewData | undefined>(undefined);
|
||||||
|
|
||||||
|
const showDashboardDesignPanel = ref(false);
|
||||||
|
const currentDashboardDesign = ref<DesignPreviewData | undefined>(undefined);
|
||||||
|
|
||||||
|
const showDashboardPublishPanel = ref(false);
|
||||||
|
const currentDashboardPublish = ref<DesignPreviewData | undefined>(undefined);
|
||||||
|
|
||||||
const showSystemSummaryPanel = ref(false);
|
const showSystemSummaryPanel = ref(false);
|
||||||
const currentSystemSummary = ref<DesignPreviewData | undefined>(undefined);
|
const currentSystemSummary = ref<DesignPreviewData | undefined>(undefined);
|
||||||
|
|
||||||
@@ -198,7 +234,15 @@ const loadingAnimationTitle = ref('AI 正在开发...');
|
|||||||
|
|
||||||
// 是否有任何设计面板打开
|
// 是否有任何设计面板打开
|
||||||
const hasAnyDesignPanelOpen = computed(
|
const hasAnyDesignPanelOpen = computed(
|
||||||
() => showSystemSummaryPanel.value || showLoadingAnimation.value,
|
() =>
|
||||||
|
showDesignPanel.value ||
|
||||||
|
showAppDesignPanel.value ||
|
||||||
|
showAppSettingsPanel.value ||
|
||||||
|
showDashboardBasicInfoPanel.value ||
|
||||||
|
showDashboardDesignPanel.value ||
|
||||||
|
showDashboardPublishPanel.value ||
|
||||||
|
showSystemSummaryPanel.value ||
|
||||||
|
showLoadingAnimation.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
// ==================== 工作流变量 ====================
|
// ==================== 工作流变量 ====================
|
||||||
@@ -246,15 +290,43 @@ const handleDesignPreview = (data: DesignPreviewData) => {
|
|||||||
// 关闭加载动画
|
// 关闭加载动画
|
||||||
showLoadingAnimation.value = false;
|
showLoadingAnimation.value = false;
|
||||||
|
|
||||||
if (data.type === 'system_summary') {
|
switch (data.type) {
|
||||||
|
case 'app_design': {
|
||||||
|
currentAppDesign.value = data;
|
||||||
|
showAppDesignPanel.value = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'app_settings': {
|
||||||
|
currentAppSettings.value = data;
|
||||||
|
showAppSettingsPanel.value = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'dashboard_basic_info': {
|
||||||
|
currentDashboardBasicInfo.value = data;
|
||||||
|
showDashboardBasicInfoPanel.value = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'dashboard_design': {
|
||||||
|
currentDashboardDesign.value = data;
|
||||||
|
showDashboardDesignPanel.value = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'dashboard_publish': {
|
||||||
|
currentDashboardPublish.value = data;
|
||||||
|
showDashboardPublishPanel.value = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'system_summary': {
|
||||||
currentSystemSummary.value = data;
|
currentSystemSummary.value = data;
|
||||||
showSystemSummaryPanel.value = true;
|
showSystemSummaryPanel.value = true;
|
||||||
return undefined;
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
currentDesign.value = data;
|
||||||
|
showDesignPanel.value = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
waitingForInput.value = false;
|
|
||||||
waitingConfig.value = null;
|
|
||||||
return `**${data.title || '设计预览'}**\n\n轻量版已移除在线开发设计确认面板。请将该流程改为 LLM、对话、条件、并行、子流程或知识库检索等 AI 协作节点后再运行。`;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const { handleStreamEvent, updateAssistantMessage } = useEventHandler({
|
const { handleStreamEvent, updateAssistantMessage } = useEventHandler({
|
||||||
@@ -738,6 +810,78 @@ const createDesignCloseHandler = (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDesignConfirm = createDesignConfirmHandler(
|
||||||
|
showDesignPanel,
|
||||||
|
currentDesign,
|
||||||
|
'确认设计',
|
||||||
|
);
|
||||||
|
const handleDesignClose = createDesignCloseHandler(
|
||||||
|
showDesignPanel,
|
||||||
|
currentDesign,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleAppDesignConfirm = createDesignConfirmHandler(
|
||||||
|
showAppDesignPanel,
|
||||||
|
currentAppDesign,
|
||||||
|
'确认应用设计',
|
||||||
|
);
|
||||||
|
const handleAppDesignClose = createDesignCloseHandler(
|
||||||
|
showAppDesignPanel,
|
||||||
|
currentAppDesign,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleAppSettingsConfirm = createDesignConfirmHandler(
|
||||||
|
showAppSettingsPanel,
|
||||||
|
currentAppSettings,
|
||||||
|
'确认应用设置',
|
||||||
|
);
|
||||||
|
const handleAppSettingsClose = createDesignCloseHandler(
|
||||||
|
showAppSettingsPanel,
|
||||||
|
currentAppSettings,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDashboardBasicInfoConfirm = createDesignConfirmHandler(
|
||||||
|
showDashboardBasicInfoPanel,
|
||||||
|
currentDashboardBasicInfo,
|
||||||
|
'确认仪表盘基础信息',
|
||||||
|
);
|
||||||
|
const handleDashboardBasicInfoClose = createDesignCloseHandler(
|
||||||
|
showDashboardBasicInfoPanel,
|
||||||
|
currentDashboardBasicInfo,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDashboardDesignConfirm = createDesignConfirmHandler(
|
||||||
|
showDashboardDesignPanel,
|
||||||
|
currentDashboardDesign,
|
||||||
|
'确认仪表盘设计',
|
||||||
|
);
|
||||||
|
const handleDashboardDesignClose = createDesignCloseHandler(
|
||||||
|
showDashboardDesignPanel,
|
||||||
|
currentDashboardDesign,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDashboardPublishConfirm = (data: Record<string, any>) => {
|
||||||
|
showDashboardPublishPanel.value = false;
|
||||||
|
currentDashboardPublish.value = undefined;
|
||||||
|
|
||||||
|
const userMsg: ChatMessage = {
|
||||||
|
id: generateId(),
|
||||||
|
role: 'user',
|
||||||
|
content: `发布到菜单:${data.menu_name}`,
|
||||||
|
timestamp: new Date(),
|
||||||
|
};
|
||||||
|
messages.value.push(userMsg);
|
||||||
|
|
||||||
|
waitingForInput.value = false;
|
||||||
|
waitingConfig.value = null;
|
||||||
|
|
||||||
|
resumeExecution(JSON.stringify(data));
|
||||||
|
};
|
||||||
|
const handleDashboardPublishClose = createDesignCloseHandler(
|
||||||
|
showDashboardPublishPanel,
|
||||||
|
currentDashboardPublish,
|
||||||
|
);
|
||||||
|
|
||||||
const handleSystemSummaryConfirm = createDesignConfirmHandler(
|
const handleSystemSummaryConfirm = createDesignConfirmHandler(
|
||||||
showSystemSummaryPanel,
|
showSystemSummaryPanel,
|
||||||
currentSystemSummary,
|
currentSystemSummary,
|
||||||
@@ -873,6 +1017,66 @@ onUnmounted(() => {
|
|||||||
class="ml-3 h-full min-h-[400px] flex-1 rounded-lg"
|
class="ml-3 h-full min-h-[400px] flex-1 rounded-lg"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- 设计编辑面板 -->
|
||||||
|
<DesignEditorPanel
|
||||||
|
v-if="showDesignPanel"
|
||||||
|
:visible="showDesignPanel"
|
||||||
|
:design="currentDesign as any"
|
||||||
|
@update:visible="showDesignPanel = $event"
|
||||||
|
@confirm="handleDesignConfirm"
|
||||||
|
@close="handleDesignClose"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 应用设计面板 -->
|
||||||
|
<AppDesignPanel
|
||||||
|
v-if="showAppDesignPanel"
|
||||||
|
:visible="showAppDesignPanel"
|
||||||
|
:design="currentAppDesign as any"
|
||||||
|
@update:visible="showAppDesignPanel = $event"
|
||||||
|
@confirm="handleAppDesignConfirm"
|
||||||
|
@close="handleAppDesignClose"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 应用设置面板 -->
|
||||||
|
<AppSettingsPanel
|
||||||
|
v-if="showAppSettingsPanel"
|
||||||
|
:visible="showAppSettingsPanel"
|
||||||
|
:settings="currentAppSettings as any"
|
||||||
|
@update:visible="showAppSettingsPanel = $event"
|
||||||
|
@confirm="handleAppSettingsConfirm"
|
||||||
|
@close="handleAppSettingsClose"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 仪表盘基础信息面板 -->
|
||||||
|
<DashboardBasicInfoConfirmPanel
|
||||||
|
v-if="showDashboardBasicInfoPanel"
|
||||||
|
:visible="showDashboardBasicInfoPanel"
|
||||||
|
:basic-info="currentDashboardBasicInfo as any"
|
||||||
|
@update:visible="showDashboardBasicInfoPanel = $event"
|
||||||
|
@confirm="handleDashboardBasicInfoConfirm"
|
||||||
|
@close="handleDashboardBasicInfoClose"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 仪表盘设计面板 -->
|
||||||
|
<DashboardDesignConfirmPanel
|
||||||
|
v-if="showDashboardDesignPanel"
|
||||||
|
:visible="showDashboardDesignPanel"
|
||||||
|
:design="currentDashboardDesign as any"
|
||||||
|
@update:visible="showDashboardDesignPanel = $event"
|
||||||
|
@confirm="handleDashboardDesignConfirm"
|
||||||
|
@close="handleDashboardDesignClose"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 仪表盘发布面板 -->
|
||||||
|
<DashboardPublishConfirmPanel
|
||||||
|
v-if="showDashboardPublishPanel"
|
||||||
|
:visible="showDashboardPublishPanel"
|
||||||
|
:publish-data="currentDashboardPublish as any"
|
||||||
|
@update:visible="showDashboardPublishPanel = $event"
|
||||||
|
@confirm="handleDashboardPublishConfirm"
|
||||||
|
@close="handleDashboardPublishClose"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 系统总结面板 -->
|
<!-- 系统总结面板 -->
|
||||||
<SystemSummaryConfirmPanel
|
<SystemSummaryConfirmPanel
|
||||||
v-if="showSystemSummaryPanel"
|
v-if="showSystemSummaryPanel"
|
||||||
@@ -886,6 +1090,60 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
<!-- 侧边栏布局时的设计面板(保持原有行为) -->
|
<!-- 侧边栏布局时的设计面板(保持原有行为) -->
|
||||||
<template v-if="layout === 'sidebar'">
|
<template v-if="layout === 'sidebar'">
|
||||||
|
<DesignEditorPanel
|
||||||
|
v-if="showDesignPanel"
|
||||||
|
:visible="showDesignPanel"
|
||||||
|
:design="currentDesign as any"
|
||||||
|
@update:visible="showDesignPanel = $event"
|
||||||
|
@confirm="handleDesignConfirm"
|
||||||
|
@close="handleDesignClose"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<AppDesignPanel
|
||||||
|
v-if="showAppDesignPanel"
|
||||||
|
:visible="showAppDesignPanel"
|
||||||
|
:design="currentAppDesign as any"
|
||||||
|
@update:visible="showAppDesignPanel = $event"
|
||||||
|
@confirm="handleAppDesignConfirm"
|
||||||
|
@close="handleAppDesignClose"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<AppSettingsPanel
|
||||||
|
v-if="showAppSettingsPanel"
|
||||||
|
:visible="showAppSettingsPanel"
|
||||||
|
:settings="currentAppSettings as any"
|
||||||
|
@update:visible="showAppSettingsPanel = $event"
|
||||||
|
@confirm="handleAppSettingsConfirm"
|
||||||
|
@close="handleAppSettingsClose"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DashboardBasicInfoConfirmPanel
|
||||||
|
v-if="showDashboardBasicInfoPanel"
|
||||||
|
:visible="showDashboardBasicInfoPanel"
|
||||||
|
:basic-info="currentDashboardBasicInfo as any"
|
||||||
|
@update:visible="showDashboardBasicInfoPanel = $event"
|
||||||
|
@confirm="handleDashboardBasicInfoConfirm"
|
||||||
|
@close="handleDashboardBasicInfoClose"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DashboardDesignConfirmPanel
|
||||||
|
v-if="showDashboardDesignPanel"
|
||||||
|
:visible="showDashboardDesignPanel"
|
||||||
|
:design="currentDashboardDesign as any"
|
||||||
|
@update:visible="showDashboardDesignPanel = $event"
|
||||||
|
@confirm="handleDashboardDesignConfirm"
|
||||||
|
@close="handleDashboardDesignClose"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DashboardPublishConfirmPanel
|
||||||
|
v-if="showDashboardPublishPanel"
|
||||||
|
:visible="showDashboardPublishPanel"
|
||||||
|
:publish-data="currentDashboardPublish as any"
|
||||||
|
@update:visible="showDashboardPublishPanel = $event"
|
||||||
|
@confirm="handleDashboardPublishConfirm"
|
||||||
|
@close="handleDashboardPublishClose"
|
||||||
|
/>
|
||||||
|
|
||||||
<SystemSummaryConfirmPanel
|
<SystemSummaryConfirmPanel
|
||||||
v-if="showSystemSummaryPanel"
|
v-if="showSystemSummaryPanel"
|
||||||
:visible="showSystemSummaryPanel"
|
:visible="showSystemSummaryPanel"
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ interface EventHandlerConfig {
|
|||||||
running: Ref<boolean>;
|
running: Ref<boolean>;
|
||||||
conversationId: Ref<null | string>;
|
conversationId: Ref<null | string>;
|
||||||
// 设计预览回调
|
// 设计预览回调
|
||||||
onDesignPreview?: (data: DesignPreviewData) => string | void;
|
onDesignPreview?: (data: DesignPreviewData) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 生成消息 ID */
|
/** 生成消息 ID */
|
||||||
@@ -104,12 +104,10 @@ export function useEventHandler(config: EventHandlerConfig) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 调用设计预览回调
|
// 调用设计预览回调
|
||||||
const customWaitingContent = onDesignPreview?.(previewData);
|
onDesignPreview?.(previewData);
|
||||||
|
|
||||||
// 显示提示消息
|
// 显示提示消息
|
||||||
const waitingContent =
|
const waitingContent = `**${configData.title}**\n\n${configData.message || '请在右侧面板中确认或编辑设计'}`;
|
||||||
customWaitingContent ||
|
|
||||||
`**${configData.title}**\n\n${configData.message || '请在右侧面板中确认或编辑设计'}`;
|
|
||||||
const initialMsg = messages.value.find((m) => m.id === msgId);
|
const initialMsg = messages.value.find((m) => m.id === msgId);
|
||||||
if (initialMsg && !initialMsg.content?.trim()) {
|
if (initialMsg && !initialMsg.content?.trim()) {
|
||||||
updateAssistantMessage(msgId, {
|
updateAssistantMessage(msgId, {
|
||||||
|
|||||||
@@ -39,22 +39,79 @@ const widgetComponents: Record<
|
|||||||
string,
|
string,
|
||||||
ReturnType<typeof defineAsyncComponent>
|
ReturnType<typeof defineAsyncComponent>
|
||||||
> = {
|
> = {
|
||||||
|
'stat-card': defineAsyncComponent(() => import('./widgets/StatCard.vue')),
|
||||||
|
'progress-card': defineAsyncComponent(
|
||||||
|
() => import('./widgets/ProgressCard.vue'),
|
||||||
|
),
|
||||||
|
'chart-line': defineAsyncComponent(() => import('./widgets/ChartLine.vue')),
|
||||||
|
'chart-bar': defineAsyncComponent(() => import('./widgets/ChartBar.vue')),
|
||||||
|
'chart-pie': defineAsyncComponent(() => import('./widgets/ChartPie.vue')),
|
||||||
|
'chart-gauge': defineAsyncComponent(() => import('./widgets/ChartGauge.vue')),
|
||||||
|
'chart-area': defineAsyncComponent(() => import('./widgets/ChartArea.vue')),
|
||||||
|
'chart-radar': defineAsyncComponent(() => import('./widgets/ChartRadar.vue')),
|
||||||
|
'chart-funnel': defineAsyncComponent(
|
||||||
|
() => import('./widgets/ChartFunnel.vue'),
|
||||||
|
),
|
||||||
|
'chart-scatter': defineAsyncComponent(
|
||||||
|
() => import('./widgets/ChartScatter.vue'),
|
||||||
|
),
|
||||||
|
'chart-ring': defineAsyncComponent(() => import('./widgets/ChartRing.vue')),
|
||||||
|
'chart-heatmap': defineAsyncComponent(
|
||||||
|
() => import('./widgets/ChartHeatmap.vue'),
|
||||||
|
),
|
||||||
|
'chart-kline': defineAsyncComponent(() => import('./widgets/ChartKline.vue')),
|
||||||
|
'chart-sankey': defineAsyncComponent(
|
||||||
|
() => import('./widgets/ChartSankey.vue'),
|
||||||
|
),
|
||||||
|
'todo-list': defineAsyncComponent(() => import('./widgets/TodoList.vue')),
|
||||||
'notice-list': defineAsyncComponent(() => import('./widgets/NoticeList.vue')),
|
'notice-list': defineAsyncComponent(() => import('./widgets/NoticeList.vue')),
|
||||||
|
'ranking-list': defineAsyncComponent(
|
||||||
|
() => import('./widgets/RankingList.vue'),
|
||||||
|
),
|
||||||
'announcement-list': defineAsyncComponent(
|
'announcement-list': defineAsyncComponent(
|
||||||
() => import('./widgets/AnnouncementList.vue'),
|
() => import('./widgets/AnnouncementList.vue'),
|
||||||
),
|
),
|
||||||
'approval-center': defineAsyncComponent(
|
|
||||||
() => import('./widgets/ApprovalCenter.vue'),
|
|
||||||
),
|
|
||||||
'quick-links': defineAsyncComponent(() => import('./widgets/QuickLinks.vue')),
|
'quick-links': defineAsyncComponent(() => import('./widgets/QuickLinks.vue')),
|
||||||
'welcome-card': defineAsyncComponent(
|
'welcome-card': defineAsyncComponent(
|
||||||
() => import('./widgets/WelcomeCard.vue'),
|
() => import('./widgets/WelcomeCard.vue'),
|
||||||
),
|
),
|
||||||
|
calendar: defineAsyncComponent(() => import('./widgets/CalendarWidget.vue')),
|
||||||
|
countdown: defineAsyncComponent(
|
||||||
|
() => import('./widgets/CountdownWidget.vue'),
|
||||||
|
),
|
||||||
|
clock: defineAsyncComponent(() => import('./widgets/ClockWidget.vue')),
|
||||||
weather: defineAsyncComponent(() => import('./widgets/WeatherWidget.vue')),
|
weather: defineAsyncComponent(() => import('./widgets/WeatherWidget.vue')),
|
||||||
|
'image-carousel': defineAsyncComponent(
|
||||||
|
() => import('./widgets/ImageCarousel.vue'),
|
||||||
|
),
|
||||||
|
'data-table': defineAsyncComponent(() => import('./widgets/DataTable.vue')),
|
||||||
|
'form-render': defineAsyncComponent(
|
||||||
|
() => import('./widgets/FormRenderWidget.vue'),
|
||||||
|
),
|
||||||
|
iframe: defineAsyncComponent(() => import('./widgets/IframeWidget.vue')),
|
||||||
|
'video-player': defineAsyncComponent(
|
||||||
|
() => import('./widgets/VideoPlayer.vue'),
|
||||||
|
),
|
||||||
|
image: defineAsyncComponent(() => import('./widgets/ImageWidget.vue')),
|
||||||
|
'approval-center': defineAsyncComponent(
|
||||||
|
() => import('./widgets/ApprovalCenter.vue'),
|
||||||
|
),
|
||||||
'my-apps': defineAsyncComponent(() => import('./widgets/MyApps.vue')),
|
'my-apps': defineAsyncComponent(() => import('./widgets/MyApps.vue')),
|
||||||
'server-monitor': defineAsyncComponent(
|
'server-monitor': defineAsyncComponent(
|
||||||
() => import('./widgets/ServerMonitor.vue'),
|
() => import('./widgets/ServerMonitor.vue'),
|
||||||
),
|
),
|
||||||
|
'filter-input': defineAsyncComponent(
|
||||||
|
() => import('./widgets/FilterInput.vue'),
|
||||||
|
),
|
||||||
|
'filter-select': defineAsyncComponent(
|
||||||
|
() => import('./widgets/FilterSelect.vue'),
|
||||||
|
),
|
||||||
|
'filter-date': defineAsyncComponent(
|
||||||
|
() => import('./widgets/FilterDate.vue'),
|
||||||
|
),
|
||||||
|
'filter-date-range': defineAsyncComponent(
|
||||||
|
() => import('./widgets/FilterDateRange.vue'),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
const store = useDashboardDesignStore();
|
const store = useDashboardDesignStore();
|
||||||
|
|||||||
@@ -65,9 +65,7 @@ const loadApps = async () => {
|
|||||||
// 点击应用
|
// 点击应用
|
||||||
const handleClick = (app: ApplicationListItem | StaticAppItem) => {
|
const handleClick = (app: ApplicationListItem | StaticAppItem) => {
|
||||||
const path = 'path' in app ? app.path : '';
|
const path = 'path' in app ? app.path : '';
|
||||||
const target =
|
const target = path || ('code' in app && app.code ? `/app/${app.code}` : '');
|
||||||
path ||
|
|
||||||
('code' in app && app.code ? `/app/${app.code}` : '');
|
|
||||||
|
|
||||||
if (!target) return;
|
if (!target) return;
|
||||||
if (/^https?:\/\//.test(target)) {
|
if (/^https?:\/\//.test(target)) {
|
||||||
|
|||||||
@@ -71,6 +71,43 @@ function createLightAiMenuRoute(
|
|||||||
return route as RouteRecordStringComponent;
|
return route as RouteRecordStringComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PREFETCH_LIGHT_PAGE_KEYS = [
|
||||||
|
'../views/_core/agent-chat/index.vue',
|
||||||
|
'../views/_core/menu/index.vue',
|
||||||
|
'../views/_core/page-render/index.vue',
|
||||||
|
'../views/_core/role/index.vue',
|
||||||
|
'../views/_core/user/index.vue',
|
||||||
|
'../views/ai-platform/agent/index.vue',
|
||||||
|
'../views/ai-platform/model/index.vue',
|
||||||
|
'../views/ai-platform/workflow-runs/index.vue',
|
||||||
|
'../views/ai-platform/workflow/index.vue',
|
||||||
|
];
|
||||||
|
|
||||||
|
let lightPagesPrefetched = false;
|
||||||
|
|
||||||
|
function scheduleIdleTask(callback: () => void) {
|
||||||
|
if (typeof window === 'undefined') return;
|
||||||
|
const requestIdle = (window as any).requestIdleCallback;
|
||||||
|
if (typeof requestIdle === 'function') {
|
||||||
|
requestIdle(callback, { timeout: 3000 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.setTimeout(callback, 1200);
|
||||||
|
}
|
||||||
|
|
||||||
|
function prefetchLightPages(pageMap: ComponentRecordType) {
|
||||||
|
if (lightPagesPrefetched) return;
|
||||||
|
lightPagesPrefetched = true;
|
||||||
|
scheduleIdleTask(() => {
|
||||||
|
for (const key of PREFETCH_LIGHT_PAGE_KEYS) {
|
||||||
|
const loader = pageMap[key];
|
||||||
|
if (typeof loader === 'function') {
|
||||||
|
void loader().catch(() => undefined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const LIGHT_AI_PLATFORM_MENU_ROUTES = [
|
const LIGHT_AI_PLATFORM_MENU_ROUTES = [
|
||||||
createLightAiMenuRoute({
|
createLightAiMenuRoute({
|
||||||
component: '/_core/agent-chat/index',
|
component: '/_core/agent-chat/index',
|
||||||
@@ -220,7 +257,7 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
|
|||||||
};
|
};
|
||||||
const routePageMap = normalizePageMap(pageMap);
|
const routePageMap = normalizePageMap(pageMap);
|
||||||
|
|
||||||
return await generateAccessible(preferences.app.accessMode, {
|
const accessible = await generateAccessible(preferences.app.accessMode, {
|
||||||
...options,
|
...options,
|
||||||
fetchMenuListAsync: async () => {
|
fetchMenuListAsync: async () => {
|
||||||
const appContextStore = useAppContextStore();
|
const appContextStore = useAppContextStore();
|
||||||
@@ -235,6 +272,8 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
|
|||||||
layoutMap,
|
layoutMap,
|
||||||
pageMap,
|
pageMap,
|
||||||
});
|
});
|
||||||
|
prefetchLightPages(pageMap);
|
||||||
|
return accessible;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { generateAccess };
|
export { generateAccess };
|
||||||
|
|||||||
+142
-42
@@ -25,6 +25,8 @@ const emit = defineEmits<{
|
|||||||
select: [nodeId: string];
|
select: [nodeId: string];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
type TagType = 'danger' | 'info' | 'primary' | 'success' | 'warning';
|
||||||
|
|
||||||
function formatDuration(ms?: number) {
|
function formatDuration(ms?: number) {
|
||||||
if (!ms && ms !== 0) return '-';
|
if (!ms && ms !== 0) return '-';
|
||||||
if (ms < 1000) return `${ms}ms`;
|
if (ms < 1000) return `${ms}ms`;
|
||||||
@@ -50,15 +52,19 @@ function getCommunication(log: ExecutionLogEntry) {
|
|||||||
return log.metadata?.communication || log.event?.communication || {};
|
return log.metadata?.communication || log.event?.communication || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCollaboration(log: ExecutionLogEntry) {
|
||||||
|
return log.metadata?.collaboration || log.event?.collaboration || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEventCollaboration(event: WorkflowRunEvent) {
|
||||||
|
return event.collaboration || event.event?.collaboration || {};
|
||||||
|
}
|
||||||
|
|
||||||
function getMetaItems(log: ExecutionLogEntry) {
|
function getMetaItems(log: ExecutionLogEntry) {
|
||||||
const metadata = log.metadata || {};
|
const metadata = log.metadata || {};
|
||||||
const items: Array<{
|
const items: Array<{ label: string; type?: TagType }> = [];
|
||||||
label: string;
|
|
||||||
type?: 'danger' | 'info' | 'primary' | 'success' | 'warning';
|
|
||||||
}> = [];
|
|
||||||
const communication = getCommunication(log);
|
const communication = getCommunication(log);
|
||||||
const collaboration =
|
const collaboration = getCollaboration(log);
|
||||||
metadata.collaboration || log.event?.collaboration || {};
|
|
||||||
const branchLabel =
|
const branchLabel =
|
||||||
log.branch_label ||
|
log.branch_label ||
|
||||||
log.branch ||
|
log.branch ||
|
||||||
@@ -88,24 +94,14 @@ function getMetaItems(log: ExecutionLogEntry) {
|
|||||||
if (log.type || metadata.stream_event) {
|
if (log.type || metadata.stream_event) {
|
||||||
items.push({
|
items.push({
|
||||||
label: getEventTypeLabel(log.type || log.event?.type),
|
label: getEventTypeLabel(log.type || log.event?.type),
|
||||||
type: log.status === 'failed' ? 'danger' : 'info',
|
type: getLogTone(log),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (branchLabel) {
|
if (branchLabel) items.push({ label: `分支: ${branchLabel}`, type: 'primary' });
|
||||||
items.push({ label: `分支: ${branchLabel}`, type: 'primary' });
|
if (subflowName) items.push({ label: `子流程: ${subflowName}`, type: 'success' });
|
||||||
}
|
if (providerName) items.push({ label: `提供商: ${providerName}`, type: 'info' });
|
||||||
if (subflowName) {
|
if (modelName) items.push({ label: `模型: ${modelName}`, type: 'info' });
|
||||||
items.push({ label: `子流程: ${subflowName}`, type: 'success' });
|
if (log.tokens_used) items.push({ label: `Token ${log.tokens_used}`, type: 'info' });
|
||||||
}
|
|
||||||
if (providerName) {
|
|
||||||
items.push({ label: `提供商: ${providerName}`, type: 'info' });
|
|
||||||
}
|
|
||||||
if (modelName) {
|
|
||||||
items.push({ label: `模型: ${modelName}`, type: 'info' });
|
|
||||||
}
|
|
||||||
if (log.tokens_used) {
|
|
||||||
items.push({ label: `Token ${log.tokens_used}`, type: 'info' });
|
|
||||||
}
|
|
||||||
if (communication.channel) {
|
if (communication.channel) {
|
||||||
items.push({ label: getChannelLabel(communication.channel), type: 'info' });
|
items.push({ label: getChannelLabel(communication.channel), type: 'info' });
|
||||||
}
|
}
|
||||||
@@ -118,6 +114,7 @@ function getMetaItems(log: ExecutionLogEntry) {
|
|||||||
|
|
||||||
function getChannelLabel(channel: string) {
|
function getChannelLabel(channel: string) {
|
||||||
const labels: Record<string, string> = {
|
const labels: Record<string, string> = {
|
||||||
|
agent_chat: '智能体对话',
|
||||||
human_input: '人机协作',
|
human_input: '人机协作',
|
||||||
parallel_branch: '并行分支',
|
parallel_branch: '并行分支',
|
||||||
subflow: '子流程',
|
subflow: '子流程',
|
||||||
@@ -132,12 +129,18 @@ function getEventTypeLabel(type?: string) {
|
|||||||
complete: '完成',
|
complete: '完成',
|
||||||
error: '错误',
|
error: '错误',
|
||||||
llm_chunk: 'LLM 输出',
|
llm_chunk: 'LLM 输出',
|
||||||
|
loop_complete: '循环完成',
|
||||||
|
loop_iteration_complete: '循环迭代完成',
|
||||||
|
loop_iteration_error: '循环迭代失败',
|
||||||
|
loop_iteration_start: '循环迭代开始',
|
||||||
|
loop_start: '循环开始',
|
||||||
message: '消息',
|
message: '消息',
|
||||||
node_complete: '节点完成',
|
node_complete: '节点完成',
|
||||||
node_event: '节点事件',
|
node_event: '节点事件',
|
||||||
node_start: '节点开始',
|
node_start: '节点开始',
|
||||||
parallel_complete: '并行完成',
|
parallel_complete: '并行完成',
|
||||||
parallel_start: '并行开始',
|
parallel_start: '并行开始',
|
||||||
|
resume: '恢复执行',
|
||||||
start: '开始',
|
start: '开始',
|
||||||
waiting_input: '等待输入',
|
waiting_input: '等待输入',
|
||||||
};
|
};
|
||||||
@@ -150,13 +153,8 @@ function countItems(value: any) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEventSummary(event: WorkflowRunEvent) {
|
function getWaitingSummary(event: WorkflowRunEvent) {
|
||||||
const eventType = event.type || event.event?.type;
|
|
||||||
const waitingConfig = event.waiting_config || event.config;
|
const waitingConfig = event.waiting_config || event.config;
|
||||||
|
|
||||||
if (event.error_message) return event.error_message;
|
|
||||||
if (event.error) return event.error;
|
|
||||||
if (eventType === 'waiting_input') {
|
|
||||||
return stringifyBrief(
|
return stringifyBrief(
|
||||||
waitingConfig?.title ||
|
waitingConfig?.title ||
|
||||||
waitingConfig?.question ||
|
waitingConfig?.question ||
|
||||||
@@ -166,6 +164,13 @@ function getEventSummary(event: WorkflowRunEvent) {
|
|||||||
160,
|
160,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getEventSummary(event: WorkflowRunEvent) {
|
||||||
|
const eventType = event.type || event.event?.type;
|
||||||
|
|
||||||
|
if (event.error_message) return event.error_message;
|
||||||
|
if (event.error) return event.error;
|
||||||
|
if (eventType === 'waiting_input') return getWaitingSummary(event);
|
||||||
if (eventType === 'parallel_start') {
|
if (eventType === 'parallel_start') {
|
||||||
return `启动 ${countItems(event.branches || event.branch_labels)} 个并行分支`;
|
return `启动 ${countItems(event.branches || event.branch_labels)} 个并行分支`;
|
||||||
}
|
}
|
||||||
@@ -196,13 +201,56 @@ function getEventSummary(event: WorkflowRunEvent) {
|
|||||||
return stringifyBrief(event, 140);
|
return stringifyBrief(event, 140);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getEventMetaItems(event: WorkflowRunEvent) {
|
||||||
|
const collaboration = getEventCollaboration(event);
|
||||||
|
const items: Array<{ label: string; type?: TagType }> = [];
|
||||||
|
const branchLabel =
|
||||||
|
event.branch_label ||
|
||||||
|
event.branch_id ||
|
||||||
|
collaboration.branch_label ||
|
||||||
|
collaboration.branch_id;
|
||||||
|
const subflowName = event.subflow_name || collaboration.subflow_name;
|
||||||
|
const providerName = event.provider_name || collaboration.provider_name;
|
||||||
|
const modelName =
|
||||||
|
event.model ||
|
||||||
|
event.model_name ||
|
||||||
|
event.model_id ||
|
||||||
|
collaboration.model ||
|
||||||
|
collaboration.model_name ||
|
||||||
|
collaboration.model_id;
|
||||||
|
|
||||||
|
if (branchLabel) items.push({ label: `分支 ${branchLabel}`, type: 'primary' });
|
||||||
|
if (subflowName) items.push({ label: `子流程 ${subflowName}`, type: 'success' });
|
||||||
|
if (providerName) items.push({ label: providerName, type: 'info' });
|
||||||
|
if (modelName) items.push({ label: `模型 ${modelName}`, type: 'info' });
|
||||||
|
if (event.tokens_used || event.total_tokens) {
|
||||||
|
items.push({
|
||||||
|
label: `Token ${event.tokens_used || event.total_tokens}`,
|
||||||
|
type: 'info',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
function getLogEvents(log: ExecutionLogEntry): WorkflowRunEvent[] {
|
function getLogEvents(log: ExecutionLogEntry): WorkflowRunEvent[] {
|
||||||
const primaryEvent = log.event ? [log.event] : [];
|
const events = [
|
||||||
const directEvents = Array.isArray(log.events) ? log.events : [];
|
...(log.event ? [log.event] : []),
|
||||||
const metadataEvents = Array.isArray(log.metadata?.events)
|
...(Array.isArray(log.events) ? log.events : []),
|
||||||
? log.metadata.events
|
...(Array.isArray(log.metadata?.events) ? log.metadata.events : []),
|
||||||
: [];
|
].filter(Boolean);
|
||||||
return [...primaryEvent, ...directEvents, ...metadataEvents].filter(Boolean);
|
const seen = new Set<string>();
|
||||||
|
return events.filter((event) => {
|
||||||
|
const key = [
|
||||||
|
event.type || event.event?.type || '',
|
||||||
|
event.node_id || event.event?.node_id || '',
|
||||||
|
event.timestamp || event.event?.timestamp || '',
|
||||||
|
stringifyBrief(event.content || event.message || event.error_message, 80),
|
||||||
|
].join('|');
|
||||||
|
if (seen.has(key)) return false;
|
||||||
|
seen.add(key);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVisibleEvents(log: ExecutionLogEntry) {
|
function getVisibleEvents(log: ExecutionLogEntry) {
|
||||||
@@ -229,6 +277,33 @@ function getLogDetail(log: ExecutionLogEntry) {
|
|||||||
communication.message,
|
communication.message,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getLogTitle(log: ExecutionLogEntry) {
|
||||||
|
if (log.node_label) return log.node_label;
|
||||||
|
if (log.node_id && log.node_id !== 'workflow') return log.node_id;
|
||||||
|
return getEventTypeLabel(log.type || log.event?.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLogTone(log: ExecutionLogEntry): TagType {
|
||||||
|
if (log.status === 'failed' || log.type === 'error') return 'danger';
|
||||||
|
if (log.status === 'waiting' || log.type === 'waiting_input') return 'warning';
|
||||||
|
if (log.status === 'completed' || log.type === 'complete') return 'success';
|
||||||
|
if (log.status === 'running') return 'primary';
|
||||||
|
return 'info';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEventTone(event: WorkflowRunEvent): TagType {
|
||||||
|
const type = event.type || event.event?.type;
|
||||||
|
if (type === 'error' || event.error || event.error_message) return 'danger';
|
||||||
|
if (type === 'waiting_input') return 'warning';
|
||||||
|
if (type === 'complete' || type === 'node_complete' || type === 'parallel_complete') {
|
||||||
|
return 'success';
|
||||||
|
}
|
||||||
|
if (type === 'start' || type === 'node_start' || type === 'parallel_start') {
|
||||||
|
return 'primary';
|
||||||
|
}
|
||||||
|
return 'info';
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -240,8 +315,10 @@ function getLogDetail(log: ExecutionLogEntry) {
|
|||||||
<ElTimeline v-else class="px-2 py-3">
|
<ElTimeline v-else class="px-2 py-3">
|
||||||
<ElTimelineItem
|
<ElTimelineItem
|
||||||
v-for="(log, index) in logs"
|
v-for="(log, index) in logs"
|
||||||
:key="`${log.node_id}-${index}`"
|
:key="`${log.node_id}-${log.type || 'node'}-${index}`"
|
||||||
:timestamp="formatDuration(log.elapsed_time)"
|
:timestamp="formatDuration(log.elapsed_time)"
|
||||||
|
:type="getLogTone(log)"
|
||||||
|
:hollow="log.status === 'running' || log.status === 'waiting'"
|
||||||
placement="top"
|
placement="top"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
@@ -255,15 +332,15 @@ function getLogDetail(log: ExecutionLogEntry) {
|
|||||||
@click="emit('select', log.node_id)"
|
@click="emit('select', log.node_id)"
|
||||||
>
|
>
|
||||||
<div class="mb-1 flex items-center justify-between gap-2">
|
<div class="mb-1 flex items-center justify-between gap-2">
|
||||||
<span class="text-foreground text-sm font-medium">
|
<span class="text-foreground min-w-0 truncate text-sm font-medium">
|
||||||
{{ log.node_label || log.node_id }}
|
{{ getLogTitle(log) }}
|
||||||
</span>
|
</span>
|
||||||
<RunStatusTag :status="log.status" />
|
<RunStatusTag :status="log.status" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="text-muted-foreground flex flex-wrap items-center gap-1 text-xs"
|
class="text-muted-foreground flex flex-wrap items-center gap-1 text-xs"
|
||||||
>
|
>
|
||||||
<span>{{ log.node_type }}</span>
|
<span v-if="log.node_type">{{ log.node_type }}</span>
|
||||||
<ElTag
|
<ElTag
|
||||||
v-for="item in getMetaItems(log)"
|
v-for="item in getMetaItems(log)"
|
||||||
:key="item.label"
|
:key="item.label"
|
||||||
@@ -291,15 +368,38 @@ function getLogDetail(log: ExecutionLogEntry) {
|
|||||||
<div
|
<div
|
||||||
v-for="(event, eventIndex) in getVisibleEvents(log)"
|
v-for="(event, eventIndex) in getVisibleEvents(log)"
|
||||||
:key="`${log.node_id}-event-${eventIndex}`"
|
:key="`${log.node_id}-event-${eventIndex}`"
|
||||||
class="text-muted-foreground flex gap-2 text-xs"
|
class="border-border/70 bg-background/60 mb-1 rounded border px-2 py-1 last:mb-0"
|
||||||
|
>
|
||||||
|
<div class="flex min-w-0 items-start gap-2">
|
||||||
|
<ElTag
|
||||||
|
class="shrink-0"
|
||||||
|
:type="getEventTone(event)"
|
||||||
|
size="small"
|
||||||
|
effect="plain"
|
||||||
>
|
>
|
||||||
<span class="shrink-0 font-medium">
|
|
||||||
{{ getEventTypeLabel(event.type || event.event?.type) }}
|
{{ getEventTypeLabel(event.type || event.event?.type) }}
|
||||||
</span>
|
</ElTag>
|
||||||
<span class="line-clamp-2 min-w-0 whitespace-pre-wrap">
|
<span
|
||||||
|
class="text-muted-foreground line-clamp-2 min-w-0 whitespace-pre-wrap text-xs"
|
||||||
|
>
|
||||||
{{ getEventSummary(event) }}
|
{{ getEventSummary(event) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="getEventMetaItems(event).length"
|
||||||
|
class="mt-1 flex flex-wrap gap-1 pl-[68px]"
|
||||||
|
>
|
||||||
|
<ElTag
|
||||||
|
v-for="item in getEventMetaItems(event)"
|
||||||
|
:key="item.label"
|
||||||
|
:type="item.type"
|
||||||
|
size="small"
|
||||||
|
effect="plain"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</ElTag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="getHiddenEventCount(log)"
|
v-if="getHiddenEventCount(log)"
|
||||||
class="text-muted-foreground mt-1 text-xs"
|
class="text-muted-foreground mt-1 text-xs"
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ const components: Record<string, any> = {
|
|||||||
template: defineAsyncComponent(() => import('../panels/TemplatePanel.vue')),
|
template: defineAsyncComponent(() => import('../panels/TemplatePanel.vue')),
|
||||||
parallel: defineAsyncComponent(() => import('../panels/ParallelPanel.vue')),
|
parallel: defineAsyncComponent(() => import('../panels/ParallelPanel.vue')),
|
||||||
merge: defineAsyncComponent(() => import('../panels/MergePanel.vue')),
|
merge: defineAsyncComponent(() => import('../panels/MergePanel.vue')),
|
||||||
|
db_insert: defineAsyncComponent(() => import('../panels/DbInsertPanel.vue')),
|
||||||
|
db_update: defineAsyncComponent(() => import('../panels/DbUpdatePanel.vue')),
|
||||||
|
db_query: defineAsyncComponent(() => import('../panels/DbQueryPanel.vue')),
|
||||||
|
db_delete: defineAsyncComponent(() => import('../panels/DbDeletePanel.vue')),
|
||||||
|
db_sql: defineAsyncComponent(() => import('../panels/DbSqlPanel.vue')),
|
||||||
// 对话流节点
|
// 对话流节点
|
||||||
question: defineAsyncComponent(() => import('../panels/QuestionPanel.vue')),
|
question: defineAsyncComponent(() => import('../panels/QuestionPanel.vue')),
|
||||||
choice: defineAsyncComponent(() => import('../panels/ChoicePanel.vue')),
|
choice: defineAsyncComponent(() => import('../panels/ChoicePanel.vue')),
|
||||||
@@ -40,14 +45,88 @@ const components: Record<string, any> = {
|
|||||||
confirm: defineAsyncComponent(() => import('../panels/ConfirmPanel.vue')),
|
confirm: defineAsyncComponent(() => import('../panels/ConfirmPanel.vue')),
|
||||||
// 意图识别节点
|
// 意图识别节点
|
||||||
intent: defineAsyncComponent(() => import('../panels/IntentPanel.vue')),
|
intent: defineAsyncComponent(() => import('../panels/IntentPanel.vue')),
|
||||||
|
// Snowflake Cortex 节点
|
||||||
|
snowflake_cortex_llm: defineAsyncComponent(
|
||||||
|
() => import('../panels/SnowflakeCortexLLMPanel.vue'),
|
||||||
|
),
|
||||||
|
snowflake_cortex_analyst: defineAsyncComponent(
|
||||||
|
() => import('../panels/SnowflakeCortexAnalystPanel.vue'),
|
||||||
|
),
|
||||||
// 循环节点
|
// 循环节点
|
||||||
loop: defineAsyncComponent(() => import('../panels/LoopPanel.vue')),
|
loop: defineAsyncComponent(() => import('../panels/LoopPanel.vue')),
|
||||||
|
// 表单节点
|
||||||
|
form_basic_info: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormBasicInfoPanel.vue'),
|
||||||
|
),
|
||||||
|
form_database_design: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormDatabaseDesignPanel.vue'),
|
||||||
|
),
|
||||||
|
form_database_create: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormDatabaseCreatePanel.vue'),
|
||||||
|
),
|
||||||
|
form_ui_design: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormUIDesignPanel.vue'),
|
||||||
|
),
|
||||||
|
form_list_design: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormListDesignPanel.vue'),
|
||||||
|
),
|
||||||
|
form_create: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormCreatePanel.vue'),
|
||||||
|
),
|
||||||
|
form_publish: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormPublishPanel.vue'),
|
||||||
|
),
|
||||||
|
// 应用节点
|
||||||
|
app_create: defineAsyncComponent(
|
||||||
|
() => import('../panels/AppCreatePanel.vue'),
|
||||||
|
),
|
||||||
|
app_design: defineAsyncComponent(
|
||||||
|
() => import('../panels/AppDesignPanel.vue'),
|
||||||
|
),
|
||||||
|
app_settings: defineAsyncComponent(
|
||||||
|
() => import('../panels/AppSettingsPanel.vue'),
|
||||||
|
),
|
||||||
|
app_update: defineAsyncComponent(
|
||||||
|
() => import('../panels/AppUpdatePanel.vue'),
|
||||||
|
),
|
||||||
|
// 仪表盘节点
|
||||||
|
dashboard_basic_info: defineAsyncComponent(
|
||||||
|
() => import('../panels/DashboardBasicInfoPanel.vue'),
|
||||||
|
),
|
||||||
|
dashboard_design: defineAsyncComponent(
|
||||||
|
() => import('../panels/DashboardDesignPanel.vue'),
|
||||||
|
),
|
||||||
|
dashboard_create: defineAsyncComponent(
|
||||||
|
() => import('../panels/DashboardCreatePanel.vue'),
|
||||||
|
),
|
||||||
|
dashboard_publish: defineAsyncComponent(
|
||||||
|
() => import('../panels/DashboardPublishPanel.vue'),
|
||||||
|
),
|
||||||
// 系统总结节点
|
// 系统总结节点
|
||||||
system_summary: defineAsyncComponent(
|
system_summary: defineAsyncComponent(
|
||||||
() => import('../panels/SystemSummaryPanel.vue'),
|
() => import('../panels/SystemSummaryPanel.vue'),
|
||||||
),
|
),
|
||||||
// 子流程节点
|
// 子流程节点
|
||||||
subflow: defineAsyncComponent(() => import('../panels/SubflowPanel.vue')),
|
subflow: defineAsyncComponent(() => import('../panels/SubflowPanel.vue')),
|
||||||
|
// 表单数据节点
|
||||||
|
form_data_create: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormDataPanel.vue'),
|
||||||
|
),
|
||||||
|
form_data_read: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormDataPanel.vue'),
|
||||||
|
),
|
||||||
|
form_data_update: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormDataPanel.vue'),
|
||||||
|
),
|
||||||
|
form_data_delete: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormDataPanel.vue'),
|
||||||
|
),
|
||||||
|
form_data_list: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormDataPanel.vue'),
|
||||||
|
),
|
||||||
|
form_schema_to_llm: defineAsyncComponent(
|
||||||
|
() => import('../panels/FormDataPanel.vue'),
|
||||||
|
),
|
||||||
// Text-to-SQL 节点
|
// Text-to-SQL 节点
|
||||||
text_to_sql: defineAsyncComponent(
|
text_to_sql: defineAsyncComponent(
|
||||||
() => import('../panels/TextToSqlPanel.vue'),
|
() => import('../panels/TextToSqlPanel.vue'),
|
||||||
|
|||||||
@@ -23,22 +23,36 @@ import {
|
|||||||
Clock,
|
Clock,
|
||||||
Code,
|
Code,
|
||||||
Combine,
|
Combine,
|
||||||
|
CornerDownLeft,
|
||||||
|
Database,
|
||||||
|
DatabaseBackup,
|
||||||
DatabaseZap,
|
DatabaseZap,
|
||||||
|
FilePlus,
|
||||||
|
FileText,
|
||||||
Fullscreen,
|
Fullscreen,
|
||||||
GitBranch,
|
GitBranch,
|
||||||
GitFork,
|
GitFork,
|
||||||
Globe,
|
Globe,
|
||||||
HelpCircle,
|
HelpCircle,
|
||||||
|
LayoutDashboard,
|
||||||
LayoutTemplate,
|
LayoutTemplate,
|
||||||
ListChecks,
|
ListChecks,
|
||||||
Map,
|
Map,
|
||||||
|
MessageSquareMore,
|
||||||
MessageSquareText,
|
MessageSquareText,
|
||||||
Minus,
|
Minus,
|
||||||
Play,
|
Play,
|
||||||
Plus,
|
Plus,
|
||||||
Redo2,
|
Redo2,
|
||||||
RefreshCw,
|
RefreshCw,
|
||||||
|
Save,
|
||||||
|
Search,
|
||||||
|
Send,
|
||||||
|
Settings,
|
||||||
|
Snowflake,
|
||||||
Square,
|
Square,
|
||||||
|
TableProperties,
|
||||||
|
Trash2,
|
||||||
Undo2,
|
Undo2,
|
||||||
Upload,
|
Upload,
|
||||||
Workflow,
|
Workflow,
|
||||||
@@ -70,11 +84,32 @@ import ContextMenu from './components/ContextMenu.vue';
|
|||||||
import Panel from './components/Panel.vue';
|
import Panel from './components/Panel.vue';
|
||||||
import VersionHistoryPanel from './components/VersionHistoryPanel.vue';
|
import VersionHistoryPanel from './components/VersionHistoryPanel.vue';
|
||||||
import AddButtonEdge from './edges/AddButtonEdge.vue';
|
import AddButtonEdge from './edges/AddButtonEdge.vue';
|
||||||
|
import AppCreateNode from './nodes/AppCreateNode.vue';
|
||||||
|
import AppDesignNode from './nodes/AppDesignNode.vue';
|
||||||
|
import AppSettingsNode from './nodes/AppSettingsNode.vue';
|
||||||
|
import AppUpdateNode from './nodes/AppUpdateNode.vue';
|
||||||
import ChoiceNode from './nodes/ChoiceNode.vue';
|
import ChoiceNode from './nodes/ChoiceNode.vue';
|
||||||
import CodeNode from './nodes/CodeNode.vue';
|
import CodeNode from './nodes/CodeNode.vue';
|
||||||
import ConditionNode from './nodes/ConditionNode.vue';
|
import ConditionNode from './nodes/ConditionNode.vue';
|
||||||
import ConfirmNode from './nodes/ConfirmNode.vue';
|
import ConfirmNode from './nodes/ConfirmNode.vue';
|
||||||
|
import DashboardBasicInfoNode from './nodes/DashboardBasicInfoNode.vue';
|
||||||
|
import DashboardCreateNode from './nodes/DashboardCreateNode.vue';
|
||||||
|
import DashboardDesignNode from './nodes/DashboardDesignNode.vue';
|
||||||
|
import DashboardPublishNode from './nodes/DashboardPublishNode.vue';
|
||||||
|
import DbDeleteNode from './nodes/DbDeleteNode.vue';
|
||||||
|
import DbInsertNode from './nodes/DbInsertNode.vue';
|
||||||
|
import DbQueryNode from './nodes/DbQueryNode.vue';
|
||||||
|
import DbSqlNode from './nodes/DbSqlNode.vue';
|
||||||
|
import DbUpdateNode from './nodes/DbUpdateNode.vue';
|
||||||
import EndNode from './nodes/EndNode.vue';
|
import EndNode from './nodes/EndNode.vue';
|
||||||
|
import FormBasicInfoNode from './nodes/FormBasicInfoNode.vue';
|
||||||
|
import FormCreateNode from './nodes/FormCreateNode.vue';
|
||||||
|
import FormDatabaseCreateNode from './nodes/FormDatabaseCreateNode.vue';
|
||||||
|
import FormDatabaseDesignNode from './nodes/FormDatabaseDesignNode.vue';
|
||||||
|
import FormDataNode from './nodes/FormDataNode.vue';
|
||||||
|
import FormListDesignNode from './nodes/FormListDesignNode.vue';
|
||||||
|
import FormPublishNode from './nodes/FormPublishNode.vue';
|
||||||
|
import FormUIDesignNode from './nodes/FormUIDesignNode.vue';
|
||||||
import HttpNode from './nodes/HttpNode.vue';
|
import HttpNode from './nodes/HttpNode.vue';
|
||||||
import IntentNode from './nodes/IntentNode.vue';
|
import IntentNode from './nodes/IntentNode.vue';
|
||||||
import KnowledgeRetrievalNode from './nodes/KnowledgeRetrievalNode.vue';
|
import KnowledgeRetrievalNode from './nodes/KnowledgeRetrievalNode.vue';
|
||||||
@@ -84,12 +119,13 @@ import MergeNode from './nodes/MergeNode.vue';
|
|||||||
import MessageNode from './nodes/MessageNode.vue';
|
import MessageNode from './nodes/MessageNode.vue';
|
||||||
import ParallelNode from './nodes/ParallelNode.vue';
|
import ParallelNode from './nodes/ParallelNode.vue';
|
||||||
import QuestionNode from './nodes/QuestionNode.vue';
|
import QuestionNode from './nodes/QuestionNode.vue';
|
||||||
|
import SnowflakeCortexAnalystNode from './nodes/SnowflakeCortexAnalystNode.vue';
|
||||||
|
import SnowflakeCortexLLMNode from './nodes/SnowflakeCortexLLMNode.vue';
|
||||||
import StartNode from './nodes/StartNode.vue';
|
import StartNode from './nodes/StartNode.vue';
|
||||||
import SubflowNode from './nodes/SubflowNode.vue';
|
import SubflowNode from './nodes/SubflowNode.vue';
|
||||||
import SystemSummaryNode from './nodes/SystemSummaryNode.vue';
|
import SystemSummaryNode from './nodes/SystemSummaryNode.vue';
|
||||||
import TemplateNode from './nodes/TemplateNode.vue';
|
import TemplateNode from './nodes/TemplateNode.vue';
|
||||||
import TextToSqlNode from './nodes/TextToSqlNode.vue';
|
import TextToSqlNode from './nodes/TextToSqlNode.vue';
|
||||||
import UnsupportedNode from './nodes/UnsupportedNode.vue';
|
|
||||||
|
|
||||||
import '@vue-flow/minimap/dist/style.css';
|
import '@vue-flow/minimap/dist/style.css';
|
||||||
import '@vue-flow/core/dist/style.css';
|
import '@vue-flow/core/dist/style.css';
|
||||||
@@ -120,41 +156,6 @@ const contextMenu = ref({
|
|||||||
node: null as any,
|
node: null as any,
|
||||||
});
|
});
|
||||||
|
|
||||||
const legacyNodeTypes = [
|
|
||||||
'db_insert',
|
|
||||||
'db_update',
|
|
||||||
'db_query',
|
|
||||||
'db_delete',
|
|
||||||
'db_sql',
|
|
||||||
'snowflake_cortex_llm',
|
|
||||||
'snowflake_cortex_analyst',
|
|
||||||
'form_basic_info',
|
|
||||||
'form_database_design',
|
|
||||||
'form_database_create',
|
|
||||||
'form_ui_design',
|
|
||||||
'form_list_design',
|
|
||||||
'form_create',
|
|
||||||
'form_publish',
|
|
||||||
'app_create',
|
|
||||||
'app_design',
|
|
||||||
'app_settings',
|
|
||||||
'app_update',
|
|
||||||
'dashboard_basic_info',
|
|
||||||
'dashboard_design',
|
|
||||||
'dashboard_create',
|
|
||||||
'dashboard_publish',
|
|
||||||
'form_data_create',
|
|
||||||
'form_data_read',
|
|
||||||
'form_data_update',
|
|
||||||
'form_data_delete',
|
|
||||||
'form_data_list',
|
|
||||||
'form_schema_to_llm',
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
const legacyNodeTypeMap = Object.fromEntries(
|
|
||||||
legacyNodeTypes.map((type) => [type, markRaw(UnsupportedNode)]),
|
|
||||||
);
|
|
||||||
|
|
||||||
// 注册自定义节点
|
// 注册自定义节点
|
||||||
const nodeTypes = {
|
const nodeTypes = {
|
||||||
start: markRaw(StartNode),
|
start: markRaw(StartNode),
|
||||||
@@ -166,6 +167,11 @@ const nodeTypes = {
|
|||||||
template: markRaw(TemplateNode),
|
template: markRaw(TemplateNode),
|
||||||
parallel: markRaw(ParallelNode),
|
parallel: markRaw(ParallelNode),
|
||||||
merge: markRaw(MergeNode),
|
merge: markRaw(MergeNode),
|
||||||
|
db_insert: markRaw(DbInsertNode),
|
||||||
|
db_update: markRaw(DbUpdateNode),
|
||||||
|
db_query: markRaw(DbQueryNode),
|
||||||
|
db_delete: markRaw(DbDeleteNode),
|
||||||
|
db_sql: markRaw(DbSqlNode),
|
||||||
// 对话流节点
|
// 对话流节点
|
||||||
question: markRaw(QuestionNode),
|
question: markRaw(QuestionNode),
|
||||||
choice: markRaw(ChoiceNode),
|
choice: markRaw(ChoiceNode),
|
||||||
@@ -173,17 +179,44 @@ const nodeTypes = {
|
|||||||
confirm: markRaw(ConfirmNode),
|
confirm: markRaw(ConfirmNode),
|
||||||
// 意图识别节点
|
// 意图识别节点
|
||||||
intent: markRaw(IntentNode),
|
intent: markRaw(IntentNode),
|
||||||
|
// Snowflake Cortex 节点
|
||||||
|
snowflake_cortex_llm: markRaw(SnowflakeCortexLLMNode),
|
||||||
|
snowflake_cortex_analyst: markRaw(SnowflakeCortexAnalystNode),
|
||||||
// 循环节点
|
// 循环节点
|
||||||
loop: markRaw(LoopNode),
|
loop: markRaw(LoopNode),
|
||||||
|
// 表单节点
|
||||||
|
form_basic_info: markRaw(FormBasicInfoNode),
|
||||||
|
form_database_design: markRaw(FormDatabaseDesignNode),
|
||||||
|
form_database_create: markRaw(FormDatabaseCreateNode),
|
||||||
|
form_ui_design: markRaw(FormUIDesignNode),
|
||||||
|
form_list_design: markRaw(FormListDesignNode),
|
||||||
|
form_create: markRaw(FormCreateNode),
|
||||||
|
form_publish: markRaw(FormPublishNode),
|
||||||
|
// 应用管理节点
|
||||||
|
app_create: markRaw(AppCreateNode),
|
||||||
|
app_design: markRaw(AppDesignNode),
|
||||||
|
app_settings: markRaw(AppSettingsNode),
|
||||||
|
app_update: markRaw(AppUpdateNode),
|
||||||
|
// 仪表盘节点
|
||||||
|
dashboard_basic_info: markRaw(DashboardBasicInfoNode),
|
||||||
|
dashboard_design: markRaw(DashboardDesignNode),
|
||||||
|
dashboard_create: markRaw(DashboardCreateNode),
|
||||||
|
dashboard_publish: markRaw(DashboardPublishNode),
|
||||||
// 系统总结节点
|
// 系统总结节点
|
||||||
system_summary: markRaw(SystemSummaryNode),
|
system_summary: markRaw(SystemSummaryNode),
|
||||||
// 子流程节点
|
// 子流程节点
|
||||||
subflow: markRaw(SubflowNode),
|
subflow: markRaw(SubflowNode),
|
||||||
|
// 表单数据节点
|
||||||
|
form_data_create: markRaw(FormDataNode),
|
||||||
|
form_data_read: markRaw(FormDataNode),
|
||||||
|
form_data_update: markRaw(FormDataNode),
|
||||||
|
form_data_delete: markRaw(FormDataNode),
|
||||||
|
form_data_list: markRaw(FormDataNode),
|
||||||
|
form_schema_to_llm: markRaw(FormDataNode),
|
||||||
// Text-to-SQL 节点
|
// Text-to-SQL 节点
|
||||||
text_to_sql: markRaw(TextToSqlNode),
|
text_to_sql: markRaw(TextToSqlNode),
|
||||||
// 知识库节点
|
// 知识库节点
|
||||||
knowledge_retrieval: markRaw(KnowledgeRetrievalNode),
|
knowledge_retrieval: markRaw(KnowledgeRetrievalNode),
|
||||||
...legacyNodeTypeMap,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 注册自定义边类型
|
// 注册自定义边类型
|
||||||
@@ -326,19 +359,7 @@ const getNodeLabel = (type: string): string => {
|
|||||||
return $t(`ai-platform.workflow.editor.nodeLabels.${type}`) || type;
|
return $t(`ai-platform.workflow.editor.nodeLabels.${type}`) || type;
|
||||||
};
|
};
|
||||||
|
|
||||||
type NodePaletteItem = {
|
const nodeCategories = computed(() => [
|
||||||
color: string;
|
|
||||||
icon: string;
|
|
||||||
label: string;
|
|
||||||
type: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type NodePaletteCategory = {
|
|
||||||
name: string;
|
|
||||||
nodes: NodePaletteItem[];
|
|
||||||
};
|
|
||||||
|
|
||||||
const nodeCategories = computed<NodePaletteCategory[]>(() => [
|
|
||||||
{
|
{
|
||||||
name: $t('ai-platform.workflow.editor.categories.basic'),
|
name: $t('ai-platform.workflow.editor.categories.basic'),
|
||||||
nodes: [
|
nodes: [
|
||||||
@@ -367,11 +388,93 @@ const nodeCategories = computed<NodePaletteCategory[]>(() => [
|
|||||||
icon: 'LayoutTemplate',
|
icon: 'LayoutTemplate',
|
||||||
color: 'blue',
|
color: 'blue',
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'system_summary',
|
name: $t('ai-platform.workflow.editor.categories.formDesign'),
|
||||||
label: getNodeLabel('system_summary'),
|
nodes: [
|
||||||
icon: 'ClipboardCheck',
|
{
|
||||||
color: 'cyan',
|
type: 'form_basic_info',
|
||||||
|
label: getNodeLabel('form_basic_info'),
|
||||||
|
icon: 'FileText',
|
||||||
|
color: 'purple',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form_database_design',
|
||||||
|
label: getNodeLabel('form_database_design'),
|
||||||
|
icon: 'Database',
|
||||||
|
color: 'purple',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form_database_create',
|
||||||
|
label: getNodeLabel('form_database_create'),
|
||||||
|
icon: 'DatabaseZap',
|
||||||
|
color: 'purple',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form_ui_design',
|
||||||
|
label: getNodeLabel('form_ui_design'),
|
||||||
|
icon: 'LayoutTemplate',
|
||||||
|
color: 'purple',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form_list_design',
|
||||||
|
label: getNodeLabel('form_list_design'),
|
||||||
|
icon: 'TableProperties',
|
||||||
|
color: 'purple',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form_create',
|
||||||
|
label: getNodeLabel('form_create'),
|
||||||
|
icon: 'FilePlus',
|
||||||
|
color: 'purple',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form_publish',
|
||||||
|
label: getNodeLabel('form_publish'),
|
||||||
|
icon: 'Send',
|
||||||
|
color: 'purple',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: $t('ai-platform.workflow.editor.categories.formData'),
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
type: 'form_data_create',
|
||||||
|
label: getNodeLabel('form_data_create'),
|
||||||
|
icon: 'FilePlus',
|
||||||
|
color: 'green',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form_data_read',
|
||||||
|
label: getNodeLabel('form_data_read'),
|
||||||
|
icon: 'FileText',
|
||||||
|
color: 'blue',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form_data_update',
|
||||||
|
label: getNodeLabel('form_data_update'),
|
||||||
|
icon: 'FileText',
|
||||||
|
color: 'orange',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form_data_delete',
|
||||||
|
label: getNodeLabel('form_data_delete'),
|
||||||
|
icon: 'Trash2',
|
||||||
|
color: 'red',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form_data_list',
|
||||||
|
label: getNodeLabel('form_data_list'),
|
||||||
|
icon: 'Search',
|
||||||
|
color: 'blue',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'form_schema_to_llm',
|
||||||
|
label: getNodeLabel('form_schema_to_llm'),
|
||||||
|
icon: 'Code',
|
||||||
|
color: 'purple',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -404,6 +507,47 @@ const nodeCategories = computed<NodePaletteCategory[]>(() => [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: $t('ai-platform.workflow.editor.categories.database'),
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
type: 'text_to_sql',
|
||||||
|
label: getNodeLabel('text_to_sql'),
|
||||||
|
icon: 'DatabaseZap',
|
||||||
|
color: 'cyan',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'db_insert',
|
||||||
|
label: getNodeLabel('db_insert'),
|
||||||
|
icon: 'DatabaseZap',
|
||||||
|
color: 'green',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'db_update',
|
||||||
|
label: getNodeLabel('db_update'),
|
||||||
|
icon: 'DatabaseBackup',
|
||||||
|
color: 'green',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'db_query',
|
||||||
|
label: getNodeLabel('db_query'),
|
||||||
|
icon: 'Search',
|
||||||
|
color: 'green',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'db_delete',
|
||||||
|
label: getNodeLabel('db_delete'),
|
||||||
|
icon: 'Trash2',
|
||||||
|
color: 'green',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'db_sql',
|
||||||
|
label: getNodeLabel('db_sql'),
|
||||||
|
icon: 'Database',
|
||||||
|
color: 'green',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: $t('ai-platform.workflow.editor.categories.flowControl'),
|
name: $t('ai-platform.workflow.editor.categories.flowControl'),
|
||||||
nodes: [
|
nodes: [
|
||||||
@@ -452,12 +596,84 @@ const nodeCategories = computed<NodePaletteCategory[]>(() => [
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: $t('ai-platform.workflow.editor.categories.database'),
|
name: 'Snowflake',
|
||||||
nodes: [
|
nodes: [
|
||||||
{
|
{
|
||||||
type: 'text_to_sql',
|
type: 'snowflake_cortex_llm',
|
||||||
label: getNodeLabel('text_to_sql'),
|
label: getNodeLabel('snowflake_cortex_llm'),
|
||||||
icon: 'DatabaseZap',
|
icon: 'Snowflake',
|
||||||
|
color: 'cyan',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'snowflake_cortex_analyst',
|
||||||
|
label: getNodeLabel('snowflake_cortex_analyst'),
|
||||||
|
icon: 'MessageSquareMore',
|
||||||
|
color: 'cyan',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: $t('ai-platform.workflow.editor.categories.appManage'),
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
type: 'app_create',
|
||||||
|
label: getNodeLabel('app_create'),
|
||||||
|
icon: 'LayoutTemplate',
|
||||||
|
color: 'indigo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'app_design',
|
||||||
|
label: getNodeLabel('app_design'),
|
||||||
|
icon: 'LayoutDashboard',
|
||||||
|
color: 'indigo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'app_settings',
|
||||||
|
label: getNodeLabel('app_settings'),
|
||||||
|
icon: 'Settings',
|
||||||
|
color: 'indigo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'app_update',
|
||||||
|
label: getNodeLabel('app_update'),
|
||||||
|
icon: 'Save',
|
||||||
|
color: 'indigo',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: $t('ai-platform.workflow.editor.categories.dashboard'),
|
||||||
|
icon: 'LayoutDashboard',
|
||||||
|
color: 'cyan',
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
type: 'dashboard_basic_info',
|
||||||
|
label: getNodeLabel('dashboard_basic_info'),
|
||||||
|
icon: 'FileText',
|
||||||
|
color: 'cyan',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'dashboard_design',
|
||||||
|
label: getNodeLabel('dashboard_design'),
|
||||||
|
icon: 'LayoutDashboard',
|
||||||
|
color: 'cyan',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'dashboard_create',
|
||||||
|
label: getNodeLabel('dashboard_create'),
|
||||||
|
icon: 'FilePlus',
|
||||||
|
color: 'cyan',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'dashboard_publish',
|
||||||
|
label: getNodeLabel('dashboard_publish'),
|
||||||
|
icon: 'Upload',
|
||||||
|
color: 'cyan',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'system_summary',
|
||||||
|
label: getNodeLabel('system_summary'),
|
||||||
|
icon: 'ClipboardCheck',
|
||||||
color: 'cyan',
|
color: 'cyan',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -487,6 +703,10 @@ const iconComponents: Record<string, any> = {
|
|||||||
Combine,
|
Combine,
|
||||||
Square,
|
Square,
|
||||||
DatabaseZap,
|
DatabaseZap,
|
||||||
|
DatabaseBackup,
|
||||||
|
Search,
|
||||||
|
Trash2,
|
||||||
|
Database,
|
||||||
// 对话交互节点图标
|
// 对话交互节点图标
|
||||||
MessageSquareText,
|
MessageSquareText,
|
||||||
HelpCircle,
|
HelpCircle,
|
||||||
@@ -494,8 +714,23 @@ const iconComponents: Record<string, any> = {
|
|||||||
CircleHelp,
|
CircleHelp,
|
||||||
// 意图识别节点图标
|
// 意图识别节点图标
|
||||||
Brain,
|
Brain,
|
||||||
|
// Snowflake Cortex 节点图标
|
||||||
|
Snowflake,
|
||||||
|
MessageSquareMore,
|
||||||
// 循环节点图标
|
// 循环节点图标
|
||||||
RefreshCw,
|
RefreshCw,
|
||||||
|
CornerDownLeft,
|
||||||
|
// 表单节点图标
|
||||||
|
FileText,
|
||||||
|
TableProperties,
|
||||||
|
Send,
|
||||||
|
// 应用节点图标
|
||||||
|
LayoutDashboard,
|
||||||
|
Settings,
|
||||||
|
Save,
|
||||||
|
// 仪表盘节点图标
|
||||||
|
FilePlus,
|
||||||
|
Upload,
|
||||||
// 系统总结节点图标
|
// 系统总结节点图标
|
||||||
ClipboardCheck,
|
ClipboardCheck,
|
||||||
// 子流程节点图标
|
// 子流程节点图标
|
||||||
@@ -506,7 +741,21 @@ const iconComponents: Record<string, any> = {
|
|||||||
|
|
||||||
// 过滤后的节点分类
|
// 过滤后的节点分类
|
||||||
const filteredNodeCategories = computed(() => {
|
const filteredNodeCategories = computed(() => {
|
||||||
const categories = nodeCategories.value;
|
// 首先根据工作流类型过滤分类
|
||||||
|
let categories = nodeCategories.value;
|
||||||
|
|
||||||
|
// 如果是通用类型,排除表单设计、应用管理、仪表盘分组
|
||||||
|
if (workflow.value?.workflow_type === 'general') {
|
||||||
|
const excludeNames = new Set([
|
||||||
|
$t('ai-platform.workflow.editor.categories.appManage'),
|
||||||
|
$t('ai-platform.workflow.editor.categories.dashboard'),
|
||||||
|
$t('ai-platform.workflow.editor.categories.formDesign'),
|
||||||
|
]);
|
||||||
|
categories = nodeCategories.value.filter(
|
||||||
|
(category: { name: string; nodes: any[] }) =>
|
||||||
|
!excludeNames.has(category.name),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// 再根据搜索关键词过滤
|
// 再根据搜索关键词过滤
|
||||||
if (!nodeSearchQuery.value.trim()) {
|
if (!nodeSearchQuery.value.trim()) {
|
||||||
@@ -516,16 +765,19 @@ const filteredNodeCategories = computed(() => {
|
|||||||
const query = nodeSearchQuery.value.toLowerCase();
|
const query = nodeSearchQuery.value.toLowerCase();
|
||||||
return categories
|
return categories
|
||||||
.map(
|
.map(
|
||||||
(category: NodePaletteCategory) => ({
|
(category: {
|
||||||
|
name: string;
|
||||||
|
nodes: { color: string; icon: string; label: string; type: string }[];
|
||||||
|
}) => ({
|
||||||
...category,
|
...category,
|
||||||
nodes: category.nodes.filter(
|
nodes: category.nodes.filter(
|
||||||
(node: NodePaletteItem) =>
|
(node: { label: string; type: string }) =>
|
||||||
node.label.toLowerCase().includes(query) ||
|
node.label.toLowerCase().includes(query) ||
|
||||||
node.type.toLowerCase().includes(query),
|
node.type.toLowerCase().includes(query),
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.filter((category: NodePaletteCategory) => category.nodes.length > 0);
|
.filter((category: { nodes: any[] }) => category.nodes.length > 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听视口变化(包括滚轮缩放)
|
// 监听视口变化(包括滚轮缩放)
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { computed } from 'vue';
|
|
||||||
|
|
||||||
import { CircleHelp } from '@vben/icons';
|
|
||||||
|
|
||||||
import BaseNode from './BaseNode.vue';
|
|
||||||
|
|
||||||
const props = defineProps(['selected', 'data', 'id', 'type']);
|
|
||||||
|
|
||||||
const nodeType = computed(() => props.type || props.data?.type || 'legacy');
|
|
||||||
const nodeLabel = computed(
|
|
||||||
() => props.data?.label || props.data?.name || nodeType.value,
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<BaseNode
|
|
||||||
:selected="selected"
|
|
||||||
:execution-status="data?.executionStatus"
|
|
||||||
:execution-result="data?.executionResult"
|
|
||||||
:label="nodeLabel"
|
|
||||||
:inputs="[{ id: 'target' }]"
|
|
||||||
:outputs="[{ id: 'source' }]"
|
|
||||||
:node-id="id"
|
|
||||||
:node-type="nodeType"
|
|
||||||
>
|
|
||||||
<template #icon><CircleHelp class="size-5" /></template>
|
|
||||||
<template #desc>历史节点</template>
|
|
||||||
|
|
||||||
<div class="space-y-2">
|
|
||||||
<div
|
|
||||||
class="border-border bg-muted text-muted-foreground rounded border px-2 py-1 text-xs"
|
|
||||||
>
|
|
||||||
该节点属于已精简模块,仅保留在旧流程中展示。
|
|
||||||
</div>
|
|
||||||
<div class="text-muted-foreground flex justify-between text-[11px]">
|
|
||||||
<span>Type</span>
|
|
||||||
<span class="font-mono">{{ nodeType }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</BaseNode>
|
|
||||||
</template>
|
|
||||||
@@ -1,11 +1,32 @@
|
|||||||
import { markRaw } from 'vue';
|
import { markRaw } from 'vue';
|
||||||
|
|
||||||
import AddButtonEdge from '../editor/edges/AddButtonEdge.vue';
|
import AddButtonEdge from '../editor/edges/AddButtonEdge.vue';
|
||||||
|
import AppCreateNode from '../editor/nodes/AppCreateNode.vue';
|
||||||
|
import AppDesignNode from '../editor/nodes/AppDesignNode.vue';
|
||||||
|
import AppSettingsNode from '../editor/nodes/AppSettingsNode.vue';
|
||||||
|
import AppUpdateNode from '../editor/nodes/AppUpdateNode.vue';
|
||||||
import ChoiceNode from '../editor/nodes/ChoiceNode.vue';
|
import ChoiceNode from '../editor/nodes/ChoiceNode.vue';
|
||||||
import CodeNode from '../editor/nodes/CodeNode.vue';
|
import CodeNode from '../editor/nodes/CodeNode.vue';
|
||||||
import ConditionNode from '../editor/nodes/ConditionNode.vue';
|
import ConditionNode from '../editor/nodes/ConditionNode.vue';
|
||||||
import ConfirmNode from '../editor/nodes/ConfirmNode.vue';
|
import ConfirmNode from '../editor/nodes/ConfirmNode.vue';
|
||||||
|
import DashboardBasicInfoNode from '../editor/nodes/DashboardBasicInfoNode.vue';
|
||||||
|
import DashboardCreateNode from '../editor/nodes/DashboardCreateNode.vue';
|
||||||
|
import DashboardDesignNode from '../editor/nodes/DashboardDesignNode.vue';
|
||||||
|
import DashboardPublishNode from '../editor/nodes/DashboardPublishNode.vue';
|
||||||
|
import DbDeleteNode from '../editor/nodes/DbDeleteNode.vue';
|
||||||
|
import DbInsertNode from '../editor/nodes/DbInsertNode.vue';
|
||||||
|
import DbQueryNode from '../editor/nodes/DbQueryNode.vue';
|
||||||
|
import DbSqlNode from '../editor/nodes/DbSqlNode.vue';
|
||||||
|
import DbUpdateNode from '../editor/nodes/DbUpdateNode.vue';
|
||||||
import EndNode from '../editor/nodes/EndNode.vue';
|
import EndNode from '../editor/nodes/EndNode.vue';
|
||||||
|
import FormBasicInfoNode from '../editor/nodes/FormBasicInfoNode.vue';
|
||||||
|
import FormCreateNode from '../editor/nodes/FormCreateNode.vue';
|
||||||
|
import FormDatabaseCreateNode from '../editor/nodes/FormDatabaseCreateNode.vue';
|
||||||
|
import FormDatabaseDesignNode from '../editor/nodes/FormDatabaseDesignNode.vue';
|
||||||
|
import FormDataNode from '../editor/nodes/FormDataNode.vue';
|
||||||
|
import FormListDesignNode from '../editor/nodes/FormListDesignNode.vue';
|
||||||
|
import FormPublishNode from '../editor/nodes/FormPublishNode.vue';
|
||||||
|
import FormUIDesignNode from '../editor/nodes/FormUIDesignNode.vue';
|
||||||
import HttpNode from '../editor/nodes/HttpNode.vue';
|
import HttpNode from '../editor/nodes/HttpNode.vue';
|
||||||
import IntentNode from '../editor/nodes/IntentNode.vue';
|
import IntentNode from '../editor/nodes/IntentNode.vue';
|
||||||
import KnowledgeRetrievalNode from '../editor/nodes/KnowledgeRetrievalNode.vue';
|
import KnowledgeRetrievalNode from '../editor/nodes/KnowledgeRetrievalNode.vue';
|
||||||
@@ -15,47 +36,13 @@ import MergeNode from '../editor/nodes/MergeNode.vue';
|
|||||||
import MessageNode from '../editor/nodes/MessageNode.vue';
|
import MessageNode from '../editor/nodes/MessageNode.vue';
|
||||||
import ParallelNode from '../editor/nodes/ParallelNode.vue';
|
import ParallelNode from '../editor/nodes/ParallelNode.vue';
|
||||||
import QuestionNode from '../editor/nodes/QuestionNode.vue';
|
import QuestionNode from '../editor/nodes/QuestionNode.vue';
|
||||||
|
import SnowflakeCortexAnalystNode from '../editor/nodes/SnowflakeCortexAnalystNode.vue';
|
||||||
|
import SnowflakeCortexLLMNode from '../editor/nodes/SnowflakeCortexLLMNode.vue';
|
||||||
import StartNode from '../editor/nodes/StartNode.vue';
|
import StartNode from '../editor/nodes/StartNode.vue';
|
||||||
import SubflowNode from '../editor/nodes/SubflowNode.vue';
|
import SubflowNode from '../editor/nodes/SubflowNode.vue';
|
||||||
import SystemSummaryNode from '../editor/nodes/SystemSummaryNode.vue';
|
import SystemSummaryNode from '../editor/nodes/SystemSummaryNode.vue';
|
||||||
import TemplateNode from '../editor/nodes/TemplateNode.vue';
|
import TemplateNode from '../editor/nodes/TemplateNode.vue';
|
||||||
import TextToSqlNode from '../editor/nodes/TextToSqlNode.vue';
|
import TextToSqlNode from '../editor/nodes/TextToSqlNode.vue';
|
||||||
import UnsupportedNode from '../editor/nodes/UnsupportedNode.vue';
|
|
||||||
|
|
||||||
const legacyNodeTypes = [
|
|
||||||
'db_insert',
|
|
||||||
'db_update',
|
|
||||||
'db_query',
|
|
||||||
'db_delete',
|
|
||||||
'db_sql',
|
|
||||||
'snowflake_cortex_llm',
|
|
||||||
'snowflake_cortex_analyst',
|
|
||||||
'form_basic_info',
|
|
||||||
'form_database_design',
|
|
||||||
'form_database_create',
|
|
||||||
'form_ui_design',
|
|
||||||
'form_list_design',
|
|
||||||
'form_create',
|
|
||||||
'form_publish',
|
|
||||||
'app_create',
|
|
||||||
'app_design',
|
|
||||||
'app_settings',
|
|
||||||
'app_update',
|
|
||||||
'dashboard_basic_info',
|
|
||||||
'dashboard_design',
|
|
||||||
'dashboard_create',
|
|
||||||
'dashboard_publish',
|
|
||||||
'form_data_create',
|
|
||||||
'form_data_read',
|
|
||||||
'form_data_update',
|
|
||||||
'form_data_delete',
|
|
||||||
'form_data_list',
|
|
||||||
'form_schema_to_llm',
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
const legacyNodeTypeMap = Object.fromEntries(
|
|
||||||
legacyNodeTypes.map((type) => [type, markRaw(UnsupportedNode)]),
|
|
||||||
);
|
|
||||||
|
|
||||||
export const workflowNodeTypes = {
|
export const workflowNodeTypes = {
|
||||||
start: markRaw(StartNode),
|
start: markRaw(StartNode),
|
||||||
@@ -67,17 +54,44 @@ export const workflowNodeTypes = {
|
|||||||
template: markRaw(TemplateNode),
|
template: markRaw(TemplateNode),
|
||||||
parallel: markRaw(ParallelNode),
|
parallel: markRaw(ParallelNode),
|
||||||
merge: markRaw(MergeNode),
|
merge: markRaw(MergeNode),
|
||||||
|
db_insert: markRaw(DbInsertNode),
|
||||||
|
db_update: markRaw(DbUpdateNode),
|
||||||
|
db_query: markRaw(DbQueryNode),
|
||||||
|
db_delete: markRaw(DbDeleteNode),
|
||||||
|
db_sql: markRaw(DbSqlNode),
|
||||||
question: markRaw(QuestionNode),
|
question: markRaw(QuestionNode),
|
||||||
choice: markRaw(ChoiceNode),
|
choice: markRaw(ChoiceNode),
|
||||||
message: markRaw(MessageNode),
|
message: markRaw(MessageNode),
|
||||||
confirm: markRaw(ConfirmNode),
|
confirm: markRaw(ConfirmNode),
|
||||||
intent: markRaw(IntentNode),
|
intent: markRaw(IntentNode),
|
||||||
|
snowflake_cortex_llm: markRaw(SnowflakeCortexLLMNode),
|
||||||
|
snowflake_cortex_analyst: markRaw(SnowflakeCortexAnalystNode),
|
||||||
loop: markRaw(LoopNode),
|
loop: markRaw(LoopNode),
|
||||||
|
form_basic_info: markRaw(FormBasicInfoNode),
|
||||||
|
form_database_design: markRaw(FormDatabaseDesignNode),
|
||||||
|
form_database_create: markRaw(FormDatabaseCreateNode),
|
||||||
|
form_ui_design: markRaw(FormUIDesignNode),
|
||||||
|
form_list_design: markRaw(FormListDesignNode),
|
||||||
|
form_create: markRaw(FormCreateNode),
|
||||||
|
form_publish: markRaw(FormPublishNode),
|
||||||
|
app_create: markRaw(AppCreateNode),
|
||||||
|
app_design: markRaw(AppDesignNode),
|
||||||
|
app_settings: markRaw(AppSettingsNode),
|
||||||
|
app_update: markRaw(AppUpdateNode),
|
||||||
|
dashboard_basic_info: markRaw(DashboardBasicInfoNode),
|
||||||
|
dashboard_design: markRaw(DashboardDesignNode),
|
||||||
|
dashboard_create: markRaw(DashboardCreateNode),
|
||||||
|
dashboard_publish: markRaw(DashboardPublishNode),
|
||||||
system_summary: markRaw(SystemSummaryNode),
|
system_summary: markRaw(SystemSummaryNode),
|
||||||
subflow: markRaw(SubflowNode),
|
subflow: markRaw(SubflowNode),
|
||||||
|
form_data_create: markRaw(FormDataNode),
|
||||||
|
form_data_read: markRaw(FormDataNode),
|
||||||
|
form_data_update: markRaw(FormDataNode),
|
||||||
|
form_data_delete: markRaw(FormDataNode),
|
||||||
|
form_data_list: markRaw(FormDataNode),
|
||||||
|
form_schema_to_llm: markRaw(FormDataNode),
|
||||||
text_to_sql: markRaw(TextToSqlNode),
|
text_to_sql: markRaw(TextToSqlNode),
|
||||||
knowledge_retrieval: markRaw(KnowledgeRetrievalNode),
|
knowledge_retrieval: markRaw(KnowledgeRetrievalNode),
|
||||||
...legacyNodeTypeMap,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const workflowEdgeTypes = {
|
export const workflowEdgeTypes = {
|
||||||
|
|||||||
Reference in New Issue
Block a user