vue-agent-start 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/package.json +30 -0
  2. package/pnpm-workspace.yaml +3 -0
  3. package/src/agent-flow/adapter/backend.ts +99 -0
  4. package/src/agent-flow/components/ChatIframePanel.vue +773 -0
  5. package/src/agent-flow/components/DatasetItemCard.vue +313 -0
  6. package/src/agent-flow/components/MemoryWindow.vue +104 -0
  7. package/src/agent-flow/components/PromptEditor.vue +804 -0
  8. package/src/agent-flow/components/PromptEditorTagPanel.vue +460 -0
  9. package/src/agent-flow/components/SvgIcon.vue +32 -0
  10. package/src/agent-flow/components/ToolItemCard.vue +169 -0
  11. package/src/agent-flow/components/VariableCard.vue +161 -0
  12. package/src/agent-flow/components/VariableSelector.vue +162 -0
  13. package/src/agent-flow/components/chat-iframe-types.ts +35 -0
  14. package/src/agent-flow/components/stubs/DatasetChooser.vue +70 -0
  15. package/src/agent-flow/components/stubs/Embedding.vue +22 -0
  16. package/src/agent-flow/components/stubs/ModelSelect.vue +24 -0
  17. package/src/agent-flow/components/stubs/RestfulSelectCard.vue +24 -0
  18. package/src/agent-flow/components/stubs/ToolChooser.vue +96 -0
  19. package/src/agent-flow/components/stubs/TriggersItemCard.vue +126 -0
  20. package/src/agent-flow/components/stubs/VariableModal.vue +115 -0
  21. package/src/agent-flow/index.ts +73 -0
  22. package/src/agent-flow/stores/workflow.ts +72 -0
  23. package/src/agent-flow/utils/langUtils.ts +173 -0
  24. package/src/agent-flow/workflow/Ability.vue +65 -0
  25. package/src/agent-flow/workflow/AuthorizationItem.vue +101 -0
  26. package/src/agent-flow/workflow/ConversationVar.vue +42 -0
  27. package/src/agent-flow/workflow/CustomEdge.vue +94 -0
  28. package/src/agent-flow/workflow/EnvironmentVar.vue +40 -0
  29. package/src/agent-flow/workflow/FlowDesigner.vue +2802 -0
  30. package/src/agent-flow/workflow/Icon.vue +179 -0
  31. package/src/agent-flow/workflow/NodeConfig.vue +509 -0
  32. package/src/agent-flow/workflow/NodeConfigCard.vue +460 -0
  33. package/src/agent-flow/workflow/NodeHandle.vue +147 -0
  34. package/src/agent-flow/workflow/NodeHeaderToolbar.vue +77 -0
  35. package/src/agent-flow/workflow/NodeHoverToolbar.vue +176 -0
  36. package/src/agent-flow/workflow/OutputItemCard.vue +668 -0
  37. package/src/agent-flow/workflow/ParamTableItem.vue +200 -0
  38. package/src/agent-flow/workflow/StructTable.vue +202 -0
  39. package/src/agent-flow/workflow/VarInsertField.vue +517 -0
  40. package/src/agent-flow/workflow/VarSelectField.vue +223 -0
  41. package/src/agent-flow/workflow/VariableSelectorItem.vue +48 -0
  42. package/src/agent-flow/workflow/WfField.vue +206 -0
  43. package/src/agent-flow/workflow/_config-base.css +470 -0
  44. package/src/agent-flow/workflow/composables/useNode.js +55 -0
  45. package/src/agent-flow/workflow/index.vue +53 -0
  46. package/src/agent-flow/workflow/nodeCard/AgentNodeCard.vue +180 -0
  47. package/src/agent-flow/workflow/nodeCard/AnswerNodeCard.vue +65 -0
  48. package/src/agent-flow/workflow/nodeCard/ClassifierCard.vue +152 -0
  49. package/src/agent-flow/workflow/nodeCard/CodeNodeCard.vue +139 -0
  50. package/src/agent-flow/workflow/nodeCard/ConditionNodeCard.vue +323 -0
  51. package/src/agent-flow/workflow/nodeCard/DocumentExtractorCard.vue +83 -0
  52. package/src/agent-flow/workflow/nodeCard/EndNodeCard.vue +123 -0
  53. package/src/agent-flow/workflow/nodeCard/HttpNodeCard.vue +451 -0
  54. package/src/agent-flow/workflow/nodeCard/HumanInputCard.vue +152 -0
  55. package/src/agent-flow/workflow/nodeCard/IterationCard.vue +66 -0
  56. package/src/agent-flow/workflow/nodeCard/KnowledgeRetrievalCard.vue +48 -0
  57. package/src/agent-flow/workflow/nodeCard/LLMNodeCard.vue +206 -0
  58. package/src/agent-flow/workflow/nodeCard/ListOperatorCard.vue +188 -0
  59. package/src/agent-flow/workflow/nodeCard/ParameterExtractorCard.vue +352 -0
  60. package/src/agent-flow/workflow/nodeCard/ServiceApiNodeCard.vue +188 -0
  61. package/src/agent-flow/workflow/nodeCard/StartNodeCard.vue +216 -0
  62. package/src/agent-flow/workflow/nodeCard/VariableAssignerCard.vue +125 -0
  63. package/src/agent-flow/workflow/nodeCard/VariableNodeCard.vue +121 -0
  64. package/src/agent-flow/workflow/nodes/AgentNode.vue +122 -0
  65. package/src/agent-flow/workflow/nodes/AnswerNode.vue +99 -0
  66. package/src/agent-flow/workflow/nodes/ClassifierNode.vue +199 -0
  67. package/src/agent-flow/workflow/nodes/CodeNode.vue +152 -0
  68. package/src/agent-flow/workflow/nodes/ConditionNode.vue +232 -0
  69. package/src/agent-flow/workflow/nodes/DocumentExtractorNode.vue +96 -0
  70. package/src/agent-flow/workflow/nodes/EndNode.vue +119 -0
  71. package/src/agent-flow/workflow/nodes/FileUploadNode.vue +97 -0
  72. package/src/agent-flow/workflow/nodes/HttpNode.vue +204 -0
  73. package/src/agent-flow/workflow/nodes/HumanInputNode.vue +110 -0
  74. package/src/agent-flow/workflow/nodes/IterationNode.vue +98 -0
  75. package/src/agent-flow/workflow/nodes/KnowledgeRetrievalNode.vue +253 -0
  76. package/src/agent-flow/workflow/nodes/LLMNode.vue +134 -0
  77. package/src/agent-flow/workflow/nodes/ListOperatorNode.vue +111 -0
  78. package/src/agent-flow/workflow/nodes/LoopNode.vue +94 -0
  79. package/src/agent-flow/workflow/nodes/ParameterExtractorNode.vue +147 -0
  80. package/src/agent-flow/workflow/nodes/ServiceApiNode.vue +161 -0
  81. package/src/agent-flow/workflow/nodes/StartNode.vue +199 -0
  82. package/src/agent-flow/workflow/nodes/TemplateNode.vue +103 -0
  83. package/src/agent-flow/workflow/nodes/UserInputNode.vue +92 -0
  84. package/src/agent-flow/workflow/nodes/VariableAssignerNode.vue +145 -0
  85. package/src/agent-flow/workflow/nodes/VariableNode.vue +130 -0
  86. package/src/agent-flow/workflow/nodes/_node-base.css +338 -0
  87. package/src/agent-flow/workflow/utils/node_card_form.ts +335 -0
  88. package/src/agent-flow/workflow/utils/node_config.ts +63 -0
  89. package/src/agent-flow/workflow/utils/workflow_utils.ts +151 -0
  90. package/src/agent-studio/adapters/springAgentStart.ts +390 -0
  91. package/src/agent-studio/api/index.ts +1 -0
  92. package/src/agent-studio/api/types.ts +173 -0
  93. package/src/agent-studio/components/AgentApiDocs.vue +500 -0
  94. package/src/agent-studio/components/AgentAppsPage.vue +1601 -0
  95. package/src/agent-studio/components/AgentCardGrid.vue +259 -0
  96. package/src/agent-studio/components/AgentChatPage.vue +553 -0
  97. package/src/agent-studio/components/AgentDebugPanel.vue +350 -0
  98. package/src/agent-studio/components/AgentLogsPanel.vue +391 -0
  99. package/src/agent-studio/components/AgentMonitorPanel.vue +204 -0
  100. package/src/agent-studio/components/AgentOrchestrate.vue +505 -0
  101. package/src/agent-studio/components/AgentPromptEditor.vue +237 -0
  102. package/src/agent-studio/components/AgentStudioShell.vue +227 -0
  103. package/src/agent-studio/components/AgentToolsPanel.vue +394 -0
  104. package/src/agent-studio/components/AgentVariablesPanel.vue +205 -0
  105. package/src/agent-studio/components/ApiKeyManager.vue +251 -0
  106. package/src/agent-studio/components/AppDesignDrawer.vue +3391 -0
  107. package/src/agent-studio/components/CreateAppModal.vue +737 -0
  108. package/src/agent-studio/components/SparkChart.vue +200 -0
  109. package/src/agent-studio/components/VariableEditorModal.vue +499 -0
  110. package/src/agent-studio/composables/useAgentStudio.ts +347 -0
  111. package/src/agent-studio/index.ts +60 -0
  112. package/src/agent-studio/panels/DrawerFlowDesigner.vue +203 -0
  113. package/src/agent-studio/panels/LogAnnotationPanel.vue +490 -0
  114. package/src/agent-studio/panels/MonitorPanel.vue +535 -0
  115. package/src/agent-studio/types.ts +242 -0
  116. package/src/index.ts +155 -0
  117. package/src/knowledge-hub/adapters/springAgentStart.ts +472 -0
  118. package/src/knowledge-hub/components/AddDocumentsWizard.vue +1452 -0
  119. package/src/knowledge-hub/components/CreateDatasetWizard.vue +1723 -0
  120. package/src/knowledge-hub/components/DatasetCardGrid.vue +467 -0
  121. package/src/knowledge-hub/components/DatasetDetailDrawer.vue +888 -0
  122. package/src/knowledge-hub/components/DatasetPicker.vue +65 -0
  123. package/src/knowledge-hub/components/DatasetPickerModal.vue +526 -0
  124. package/src/knowledge-hub/components/DatasetSettingsPanel.vue +908 -0
  125. package/src/knowledge-hub/components/DatasetSidebar.vue +781 -0
  126. package/src/knowledge-hub/components/DocumentChunksView.vue +802 -0
  127. package/src/knowledge-hub/components/DocumentTable.vue +552 -0
  128. package/src/knowledge-hub/components/HitTestingPanel.vue +74 -0
  129. package/src/knowledge-hub/components/KnowledgeApp.vue +66 -0
  130. package/src/knowledge-hub/components/KnowledgeHubApp.vue +504 -0
  131. package/src/knowledge-hub/components/RecallTestingPanelV2.vue +515 -0
  132. package/src/knowledge-hub/components/RetrievalConfigPopover.vue +270 -0
  133. package/src/knowledge-hub/components/RetrievalMethodPicker.vue +547 -0
  134. package/src/knowledge-hub/components/RetrievedList.vue +24 -0
  135. package/src/knowledge-hub/components/internal/KhDialog.vue +195 -0
  136. package/src/knowledge-hub/composables/useKnowledge.ts +89 -0
  137. package/src/knowledge-hub/i18n/index.ts +2 -0
  138. package/src/knowledge-hub/i18n/messages.ts +422 -0
  139. package/src/knowledge-hub/i18n/useKhI18n.ts +107 -0
  140. package/src/knowledge-hub/index.ts +46 -0
  141. package/src/knowledge-hub/styles/index.css +4 -0
  142. package/src/knowledge-hub/styles/tokens.css +138 -0
  143. package/src/knowledge-hub/types/api.ts +213 -0
  144. package/src/knowledge-hub/types/dataset.ts +88 -0
  145. package/src/knowledge-hub/types/document.ts +45 -0
  146. package/src/knowledge-hub/types/index.ts +9 -0
  147. package/src/knowledge-hub/types/retrieval.ts +46 -0
  148. package/src/provider-hub/components/CredentialForm.vue +103 -0
  149. package/src/provider-hub/components/DefaultModelsPanel.vue +270 -0
  150. package/src/provider-hub/components/GroupedModelSelect.vue +445 -0
  151. package/src/provider-hub/components/ModelCardGrid.vue +332 -0
  152. package/src/provider-hub/components/ModelParameterDrawer.vue +739 -0
  153. package/src/provider-hub/components/ModelPickerPopover.vue +1282 -0
  154. package/src/provider-hub/components/ProviderApp.vue +159 -0
  155. package/src/provider-hub/components/ProviderCredentialModal.vue +321 -0
  156. package/src/provider-hub/components/ProviderGallery.vue +131 -0
  157. package/src/provider-hub/components/ProviderHubShell.vue +1992 -0
  158. package/src/provider-hub/components/ProviderIcon.vue +130 -0
  159. package/src/provider-hub/composables/useProviderHub.ts +358 -0
  160. package/src/provider-hub/index.ts +43 -0
  161. package/src/provider-hub/svg/MiniMax.svg +1 -0
  162. package/src/provider-hub/svg/Volcengine.svg +1 -0
  163. package/src/provider-hub/svg/Zhipu.svg +1 -0
  164. package/src/provider-hub/svg/deepseek.svg +1 -0
  165. package/src/provider-hub/svg/moonshot.svg +1 -0
  166. package/src/provider-hub/svg/openai.svg +1 -0
  167. package/src/provider-hub/svg/qwen.svg +1 -0
  168. package/src/provider-hub/svg/siliconflow.svg +1 -0
  169. package/src/provider-hub/types.ts +256 -0
@@ -0,0 +1,145 @@
1
+ <script setup>
2
+ import { computed, ref } from 'vue';
3
+
4
+ import Icon from '../Icon.vue';
5
+ import NodeHandle from '../NodeHandle.vue';
6
+ import NodeHoverToolbar from '../NodeHoverToolbar.vue';
7
+
8
+ const props = defineProps({
9
+ id: String,
10
+ data: {
11
+ type: Object,
12
+ default: () => ({
13
+ label: '变量赋值',
14
+ description: '把上游变量写回到会话/环境变量',
15
+ assignments: [],
16
+ }),
17
+ },
18
+ });
19
+
20
+ const emit = defineEmits(['duplicate', 'delete', 'connection-plus-click']);
21
+
22
+ const isHovered = ref(false);
23
+ const onMouseEnter = () => (isHovered.value = true);
24
+ const onMouseLeave = () => (isHovered.value = false);
25
+ const duplicateNode = () => emit('duplicate', props.id);
26
+ const deleteNode = () => emit('delete', props.id);
27
+ const onConnectionPlusClick = (event, nodeId, handleId) => {
28
+ emit('connection-plus-click', event, nodeId, handleId);
29
+ };
30
+
31
+ const preview = computed(() => (props.data.assignments || []).slice(0, 3));
32
+ const total = computed(() => props.data.assignments?.length || 0);
33
+ </script>
34
+
35
+ <template>
36
+ <div
37
+ class="wf-node variable-assigner-node"
38
+ @mouseenter="onMouseEnter"
39
+ @mouseleave="onMouseLeave"
40
+ >
41
+ <NodeHoverToolbar
42
+ v-if="isHovered"
43
+ node-type="variable_assigner"
44
+ @duplicate="duplicateNode"
45
+ @delete="deleteNode"
46
+ />
47
+
48
+ <div class="wf-node-header">
49
+ <div class="wf-node-icon">
50
+ <Icon name="variable" />
51
+ </div>
52
+ <div class="wf-node-info">
53
+ <div class="wf-node-title">{{ data.label }}</div>
54
+ <div class="wf-node-subtitle">变量赋值</div>
55
+ </div>
56
+ </div>
57
+
58
+ <div class="wf-node-content">
59
+ <div class="wf-node-description">{{ data.description }}</div>
60
+ <div v-if="total > 0" class="wf-node-preview">
61
+ <div class="wf-node-preview-label">赋值项 ({{ total }})</div>
62
+ <div class="assigner-list">
63
+ <div v-for="a in preview" :key="a.target" class="assigner-row">
64
+ <span class="assigner-target">{{ a.target || '?' }}</span>
65
+ <span class="assigner-arrow">←</span>
66
+ <span class="assigner-source">{{ a.source || '?' }}</span>
67
+ </div>
68
+ <div v-if="total > 3" class="assigner-more">
69
+ +{{ total - 3 }} 项
70
+ </div>
71
+ </div>
72
+ </div>
73
+ <div v-else class="wf-node-empty">
74
+ <span class="wf-node-empty-text">配置赋值项</span>
75
+ </div>
76
+ </div>
77
+
78
+ <NodeHandle
79
+ :id="id"
80
+ type="target"
81
+ position="Left"
82
+ class-name="flow-node-handle-left"
83
+ :style="{ background: '#059669', border: '2px solid #ffffff' }"
84
+ />
85
+ <NodeHandle
86
+ :id="id"
87
+ type="source"
88
+ position="Right"
89
+ :is-hovered="isHovered"
90
+ class-name="flow-node-handle-right"
91
+ :style="{ background: '#059669', border: '2px solid #ffffff' }"
92
+ @connection-plus-click="onConnectionPlusClick"
93
+ />
94
+ </div>
95
+ </template>
96
+
97
+ <style scoped>
98
+ .variable-assigner-node {
99
+ --wf-accent: #059669;
100
+ --wf-accent-hover: #047857;
101
+ }
102
+
103
+ .assigner-list {
104
+ display: flex;
105
+ flex-direction: column;
106
+ gap: 3px;
107
+ margin-top: 4px;
108
+ }
109
+
110
+ .assigner-row {
111
+ display: flex;
112
+ align-items: center;
113
+ gap: 6px;
114
+ padding: 2px 6px;
115
+ font-size: 11px;
116
+ background: color-mix(in srgb, var(--wf-accent) 8%, transparent);
117
+ border-radius: 4px;
118
+ }
119
+
120
+ .assigner-target {
121
+ color: color-mix(in srgb, var(--wf-accent) 85%, #000);
122
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
123
+ font-weight: 500;
124
+ }
125
+
126
+ .assigner-arrow {
127
+ color: #6b7280;
128
+ font-weight: 600;
129
+ }
130
+
131
+ .assigner-source {
132
+ color: #1f2937;
133
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
134
+ overflow: hidden;
135
+ text-overflow: ellipsis;
136
+ white-space: nowrap;
137
+ }
138
+
139
+ .assigner-more {
140
+ padding: 2px 6px;
141
+ font-size: 10px;
142
+ font-style: italic;
143
+ color: #9ca3af;
144
+ }
145
+ </style>
@@ -0,0 +1,130 @@
1
+ <script setup>
2
+ import { computed, ref } from 'vue';
3
+
4
+ import workflow_utils from '@/workflow/utils/workflow_utils';
5
+
6
+ import Icon from '../Icon.vue';
7
+ import NodeHandle from '../NodeHandle.vue';
8
+ import NodeHoverToolbar from '../NodeHoverToolbar.vue';
9
+
10
+ const props = defineProps({
11
+ id: String,
12
+ data: {
13
+ type: Object,
14
+ default: () => ({
15
+ label: '变量聚合',
16
+ description: '变量聚合节点',
17
+ output: [{ children: [] }],
18
+ }),
19
+ },
20
+ });
21
+
22
+ const emit = defineEmits(['duplicate', 'delete', 'connection-plus-click']);
23
+
24
+ const isHovered = ref(false);
25
+
26
+ const onMouseEnter = () => (isHovered.value = true);
27
+ const onMouseLeave = () => (isHovered.value = false);
28
+ const duplicateNode = () => emit('duplicate', props.id);
29
+ const deleteNode = () => emit('delete', props.id);
30
+ const onConnectionPlusClick = (event, nodeId, handleId) => {
31
+ emit('connection-plus-click', event, nodeId, handleId);
32
+ };
33
+
34
+ const getAnswerTextLabel = (variableSelector) =>
35
+ workflow_utils.getVariableLabel(variableSelector);
36
+
37
+ const aggregated = computed(() => props.data?.output?.[0]?.children ?? []);
38
+ </script>
39
+
40
+ <template>
41
+ <div
42
+ class="wf-node variable-node"
43
+ @mouseenter="onMouseEnter"
44
+ @mouseleave="onMouseLeave"
45
+ >
46
+ <NodeHoverToolbar
47
+ v-if="isHovered"
48
+ node-type="variable"
49
+ @duplicate="duplicateNode"
50
+ @delete="deleteNode"
51
+ />
52
+
53
+ <div class="wf-node-header">
54
+ <div class="wf-node-icon">
55
+ <Icon name="variable" />
56
+ </div>
57
+ <div class="wf-node-info">
58
+ <div class="wf-node-title">{{ data.label }}</div>
59
+ <div class="wf-node-subtitle">变量聚合</div>
60
+ </div>
61
+ </div>
62
+
63
+ <div class="wf-node-content">
64
+ <div class="wf-node-description">{{ data.description }}</div>
65
+ <div v-if="aggregated.length > 0" class="wf-node-preview">
66
+ <div class="wf-node-preview-label">聚合变量</div>
67
+ <div class="wf-node-preview-list">
68
+ <div v-for="it in aggregated" :key="it.name" class="variable-row">
69
+ <div class="variable-name">{{ it.name }}</div>
70
+ <div class="variable-source">
71
+ {{ getAnswerTextLabel(it.variableSelector) }}
72
+ </div>
73
+ </div>
74
+ </div>
75
+ </div>
76
+ <div v-else class="wf-node-empty">
77
+ <span class="wf-node-empty-text">配置变量聚合</span>
78
+ </div>
79
+ </div>
80
+
81
+ <NodeHandle
82
+ :id="id"
83
+ type="target"
84
+ position="Left"
85
+ class-name="flow-node-handle-left"
86
+ :style="{ background: '#0ea5e9', border: '2px solid #ffffff' }"
87
+ />
88
+ <NodeHandle
89
+ :id="id"
90
+ type="source"
91
+ position="Right"
92
+ :is-hovered="isHovered"
93
+ class-name="flow-node-handle-right"
94
+ :style="{ background: '#0ea5e9', border: '2px solid #ffffff' }"
95
+ @connection-plus-click="onConnectionPlusClick"
96
+ />
97
+ </div>
98
+ </template>
99
+
100
+ <style scoped>
101
+ .variable-node {
102
+ --wf-accent: #0ea5e9;
103
+ --wf-accent-hover: #0284c7;
104
+ }
105
+
106
+ .variable-row {
107
+ display: flex;
108
+ align-items: center;
109
+ gap: 8px;
110
+ font-size: 11px;
111
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
112
+ }
113
+
114
+ .variable-name {
115
+ flex: none;
116
+ padding: 1px 6px;
117
+ color: #ffffff;
118
+ background: var(--wf-accent);
119
+ border-radius: 4px;
120
+ }
121
+
122
+ .variable-source {
123
+ flex: 1;
124
+ min-width: 0;
125
+ overflow: hidden;
126
+ color: #4b5563;
127
+ text-overflow: ellipsis;
128
+ white-space: nowrap;
129
+ }
130
+ </style>
@@ -0,0 +1,338 @@
1
+ /* =========================================================
2
+ * agent-flow · 节点通用基础样式
3
+ * 所有节点视觉的共享部分(卡片外观、header、icon、toolbar、
4
+ * status、content 排版、metrics/config 预览、utility 行)。
5
+ * 各节点的 <style scoped> 只负责设置 --wf-accent / --wf-accent-hover
6
+ * 两个 CSS 变量来切换颜色,其余一律走这里。
7
+ * 命名空间:wf- 前缀,避免污染宿主项目样式。
8
+ * ========================================================= */
9
+
10
+ /* -------- 卡片外观 -------- */
11
+ .wf-node {
12
+ --wf-accent: #6b7280;
13
+ --wf-accent-hover: #4b5563;
14
+ --wf-node-bg: #ffffff;
15
+ --wf-node-border: #e5e7eb;
16
+ --wf-node-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
17
+ --wf-node-shadow-hover: 0 4px 16px rgba(0, 0, 0, 0.15);
18
+
19
+ position: relative;
20
+ width: 300px;
21
+ padding: 16px;
22
+ background: var(--wf-node-bg);
23
+ border: 2px solid var(--wf-accent, var(--wf-node-border));
24
+ border-radius: 12px;
25
+ box-shadow: var(--wf-node-shadow);
26
+ transition: box-shadow 0.2s, border-color 0.2s;
27
+ }
28
+
29
+ .wf-node:hover {
30
+ border-color: var(--wf-accent-hover, #6366f1);
31
+ box-shadow: var(--wf-node-shadow-hover);
32
+ }
33
+
34
+ /* 选中态:走 VueFlow 的 .selected 类(<VueFlow> 会在被选中节点根元素加上)
35
+ * 我们的 .wf-node 加在内部 div 上,所以用父选择器 .selected .wf-node
36
+ *
37
+ * 更强的视觉反馈——之前的 2px @25% halo 在原本已经带 accent 边框的卡片上
38
+ * 几乎看不出来。加厚成 3px @45% halo,叠一层淡 accent 背景 + 更浓的投影,
39
+ * 用户一眼就能看出"这是当前正在配置的节点"。纯 CSS,没有 JS reactivity 开销。 */
40
+ .selected .wf-node,
41
+ .wf-node.wf-node-selected {
42
+ background:
43
+ linear-gradient(
44
+ color-mix(in srgb, var(--wf-accent, #6366f1) 6%, #ffffff),
45
+ color-mix(in srgb, var(--wf-accent, #6366f1) 6%, #ffffff)
46
+ ),
47
+ var(--wf-node-bg);
48
+ border-color: var(--wf-accent, #6366f1) !important;
49
+ box-shadow:
50
+ 0 0 0 3px color-mix(in srgb, var(--wf-accent, #6366f1) 45%, transparent),
51
+ 0 6px 16px rgba(15, 23, 42, 0.12) !important;
52
+ }
53
+
54
+ .wf-node.wf-node-dimmed {
55
+ opacity: 0.6;
56
+ border-color: #d1d5db !important;
57
+ }
58
+
59
+ /* 节点右上角状态徽章 */
60
+ .wf-node-badge {
61
+ position: absolute;
62
+ top: -8px;
63
+ right: -8px;
64
+ display: inline-flex;
65
+ align-items: center;
66
+ gap: 4px;
67
+ padding: 2px 6px;
68
+ font-size: 10px;
69
+ font-weight: 600;
70
+ color: #ffffff;
71
+ background: #6b7280;
72
+ border: 2px solid #ffffff;
73
+ border-radius: 999px;
74
+ box-shadow: 0 2px 4px rgba(15, 23, 42, 0.1);
75
+ }
76
+
77
+ .wf-node-badge-running {
78
+ background: #f59e0b;
79
+ animation: wf-node-pulse 1.6s infinite;
80
+ }
81
+
82
+ .wf-node-badge-success {
83
+ background: #10b981;
84
+ }
85
+
86
+ .wf-node-badge-failed {
87
+ background: #ef4444;
88
+ }
89
+
90
+ /* -------- Header:icon + 标题 + 副标题 -------- */
91
+ .wf-node-header {
92
+ position: relative;
93
+ display: flex;
94
+ align-items: flex-start;
95
+ gap: 12px;
96
+ margin-bottom: 12px;
97
+ }
98
+
99
+ .wf-node-icon {
100
+ display: flex;
101
+ align-items: center;
102
+ justify-content: center;
103
+ flex: none;
104
+ width: 32px;
105
+ height: 32px;
106
+ color: #ffffff;
107
+ background: var(--wf-accent);
108
+ border-radius: 8px;
109
+ }
110
+
111
+ .wf-node-icon :deep(.icon),
112
+ .wf-node-icon svg {
113
+ width: 18px;
114
+ height: 18px;
115
+ }
116
+
117
+ .wf-node-info {
118
+ flex: 1;
119
+ min-width: 0;
120
+ }
121
+
122
+ .wf-node-title {
123
+ font-size: 14px;
124
+ font-weight: 600;
125
+ color: #1f2937;
126
+ margin-bottom: 4px;
127
+ overflow: hidden;
128
+ text-overflow: ellipsis;
129
+ white-space: nowrap;
130
+ }
131
+
132
+ .wf-node-subtitle {
133
+ display: flex;
134
+ gap: 8px;
135
+ font-size: 12px;
136
+ color: var(--wf-accent);
137
+ font-weight: 500;
138
+ }
139
+
140
+ .wf-node-description {
141
+ font-size: 12px;
142
+ color: #6b7280;
143
+ line-height: 1.4;
144
+ }
145
+
146
+ /* 节点悬浮工具栏样式已移到 NodeHoverToolbar.vue 的 scoped style。
147
+ * 这里只保留 readonly 状态下的隐藏规则(选择器已同时匹配新旧两版)。 */
148
+
149
+ /* -------- 状态指示灯 -------- */
150
+ .wf-node-status {
151
+ position: absolute;
152
+ top: 8px;
153
+ right: 8px;
154
+ }
155
+
156
+ .wf-node-status-indicator {
157
+ width: 8px;
158
+ height: 8px;
159
+ border-radius: 50%;
160
+ background: #d1d5db;
161
+ }
162
+
163
+ .wf-node-status-indicator.wf-is-running {
164
+ background: var(--wf-accent);
165
+ animation: wf-node-pulse 2s infinite;
166
+ }
167
+
168
+ .wf-node-status-indicator.wf-is-completed {
169
+ background: #10b981;
170
+ }
171
+
172
+ /* -------- Content 区 -------- */
173
+ .wf-node-content {
174
+ margin-bottom: 8px;
175
+ }
176
+
177
+ /* Start 节点的 trigger 预览行 */
178
+ .wf-node-triggers {
179
+ display: flex;
180
+ align-items: center;
181
+ gap: 8px;
182
+ padding: 8px;
183
+ background: #d1fae5;
184
+ border-radius: 8px;
185
+ }
186
+
187
+ .wf-node-triggers-icon {
188
+ width: 16px;
189
+ height: 16px;
190
+ object-fit: cover;
191
+ border-radius: 4px;
192
+ }
193
+
194
+ .wf-node-triggers-scope {
195
+ width: 80px;
196
+ overflow: hidden;
197
+ color: #6b7280;
198
+ text-overflow: ellipsis;
199
+ white-space: nowrap;
200
+ }
201
+
202
+ /* LLM / Agent 提示词预览:中性灰底,适合代码/长文本 */
203
+ .wf-node-config-preview {
204
+ padding: 8px;
205
+ background: #f8fafc;
206
+ border: 1px solid #e2e8f0;
207
+ border-radius: 6px;
208
+ }
209
+
210
+ .wf-node-config-label {
211
+ margin-bottom: 4px;
212
+ font-size: 11px;
213
+ font-weight: 500;
214
+ color: #64748b;
215
+ }
216
+
217
+ .wf-node-config-value {
218
+ font-size: 12px;
219
+ color: #334155;
220
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
221
+ word-break: break-all;
222
+ }
223
+
224
+ /* 通用带 accent 淡色的配置预览:适合"输入变量/所选知识库/HTTP URL"等短文本摘要
225
+ * 用 color-mix 依据 --wf-accent 生成淡底色,减少每节点手写颜色 */
226
+ .wf-node-preview {
227
+ padding: 10px;
228
+ background: color-mix(in srgb, var(--wf-accent) 8%, transparent);
229
+ border: 1px solid color-mix(in srgb, var(--wf-accent) 30%, transparent);
230
+ border-radius: 6px;
231
+ }
232
+
233
+ .wf-node-preview-label {
234
+ margin-bottom: 4px;
235
+ font-size: 11px;
236
+ font-weight: 500;
237
+ color: color-mix(in srgb, var(--wf-accent) 85%, #000);
238
+ }
239
+
240
+ .wf-node-preview-value {
241
+ font-size: 12px;
242
+ color: #1f2937;
243
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
244
+ word-break: break-all;
245
+ }
246
+
247
+ .wf-node-preview-list {
248
+ display: flex;
249
+ flex-direction: column;
250
+ gap: 4px;
251
+ font-size: 12px;
252
+ color: #1f2937;
253
+ }
254
+
255
+ /* LLM 参数指标行 */
256
+ .wf-node-metrics {
257
+ display: flex;
258
+ gap: 12px;
259
+ padding-top: 8px;
260
+ border-top: 1px solid #e5e7eb;
261
+ }
262
+
263
+ .wf-node-metric {
264
+ display: flex;
265
+ flex-direction: column;
266
+ gap: 2px;
267
+ }
268
+
269
+ .wf-node-metric-label {
270
+ font-size: 10px;
271
+ font-weight: 500;
272
+ color: #9ca3af;
273
+ }
274
+
275
+ .wf-node-metric-value {
276
+ font-size: 12px;
277
+ font-weight: 600;
278
+ color: #374151;
279
+ }
280
+
281
+ /* End 节点回复预览 */
282
+ .wf-node-answer-preview {
283
+ padding: 10px;
284
+ border: 1px solid #fed7aa;
285
+ border-radius: 6px;
286
+ }
287
+
288
+ .wf-node-answer-text {
289
+ font-size: 12px;
290
+ color: #9a3412;
291
+ font-style: italic;
292
+ line-height: 1.4;
293
+ }
294
+
295
+ .wf-node-answer-row {
296
+ display: flex;
297
+ gap: 8px;
298
+ }
299
+
300
+ .wf-node-empty {
301
+ padding: 12px;
302
+ text-align: center;
303
+ border: 1px dashed #d1d5db;
304
+ border-radius: 6px;
305
+ }
306
+
307
+ .wf-node-empty-text {
308
+ font-size: 12px;
309
+ font-style: italic;
310
+ color: #9ca3af;
311
+ }
312
+
313
+ /* -------- 只读模式:隐藏所有节点悬浮操作 -------- */
314
+ .wf-readonly .wf-node-toolbar,
315
+ .wf-readonly .wf-hover-toolbar {
316
+ display: none !important;
317
+ }
318
+
319
+ /* -------- utility -------- */
320
+ .wf-row {
321
+ display: flex;
322
+ justify-content: space-between;
323
+ }
324
+
325
+ .wf-row-gap-sm {
326
+ display: flex;
327
+ gap: 8px;
328
+ }
329
+
330
+ @keyframes wf-node-pulse {
331
+ 0%,
332
+ 100% {
333
+ opacity: 1;
334
+ }
335
+ 50% {
336
+ opacity: 0.5;
337
+ }
338
+ }