Files
multi-agent-bidding/templates/index.html
hubian 05950a3c84 feat: 多智能体竞标调度系统 v1.0.0
核心组件:
- Orchestrator: 意图理解、任务拆分、竞标管理、结果验证
- Worker: 竞标任务、执行交付
- TaskBoard: 状态管理、信息存储
- BidEvaluator: 竞标评估算法
- ExecutionMonitor: 执行监控、超时处理
- LLMClient: 大模型接口调用

功能特性:
- 竞标机制:Agent主动竞争任务
- 动态调度:串行/并行任务智能调度
- 智能容错:超时切换、验证重试
- 质量保证:结果验证、历史追踪

Web界面:首页、请求列表、任务列表、Agent管理
API接口:请求/任务/Agent管理、测试接口
端口:19015
2026-04-12 01:54:15 +08:00

279 lines
11 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多智能体竞标调度系统</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.css" rel="stylesheet">
<style>
body { background-color: #f5f7fa; }
.hero-section {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 60px 0;
}
.stat-card {
background: white;
border-radius: 12px;
padding: 20px;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}
.feature-card {
background: white;
border-radius: 12px;
padding: 30px;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
transition: transform 0.2s;
}
.feature-card:hover {
transform: translateY(-5px);
}
.input-area {
background: white;
border-radius: 12px;
padding: 30px;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}
.result-area {
background: #1a1a2e;
border-radius: 12px;
padding: 20px;
color: #eee;
min-height: 300px;
}
.agent-badge {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
padding: 8px 16px;
border-radius: 20px;
font-size: 0.85rem;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="/">
<i class="ri-robot-2-line"></i> 多智能体竞标调度系统
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link active" href="/">首页</a></li>
<li class="nav-item"><a class="nav-link" href="/requests">请求列表</a></li>
<li class="nav-item"><a class="nav-link" href="/tasks">任务列表</a></li>
<li class="nav-item"><a class="nav-link" href="/agents">Agent管理</a></li>
</ul>
</div>
</div>
</nav>
<div class="hero-section">
<div class="container text-center">
<h1 class="display-4"><i class="ri-robot-2-fill"></i> 多智能体竞标调度系统</h1>
<p class="lead">任务竞标 · 动态调度 · 智能容错</p>
<div class="mt-4">
<span class="agent-badge me-2"><i class="ri-code-line"></i> 代码专家</span>
<span class="agent-badge me-2"><i class="ri-search-line"></i> 搜索专家</span>
<span class="agent-badge me-2"><i class="ri-edit-line"></i> 写作专家</span>
<span class="agent-badge"><i class="ri-bar-chart-line"></i> 分析专家</span>
</div>
</div>
</div>
<div class="container py-4">
<!-- 统计卡片 -->
<div class="row mb-4">
<div class="col-md-3">
<div class="stat-card text-center">
<i class="ri-message-3-line fs-1 text-primary"></i>
<h3 id="stat-requests">0</h3>
<p class="text-muted">用户请求</p>
</div>
</div>
<div class="col-md-3">
<div class="stat-card text-center">
<i class="ri-task-line fs-1 text-success"></i>
<h3 id="stat-tasks">0</h3>
<p class="text-muted">任务总数</p>
</div>
</div>
<div class="col-md-3">
<div class="stat-card text-center">
<i class="ri-robot-line fs-1 text-warning"></i>
<h3 id="stat-agents">4</h3>
<p class="text-muted">注册Agent</p>
</div>
</div>
<div class="col-md-3">
<div class="stat-card text-center">
<i class="ri-flashlight-line fs-1 text-danger"></i>
<h3 id="stat-active">0</h3>
<p class="text-muted">活跃执行</p>
</div>
</div>
</div>
<!-- 输入区域 -->
<div class="row mb-4">
<div class="col-md-6">
<div class="input-area">
<h5><i class="ri-chat-3-line"></i> 发送请求</h5>
<div class="mb-3">
<textarea id="user-input" class="form-control" rows="5"
placeholder="输入你的请求例如帮我写一个Python爬虫爬取新闻网站..."></textarea>
</div>
<button id="submit-btn" class="btn btn-primary w-100">
<i class="ri-send-plane-fill"></i> 发送请求
</button>
<div class="mt-3">
<h6>快速测试:</h6>
<button class="btn btn-outline-secondary btn-sm me-2" onclick="quickTest('intent')">意图分析</button>
<button class="btn btn-outline-secondary btn-sm me-2" onclick="quickTest('split')">任务拆分</button>
<button class="btn btn-outline-secondary btn-sm" onclick="quickTest('full')">完整流程</button>
</div>
</div>
</div>
<div class="col-md-6">
<div class="result-area">
<h6><i class="ri-terminal-line"></i> 执行日志</h6>
<div id="log-output" style="font-family: monospace; white-space: pre-wrap; max-height: 280px; overflow-y: auto;">
等待输入...
</div>
</div>
</div>
</div>
<!-- 功能介绍 -->
<div class="row">
<div class="col-md-4">
<div class="feature-card">
<i class="ri-award-line fs-1 text-primary"></i>
<h5 class="mt-3">竞标机制</h5>
<p>Agent主动竞争任务展示能力和方案规划Agent综合评估选择最佳执行者。</p>
</div>
</div>
<div class="col-md-4">
<div class="feature-card">
<i class="ri-flow-chart fs-1 text-success"></i>
<h5 class="mt-3">动态调度</h5>
<p>串行任务严格按依赖执行,并行任务最大化并发,智能分配执行顺序。</p>
</div>
</div>
<div class="col-md-4">
<div class="feature-card">
<i class="ri-shield-check-line fs-1 text-warning"></i>
<h5 class="mt-3">智能容错</h5>
<p>超时自动切换备选Agent验证失败给予重试机会失败记录用于改进。</p>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// 加载统计
function loadStats() {
fetch('/api/stats')
.then(r => r.json())
.then(data => {
document.getElementById('stat-requests').textContent = data.total_requests || 0;
document.getElementById('stat-tasks').textContent = data.total_tasks || 0;
document.getElementById('stat-agents').textContent = data.total_agents || 0;
document.getElementById('stat-active').textContent = data.active_executions || 0;
});
}
// 日志输出
function log(text, type = 'info') {
const logArea = document.getElementById('log-output');
const time = new Date().toLocaleTimeString();
const color = type === 'error' ? '#ff6b6b' : type === 'success' ? '#51cf66' : '#74c0fc';
logArea.innerHTML += `<span style="color:${color}">[${time}] ${text}</span>\n`;
logArea.scrollTop = logArea.scrollHeight;
}
// 提交请求
document.getElementById('submit-btn').addEventListener('click', async () => {
const input = document.getElementById('user-input').value.trim();
if (!input) {
log('请输入请求内容', 'error');
return;
}
log('发送请求...');
document.getElementById('submit-btn').disabled = true;
try {
const response = await fetch('/api/request', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({content: input})
});
const data = await response.json();
if (data.error) {
log(`错误: ${data.error}`, 'error');
} else {
log(`请求ID: ${data.id}`, 'success');
log(`状态: ${data.status}`);
if (data.task_graph) {
const tasks = Object.keys(data.task_graph.tasks);
log(`拆分任务: ${tasks.length}`);
}
if (data.final_result) {
log(`结果: ${JSON.stringify(data.final_result)}`, 'success');
}
}
} catch (e) {
log(`请求失败: ${e}`, 'error');
}
document.getElementById('submit-btn').disabled = false;
loadStats();
});
// 快速测试
async function quickTest(type) {
const input = document.getElementById('user-input').value.trim() || '帮我写一个Python爬虫';
log(`测试 ${type}...`);
try {
const url = type === 'intent' ? '/api/test_intent' :
type === 'split' ? '/api/test_split' : '/api/request';
const response = await fetch(url, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(type === 'full' ? {content: input} : {prompt: input})
});
const data = await response.json();
if (data.error) {
log(`错误: ${data.error}`, 'error');
} else {
log(`结果:`, 'success');
log(JSON.stringify(data.intent || data.tasks || data, null, 2));
}
} catch (e) {
log(`测试失败: ${e}`, 'error');
}
loadStats();
}
// 初始化
loadStats();
</script>
</body>
</html>