feat(task):优化任务执行与智能体展示功能

- 更新action.svg图标样式- 重构AgentRepo组件,优化智能体列表展示逻辑
- 改进ExecutePlan组件,支持object类型节点渲染
- 完善TaskResult组件,增加执行计划存储与清理机制
- 调整TaskSyllabus组件,优化卡片激活状态样式
- 在Task组件中添加搜索建议功能
- 更新主题配色变量和全局样式- 替换ElInput为ElAutocomplete组件
- 清理无用的jsplumb连接代码- 优化组件间通信与状态管理
This commit is contained in:
zhaoweijie
2025-10-31 18:42:31 +08:00
parent 0c571dec21
commit 974af053ca
12 changed files with 372 additions and 194 deletions

View File

@@ -5,12 +5,8 @@ import { pick } from 'lodash'
import api from '@/api/index.ts'
import SvgIcon from '@/components/SvgIcon/index.vue'
import {
agentMapDuty,
getActionTypeDisplay,
getAgentMapIcon,
} from '@/layout/components/config.ts'
import { type TaskProcess, useAgentsStore } from '@/stores'
import { agentMapDuty, getActionTypeDisplay, getAgentMapIcon } from '@/layout/components/config.ts'
import { type Agent, useAgentsStore } from '@/stores'
import { onMounted } from 'vue'
import { v4 as uuidv4 } from 'uuid'
@@ -31,23 +27,6 @@ onMounted(() => {
}
})
// 自定义提示框鼠标移入小红点时显示
const tooltipVisibleKey = ref('')
const tooltipPosition = ref({ x: 0, y: 0 })
const showTooltip = (event: MouseEvent, item: TaskProcess & { key: string }) => {
tooltipVisibleKey.value = item.key
const rect = (event.target as HTMLElement).getBoundingClientRect()
tooltipPosition.value = {
x: rect.left + rect.width / 2,
y: rect.top - 10,
}
}
const hideTooltip = () => {
tooltipVisibleKey.value = ''
}
// 上传agent文件
const fileInput = ref<HTMLInputElement>()
@@ -116,10 +95,30 @@ const taskProcess = computed(() => {
key: uuidv4(),
}))
})
const agentListRef = ref<HTMLElement | null>()
// 根据currentTask排序agent列表
const agentList = computed(() => {
const startArr: Agent[] = []
const endArr: Agent[] = []
if (!agentsStore.agents.length) {
return startArr
}
for (const agent of agentsStore.agents) {
if (agentsStore.currentTask?.AgentSelection?.includes(agent.Name)) {
startArr.push(agent)
} else {
endArr.push(agent)
}
}
return [...startArr, ...endArr]
})
</script>
<template>
<div class="agent-repo h-full flex flex-col">
<div class="agent-repo h-full flex flex-col" id="agent-repo">
<!-- 头部 -->
<div class="flex items-center justify-between">
<span class="text-[18px] font-bold">智能体库</span>
@@ -129,73 +128,112 @@ const taskProcess = computed(() => {
<svg-icon icon-class="plus" color="var(--color-text)" size="18px" />
</div>
</div>
<!-- 人员列表 -->
<div class="mt-[18px] flex-1 overflow-y-auto relative" @scroll="handleScroll">
<div
class="flex items-center justify-between user-item relative"
v-for="item in agentsStore.agents"
<!-- 智能体列表 -->
<div
class="mt-[18px] flex-1 overflow-y-auto relative"
ref="agentListRef"
@scroll="handleScroll"
>
<el-popover
v-for="item in agentList"
:key="item.Name"
trigger="hover"
placement="bottom"
:show-arrow="false"
:disabled="!agentsStore.currentTask?.AgentSelection?.includes(item.Name)"
popper-class="agent-repo-item-popover active-card"
:append-to="agentListRef"
width="100%"
>
<!-- 右侧链接点 -->
<div
class="absolute right-0 top-1/2 transform -translate-y-1/2"
:id="`agent-repo-${item.Name}`"
></div>
<div
class="w-[41px] h-[41px] rounded-full flex items-center justify-center"
:style="{ background: getAgentMapIcon(item.Name).color }"
>
<svg-icon
:icon-class="getAgentMapIcon(item.Name).icon"
color="var(--color-text)"
size="24px"
/>
</div>
<div class="text-[14px] flex flex-col items-end justify-end">
<div class="flex items-center gap-[7px]">
<template #reference>
<div
class="flex items-center justify-between user-item relative h-[41px]"
:class="
agentsStore.currentTask?.AgentSelection?.includes(item.Name) ? 'active-card' : ''
"
>
<div
v-for="item1 in taskProcess.filter((i) => i.AgentName === item.Name)"
:key="item1.key"
class="relative inline-block"
class="w-[41px] h-[41px] rounded-full flex items-center justify-center flex-shrink-0"
:style="{ background: getAgentMapIcon(item.Name).color }"
>
<el-popover
placement="bottom"
:width="200"
trigger="click"
:content="item1.Description"
:title="getActionTypeDisplay(item1.ActionType)?.name"
<svg-icon
:icon-class="getAgentMapIcon(item.Name).icon"
color="var(--color-text)"
size="24px"
/>
</div>
<div class="flex-1 text-[14px] flex flex-col items-end justify-end truncate ml-1">
<span
class="w-full truncate text-right"
:style="
agentsStore.currentTask?.AgentSelection?.includes(item.Name)
? 'color:#00F3FF'
: ''
"
>{{ item.Name }}</span
>
<template #reference>
<div class="group relative inline-block">
<!-- 小圆点 -->
<div
class="w-[6px] h-[6px] rounded-full"
:style="{ background: getActionTypeDisplay(item1.ActionType)?.color }"
@mouseenter="(el) => showTooltip(el, item1)"
@mouseleave="hideTooltip"
></div>
<!-- 弹窗 -->
<teleport to="body">
<div
v-if="tooltipVisibleKey === item1.key"
class="fixed transform -translate-x-1/2 -translate-y-full mb-2 p-2 bg-[var(--el-bg-color-overlay)] text-sm rounded-[8px] z-50"
:style="{
left: tooltipPosition.x + 'px',
top: tooltipPosition.y + 'px',
}"
>
{{ getActionTypeDisplay(item1.ActionType)?.name }}
</div>
</teleport>
</div>
</template>
</el-popover>
<div
v-if="agentsStore.currentTask?.AgentSelection?.includes(item.Name)"
class="flex items-center gap-[7px] h-[8px] mr-1"
>
<!-- 小圆点 -->
<div
v-for="item1 in taskProcess.filter((i) => i.AgentName === item.Name)"
:key="item1.key"
class="w-[6px] h-[6px] rounded-full"
:style="{ background: getActionTypeDisplay(item1.ActionType)?.color }"
></div>
</div>
</div>
</div>
</template>
<div>
<div class="flex items-center justify-between">
<div
class="w-[41px] h-[41px] rounded-full flex items-center justify-center flex-shrink-0 relative right-[2px] bottom-[2px] self-start"
:style="{ background: getAgentMapIcon(item.Name).color }"
>
<svg-icon
:icon-class="getAgentMapIcon(item.Name).icon"
color="var(--color-text)"
size="24px"
/>
</div>
<div
class="flex-1 text-[14px] flex flex-col items-center justify-center break-all ml-1 text-[14px] text-[#00F3FF] p-[8px] pl-[0]"
>
{{ item.Name }}
</div>
</div>
<div class="w-full flex justify-center">
<div
class="rounded-[9px] bg-[var(--color-bg-quaternary)] text-[12px] py-0.5 px-5 text-center my-2"
>
当前指责
</div>
</div>
<div class="p-[8px] pt-0">
<div
v-for="(item1, index1) in taskProcess.filter((i) => i.AgentName === item.Name)"
:key="item1.key"
class="text-[12px]"
>
<div>
<div class="mx-1 inline-block h-[14px]">
<div
:style="{ background: getActionTypeDisplay(item1.ActionType)?.color }"
class="w-[6px] h-[6px] rounded-full mt-[7px]"
></div>
</div>
<span :style="{ color: getActionTypeDisplay(item1.ActionType)?.color }">{{ getActionTypeDisplay(item1.ActionType)?.name }}</span>
<span>{{ item1.Description }}</span>
</div>
<!-- 分割线 -->
<div v-if="index1 !== taskProcess.filter((i) => i.AgentName === item.Name).length - 1" class="h-[1px] w-full bg-[#494B51] my-[8px]"></div>
</div>
</div>
<span class="mb-1">{{ item.Name }}</span>
</div>
</div>
</el-popover>
</div>
<!-- 底部提示栏 -->
<div class="w-full grid grid-cols-3 gap-x-[10px] bg-[#1d222b] rounded-[20px] p-[8px] mt-[10px]">
@@ -214,6 +252,7 @@ const taskProcess = computed(() => {
<style scoped lang="scss">
.agent-repo {
padding: 0 8px;
.plus-button {
background: #1d2128;
width: 24px;
@@ -234,7 +273,7 @@ const taskProcess = computed(() => {
.user-item {
background: #1d222b;
border-radius: 20px;
border-radius: 40px;
padding-right: 12px;
cursor: pointer;
transition: all 0.25s ease;
@@ -249,5 +288,17 @@ const taskProcess = computed(() => {
color: #b8b8b8;
}
}
.active-card {
border-left: none !important;
}
}
#agent-repo {
:deep(.agent-repo-item-popover) {
padding: 0;
border-radius: 20px;
background: var(--color-bg-secondary);
}
}
</style>