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,668 @@
1
+ <script setup lang="ts">
2
+ import { computed, defineComponent, h, ref } from 'vue';
3
+
4
+ import {
5
+ DeleteOutlined,
6
+ EditOutlined,
7
+ PlusOutlined,
8
+ } from '@ant-design/icons-vue';
9
+
10
+ defineProps({
11
+ showTitle: {
12
+ type: Boolean,
13
+ default: () => true,
14
+ },
15
+ readonly: {
16
+ type: Boolean,
17
+ default: () => false,
18
+ },
19
+ parentHierarchy: {
20
+ type: Array,
21
+ default: () => [],
22
+ },
23
+ mainData: {
24
+ type: Object,
25
+ default: () => {},
26
+ },
27
+ });
28
+
29
+ const visible = ref<boolean>(false);
30
+
31
+ const formState: any = defineModel();
32
+ const editItem: any = ref({});
33
+ const model: any = ref({});
34
+ const parentModel: any = ref({});
35
+
36
+ const structData = computed(() => formState.value?.structOutput?.data ?? []);
37
+ const rootChildren = computed(() => structData.value[0]?.children ?? []);
38
+ const totalFields = computed(() => {
39
+ let count = 0;
40
+ const walk = (arr: any[]) => {
41
+ arr?.forEach((n) => {
42
+ count += 1;
43
+ if (n.children) walk(n.children);
44
+ });
45
+ };
46
+ walk(rootChildren.value);
47
+ return count;
48
+ });
49
+
50
+ const toAddItem = (item: any) => {
51
+ model.value = {
52
+ description: '',
53
+ name: '',
54
+ type: 'string',
55
+ };
56
+ editItem.value = null;
57
+ parentModel.value = item;
58
+ visible.value = true;
59
+ };
60
+ const toEditItem = (item: any) => {
61
+ editItem.value = item;
62
+ model.value = { ...item };
63
+ visible.value = true;
64
+ };
65
+ const removeItem = (item: any) => {
66
+ const treeData = structData.value[0];
67
+ if (treeData) deleteNodeById(treeData, item.id);
68
+ };
69
+ const submitForm = () => {
70
+ if (
71
+ (model.value.type === 'array' || model.value.type === 'object') &&
72
+ !model.value.children
73
+ ) {
74
+ model.value.children = [];
75
+ }
76
+ if (editItem.value) {
77
+ Object.assign(editItem.value, model.value);
78
+ } else {
79
+ if (!parentModel.value.children) parentModel.value.children = [];
80
+ parentModel.value.children.push({ ...model.value });
81
+ }
82
+ visible.value = false;
83
+ };
84
+
85
+ function deleteNodeById(tree: any, targetId: string) {
86
+ if (tree.children && tree.children.length > 0) {
87
+ const index = tree.children.findIndex((node: any) => node.id === targetId);
88
+ if (index === -1) {
89
+ for (const child of tree.children) {
90
+ const deleted = deleteNodeById(child, targetId);
91
+ if (deleted) return true;
92
+ }
93
+ } else {
94
+ tree.children.splice(index, 1);
95
+ return true;
96
+ }
97
+ }
98
+ return false;
99
+ }
100
+
101
+ const closePanel = () => {
102
+ visible.value = false;
103
+ };
104
+
105
+ const typeLabel = (type: string) => {
106
+ if (type === 'array') return 'array';
107
+ return type || 'string';
108
+ };
109
+
110
+ const TreeNode: any = defineComponent({
111
+ name: 'OutputTreeNode',
112
+ props: {
113
+ node: { type: Object, required: true },
114
+ readonly: { type: Boolean, default: false },
115
+ depth: { type: Number, default: 0 },
116
+ },
117
+ emits: ['edit', 'add', 'remove'],
118
+ setup(props, { emit }) {
119
+ return () => {
120
+ const { node, readonly, depth } = props;
121
+ const isBranch = node.type === 'object' || node.type === 'array';
122
+ const typeClass = `output-type-${node.type || 'string'}`;
123
+
124
+ const rowChildren: any[] = [
125
+ h('span', { class: 'output-row-caret' }, isBranch ? '▾' : '·'),
126
+ h('span', { class: 'output-row-name' }, node.name || '未命名'),
127
+ h(
128
+ 'span',
129
+ { class: ['output-type-pill', typeClass] },
130
+ node.type === 'array' ? 'array' : node.type || 'string',
131
+ ),
132
+ node.description
133
+ ? h('span', { class: 'output-row-desc' }, node.description)
134
+ : null,
135
+ ];
136
+
137
+ if (!readonly) {
138
+ rowChildren.push(
139
+ h('div', { class: 'output-row-actions' }, [
140
+ isBranch
141
+ ? h(
142
+ 'a',
143
+ {
144
+ class: 'output-row-action output-row-action-add',
145
+ title: '添加子字段',
146
+ onClick: (e: Event) => {
147
+ e.stopPropagation();
148
+ emit('add', node);
149
+ },
150
+ },
151
+ [h(PlusOutlined)],
152
+ )
153
+ : null,
154
+ h(
155
+ 'a',
156
+ {
157
+ class: 'output-row-action output-row-action-edit',
158
+ title: '编辑',
159
+ onClick: (e: Event) => {
160
+ e.stopPropagation();
161
+ emit('edit', node);
162
+ },
163
+ },
164
+ [h(EditOutlined)],
165
+ ),
166
+ h(
167
+ 'a',
168
+ {
169
+ class: 'output-row-action output-row-action-danger',
170
+ title: '删除',
171
+ onClick: (e: Event) => {
172
+ e.stopPropagation();
173
+ emit('remove', node);
174
+ },
175
+ },
176
+ [h(DeleteOutlined)],
177
+ ),
178
+ ]),
179
+ );
180
+ }
181
+
182
+ const row = h(
183
+ 'div',
184
+ {
185
+ class: 'output-row',
186
+ style: { paddingLeft: `${depth * 14}px` },
187
+ onClick: () => !readonly && emit('edit', node),
188
+ },
189
+ rowChildren,
190
+ );
191
+
192
+ const children =
193
+ isBranch && node.children && node.children.length > 0
194
+ ? node.children.map((c: any) =>
195
+ h(TreeNode, {
196
+ key: c.id || c.name,
197
+ node: c,
198
+ readonly,
199
+ depth: depth + 1,
200
+ onEdit: (n: any) => emit('edit', n),
201
+ onAdd: (n: any) => emit('add', n),
202
+ onRemove: (n: any) => emit('remove', n),
203
+ }),
204
+ )
205
+ : [];
206
+
207
+ return h('div', { class: 'output-tree-node' }, [row, ...children]);
208
+ };
209
+ },
210
+ });
211
+ </script>
212
+
213
+ <template>
214
+ <div class="output-card">
215
+ <div class="output-card-head" v-if="showTitle">
216
+ <div class="output-card-head-left">
217
+ <span class="output-card-title">输出变量</span>
218
+ <span v-if="formState.structOutputEnabled" class="output-card-count">
219
+ {{ totalFields }} 字段
220
+ </span>
221
+ </div>
222
+ <div v-show="formState.structOutput?.data" class="output-card-toggle">
223
+ <span class="output-card-toggle-label">结构化输出</span>
224
+ <a-switch
225
+ size="small"
226
+ v-model:checked="formState.structOutputEnabled"
227
+ />
228
+ </div>
229
+ </div>
230
+
231
+ <div class="output-card-body">
232
+ <template v-if="formState.structOutputEnabled">
233
+ <div class="output-tree">
234
+ <template v-for="root in structData" :key="root.id">
235
+ <div class="output-tree-root">
236
+ <div class="output-tree-root-title">
237
+ <span class="output-tree-root-name">{{ root.name }}</span>
238
+ <span class="output-type-pill output-type-object">
239
+ {{ typeLabel(root.type) }}
240
+ </span>
241
+ <span v-if="root.description" class="output-tree-root-desc">
242
+ {{ root.description }}
243
+ </span>
244
+ <a
245
+ v-if="!readonly"
246
+ class="output-tree-root-add"
247
+ @click="toAddItem(root)"
248
+ >
249
+ <PlusOutlined />
250
+ <span>添加字段</span>
251
+ </a>
252
+ </div>
253
+
254
+ <div
255
+ v-if="!root.children || root.children.length === 0"
256
+ class="output-empty"
257
+ >
258
+ <span>点击右侧「添加字段」定义输出结构</span>
259
+ </div>
260
+
261
+ <div v-else class="output-tree-children">
262
+ <TreeNode
263
+ v-for="child in root.children"
264
+ :key="child.id || child.name"
265
+ :node="child"
266
+ :readonly="readonly"
267
+ :depth="1"
268
+ @edit="toEditItem"
269
+ @add="toAddItem"
270
+ @remove="removeItem"
271
+ />
272
+ </div>
273
+ </div>
274
+ </template>
275
+ </div>
276
+
277
+ <a-modal
278
+ v-model:open="visible"
279
+ title="结构化字段定义"
280
+ :ok-text="editItem ? '更新' : '添加'"
281
+ cancel-text="取消"
282
+ @ok="submitForm"
283
+ @cancel="closePanel"
284
+ >
285
+ <div class="output-modal-body">
286
+ <a-form
287
+ :model="model"
288
+ name="basic"
289
+ :label-col="{ span: 5 }"
290
+ :wrapper-col="{ span: 17 }"
291
+ autocomplete="off"
292
+ layout="horizontal"
293
+ >
294
+ <a-form-item label="名称" name="name">
295
+ <a-input
296
+ v-model:value="model.name"
297
+ placeholder="字段名,如 category"
298
+ />
299
+ </a-form-item>
300
+ <a-form-item label="描述" name="description">
301
+ <a-input
302
+ v-model:value="model.description"
303
+ placeholder="用于指导 LLM 输出"
304
+ />
305
+ </a-form-item>
306
+ <a-form-item label="类型" name="type">
307
+ <a-select v-model:value="model.type" style="width: 100%">
308
+ <a-select-option value="string">String</a-select-option>
309
+ <a-select-option value="number">Number</a-select-option>
310
+ <a-select-option value="boolean">Boolean</a-select-option>
311
+ <a-select-option value="object">Object</a-select-option>
312
+ <a-select-option value="array">Array[Object]</a-select-option>
313
+ </a-select>
314
+ </a-form-item>
315
+ <a-form-item label="示例" name="example">
316
+ <a-input
317
+ v-model:value="model.example"
318
+ placeholder="可选,示例值"
319
+ />
320
+ </a-form-item>
321
+ </a-form>
322
+ </div>
323
+ </a-modal>
324
+ </template>
325
+
326
+ <div v-else class="output-plain">
327
+ <div
328
+ v-for="(item, idx) in formState.output"
329
+ :key="`${item.name}-${idx}`"
330
+ class="output-plain-row"
331
+ >
332
+ <div class="output-plain-name">{{ item.name }}</div>
333
+ <span class="output-type-pill" :class="`output-type-${item.type}`">
334
+ {{ typeLabel(item.type) }}
335
+ </span>
336
+ <div class="output-plain-label">{{ item.label }}</div>
337
+ </div>
338
+ <div
339
+ v-if="!formState.output || formState.output.length === 0"
340
+ class="output-empty"
341
+ >
342
+ <span>暂无输出定义</span>
343
+ </div>
344
+ </div>
345
+ </div>
346
+ </div>
347
+ </template>
348
+
349
+ <style scoped>
350
+ .output-card {
351
+ display: flex;
352
+ flex-direction: column;
353
+ gap: 8px;
354
+ }
355
+
356
+ .output-card-head {
357
+ display: flex;
358
+ align-items: center;
359
+ justify-content: space-between;
360
+ gap: 8px;
361
+ }
362
+
363
+ .output-card-head-left {
364
+ display: flex;
365
+ align-items: center;
366
+ gap: 6px;
367
+ }
368
+
369
+ .output-card-title {
370
+ font-size: 12px;
371
+ font-weight: 600;
372
+ color: #1f2937;
373
+ }
374
+
375
+ .output-card-count {
376
+ padding: 1px 6px;
377
+ font-size: 10px;
378
+ font-weight: 500;
379
+ color: color-mix(in srgb, var(--wf-accent, #6366f1) 90%, #000);
380
+ background: color-mix(in srgb, var(--wf-accent, #6366f1) 12%, transparent);
381
+ border-radius: 999px;
382
+ }
383
+
384
+ .output-card-toggle {
385
+ display: flex;
386
+ align-items: center;
387
+ gap: 6px;
388
+ font-size: 11px;
389
+ color: #6b7280;
390
+ }
391
+
392
+ /* -------- 结构化输出树 -------- */
393
+ .output-tree {
394
+ display: flex;
395
+ flex-direction: column;
396
+ gap: 8px;
397
+ }
398
+
399
+ .output-tree-root {
400
+ padding: 8px 10px;
401
+ background: #f9fafb;
402
+ border: 1px solid #eef0f3;
403
+ border-radius: 8px;
404
+ }
405
+
406
+ .output-tree-root-title {
407
+ display: flex;
408
+ align-items: center;
409
+ gap: 8px;
410
+ padding-bottom: 6px;
411
+ border-bottom: 1px dashed #e5e7eb;
412
+ margin-bottom: 4px;
413
+ }
414
+
415
+ .output-tree-root-name {
416
+ font-size: 12px;
417
+ font-weight: 600;
418
+ color: #1f2937;
419
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
420
+ }
421
+
422
+ .output-tree-root-desc {
423
+ flex: 1;
424
+ min-width: 0;
425
+ font-size: 11px;
426
+ color: #9ca3af;
427
+ overflow: hidden;
428
+ text-overflow: ellipsis;
429
+ white-space: nowrap;
430
+ }
431
+
432
+ .output-tree-children {
433
+ display: flex;
434
+ flex-direction: column;
435
+ gap: 2px;
436
+ }
437
+
438
+ /* 根节点右上角"添加字段":文字按钮样式,走 vben 主题色 */
439
+ .output-tree-root-add {
440
+ display: inline-flex;
441
+ align-items: center;
442
+ gap: 4px;
443
+ margin-left: auto;
444
+ padding: 2px 8px;
445
+ font-size: 11px;
446
+ color: hsl(var(--primary));
447
+ background: hsl(var(--primary) / 10%);
448
+ border-radius: 4px;
449
+ transition: background 0.12s, color 0.12s;
450
+ }
451
+
452
+ .output-tree-root-add:hover {
453
+ color: hsl(var(--primary));
454
+ background: hsl(var(--primary) / 20%);
455
+ }
456
+
457
+ /* -------- 空态 -------- */
458
+ .output-empty {
459
+ padding: 10px;
460
+ text-align: center;
461
+ font-size: 11px;
462
+ color: #9ca3af;
463
+ background: #ffffff;
464
+ border: 1px dashed #e5e7eb;
465
+ border-radius: 6px;
466
+ }
467
+
468
+ /* -------- 非结构化输出(简单列表) -------- */
469
+ .output-plain {
470
+ display: flex;
471
+ flex-direction: column;
472
+ gap: 4px;
473
+ }
474
+
475
+ .output-plain-row {
476
+ display: flex;
477
+ align-items: center;
478
+ gap: 8px;
479
+ padding: 4px 8px;
480
+ font-size: 12px;
481
+ background: #f9fafb;
482
+ border: 1px solid #eef0f3;
483
+ border-radius: 6px;
484
+ }
485
+
486
+ .output-plain-name {
487
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
488
+ color: #1f2937;
489
+ font-weight: 500;
490
+ }
491
+
492
+ .output-plain-label {
493
+ margin-left: auto;
494
+ color: #6b7280;
495
+ font-size: 11px;
496
+ }
497
+
498
+ .output-modal-body {
499
+ padding-top: 8px;
500
+ }
501
+ </style>
502
+
503
+ <!--
504
+ 以下样式作用于由 TreeNode(inline defineComponent + h())渲染的元素。
505
+ <style scoped> 编译出的属性选择器无法命中 h() 产物,因此必须写在非
506
+ scoped 块里;类名全部为本文件专用,不存在污染其他组件的风险。
507
+ -->
508
+ <style>
509
+ .output-tree-node {
510
+ display: flex;
511
+ flex-direction: column;
512
+ }
513
+
514
+ .output-row {
515
+ position: relative;
516
+ display: flex;
517
+ align-items: center;
518
+ gap: 8px;
519
+ padding: 5px 6px 5px 4px;
520
+ font-size: 12px;
521
+ border-radius: 6px;
522
+ cursor: pointer;
523
+ transition: background 0.12s, box-shadow 0.12s;
524
+ }
525
+
526
+ .output-row:hover {
527
+ background: #ffffff;
528
+ box-shadow: inset 0 0 0 1px #e5e7eb;
529
+ }
530
+
531
+ .output-row-caret {
532
+ flex: none;
533
+ width: 10px;
534
+ font-size: 10px;
535
+ color: #9ca3af;
536
+ text-align: center;
537
+ }
538
+
539
+ .output-row-name {
540
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
541
+ color: #1f2937;
542
+ font-weight: 500;
543
+ }
544
+
545
+ .output-row-desc {
546
+ flex: 1;
547
+ min-width: 0;
548
+ color: #9ca3af;
549
+ overflow: hidden;
550
+ text-overflow: ellipsis;
551
+ white-space: nowrap;
552
+ font-size: 11px;
553
+ }
554
+
555
+ .output-row-actions {
556
+ display: inline-flex;
557
+ align-items: center;
558
+ gap: 2px;
559
+ margin-left: auto;
560
+ flex: none;
561
+ opacity: 0.85;
562
+ transition: opacity 0.15s;
563
+ }
564
+
565
+ .output-row:hover .output-row-actions {
566
+ opacity: 1;
567
+ }
568
+
569
+ .output-row-action {
570
+ display: inline-flex;
571
+ align-items: center;
572
+ justify-content: center;
573
+ width: 22px;
574
+ height: 22px;
575
+ padding: 0;
576
+ color: #6b7280;
577
+ border-radius: 4px;
578
+ font-size: 13px;
579
+ line-height: 1;
580
+ transition: background 0.12s, color 0.12s, transform 0.12s;
581
+ }
582
+
583
+ .output-row-action .anticon {
584
+ font-size: 13px;
585
+ }
586
+
587
+ .output-row-action:hover {
588
+ transform: translateY(-1px);
589
+ }
590
+
591
+ /* 编辑:跟随 vben --primary 主题色(design-tokens/default.css 中 --primary: 212 100% 45%) */
592
+ .output-row-action-edit {
593
+ color: hsl(var(--primary));
594
+ }
595
+
596
+ .output-row-action-edit:hover {
597
+ color: hsl(var(--primary));
598
+ background: hsl(var(--primary) / 14%);
599
+ }
600
+
601
+ /* 新增:走当前节点主题色(--wf-accent 由 NodeConfigCard 注入) */
602
+ .output-row-action-add {
603
+ color: var(--wf-accent, #6366f1);
604
+ }
605
+
606
+ .output-row-action-add:hover {
607
+ background: color-mix(in srgb, var(--wf-accent, #6366f1) 14%, transparent);
608
+ }
609
+
610
+ /* 删除:红色,常态即可辨识 */
611
+ .output-row-action-danger {
612
+ color: #ef4444;
613
+ }
614
+
615
+ .output-row-action-danger:hover {
616
+ color: #dc2626;
617
+ background: #fef2f2;
618
+ }
619
+
620
+ /* 类型徽章(在 h() 渲染的行内也会用到,因此和 action 一起放非 scoped) */
621
+ .output-type-pill {
622
+ flex: none;
623
+ padding: 1px 6px;
624
+ font-size: 10px;
625
+ font-weight: 600;
626
+ border-radius: 4px;
627
+ line-height: 1.5;
628
+ letter-spacing: 0.2px;
629
+ text-transform: lowercase;
630
+ border: 1px solid transparent;
631
+ }
632
+
633
+ .output-type-string {
634
+ color: #047857;
635
+ background: #d1fae5;
636
+ border-color: #6ee7b7;
637
+ }
638
+
639
+ .output-type-number {
640
+ color: #b45309;
641
+ background: #fef3c7;
642
+ border-color: #fcd34d;
643
+ }
644
+
645
+ .output-type-boolean {
646
+ color: #7c3aed;
647
+ background: #ede9fe;
648
+ border-color: #c4b5fd;
649
+ }
650
+
651
+ .output-type-object {
652
+ color: #1d4ed8;
653
+ background: #dbeafe;
654
+ border-color: #93c5fd;
655
+ }
656
+
657
+ .output-type-array {
658
+ color: #be185d;
659
+ background: #fce7f3;
660
+ border-color: #f9a8d4;
661
+ }
662
+
663
+ .output-type-file {
664
+ color: #475569;
665
+ background: #f1f5f9;
666
+ border-color: #cbd5e1;
667
+ }
668
+ </style>