agent-Specialization/static/demo/minimal-mode-v2/script.js

414 lines
14 KiB
JavaScript
Raw 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.

// 全局状态
let currentStep = 0;
let isExpanded = false;
let demoRunning = false;
// 步骤配置
const steps = [
{
type: 'thinking',
icon: 'brain',
summary: '我需要搜索最新的AI技术发展趋势。首先我应该使用搜索工具来查找相关信息...',
fullText: '我需要搜索最新的AI技术发展趋势。首先我应该使用搜索工具来查找相关信息。搜索关键词应该包括"AI技术"、"人工智能"、"2026"、"发展趋势"等。',
duration: 2000
},
{
type: 'tool',
icon: 'search',
summary: '搜索AI技术发展趋势 2026',
duration: 2500
},
{
type: 'thinking',
icon: 'brain',
summary: '搜索结果显示了一些有价值的信息。现在我需要执行一个命令来获取更详细的数据分析...',
fullText: '搜索结果显示了一些有价值的信息。现在我需要执行一个命令来获取更详细的数据分析。我将使用curl命令来获取第一个链接的内容然后进行分析。这将帮助我提供更准确和详细的答案。让我执行这个命令...\n\n在执行之前我需要确保命令的安全性和有效性。curl命令是一个常用的网络请求工具可以帮助我获取网页内容。我会添加适当的参数来确保请求的稳定性比如设置超时时间、用户代理等。\n\n同时我还需要考虑如何解析返回的HTML内容提取出关键信息。可能需要使用一些文本处理工具如grep、sed或awk来过滤和格式化数据。',
duration: 2000
},
{
type: 'tool',
icon: 'terminal',
summary: '执行命令:获取网页内容并分析',
duration: 2500
},
{
type: 'thinking',
icon: 'brain',
summary: '很好,我已经收集到了足够的信息。现在我可以整理这些内容,为用户提供一个清晰、全面的答案...',
fullText: '很好,我已经收集到了足够的信息。现在我可以整理这些内容,为用户提供一个清晰、全面的答案。我会按照趋势的重要性和影响力来组织内容。',
duration: 2000
}
];
// 最终输出文本
const finalOutputText = `根据我的搜索和分析2026年AI技术的主要发展趋势包括
1. **多模态AI模型的普及**能够同时处理文本、图像、音频等多种数据类型的AI模型将成为主流。
2. **AI安全性和可解释性**随着AI应用的广泛部署确保AI系统的安全性和决策的可解释性变得越来越重要。
3. **边缘AI计算**将AI计算能力部署到边缘设备实现更快的响应速度和更好的隐私保护。
这些趋势将深刻影响各行各业的数字化转型进程。`;
// 开始演示
async function startDemo() {
if (demoRunning) return;
demoRunning = true;
resetDemo();
// 显示等待动画
const placeholder = document.getElementById('generatingPlaceholder');
placeholder.style.display = 'flex';
await sleep(1500);
// 隐藏等待动画,显示摘要包装器
placeholder.style.display = 'none';
const summaryWrapper = document.getElementById('summaryWrapper');
summaryWrapper.style.display = 'flex';
summaryWrapper.classList.add('running');
// 执行每个步骤
for (let i = 0; i < steps.length; i++) {
currentStep = i;
await executeStep(i);
}
// 完成后移除运行状态
await sleep(500);
summaryWrapper.classList.remove('running');
// 如果展开状态,显示最后一步
if (isExpanded) {
await showDetailStep(currentStep, true);
} else {
// 折叠状态下,摘要显示第一步内容
updateSummary(steps[0]);
}
await sleep(800);
// 显示最终输出(流式)
const textOutput = document.getElementById('textOutput');
textOutput.style.display = 'block';
setTimeout(() => {
textOutput.classList.add('show');
}, 50);
// 流式输出最终文本
await streamText(document.querySelector('.text-content'), finalOutputText, 20);
demoRunning = false;
}
// 执行单个步骤
async function executeStep(stepIndex) {
const step = steps[stepIndex];
// 更新摘要(仅在折叠状态下)
if (!isExpanded) {
// 流式输出摘要文本
await streamSummary(step);
}
// 如果展开状态,显示详细内容
if (isExpanded) {
await showDetailStep(stepIndex, true);
// 如果是思考类型,流式输出完整内容
if (step.type === 'thinking' && step.fullText) {
const stepBody = document.querySelector(`.step-item[data-step="${stepIndex + 1}"] .step-body`);
if (stepBody) {
stepBody.textContent = '';
await streamText(stepBody, step.fullText, 30);
// 更新竖线高度
updateLineHeight(stepIndex + 1);
}
}
}
// 显示下一个步骤的竖线(如果有下一个步骤)
if (stepIndex < steps.length - 1) {
if (isExpanded) {
// 展开状态:显示当前步骤的竖线
const currentStepItem = document.querySelector(`.step-item[data-step="${stepIndex + 1}"]`);
if (currentStepItem) {
const line = currentStepItem.querySelector('.step-line');
if (line) {
updateLineHeight(stepIndex + 1);
}
}
} else {
// 折叠状态:显示摘要的竖线(暂时不需要,因为只在展开时才有步骤)
}
}
await sleep(step.duration);
}
// 流式输出摘要文本
async function streamSummary(step) {
const summaryIcon = document.getElementById('summaryIcon');
const summaryText = document.getElementById('summaryText');
// 更新图标
summaryIcon.innerHTML = getIconSVG(step.icon);
// 流式输出文本
summaryText.textContent = '';
await streamText(summaryText, step.summary, 30);
}
// 流式输出文本
async function streamText(element, text, speed = 30) {
element.textContent = '';
for (let i = 0; i < text.length; i++) {
element.textContent += text[i];
await sleep(speed);
}
}
// 更新摘要
function updateSummary(step) {
const summaryIcon = document.getElementById('summaryIcon');
const summaryText = document.getElementById('summaryText');
// 更新图标
summaryIcon.innerHTML = getIconSVG(step.icon);
// 更新文本
summaryText.textContent = step.summary;
}
// 显示详细步骤
async function showDetailStep(stepIndex, isNewStep = false) {
const stepItem = document.querySelector(`.step-item[data-step="${stepIndex + 1}"]`);
if (!stepItem) return;
// 添加动画类
if (isNewStep) {
stepItem.classList.add('animated');
} else {
stepItem.classList.add('instant');
}
// 显示步骤
stepItem.style.display = 'flex';
// 等待动画
await sleep(isNewStep ? 100 : 10);
// 如果有下一个步骤,显示当前步骤的竖线
if (stepIndex < steps.length - 1) {
updateLineHeight(stepIndex + 1);
}
await sleep(isNewStep ? 250 : 10);
}
// 更新竖线高度
function updateLineHeight(stepIndex) {
const stepItem = document.querySelector(`.step-item[data-step="${stepIndex}"]`);
if (!stepItem) return;
const line = stepItem.querySelector('.step-line');
const stepContent = stepItem.querySelector('.step-content');
if (!line || !stepContent) return;
// 获取内容的实际高度
const contentHeight = stepContent.offsetHeight;
// 如果是最后一个步骤,不需要竖线
if (stepIndex >= steps.length) {
line.style.height = '0';
return;
}
// 计算竖线高度:内容高度 + 间距
const gap = 16;
const lineHeight = Math.max(contentHeight + gap, 40);
line.style.height = `${lineHeight}px`;
}
// 切换展开/折叠
async function toggleExpand() {
const summaryWrapper = document.getElementById('summaryWrapper');
if (summaryWrapper.style.display === 'none') return;
isExpanded = !isExpanded;
if (isExpanded) {
// 展开:显示完整文本,隐藏摘要文本
summaryWrapper.classList.add('expanded');
const summaryText = document.getElementById('summaryText');
const summaryTextFull = document.getElementById('summaryTextFull');
const summaryLine = document.getElementById('summaryLine');
const stepsContainer = document.getElementById('stepsContainer');
// 切换文本显示
summaryText.style.display = 'none';
summaryTextFull.style.display = 'block';
// 显示连接线
await sleep(50);
summaryLine.style.height = '20px';
// 显示步骤容器
stepsContainer.style.display = 'block';
await sleep(50);
stepsContainer.classList.add('show');
// 快速显示已完成的步骤
for (let i = 0; i <= currentStep; i++) {
const isCurrentStep = i === currentStep && demoRunning;
await showDetailStep(i, isCurrentStep);
if (!isCurrentStep) {
await sleep(30); // 已有内容快速出现
}
}
} else {
// 折叠:显示摘要文本,隐藏完整文本
summaryWrapper.classList.remove('expanded');
const summaryText = document.getElementById('summaryText');
const summaryTextFull = document.getElementById('summaryTextFull');
const summaryLine = document.getElementById('summaryLine');
const stepsContainer = document.getElementById('stepsContainer');
// 隐藏步骤容器
stepsContainer.classList.remove('show');
await sleep(250);
stepsContainer.style.display = 'none';
// 隐藏连接线
summaryLine.style.height = '0';
// 切换文本显示
summaryText.style.display = 'block';
summaryTextFull.style.display = 'none';
// 更新摘要为第一步内容(不是当前步骤)
updateSummary(steps[0]);
// 重置所有步骤显示
document.querySelectorAll('.step-item').forEach(item => {
item.style.display = 'none';
item.classList.remove('instant', 'animated');
const line = item.querySelector('.step-line');
if (line) {
line.style.height = '0';
}
});
}
}
// 展开思考内容
function expandThinking(stepIndex) {
const thinkingContent = document.getElementById(`thinkingContent${stepIndex}`);
const thinkingContentFull = document.getElementById(`thinkingContentFull${stepIndex}`);
thinkingContent.style.display = 'none';
thinkingContentFull.style.display = 'block';
// 重新计算并更新竖线高度
setTimeout(() => {
updateLineHeight(stepIndex);
}, 50);
}
// 收起思考内容
function collapseThinking(stepIndex) {
const thinkingContent = document.getElementById(`thinkingContent${stepIndex}`);
const thinkingContentFull = document.getElementById(`thinkingContentFull${stepIndex}`);
thinkingContent.style.display = 'block';
thinkingContentFull.style.display = 'none';
// 重新计算并更新竖线高度
setTimeout(() => {
updateLineHeight(stepIndex);
}, 50);
}
// 重置演示
function resetDemo() {
currentStep = 0;
isExpanded = false;
demoRunning = false;
// 隐藏所有元素
document.getElementById('generatingPlaceholder').style.display = 'none';
const summaryWrapper = document.getElementById('summaryWrapper');
summaryWrapper.style.display = 'none';
summaryWrapper.classList.remove('running', 'expanded');
const summaryText = document.getElementById('summaryText');
const summaryTextFull = document.getElementById('summaryTextFull');
summaryText.style.display = 'block';
summaryTextFull.style.display = 'none';
const summaryLine = document.getElementById('summaryLine');
summaryLine.style.height = '0';
const stepsContainer = document.getElementById('stepsContainer');
stepsContainer.style.display = 'none';
stepsContainer.classList.remove('show');
const textOutput = document.getElementById('textOutput');
textOutput.style.display = 'none';
textOutput.classList.remove('show');
const textContent = textOutput.querySelector('.text-content');
if (textContent) {
textContent.innerHTML = `<p>根据我的搜索和分析2026年AI技术的主要发展趋势包括</p>
<ol>
<li><strong>多模态AI模型的普及</strong>能够同时处理文本、图像、音频等多种数据类型的AI模型将成为主流。</li>
<li><strong>AI安全性和可解释性</strong>随着AI应用的广泛部署确保AI系统的安全性和决策的可解释性变得越来越重要。</li>
<li><strong>边缘AI计算</strong>将AI计算能力部署到边缘设备实现更快的响应速度和更好的隐私保护。</li>
</ol>
<p>这些趋势将深刻影响各行各业的数字化转型进程。</p>`;
}
// 重置所有步骤
document.querySelectorAll('.step-item').forEach(item => {
item.style.display = 'none';
item.classList.remove('instant', 'animated');
const line = item.querySelector('.step-line');
if (line) {
line.style.height = '0';
}
});
// 重置思考内容
document.querySelectorAll('.thinking-content').forEach(item => {
item.style.display = 'block';
});
document.querySelectorAll('.thinking-content-full').forEach(item => {
item.style.display = 'none';
});
// 重置摘要文本
updateSummary(steps[0]);
}
// 获取图标SVG
function getIconSVG(iconType) {
const icons = {
brain: '<path d="M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2z"></path><path d="M12 6v6l4 2"></path>',
search: '<circle cx="11" cy="11" r="8"></circle><path d="m21 21-4.35-4.35"></path>',
terminal: '<polyline points="4 17 10 11 4 5"></polyline><line x1="12" y1="19" x2="20" y2="19"></line>'
};
return icons[iconType] || icons.brain;
}
// 工具函数:延迟
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 点击摘要包装器切换展开/折叠
document.getElementById('summaryWrapper').addEventListener('click', toggleExpand);