- 接入 AG-UI 运行投影、Turn 时间线和审批隔离 - 增加 Agent Skill 冻结绑定与运行时消费闭环 - 增加受控工作区、内置工具和私有 Artifact 生命周期
252 lines
5.6 KiB
Vue
252 lines
5.6 KiB
Vue
<script setup lang="ts">
|
|
import type { AgentStudioNodeData } from './types';
|
|
|
|
import { computed } from 'vue';
|
|
|
|
import { KnowledgeIcon, SkillIcon } from '@easyflow/icons';
|
|
|
|
import { Connection, Cpu, Link, Share } from '@element-plus/icons-vue';
|
|
import { ElIcon } from 'element-plus';
|
|
|
|
const props = defineProps<{
|
|
data: AgentStudioNodeData;
|
|
}>();
|
|
|
|
const iconComponent = computed(() => {
|
|
const icons = {
|
|
base: Cpu,
|
|
knowledge: KnowledgeIcon,
|
|
mcp: Link,
|
|
plugin: Connection,
|
|
skill: SkillIcon,
|
|
workflow: Share,
|
|
};
|
|
return icons[props.data.iconKey];
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<button
|
|
class="agent-studio-node"
|
|
:class="[
|
|
`agent-studio-node--${data.kind}`,
|
|
{ 'is-selected': data.selected },
|
|
]"
|
|
type="button"
|
|
:aria-pressed="data.selected"
|
|
>
|
|
<span class="agent-studio-node__icon">
|
|
<ElIcon><component :is="iconComponent" /></ElIcon>
|
|
</span>
|
|
<span class="agent-studio-node__content">
|
|
<span class="agent-studio-node__header">
|
|
<span class="agent-studio-node__title">{{ data.title }}</span>
|
|
<span v-if="data.badge" class="agent-studio-node__badge">
|
|
{{ data.badge }}
|
|
</span>
|
|
</span>
|
|
<span v-if="data.detail" class="agent-studio-node__detail">
|
|
{{ data.detail }}
|
|
</span>
|
|
<span v-if="data.previewItems?.length" class="agent-studio-node__preview">
|
|
<span v-for="item in data.previewItems" :key="item">{{ item }}</span>
|
|
<span v-if="data.remainingCount" class="agent-studio-node__remaining">
|
|
+{{ data.remainingCount }}
|
|
</span>
|
|
</span>
|
|
</span>
|
|
</button>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.agent-studio-node {
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
gap: 12px;
|
|
align-items: center;
|
|
width: 212px;
|
|
padding: 13px 14px;
|
|
color: var(--el-text-color-primary);
|
|
text-align: left;
|
|
cursor: pointer;
|
|
background: var(--el-bg-color);
|
|
background: color-mix(in srgb, var(--el-bg-color) 96%, transparent);
|
|
border: 1px solid var(--el-border-color-lighter);
|
|
border-radius: 16px;
|
|
box-shadow: 0 10px 28px rgb(15 23 42 / 8%);
|
|
transition:
|
|
background-color 160ms ease,
|
|
border-color 160ms ease,
|
|
box-shadow 160ms ease,
|
|
transform 160ms ease;
|
|
}
|
|
|
|
.agent-studio-node:hover {
|
|
background: var(--el-bg-color);
|
|
border-color: var(--el-color-primary-light-7);
|
|
border-color: color-mix(
|
|
in srgb,
|
|
var(--el-color-primary) 26%,
|
|
var(--el-border-color-lighter)
|
|
);
|
|
box-shadow: 0 14px 32px rgb(15 23 42 / 10%);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.agent-studio-node:focus-visible {
|
|
outline: 2px solid var(--el-color-primary-light-5);
|
|
outline-offset: 3px;
|
|
}
|
|
|
|
.agent-studio-node.is-selected {
|
|
background: var(--el-color-primary-light-9);
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--el-color-primary-light-9) 54%,
|
|
var(--el-bg-color)
|
|
);
|
|
border-color: var(--el-color-primary-light-5);
|
|
border-color: color-mix(
|
|
in srgb,
|
|
var(--el-color-primary) 42%,
|
|
var(--el-border-color)
|
|
);
|
|
box-shadow: 0 16px 36px rgb(11 111 211 / 14%);
|
|
}
|
|
|
|
.agent-studio-node--base {
|
|
width: 268px;
|
|
min-height: 104px;
|
|
padding: 18px;
|
|
border-radius: 18px;
|
|
}
|
|
|
|
.agent-studio-node--knowledge,
|
|
.agent-studio-node--mcp,
|
|
.agent-studio-node--workflow,
|
|
.agent-studio-node--plugin {
|
|
min-height: 78px;
|
|
}
|
|
|
|
.agent-studio-node--skill {
|
|
align-items: flex-start;
|
|
width: 240px;
|
|
min-height: 120px;
|
|
}
|
|
|
|
.agent-studio-node__icon {
|
|
display: inline-flex;
|
|
flex: 0 0 auto;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 42px;
|
|
height: 42px;
|
|
font-size: 24px;
|
|
color: var(--el-color-primary);
|
|
background: var(--el-color-primary-light-9);
|
|
border-radius: 14px;
|
|
}
|
|
|
|
.agent-studio-node--base .agent-studio-node__icon {
|
|
width: 50px;
|
|
height: 50px;
|
|
font-size: 28px;
|
|
background: var(--el-color-primary-light-8);
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--el-color-primary-light-8) 74%,
|
|
var(--el-bg-color)
|
|
);
|
|
}
|
|
|
|
.agent-studio-node__content {
|
|
display: flex;
|
|
flex: 1;
|
|
flex-direction: column;
|
|
min-width: 0;
|
|
}
|
|
|
|
.agent-studio-node__header {
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
min-width: 0;
|
|
}
|
|
|
|
.agent-studio-node__title {
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
font-size: 15px;
|
|
font-weight: 650;
|
|
line-height: 22px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.agent-studio-node--base .agent-studio-node__title {
|
|
font-size: 18px;
|
|
line-height: 26px;
|
|
}
|
|
|
|
.agent-studio-node__badge {
|
|
flex: 0 0 auto;
|
|
padding: 2px 7px;
|
|
font-size: 11px;
|
|
line-height: 16px;
|
|
color: var(--el-color-primary);
|
|
background: var(--el-color-primary-light-9);
|
|
background: color-mix(
|
|
in srgb,
|
|
var(--el-color-primary-light-9) 74%,
|
|
var(--el-bg-color)
|
|
);
|
|
border-radius: 999px;
|
|
}
|
|
|
|
.agent-studio-node__detail {
|
|
display: -webkit-box;
|
|
margin-top: 4px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
-webkit-line-clamp: 2;
|
|
font-size: 12px;
|
|
line-height: 18px;
|
|
color: var(--el-text-color-regular);
|
|
-webkit-box-orient: vertical;
|
|
}
|
|
|
|
.agent-studio-node__preview {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-1);
|
|
padding-top: var(--space-2);
|
|
margin-top: var(--space-2);
|
|
overflow: hidden;
|
|
font-size: 12px;
|
|
line-height: 18px;
|
|
color: var(--el-text-color-regular);
|
|
border-top: 1px solid hsl(var(--line-subtle));
|
|
}
|
|
|
|
.agent-studio-node__preview > span {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.agent-studio-node__remaining {
|
|
font-weight: 650;
|
|
color: var(--el-color-primary);
|
|
}
|
|
|
|
@supports not (color: color-mix(in srgb, red, blue)) {
|
|
.agent-studio-node:hover {
|
|
border-color: var(--el-color-primary-light-7);
|
|
}
|
|
|
|
.agent-studio-node.is-selected {
|
|
border-color: var(--el-color-primary-light-5);
|
|
}
|
|
}
|
|
</style>
|