Add Report Agent Tools Card to Step5Interaction component
This commit is contained in:
parent
4bd3c856f5
commit
78c8c43699
1 changed files with 259 additions and 8 deletions
|
|
@ -148,6 +148,73 @@
|
||||||
<!-- Chat Mode -->
|
<!-- Chat Mode -->
|
||||||
<div v-if="activeTab === 'chat'" class="chat-container">
|
<div v-if="activeTab === 'chat'" class="chat-container">
|
||||||
|
|
||||||
|
<!-- Report Agent Tools Card -->
|
||||||
|
<div v-if="chatTarget === 'report_agent'" class="report-agent-tools-card">
|
||||||
|
<div class="tools-card-header">
|
||||||
|
<div class="tools-card-avatar">R</div>
|
||||||
|
<div class="tools-card-info">
|
||||||
|
<div class="tools-card-name">Report Agent - Chat</div>
|
||||||
|
<div class="tools-card-subtitle">报告生成智能体的快速对话版本,可调用 4 种专业工具</div>
|
||||||
|
</div>
|
||||||
|
<button class="tools-card-toggle" @click="showToolsDetail = !showToolsDetail">
|
||||||
|
<svg :class="{ 'is-expanded': showToolsDetail }" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<polyline points="6 9 12 15 18 9"></polyline>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div v-if="showToolsDetail" class="tools-card-body">
|
||||||
|
<div class="tools-grid">
|
||||||
|
<div class="tool-item tool-purple">
|
||||||
|
<div class="tool-icon-wrapper">
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<path d="M9 18h6M10 22h4M12 2a7 7 0 0 0-4 12.5V17a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-2.5A7 7 0 0 0 12 2z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="tool-content">
|
||||||
|
<div class="tool-name">InsightForge 深度归因</div>
|
||||||
|
<div class="tool-desc">对齐现实世界种子数据与模拟环境状态,结合Global/Local Memory机制,提供跨时空的深度归因分析</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tool-item tool-blue">
|
||||||
|
<div class="tool-icon-wrapper">
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<circle cx="12" cy="12" r="10"></circle>
|
||||||
|
<path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="tool-content">
|
||||||
|
<div class="tool-name">PanoramaSearch 全景追踪</div>
|
||||||
|
<div class="tool-desc">基于图结构的广度遍历算法,重构事件传播路径,捕获全量信息流动的拓扑结构</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tool-item tool-orange">
|
||||||
|
<div class="tool-icon-wrapper">
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="tool-content">
|
||||||
|
<div class="tool-name">QuickSearch 快速检索</div>
|
||||||
|
<div class="tool-desc">基于 GraphRAG 的即时查询接口,优化索引效率,用于快速提取具体的节点属性与离散事实</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tool-item tool-green">
|
||||||
|
<div class="tool-icon-wrapper">
|
||||||
|
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2">
|
||||||
|
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
|
||||||
|
<circle cx="9" cy="7" r="4"></circle>
|
||||||
|
<path d="M23 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="tool-content">
|
||||||
|
<div class="tool-name">InterviewSubAgent 虚拟访谈</div>
|
||||||
|
<div class="tool-desc">自主式访谈,能够并行与模拟世界中个体进行多轮对话,采集非结构化的观点数据与心理状态</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Agent Profile Card -->
|
<!-- Agent Profile Card -->
|
||||||
<div v-if="chatTarget === 'agent' && selectedAgent" class="agent-profile-card">
|
<div v-if="chatTarget === 'agent' && selectedAgent" class="agent-profile-card">
|
||||||
<div class="profile-card-header">
|
<div class="profile-card-header">
|
||||||
|
|
@ -361,6 +428,7 @@ const showAgentDropdown = ref(false)
|
||||||
const selectedAgent = ref(null)
|
const selectedAgent = ref(null)
|
||||||
const selectedAgentIndex = ref(null)
|
const selectedAgentIndex = ref(null)
|
||||||
const showFullProfile = ref(true)
|
const showFullProfile = ref(true)
|
||||||
|
const showToolsDetail = ref(true)
|
||||||
|
|
||||||
// Chat State
|
// Chat State
|
||||||
const chatInput = ref('')
|
const chatInput = ref('')
|
||||||
|
|
@ -471,11 +539,31 @@ const renderMarkdown = (content) => {
|
||||||
html = html.replace(/^## (.+)$/gm, '<h3 class="md-h3">$1</h3>')
|
html = html.replace(/^## (.+)$/gm, '<h3 class="md-h3">$1</h3>')
|
||||||
html = html.replace(/^# (.+)$/gm, '<h2 class="md-h2">$1</h2>')
|
html = html.replace(/^# (.+)$/gm, '<h2 class="md-h2">$1</h2>')
|
||||||
html = html.replace(/^> (.+)$/gm, '<blockquote class="md-quote">$1</blockquote>')
|
html = html.replace(/^> (.+)$/gm, '<blockquote class="md-quote">$1</blockquote>')
|
||||||
html = html.replace(/^- (.+)$/gm, '<li class="md-li">$1</li>')
|
|
||||||
html = html.replace(/(<li class="md-li">[\s\S]*?<\/li>)(\s*<li)/g, '$1$2')
|
// 处理列表 - 支持子列表
|
||||||
html = html.replace(/(<li class="md-li">.*<\/li>)+/g, '<ul class="md-ul">$&</ul>')
|
html = html.replace(/^(\s*)- (.+)$/gm, (match, indent, text) => {
|
||||||
html = html.replace(/^\d+\. (.+)$/gm, '<li class="md-oli">$1</li>')
|
const level = Math.floor(indent.length / 2)
|
||||||
html = html.replace(/(<li class="md-oli">.*<\/li>)+/g, '<ol class="md-ol">$&</ol>')
|
return `<li class="md-li" data-level="${level}">${text}</li>`
|
||||||
|
})
|
||||||
|
html = html.replace(/^(\s*)(\d+)\. (.+)$/gm, (match, indent, num, text) => {
|
||||||
|
const level = Math.floor(indent.length / 2)
|
||||||
|
return `<li class="md-oli" data-level="${level}">${text}</li>`
|
||||||
|
})
|
||||||
|
|
||||||
|
// 包装无序列表
|
||||||
|
html = html.replace(/(<li class="md-li"[^>]*>.*?<\/li>\s*)+/g, '<ul class="md-ul">$&</ul>')
|
||||||
|
// 包装有序列表
|
||||||
|
html = html.replace(/(<li class="md-oli"[^>]*>.*?<\/li>\s*)+/g, '<ol class="md-ol">$&</ol>')
|
||||||
|
|
||||||
|
// 清理列表项之间的所有空白
|
||||||
|
html = html.replace(/<\/li>\s+<li/g, '</li><li')
|
||||||
|
// 清理列表开始标签后的空白
|
||||||
|
html = html.replace(/<ul class="md-ul">\s+/g, '<ul class="md-ul">')
|
||||||
|
html = html.replace(/<ol class="md-ol">\s+/g, '<ol class="md-ol">')
|
||||||
|
// 清理列表结束标签前的空白
|
||||||
|
html = html.replace(/\s+<\/ul>/g, '</ul>')
|
||||||
|
html = html.replace(/\s+<\/ol>/g, '</ol>')
|
||||||
|
|
||||||
html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
|
html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
|
||||||
html = html.replace(/\*(.+?)\*/g, '<em>$1</em>')
|
html = html.replace(/\*(.+?)\*/g, '<em>$1</em>')
|
||||||
html = html.replace(/_(.+?)_/g, '<em>$1</em>')
|
html = html.replace(/_(.+?)_/g, '<em>$1</em>')
|
||||||
|
|
@ -488,6 +576,9 @@ const renderMarkdown = (content) => {
|
||||||
html = html.replace(/(<\/h[2-5]>)<\/p>/g, '$1')
|
html = html.replace(/(<\/h[2-5]>)<\/p>/g, '$1')
|
||||||
html = html.replace(/<p class="md-p">(<ul|<ol|<blockquote|<pre|<hr)/g, '$1')
|
html = html.replace(/<p class="md-p">(<ul|<ol|<blockquote|<pre|<hr)/g, '$1')
|
||||||
html = html.replace(/(<\/ul>|<\/ol>|<\/blockquote>|<\/pre>)<\/p>/g, '$1')
|
html = html.replace(/(<\/ul>|<\/ol>|<\/blockquote>|<\/pre>)<\/p>/g, '$1')
|
||||||
|
// 清理列表前后的 <br> 标签
|
||||||
|
html = html.replace(/<br>(<ul|<ol)/g, '$1')
|
||||||
|
html = html.replace(/(<\/ul>|<\/ol>)<br>/g, '$1')
|
||||||
|
|
||||||
return html
|
return html
|
||||||
}
|
}
|
||||||
|
|
@ -1286,6 +1377,158 @@ watch(() => props.simulationId, (newId) => {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Report Agent Tools Card */
|
||||||
|
.report-agent-tools-card {
|
||||||
|
border-bottom: 1px solid #E5E7EB;
|
||||||
|
background: linear-gradient(135deg, #F8FAFC 0%, #F1F5F9 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-card-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 14px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-card-avatar {
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
min-width: 44px;
|
||||||
|
min-height: 44px;
|
||||||
|
background: linear-gradient(135deg, #1F2937 0%, #374151 100%);
|
||||||
|
color: #FFFFFF;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
flex-shrink: 0;
|
||||||
|
box-shadow: 0 2px 8px rgba(31, 41, 55, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-card-info {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-card-name {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1F2937;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-card-subtitle {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #6B7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-card-toggle {
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #6B7280;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-card-toggle:hover {
|
||||||
|
background: #F9FAFB;
|
||||||
|
border-color: #D1D5DB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-card-toggle svg {
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-card-toggle svg.is-expanded {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-card-body {
|
||||||
|
padding: 0 20px 16px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-item {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 12px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid #E5E7EB;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-item:hover {
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-icon-wrapper {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
min-width: 32px;
|
||||||
|
border-radius: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-purple .tool-icon-wrapper {
|
||||||
|
background: rgba(139, 92, 246, 0.1);
|
||||||
|
color: #8B5CF6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-blue .tool-icon-wrapper {
|
||||||
|
background: rgba(59, 130, 246, 0.1);
|
||||||
|
color: #3B82F6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-orange .tool-icon-wrapper {
|
||||||
|
background: rgba(249, 115, 22, 0.1);
|
||||||
|
color: #F97316;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-green .tool-icon-wrapper {
|
||||||
|
background: rgba(34, 197, 94, 0.1);
|
||||||
|
color: #22C55E;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-content {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-name {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1F2937;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-desc {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #6B7280;
|
||||||
|
line-height: 1.4;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
/* Agent Profile Card */
|
/* Agent Profile Card */
|
||||||
.agent-profile-card {
|
.agent-profile-card {
|
||||||
border-bottom: 1px solid #E5E7EB;
|
border-bottom: 1px solid #E5E7EB;
|
||||||
|
|
@ -1653,10 +1896,10 @@ watch(() => props.simulationId, (newId) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-text {
|
.message-text {
|
||||||
padding: 12px 16px;
|
padding: 10px 14px;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.6;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-message.user .message-text {
|
.chat-message.user .message-text {
|
||||||
|
|
@ -1671,11 +1914,19 @@ watch(() => props.simulationId, (newId) => {
|
||||||
border-bottom-left-radius: 4px;
|
border-bottom-left-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-text :deep(.md-p) {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-text :deep(.md-p:last-child) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Typing Indicator */
|
/* Typing Indicator */
|
||||||
.typing-indicator {
|
.typing-indicator {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
padding: 12px 16px;
|
padding: 10px 14px;
|
||||||
background: #F3F4F6;
|
background: #F3F4F6;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
border-bottom-left-radius: 4px;
|
border-bottom-left-radius: 4px;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue