Initial commit: Multi-Agent Coordination Platform

- Vue 3 + TypeScript + Vite project structure
- Element Plus UI components with dark theme
- Pinia state management for agents and tasks
- JSPlumb integration for visual workflow editing
- SVG icon system for agent roles
- Axios request layer with API proxy configuration
- Tailwind CSS for styling
- Docker deployment with Caddy web server
- Complete development toolchain (ESLint, Prettier, Vitest)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zhaoweijie
2025-10-29 10:22:14 +08:00
commit 0c571dec21
74 changed files with 10009 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
<script setup lang="ts">
import AgentRepo from './AgentRepo/index.vue'
import TaskSyllabus from './TaskSyllabus/index.vue'
import TaskResult from './TaskResult/index.vue'
import { Jsplumb } from './utils.ts'
import { type IRawStepTask, useAgentsStore } from '@/stores'
import { AnchorLocations, BezierConnector } from '@jsplumb/browser-ui'
const agentsStore = useAgentsStore()
// 智能体库
const agentRepoJsplumb = new Jsplumb('task-template', {
connector: {
type: BezierConnector.type,
options: {
curviness: 30, // 曲线弯曲程度
stub: 20, // 添加连接点与端点的距离
alwaysRespectStubs: true,
},
},
})
// 任务流程
const taskSyllabusRef = ref<{ changeTask: (task?: IRawStepTask, isEmit?: boolean) => void }>()
// 执行结果
const taskResultRef = ref<{ createInternalLine: () => void }>()
const taskResultJsplumb = new Jsplumb('task-template')
function setCurrentTask(task: IRawStepTask) {
// 智能体库画线
agentRepoJsplumb.reset()
task.AgentSelection?.forEach((item) => {
agentRepoJsplumb.connect(
`agent-repo-${item}`,
`task-syllabus-flow-agents-${task.Id}`,
[AnchorLocations.Left, AnchorLocations.Right],
{ type: 'input' },
)
})
agentRepoJsplumb.repaintEverything()
// 执行结果画线
taskResultJsplumb.reset()
taskResultJsplumb.connect(`task-syllabus-output-object-${task.Id}`, `task-results-${task.Id}-0`, [AnchorLocations.Right, AnchorLocations.Left])
taskResultJsplumb.connect(`task-syllabus-output-object-${task.Id}`, `task-results-${task.Id}-1`, [AnchorLocations.Right, AnchorLocations.Left])
taskResultJsplumb.repaintEverything()
agentsStore.setCurrentTask(task)
// 更新任务大纲内部的线
taskSyllabusRef.value?.changeTask(task, false)
}
function changeTask() {
taskResultRef.value?.createInternalLine()
taskSyllabusRef.value?.changeTask()
}
function resetAgentRepoLine() {
agentRepoJsplumb.repaintEverything()
taskResultJsplumb.repaintEverything()
}
defineExpose({
changeTask,
})
</script>
<template>
<div
class="task-template flex gap-6 items-center h-[calc(100%-67px)] relative overflow-hidden"
id="task-template"
>
<!-- 智能体库 -->
<div class="w-[9.5%] min-w-[179px] h-full relative">
<AgentRepo @resetAgentRepoLine="agentRepoJsplumb.repaintEverything" />
</div>
<!-- 任务大纲 -->
<div class="w-[40.5%] min-w-[600px] h-full px-[20px]">
<TaskSyllabus
ref="taskSyllabusRef"
@resetAgentRepoLine="resetAgentRepoLine"
@set-current-task="setCurrentTask"
/>
</div>
<!-- 执行结果 -->
<div class="flex-1 h-full">
<TaskResult
ref="taskResultRef"
@refresh-line="taskResultJsplumb.repaintEverything"
@set-current-task="setCurrentTask"
/>
</div>
</div>
</template>
<style scoped lang="scss">
.task-template {
& > div {
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.8);
border-radius: 24px;
border: 1px solid #414752;
background: #29303c;
padding-top: 20px;
padding-bottom: 20px;
}
}
</style>
<style>
:root {
--gradient: linear-gradient(to right, #0093eb, #00d2d1);
}
</style>