2026-03-05 10:49:46 +08:00
< script setup lang = "ts" >
import { ref } from 'vue'
interface Agent {
id : number
name : string
framework : string
status : 'running' | 'stopped' | 'error'
mcpServers : number
model : string
createdAt : string
description : string
}
// Agents 数据
const agents = ref < Agent [ ] > ( [
{ id : 1 , name : 'template-google-adk-api' , framework : 'Google ADK' , status : 'running' , mcpServers : 2 , model : 'gemini-2.0-flash' , createdAt : '2025-04-10' , description : 'Google ADK template for agent deployment' } ,
{ id : 2 , name : 'mcp-google-adk-api' , framework : 'Google ADK' , status : 'error' , mcpServers : 1 , model : 'gemini-2.0-flash' , createdAt : '2025-04-08' , description : 'MCP-enabled Google ADK agent' } ,
{ id : 3 , name : 'template-openai-api' , framework : 'OpenAI' , status : 'stopped' , mcpServers : 3 , model : 'gpt-4o' , createdAt : '2025-04-05' , description : 'OpenAI API template agent' } ,
{ id : 4 , name : 'pydantic-ai-agent' , framework : 'PydanticAI' , status : 'running' , mcpServers : 2 , model : 'gpt-4o-mini' , createdAt : '2025-04-12' , description : 'PydanticAI framework agent' } ,
{ id : 5 , name : 'langchain-agent' , framework : 'LangChain' , status : 'running' , mcpServers : 4 , model : 'claude-3-5-sonnet' , createdAt : '2025-04-11' , description : 'LangChain based agent with tools' } ,
] )
// 编辑状态
const editingAgent = ref < Agent | null > ( null )
const isEditing = ref ( false )
const isCreating = ref ( false )
const searchQuery = ref ( '' )
const filterStatus = ref < string > ( 'all' )
// 新建 Agent 表单
const newAgentForm = ref ( {
name : '' ,
framework : 'Google ADK' ,
model : 'gemini-2.0-flash' ,
description : '' ,
mcpServers : [ ] as string [ ] ,
} )
const frameworks = [
{ name : 'Google ADK' , icon : 'fa-google' , color : 'from-blue-500 to-blue-600' } ,
{ name : 'OpenAI' , icon : 'fa-openai' , color : 'from-green-500 to-green-600' } ,
{ name : 'PydanticAI' , icon : 'fa-robot' , color : 'from-purple-500 to-purple-600' } ,
{ name : 'LangChain' , icon : 'fa-link' , color : 'from-orange-500 to-orange-600' } ,
]
const models = [
{ name : 'Google ADK' , models : [ 'gemini-2.0-flash' , 'gemini-1.5-pro' , 'gemini-pro' ] } ,
{ name : 'OpenAI' , models : [ 'gpt-4o' , 'gpt-4o-mini' , 'gpt-4-turbo' ] } ,
{ name : 'PydanticAI' , models : [ 'gpt-4o' , 'gpt-4o-mini' , 'claude-3-5-sonnet' ] } ,
{ name : 'LangChain' , models : [ 'claude-3-5-sonnet' , 'gpt-4o' , 'gpt-4o-mini' ] } ,
]
const availableMCPServers = [
{ name : 'linear-demo' , icon : 'fa-check-circle' , status : 'connected' } ,
{ name : 'google-maps' , icon : 'fa-map-marker-alt' , status : 'connected' } ,
{ name : 'explorer-mcp' , icon : 'fa-folder' , status : 'connected' } ,
{ name : 'postgres-mcp' , icon : 'fa-database' , status : 'disconnected' } ,
{ name : 'github-mcp' , icon : 'fa-github' , status : 'disconnected' } ,
]
// 打开新建弹窗
const openCreate = ( ) => {
newAgentForm . value = {
name : '' ,
framework : 'Google ADK' ,
model : 'gemini-2.0-flash' ,
description : '' ,
mcpServers : [ ] ,
}
isCreating . value = true
}
// 关闭新建弹窗
const closeCreate = ( ) => {
isCreating . value = false
}
// 保存新建
const saveNewAgent = ( ) => {
const newId = Math . max ( ... agents . value . map ( a => a . id ) ) + 1
agents . value . push ( {
id : newId ,
name : newAgentForm . value . name || 'Untitled Agent' ,
framework : newAgentForm . value . framework ,
status : 'stopped' ,
mcpServers : newAgentForm . value . mcpServers . length ,
model : newAgentForm . value . model ,
createdAt : new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] ,
description : newAgentForm . value . description ,
} )
isCreating . value = false
}
// 切换 MCP 服务器
const toggleMCPServer = ( serverName : string ) => {
const index = newAgentForm . value . mcpServers . indexOf ( serverName )
if ( index === - 1 ) {
newAgentForm . value . mcpServers . push ( serverName )
} else {
newAgentForm . value . mcpServers . splice ( index , 1 )
}
}
// 编辑表单数据
const editForm = ref ( {
name : '' ,
framework : '' ,
model : '' ,
description : '' ,
} )
// 打开编辑弹窗
const openEdit = ( agent : Agent ) => {
editingAgent . value = agent
editForm . value = {
name : agent . name ,
framework : agent . framework ,
model : agent . model ,
description : agent . description ,
}
isEditing . value = true
}
// 保存编辑
const saveEdit = ( ) => {
if ( editingAgent . value ) {
const index = agents . value . findIndex ( a => a . id === editingAgent . value ! . id )
if ( index !== - 1 ) {
agents . value [ index ] = {
... agents . value [ index ] ,
... editForm . value ,
}
}
}
isEditing . value = false
}
// 取消编辑
const cancelEdit = ( ) => {
isEditing . value = false
editingAgent . value = null
}
// 切换状态
const toggleStatus = ( agent : Agent ) => {
if ( agent . status === 'running' ) {
agent . status = 'stopped'
} else if ( agent . status === 'stopped' ) {
agent . status = 'running'
}
}
// 删除 Agent
const deleteAgent = ( id : number ) => {
agents . value = agents . value . filter ( a => a . id !== id )
}
// 过滤后的 Agents
const filteredAgents = ( ) => {
return agents . value . filter ( agent => {
const matchSearch = agent . name . toLowerCase ( ) . includes ( searchQuery . value . toLowerCase ( ) ) ||
agent . framework . toLowerCase ( ) . includes ( searchQuery . value . toLowerCase ( ) )
const matchStatus = filterStatus . value === 'all' || agent . status === filterStatus . value
return matchSearch && matchStatus
} )
}
// 状态颜色
const statusClass = ( status : string ) => {
switch ( status ) {
case 'running' : return 'bg-primary-success'
case 'stopped' : return 'bg-gray-500'
case 'error' : return 'bg-primary-danger'
default : return 'bg-gray-500'
}
}
< / script >
< style scoped >
/* 模态框进入动画 */
@ keyframes modal - in {
0 % {
opacity : 0 ;
transform : scale ( 0.95 ) translateY ( 20 px ) ;
}
100 % {
opacity : 1 ;
transform : scale ( 1 ) translateY ( 0 ) ;
}
}
@ keyframes fade - in {
0 % { opacity : 0 ; transform : translateY ( - 5 px ) ; }
100 % { opacity : 1 ; transform : translateY ( 0 ) ; }
}
@ keyframes float {
0 % , 100 % { transform : translateY ( 0 ) ; }
50 % { transform : translateY ( - 8 px ) ; }
}
@ keyframes scale - in {
0 % { opacity : 0 ; transform : scale ( 0.9 ) ; }
100 % { opacity : 1 ; transform : scale ( 1 ) ; }
}
. animate - modal - in {
animation : modal - in 0.4 s cubic - bezier ( 0.16 , 1 , 0.3 , 1 ) forwards ;
}
. animate - fade - in {
animation : fade - in 0.3 s ease - out forwards ;
}
. animate - float {
animation : float 3 s ease - in - out infinite ;
}
. animate - scale - in {
animation : scale - in 0.5 s ease - out forwards ;
}
< / style >
< template >
<!-- 主内容区域 -- >
< div class = "p-6 min-h-screen" >
<!-- 顶部导航 -- >
< div class = "flex justify-between items-center mb-6" >
< div class = "flex items-center gap-2" >
< i class = "fa-solid fa-robot text-gray-400" > < / i >
< span class = "font-medium" > Agents < / span >
< / div >
2026-03-06 16:39:42 +08:00
< button @click ="openCreate" class = "btn-primary" >
2026-03-05 10:49:46 +08:00
< i class = "fa-solid fa-plus" > < / i >
New Agent
< / button >
< / div >
<!-- 搜索和筛选 -- >
< div class = "flex gap-4 mb-6" >
< div class = "flex-1 relative" >
< i class = "fa-solid fa-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" > < / i >
< input
v - model = "searchQuery"
type = "text"
placeholder = "Search agents..."
2026-03-06 16:39:42 +08:00
class = "search-input w-full"
2026-03-05 10:49:46 +08:00
>
< / div >
2026-03-05 11:31:36 +08:00
< el-select v-model = "filterStatus" placeholder="Select" class="w-40" size="large" >
< el-option label = "All Status" value = "all" / >
< el-option label = "Running" value = "running" / >
< el-option label = "Stopped" value = "stopped" / >
< el-option label = "Error" value = "error" / >
< / el-select >
2026-03-05 10:49:46 +08:00
< / div >
<!-- Agents 列表 -- >
< div class = "bg-dark-700 rounded-xl overflow-hidden" >
< table class = "w-full" >
< thead class = "bg-dark-600" >
< tr >
< th class = "text-left px-5 py-3 text-sm font-medium text-gray-400" > Agent Name < / th >
< th class = "text-left px-5 py-3 text-sm font-medium text-gray-400" > Framework < / th >
< th class = "text-left px-5 py-3 text-sm font-medium text-gray-400" > Model < / th >
< th class = "text-left px-5 py-3 text-sm font-medium text-gray-400" > MCP Servers < / th >
< th class = "text-left px-5 py-3 text-sm font-medium text-gray-400" > Status < / th >
< th class = "text-left px-5 py-3 text-sm font-medium text-gray-400" > Created < / th >
< th class = "text-right px-5 py-3 text-sm font-medium text-gray-400" > Actions < / th >
< / tr >
< / thead >
< tbody >
2026-03-06 16:39:42 +08:00
< tr v-for = "agent in filteredAgents()" :key="agent.id" class="table-row" >
2026-03-05 10:49:46 +08:00
< td class = "px-5 py-4" >
< div class = "font-medium" > { { agent . name } } < / div >
< div class = "text-sm text-gray-500" > { { agent . description } } < / div >
< / td >
< td class = "px-5 py-4" >
< span class = "bg-dark-500 px-2 py-1 rounded text-sm" > { { agent . framework } } < / span >
< / td >
< td class = "px-5 py-4 text-gray-300" > { { agent . model } } < / td >
< td class = "px-5 py-4" >
< span class = "text-primary-cyan" > { { agent . mcpServers } } < / span >
< / td >
< td class = "px-5 py-4" >
< div class = "flex items-center gap-2" >
< span class = "w-2 h-2 rounded-full" :class = "statusClass(agent.status)" > < / span >
< span class = "capitalize text-sm" > { { agent . status } } < / span >
< / div >
< / td >
< td class = "px-5 py-4 text-gray-400 text-sm" > { { agent . createdAt } } < / td >
< td class = "px-5 py-4" >
< div class = "flex items-center justify-end gap-2" >
< button
@ click = "toggleStatus(agent)"
2026-03-06 16:39:42 +08:00
class = "btn-icon"
2026-03-05 10:49:46 +08:00
: title = "agent.status === 'running' ? 'Stop' : 'Start'"
>
2026-03-06 16:39:42 +08:00
< i : class = "['fa-solid', agent.status === 'running' ? 'fa-stop' : 'fa-play', 'text-gray-400']" > < / i >
2026-03-05 10:49:46 +08:00
< / button >
< button
@ click = "openEdit(agent)"
2026-03-06 16:39:42 +08:00
class = "btn-icon"
2026-03-05 10:49:46 +08:00
title = "Edit"
>
2026-03-06 16:39:42 +08:00
< i class = "fa-solid fa-pen text-gray-400" > < / i >
2026-03-05 10:49:46 +08:00
< / button >
< button
@ click = "deleteAgent(agent.id)"
2026-03-06 16:39:42 +08:00
class = "btn-icon"
2026-03-05 10:49:46 +08:00
title = "Delete"
>
< i class = "fa-solid fa-trash text-gray-400 hover:text-primary-danger" > < / i >
< / button >
< / div >
< / td >
< / tr >
< / tbody >
< / table >
<!-- 空状态 -- >
< div v-if = "filteredAgents().length === 0" class="py-12 text-center text-gray-500" >
< i class = "fa-solid fa-robot text-4xl mb-3" > < / i >
< p > No agents found < / p >
< / div >
< / div >
<!-- 编辑弹窗 -- >
< Teleport to = "body" >
2026-03-06 16:39:42 +08:00
< div v-if = "isEditing" class="fixed inset-0 bg-black/60 flex items-center justify-center z-50" >
2026-03-05 10:49:46 +08:00
< div class = "bg-dark-700 rounded-2xl w-full max-w-lg border border-dark-500 shadow-2xl" >
<!-- 弹窗头部 -- >
< div class = "flex items-center justify-between p-5 border-b border-dark-500" >
< h3 class = "text-lg font-semibold" > Edit Agent < / h3 >
< button @click ="cancelEdit" class = "text-gray-400 hover:text-white transition-colors" >
< i class = "fa-solid fa-xmark text-xl" > < / i >
< / button >
< / div >
<!-- 弹窗内容 -- >
< div class = "p-5 space-y-4" >
< div >
< label class = "block text-sm font-medium text-gray-300 mb-2" > Agent Name < / label >
< input
v - model = "editForm.name"
type = "text"
2026-03-06 16:39:42 +08:00
class = "input-field"
2026-03-05 10:49:46 +08:00
>
< / div >
< div >
< label class = "block text-sm font-medium text-gray-300 mb-2" > Framework < / label >
2026-03-05 11:31:36 +08:00
< el-select v-model = "editForm.framework" placeholder="Select" class="w-full" size="large" >
< el-option label = "Google ADK" value = "Google ADK" / >
< el-option label = "OpenAI" value = "OpenAI" / >
< el-option label = "PydanticAI" value = "PydanticAI" / >
< el-option label = "LangChain" value = "LangChain" / >
< / el-select >
2026-03-05 10:49:46 +08:00
< / div >
< div >
< label class = "block text-sm font-medium text-gray-300 mb-2" > Model < / label >
2026-03-05 11:31:36 +08:00
< el-select v-model = "editForm.model" placeholder="Select" class="w-full" size="large" >
< el-option label = "gemini-2.0-flash" value = "gemini-2.0-flash" / >
< el-option label = "gpt-4o" value = "gpt-4o" / >
< el-option label = "gpt-4o-mini" value = "gpt-4o-mini" / >
< el-option label = "claude-3-5-sonnet" value = "claude-3-5-sonnet" / >
< / el-select >
2026-03-05 10:49:46 +08:00
< / div >
< div >
< label class = "block text-sm font-medium text-gray-300 mb-2" > Description < / label >
< textarea
v - model = "editForm.description"
rows = "3"
2026-03-06 16:39:42 +08:00
class = "input-field resize-none"
2026-03-05 10:49:46 +08:00
> < / textarea >
< / div >
< / div >
<!-- 弹窗底部 -- >
< div class = "flex items-center justify-end gap-3 p-5 border-t border-dark-500" >
< button
@ click = "cancelEdit"
2026-03-06 16:39:42 +08:00
class = "btn-secondary"
2026-03-05 10:49:46 +08:00
>
Cancel
< / button >
< button
@ click = "saveEdit"
2026-03-06 16:39:42 +08:00
class = "btn-primary"
2026-03-05 10:49:46 +08:00
>
Save Changes
< / button >
< / div >
< / div >
< / div >
< / Teleport >
<!-- 新建 Agent 模态框 -- >
< Teleport to = "body" >
2026-03-06 16:39:42 +08:00
< div v-if = "isCreating" class="fixed inset-0 bg-black/80 flex items-center justify-center z-50 p-4" >
2026-03-05 10:49:46 +08:00
< div class = "bg-dark-800 rounded-2xl w-full max-w-6xl h-[85vh] border border-dark-600 shadow-2xl overflow-hidden flex flex-col animate-modal-in" >
<!-- 模态框头部 -- >
< div class = "flex items-center justify-between p-5 border-b border-dark-600 bg-dark-700/50" >
< div class = "flex items-center gap-3" >
< div class = "w-10 h-10 rounded-xl bg-gradient-to-br from-primary-orange to-red-500 flex items-center justify-center animate-pulse" >
< i class = "fa-solid fa-robot text-white" > < / i >
< / div >
< div >
< h3 class = "text-xl font-semibold text-white" > Create New Agent < / h3 >
< p class = "text-sm text-gray-400" > Configure your agent workflow < / p >
< / div >
< / div >
< button @click ="closeCreate" class = "text-gray-400 hover:text-white transition-all p-2 hover:bg-dark-600 rounded-lg" >
< i class = "fa-solid fa-xmark text-xl" > < / i >
< / button >
< / div >
<!-- 三栏布局主体 -- >
< div class = "flex-1 flex overflow-hidden" >
<!-- 左侧 : 框架选择 -- >
< div class = "w-72 bg-dark-700/50 border-r border-dark-600 p-5 overflow-y-auto" >
< div class = "flex items-center gap-2 mb-4" >
< i class = "fa-solid fa-layer-group text-primary-orange" > < / i >
< h4 class = "font-medium text-white" > Framework < / h4 >
< / div >
< div class = "space-y-3" >
< div
v - for = "fw in frameworks"
: key = "fw.name"
@ click = "newAgentForm.framework = fw.name; newAgentForm.model = models.find(m => m.name === fw.name)?.models[0] || ''"
class = "p-4 rounded-xl border-2 cursor-pointer transition-all duration-300 hover:scale-105"
: class = " newAgentForm . framework === fw . name
? 'border-primary-orange bg-dark-600 shadow-lg shadow-primary-orange/20'
: 'border-dark-500 bg-dark-700 hover:border-gray-500' "
>
< div class = "flex items-center gap-3" >
< div : class = "['w-10 h-10 rounded-lg bg-gradient-to-br flex items-center justify-center', fw.color]" >
< i : class = "['fa-solid', fw.icon, 'text-white text-lg']" > < / i >
< / div >
< span class = "font-medium text-white" > { { fw . name } } < / span >
< / div >
< div v-if = "newAgentForm.framework === fw.name" class="mt-2 flex items-center gap-1 text-primary-orange text-sm animate-fade-in" >
< i class = "fa-solid fa-check-circle" > < / i >
< span > Selected < / span >
< / div >
< / div >
< / div >
<!-- 模型选择 -- >
< div class = "mt-6" >
< div class = "flex items-center gap-2 mb-3" >
< i class = "fa-solid fa-brain text-primary-cyan" > < / i >
< h4 class = "font-medium text-white" > Model < / h4 >
< / div >
2026-03-05 11:31:36 +08:00
< el-select v-model = "newAgentForm.model" placeholder="Select" class="w-full" size="large" >
< el-option
v - for = "model in models.find(m => m.name === newAgentForm.framework)?.models"
: key = "model"
: label = "model"
: value = "model"
/ >
< / el-select >
2026-03-05 10:49:46 +08:00
< / div >
<!-- Agent 名称 -- >
< div class = "mt-6" >
< div class = "flex items-center gap-2 mb-3" >
< i class = "fa-solid fa-tag text-primary-purple" > < / i >
< h4 class = "font-medium text-white" > Agent Name < / h4 >
< / div >
< input
v - model = "newAgentForm.name"
type = "text"
placeholder = "Enter agent name..."
class = "w-full bg-dark-600 border border-dark-500 rounded-lg px-4 py-3 text-white placeholder-gray-500 focus:outline-none focus:border-primary-orange transition-colors"
>
< / div >
< / div >
<!-- 中间 : 流程画布 -- >
< div class = "flex-1 bg-dark-900 relative overflow-hidden" >
<!-- 背景网格 -- >
< div class = "absolute inset-0 opacity-10" style = "background-image: radial-gradient(circle, #1E6BF9 1px, transparent 1px); background-size: 30px 30px;" > < / div >
<!-- 流程节点 -- >
< div class = "h-full flex flex-col items-center justify-center p-8 relative z-10" >
<!-- 开始节点 -- >
< div class = "node bg-gradient-to-r from-blue-500 to-blue-600 rounded-xl w-64 p-4 shadow-lg shadow-blue-500/30 animate-float" >
< div class = "flex items-center gap-3" >
< div class = "w-8 h-8 rounded-lg bg-white/20 flex items-center justify-center" >
< i class = "fa-solid fa-play text-white text-sm" > < / i >
< / div >
< div >
< div class = "font-medium text-white" > Start < / div >
< div class = "text-xs text-blue-200" > Agent begins < / div >
< / div >
< / div >
< / div >
<!-- 连接线 -- >
< div class = "h-8 w-0.5 bg-gradient-to-b from-blue-500 to-primary-orange animate-pulse" > < / div >
<!-- 框架节点 -- >
< div class = "node bg-dark-700 border-2 border-primary-orange rounded-xl w-64 p-4 shadow-lg shadow-primary-orange/20 animate-scale-in" >
< div class = "flex items-center gap-3" >
< div class = "w-10 h-10 rounded-lg bg-gradient-to-br from-primary-orange to-red-500 flex items-center justify-center" >
< i : class = "['fa-solid', frameworks.find(f => f.name === newAgentForm.framework)?.icon || 'fa-robot', 'text-white']" > < / i >
< / div >
< div >
< div class = "font-medium text-white" > { { newAgentForm . framework } } < / div >
< div class = "text-xs text-gray-400" > { { newAgentForm . model } } < / div >
< / div >
< / div >
< / div >
<!-- 连接线 -- >
< div class = "h-8 w-0.5 bg-gradient-to-b from-primary-orange to-purple-500 animate-pulse" > < / div >
<!-- MCP 服务器节点 -- >
< div class = "node bg-dark-700 border-2 border-purple-500 rounded-xl w-64 p-4 shadow-lg shadow-purple-500/20 animate-scale-in" style = "animation-delay: 0.2s" >
< div class = "flex items-center justify-between mb-2" >
< div class = "flex items-center gap-2" >
< i class = "fa-solid fa-server text-purple-400" > < / i >
< span class = "font-medium text-white" > MCP Servers < / span >
< / div >
< span class = "bg-purple-500/30 text-purple-300 text-xs px-2 py-0.5 rounded" > { { newAgentForm . mcpServers . length } } connected < / span >
< / div >
< div class = "flex flex-wrap gap-2" >
< span v-for = "mcp in newAgentForm.mcpServers" :key="mcp" class="bg-dark-600 text-gray-300 text-xs px-2 py-1 rounded flex items-center gap-1" >
< i class = "fa-solid fa-check-circle text-green-400" > < / i >
{ { mcp } }
< / span >
< span v-if = "newAgentForm.mcpServers.length === 0" class="text-gray-500 text-xs" > No servers selected < / span >
< / div >
< / div >
<!-- 连接线 -- >
< div class = "h-8 w-0.5 bg-gradient-to-b from-purple-500 to-green-500 animate-pulse" > < / div >
<!-- 结束节点 -- >
< div class = "node bg-gradient-to-r from-green-500 to-emerald-600 rounded-xl w-64 p-4 shadow-lg shadow-green-500/30 animate-float" style = "animation-delay: 0.5s" >
< div class = "flex items-center gap-3" >
< div class = "w-8 h-8 rounded-lg bg-white/20 flex items-center justify-center" >
< i class = "fa-solid fa-check text-white text-sm" > < / i >
< / div >
< div >
< div class = "font-medium text-white" > Ready < / div >
< div class = "text-xs text-green-200" > Agent configured < / div >
< / div >
< / div >
< / div >
< / div >
<!-- 装饰性光效 -- >
< div class = "absolute top-1/4 -left-20 w-40 h-40 bg-primary-orange/10 rounded-full blur-3xl animate-pulse" > < / div >
< div class = "absolute bottom-1/4 -right-20 w-40 h-40 bg-purple-500/10 rounded-full blur-3xl animate-pulse" style = "animation-delay: 0.5s" > < / div >
< / div >
<!-- 右侧 : MCP 服务器选择 -- >
< div class = "w-80 bg-dark-700/50 border-l border-dark-600 p-5 overflow-y-auto" >
< div class = "flex items-center gap-2 mb-4" >
< i class = "fa-solid fa-plug text-primary-success" > < / i >
< h4 class = "font-medium text-white" > MCP Servers < / h4 >
< span class = "text-xs text-gray-500" > ( { { newAgentForm . mcpServers . length } } selected ) < / span >
< / div >
< div class = "space-y-3" >
< div
v - for = "server in availableMCPServers"
: key = "server.name"
@ click = "toggleMCPServer(server.name)"
class = "p-4 rounded-xl border-2 cursor-pointer transition-all duration-300 hover:scale-105"
: class = " newAgentForm . mcpServers . includes ( server . name )
? 'border-green-500 bg-dark-600 shadow-lg shadow-green-500/20'
: 'border-dark-500 bg-dark-700 hover:border-gray-500' "
>
< div class = "flex items-center justify-between" >
< div class = "flex items-center gap-3" >
< div class = "w-10 h-10 rounded-lg bg-dark-500 flex items-center justify-center" >
< i : class = "['fa-solid', server.icon, server.status === 'connected' ? 'text-green-400' : 'text-gray-500']" > < / i >
< / div >
< div >
< div class = "font-medium text-white" > { { server . name } } < / div >
< div class = "text-xs flex items-center gap-1" : class = "server.status === 'connected' ? 'text-green-400' : 'text-gray-500'" >
< span class = "w-1.5 h-1.5 rounded-full" : class = "server.status === 'connected' ? 'bg-green-400' : 'bg-gray-500'" > < / span >
{ { server . status } }
< / div >
< / div >
< / div >
< div
class = "w-6 h-6 rounded-md flex items-center justify-center transition-all"
: class = "newAgentForm.mcpServers.includes(server.name) ? 'bg-green-500' : 'bg-dark-500'"
>
< i v-if = "newAgentForm.mcpServers.includes(server.name)" class="fa-solid fa-check text-white text-xs" > < / i >
< / div >
< / div >
< / div >
< / div >
<!-- 描述 -- >
< div class = "mt-6" >
< div class = "flex items-center gap-2 mb-3" >
< i class = "fa-solid fa-align-left text-gray-400" > < / i >
< h4 class = "font-medium text-white" > Description < / h4 >
< / div >
< textarea
v - model = "newAgentForm.description"
rows = "4"
placeholder = "Describe your agent's purpose..."
class = "w-full bg-dark-600 border border-dark-500 rounded-lg px-4 py-3 text-white placeholder-gray-500 focus:outline-none focus:border-primary-orange transition-colors resize-none"
> < / textarea >
< / div >
< / div >
< / div >
<!-- 底部操作栏 -- >
< div class = "flex items-center justify-between p-5 border-t border-dark-600 bg-dark-700/50" >
< div class = "flex items-center gap-2 text-sm text-gray-400" >
< i class = "fa-solid fa-circle-info" > < / i >
< span > Configure your agent settings < / span >
< / div >
< div class = "flex items-center gap-3" >
< button
@ click = "closeCreate"
2026-03-06 16:39:42 +08:00
class = "btn-secondary px-6 py-2.5"
2026-03-05 10:49:46 +08:00
>
Cancel
< / button >
< button
@ click = "saveNewAgent"
2026-03-06 16:39:42 +08:00
class = "btn-primary px-6 py-2.5"
2026-03-05 10:49:46 +08:00
>
< i class = "fa-solid fa-plus" > < / i >
Create Agent
< / button >
< / div >
< / div >
< / div >
< / div >
< / Teleport >
< / div >
< / template >