修改了数据集上传,修改了模型配置页面
This commit is contained in:
@@ -34,85 +34,6 @@
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<!-- 网格布局样式 -->
|
||||
<style>
|
||||
/* 2x2网格布局 - 通用 */
|
||||
.grid-2x2 {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
grid-template-rows: repeat(2, auto) !important;
|
||||
gap: 1rem !important;
|
||||
}
|
||||
|
||||
/* 1x4网格布局 - 用于模型选择区域 */
|
||||
.grid-1x4 {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(4, 1fr) !important;
|
||||
grid-template-rows: 1 !important;
|
||||
gap: 1rem !important;
|
||||
}
|
||||
|
||||
/* 结果展示区域的2x2布局 */
|
||||
#comparisonResults .grid-2x2 {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
grid-template-rows: repeat(2, auto) !important;
|
||||
gap: 1rem !important;
|
||||
}
|
||||
|
||||
/* 模型选择区域的1x4布局 */
|
||||
#compare-config-section .grid-1x4 {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(4, 1fr) !important;
|
||||
grid-template-rows: 1 !important;
|
||||
gap: 1rem !important;
|
||||
}
|
||||
|
||||
/* 确保结果展示的卡片是网格项 */
|
||||
#comparisonResults .grid-2x2 > div {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 确保模型输出卡片正确排列 */
|
||||
#comparisonResults .grid-2x2 > div:nth-child(1) { grid-row: 1; grid-column: 1; } /* 模型A - 左上 */
|
||||
#comparisonResults .grid-2x2 > div:nth-child(2) { grid-row: 1; grid-column: 2; } /* 模型B - 右上 */
|
||||
#comparisonResults .grid-2x2 > div:nth-child(3) { grid-row: 2; grid-column: 1; } /* 模型C - 左下 */
|
||||
#comparisonResults .grid-2x2 > div:nth-child(4) { grid-row: 2; grid-column: 2; } /* 模型D - 右下 */
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 1200px) {
|
||||
#compare-config-section .grid-1x4 {
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
grid-template-rows: repeat(2, auto) !important;
|
||||
gap: 0.75rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
#comparisonResults .grid-2x2 {
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
grid-template-rows: repeat(2, auto) !important;
|
||||
gap: 0.75rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
#compare-config-section .grid-1x4 {
|
||||
grid-template-columns: repeat(1, 1fr) !important;
|
||||
grid-template-rows: repeat(4, auto) !important;
|
||||
gap: 0.75rem !important;
|
||||
}
|
||||
#comparisonResults .grid-2x2 {
|
||||
grid-template-columns: repeat(1, 1fr) !important;
|
||||
grid-template-rows: repeat(4, auto) !important;
|
||||
gap: 0.75rem !important;
|
||||
}
|
||||
#comparisonResults .grid-2x2 > div:nth-child(1) { grid-row: 1; grid-column: 1; }
|
||||
#comparisonResults .grid-2x2 > div:nth-child(2) { grid-row: 2; grid-column: 1; }
|
||||
#comparisonResults .grid-2x2 > div:nth-child(3) { grid-row: 3; grid-column: 1; }
|
||||
#comparisonResults .grid-2x2 > div:nth-child(4) { grid-row: 4; grid-column: 1; }
|
||||
}
|
||||
</style>
|
||||
<style type="text/tailwindcss">
|
||||
@layer utilities {
|
||||
.gradient-blue {
|
||||
@@ -515,7 +436,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 模型选择区 -->
|
||||
<div class="grid-1x4 mb-4">
|
||||
<div class="grid grid-cols-2 gap-4 mb-4">
|
||||
<!-- 模型A -->
|
||||
<div class="bg-gray-50 rounded-xl p-3 border-2 border-dashboard-primary/20">
|
||||
<h3 class="text-lg font-semibold text-dashboard-text mb-3 flex items-center">
|
||||
@@ -559,50 +480,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模型C -->
|
||||
<div class="bg-gray-50 rounded-xl p-3 border-2 border-gray-300 opacity-50 transition-opacity hover:opacity-100">
|
||||
<h3 class="text-lg font-semibold text-dashboard-text mb-3 flex items-center">
|
||||
<span class="w-6 h-6 rounded-full bg-gray-500 text-white flex items-center justify-center text-sm font-bold mr-2">C</span>
|
||||
模型 C
|
||||
</h3>
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-dashboard-text mb-2">选择模型</label>
|
||||
<select id="modelCSelect" class="w-full px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-dashboard-primary/20">
|
||||
<option value="">请选择模型C (可选)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-dashboard-text mb-2">模型信息</label>
|
||||
<div id="modelCInfo" class="text-sm text-dashboard-textLight bg-white p-3 rounded-lg border border-gray-200">
|
||||
请先选择模型
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模型D -->
|
||||
<div class="bg-gray-50 rounded-xl p-3 border-2 border-gray-300 opacity-50 transition-opacity hover:opacity-100">
|
||||
<h3 class="text-lg font-semibold text-dashboard-text mb-3 flex items-center">
|
||||
<span class="w-6 h-6 rounded-full bg-gray-500 text-white flex items-center justify-center text-sm font-bold mr-2">D</span>
|
||||
模型 D
|
||||
</h3>
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-dashboard-text mb-2">选择模型</label>
|
||||
<select id="modelDSelect" class="w-full px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-dashboard-primary/20">
|
||||
<option value="">请选择模型D (可选)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-dashboard-text mb-2">模型信息</label>
|
||||
<div id="modelDInfo" class="text-sm text-dashboard-textLight bg-white p-3 rounded-lg border border-gray-200">
|
||||
请先选择模型
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 测试输入区 -->
|
||||
@@ -653,7 +530,7 @@
|
||||
<span class="font-semibold">显示配置</span>
|
||||
</button>
|
||||
<div id="comparisonResults" class="hidden">
|
||||
<div class="grid-2x2">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<!-- 模型A输出 -->
|
||||
<div class="bg-white rounded-xl p-4 border border-gray-200">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
@@ -707,59 +584,18 @@
|
||||
<div>Token数: <span id="modelBTokens">-</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模型C输出 -->
|
||||
<div class="bg-white rounded-xl p-4 border border-gray-200 hidden" id="modelCOutputCard">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="text-lg font-semibold text-dashboard-text flex items-center">
|
||||
<span class="w-6 h-6 rounded-full bg-gray-500 text-white flex items-center justify-center text-sm font-bold mr-2">C</span>
|
||||
<span id="modelCName">模型C</span>
|
||||
</h3>
|
||||
<div class="flex space-x-2">
|
||||
<button onclick="copyToClipboard('modelCOutput')" class="text-dashboard-textLight hover:text-dashboard-primary">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<div class="text-xs text-dashboard-textLight mb-2">输出结果</div>
|
||||
<div id="modelCOutput" class="bg-gray-50 p-4 rounded-lg border border-gray-200" style="min-height: 300px; max-height: 600px; overflow-y: auto;">
|
||||
<div class="text-dashboard-textLight">等待对比结果...</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-xs text-dashboard-textLight">
|
||||
<div>响应时间: <span id="modelCTime">-</span></div>
|
||||
<div>Token数: <span id="modelCTokens">-</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模型D输出 -->
|
||||
<div class="bg-white rounded-xl p-4 border border-gray-200 hidden" id="modelDOutputCard">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="text-lg font-semibold text-dashboard-text flex items-center">
|
||||
<span class="w-6 h-6 rounded-full bg-gray-500 text-white flex items-center justify-center text-sm font-bold mr-2">D</span>
|
||||
<span id="modelDName">模型D</span>
|
||||
</h3>
|
||||
<div class="flex space-x-2">
|
||||
<button onclick="copyToClipboard('modelDOutput')" class="text-dashboard-textLight hover:text-dashboard-primary">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<div class="text-xs text-dashboard-textLight mb-2">输出结果</div>
|
||||
<div id="modelDOutput" class="bg-gray-50 p-4 rounded-lg border border-gray-200" style="min-height: 300px; max-height: 600px; overflow-y: auto;">
|
||||
<div class="text-dashboard-textLight">等待对比结果...</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-xs text-dashboard-textLight">
|
||||
<div>响应时间: <span id="modelDTime">-</span></div>
|
||||
<div>Token数: <span id="modelDTokens">-</span></div>
|
||||
</div>
|
||||
<!-- 对比分析 -->
|
||||
<div class="mt-4 bg-white rounded-xl p-4 border border-gray-200">
|
||||
<h3 class="text-lg font-semibold text-dashboard-text mb-3 flex items-center">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
|
||||
</svg>
|
||||
对比分析
|
||||
</h3>
|
||||
<div id="comparisonAnalysis" class="space-y-3">
|
||||
<div class="text-dashboard-textLight">对比结果将在这里显示...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2046,9 +1882,7 @@
|
||||
|
||||
let comparisonModels = {
|
||||
modelA: null,
|
||||
modelB: null,
|
||||
modelC: null,
|
||||
modelD: null
|
||||
modelB: null
|
||||
};
|
||||
|
||||
// 初始化模型对比页面
|
||||
@@ -2087,16 +1921,12 @@
|
||||
function loadComparisonModelList() {
|
||||
const modelASelect = document.getElementById('modelASelect');
|
||||
const modelBSelect = document.getElementById('modelBSelect');
|
||||
const modelCSelect = document.getElementById('modelCSelect');
|
||||
const modelDSelect = document.getElementById('modelDSelect');
|
||||
|
||||
if (!modelASelect || !modelBSelect) return;
|
||||
|
||||
// 清空现有选项
|
||||
modelASelect.innerHTML = '<option value="">请选择模型A</option>';
|
||||
modelBSelect.innerHTML = '<option value="">请选择模型B</option>';
|
||||
if (modelCSelect) modelCSelect.innerHTML = '<option value="">请选择模型C (可选)</option>';
|
||||
if (modelDSelect) modelDSelect.innerHTML = '<option value="">请选择模型D (可选)</option>';
|
||||
|
||||
// 添加模型选项
|
||||
modelConfigs.forEach((model, index) => {
|
||||
@@ -2109,20 +1939,6 @@
|
||||
optionB.value = index;
|
||||
optionB.textContent = `${model.name} (${getProviderName(model.provider)})`;
|
||||
modelBSelect.appendChild(optionB);
|
||||
|
||||
if (modelCSelect) {
|
||||
const optionC = document.createElement('option');
|
||||
optionC.value = index;
|
||||
optionC.textContent = `${model.name} (${getProviderName(model.provider)})`;
|
||||
modelCSelect.appendChild(optionC);
|
||||
}
|
||||
|
||||
if (modelDSelect) {
|
||||
const optionD = document.createElement('option');
|
||||
optionD.value = index;
|
||||
optionD.textContent = `${model.name} (${getProviderName(model.provider)})`;
|
||||
modelDSelect.appendChild(optionD);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2130,8 +1946,6 @@
|
||||
function setupComparisonEventListeners() {
|
||||
const modelASelect = document.getElementById('modelASelect');
|
||||
const modelBSelect = document.getElementById('modelBSelect');
|
||||
const modelCSelect = document.getElementById('modelCSelect');
|
||||
const modelDSelect = document.getElementById('modelDSelect');
|
||||
const testTemperature = document.getElementById('testTemperature');
|
||||
|
||||
if (modelASelect) {
|
||||
@@ -2142,14 +1956,6 @@
|
||||
modelBSelect.onchange = () => handleModelSelection('B', modelBSelect.value);
|
||||
}
|
||||
|
||||
if (modelCSelect) {
|
||||
modelCSelect.onchange = () => handleModelSelection('C', modelCSelect.value);
|
||||
}
|
||||
|
||||
if (modelDSelect) {
|
||||
modelDSelect.onchange = () => handleModelSelection('D', modelDSelect.value);
|
||||
}
|
||||
|
||||
if (testTemperature) {
|
||||
testTemperature.oninput = (e) => {
|
||||
document.getElementById('tempDisplay').textContent = e.target.value;
|
||||
@@ -2202,27 +2008,22 @@
|
||||
function checkModelSelection() {
|
||||
const modelASelect = document.getElementById('modelASelect');
|
||||
const modelBSelect = document.getElementById('modelBSelect');
|
||||
const modelCSelect = document.getElementById('modelCSelect');
|
||||
const modelDSelect = document.getElementById('modelDSelect');
|
||||
|
||||
// 获取所有已选择的模型索引
|
||||
const selected = [];
|
||||
if (modelASelect && modelASelect.value) selected.push(modelASelect.value);
|
||||
if (modelBSelect && modelBSelect.value) selected.push(modelBSelect.value);
|
||||
if (modelCSelect && modelCSelect.value) selected.push(modelCSelect.value);
|
||||
if (modelDSelect && modelDSelect.value) selected.push(modelDSelect.value);
|
||||
if (modelASelect && modelBSelect) {
|
||||
// 禁用已选择的模型
|
||||
const selectedA = modelASelect.value;
|
||||
const selectedB = modelBSelect.value;
|
||||
|
||||
// 为每个下拉框禁用已选择的模型
|
||||
const selects = [modelASelect, modelBSelect, modelCSelect, modelDSelect];
|
||||
selects.forEach(select => {
|
||||
if (!select) return;
|
||||
Array.from(select.options).forEach((option, index) => {
|
||||
Array.from(modelASelect.options).forEach((option, index) => {
|
||||
if (index === 0) return; // 跳过第一个选项
|
||||
const optionValue = index.toString();
|
||||
// 如果该选项在其他下拉框中被选中,则禁用
|
||||
option.disabled = selected.includes(optionValue);
|
||||
option.disabled = index.toString() === selectedB;
|
||||
});
|
||||
});
|
||||
|
||||
Array.from(modelBSelect.options).forEach((option, index) => {
|
||||
if (index === 0) return; // 跳过第一个选项
|
||||
option.disabled = index.toString() === selectedA;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 折叠配置区
|
||||
@@ -2322,22 +2123,15 @@
|
||||
|
||||
// 运行模型对比
|
||||
async function runModelComparison() {
|
||||
const modelA = comparisonModels.modelA;
|
||||
const modelB = comparisonModels.modelB;
|
||||
const prompt = document.getElementById('testPrompt').value.trim();
|
||||
const temperature = parseFloat(document.getElementById('testTemperature').value);
|
||||
const maxTokens = parseInt(document.getElementById('testMaxTokens').value);
|
||||
|
||||
// 获取所有选择的模型
|
||||
const selectedModels = [];
|
||||
for (let modelType of ['A', 'B', 'C', 'D']) {
|
||||
const model = comparisonModels[`model${modelType}`];
|
||||
if (model) {
|
||||
selectedModels.push({ model, modelType });
|
||||
}
|
||||
}
|
||||
|
||||
// 验证输入
|
||||
if (selectedModels.length < 2) {
|
||||
alert('请至少选择两个模型进行对比');
|
||||
if (!modelA || !modelB) {
|
||||
alert('请选择两个模型进行对比');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2353,37 +2147,22 @@
|
||||
// 折叠配置区
|
||||
collapseConfigSection();
|
||||
|
||||
// 更新模型名称
|
||||
document.getElementById('modelAName').textContent = modelA.name;
|
||||
document.getElementById('modelBName').textContent = modelB.name;
|
||||
|
||||
// 重置输出区域
|
||||
resetOutputAreas();
|
||||
|
||||
// 显示已选择模型的流式输出状态,并显示/隐藏对应的卡片
|
||||
selectedModels.forEach(({ model, modelType }) => {
|
||||
// 更新模型名称
|
||||
const nameElement = document.getElementById(`model${modelType}Name`);
|
||||
if (nameElement) {
|
||||
nameElement.textContent = model.name;
|
||||
}
|
||||
// 显示流式输出状态
|
||||
const modelAOutput = document.getElementById('modelAOutput');
|
||||
const modelBOutput = document.getElementById('modelBOutput');
|
||||
|
||||
// 显示对应的输出卡片
|
||||
const outputCard = document.getElementById(`model${modelType}OutputCard`);
|
||||
if (outputCard) {
|
||||
outputCard.classList.remove('hidden');
|
||||
}
|
||||
|
||||
// 显示流式输出状态
|
||||
const outputElement = document.getElementById(`model${modelType}Output`);
|
||||
if (outputElement) {
|
||||
outputElement.innerHTML = '<div class="text-dashboard-text"><span class="animate-pulse">正在生成中...</span></div>';
|
||||
}
|
||||
});
|
||||
|
||||
// 隐藏未选择模型的输出卡片
|
||||
for (let modelType of ['C', 'D']) {
|
||||
const model = comparisonModels[`model${modelType}`];
|
||||
const outputCard = document.getElementById(`model${modelType}OutputCard`);
|
||||
if (outputCard && !model) {
|
||||
outputCard.classList.add('hidden');
|
||||
}
|
||||
if (modelAOutput) {
|
||||
modelAOutput.innerHTML = '<div class="text-dashboard-text"><span class="animate-pulse">正在生成中...</span></div>';
|
||||
}
|
||||
if (modelBOutput) {
|
||||
modelBOutput.innerHTML = '<div class="text-dashboard-text"><span class="animate-pulse">正在生成中...</span></div>';
|
||||
}
|
||||
|
||||
// 开始对比
|
||||
@@ -2393,44 +2172,51 @@
|
||||
|
||||
try {
|
||||
// 创建流式显示回调
|
||||
const streamingCache = {};
|
||||
const onChunkCallbacks = {};
|
||||
const modelPromises = [];
|
||||
const streamingCache = {
|
||||
'A': { output: '', responseTime: 0, streaming: false },
|
||||
'B': { output: '', responseTime: 0, streaming: false }
|
||||
};
|
||||
|
||||
// 为每个选择的模型创建回调和Promise
|
||||
selectedModels.forEach(({ model, modelType }) => {
|
||||
streamingCache[modelType] = { output: '', responseTime: 0, streaming: false };
|
||||
const onChunkA = (chunk) => {
|
||||
streamingCache['A'].output = chunk.content;
|
||||
streamingCache['A'].responseTime = Date.now();
|
||||
streamingCache['A'].streaming = true;
|
||||
displayStreamingModelResult('A', streamingCache['A']);
|
||||
};
|
||||
|
||||
onChunkCallbacks[modelType] = (chunk) => {
|
||||
streamingCache[modelType].output = chunk.content;
|
||||
streamingCache[modelType].responseTime = Date.now();
|
||||
streamingCache[modelType].streaming = true;
|
||||
displayStreamingModelResult(modelType, streamingCache[modelType]);
|
||||
};
|
||||
const onChunkB = (chunk) => {
|
||||
streamingCache['B'].output = chunk.content;
|
||||
streamingCache['B'].responseTime = Date.now();
|
||||
streamingCache['B'].streaming = true;
|
||||
displayStreamingModelResult('B', streamingCache['B']);
|
||||
};
|
||||
|
||||
// 创建模型调用Promise
|
||||
const promise = withTimeout(
|
||||
callRealModel(model, prompt, temperature, maxTokens, model.streaming ? onChunkCallbacks[modelType] : null),
|
||||
60000
|
||||
);
|
||||
modelPromises.push({ promise, modelType });
|
||||
});
|
||||
// 并行运行两个模型(带超时控制)
|
||||
const [resultA, resultB] = await Promise.allSettled([
|
||||
withTimeout(callRealModel(modelA, prompt, temperature, maxTokens, modelA.streaming ? onChunkA : null), 60000), // 60秒超时
|
||||
withTimeout(callRealModel(modelB, prompt, temperature, maxTokens, modelB.streaming ? onChunkB : null), 60000) // 60秒超时
|
||||
]);
|
||||
|
||||
// 并行运行所有模型
|
||||
const results = await Promise.allSettled(modelPromises.map(item => item.promise));
|
||||
|
||||
// 处理所有模型结果
|
||||
results.forEach((result, index) => {
|
||||
const modelType = modelPromises[index].modelType;
|
||||
|
||||
if (result.status === 'fulfilled') {
|
||||
if (!result.value.streaming) {
|
||||
displayModelResult(modelType, result.value);
|
||||
}
|
||||
} else {
|
||||
displayModelError(modelType, result.reason);
|
||||
// 处理模型A结果
|
||||
if (resultA.status === 'fulfilled') {
|
||||
if (!resultA.value.streaming) {
|
||||
displayModelResult('A', resultA.value);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
displayModelError('A', resultA.reason);
|
||||
}
|
||||
|
||||
// 处理模型B结果
|
||||
if (resultB.status === 'fulfilled') {
|
||||
if (!resultB.value.streaming) {
|
||||
displayModelResult('B', resultB.value);
|
||||
}
|
||||
} else {
|
||||
displayModelError('B', resultB.reason);
|
||||
}
|
||||
|
||||
// 生成对比分析
|
||||
generateComparisonAnalysis(modelA, modelB);
|
||||
|
||||
} catch (error) {
|
||||
console.error('对比过程中出错:', error);
|
||||
@@ -2474,23 +2260,18 @@
|
||||
// 检查是否启用流式输出
|
||||
const contentType = response.headers.get('content-type');
|
||||
const isStreaming = contentType?.includes('text/plain');
|
||||
console.log('[流式调试] Content-Type:', contentType);
|
||||
console.log('[流式调试] isStreaming:', isStreaming);
|
||||
console.log('[流式调试] onChunk:', onChunk);
|
||||
|
||||
if (isStreaming) {
|
||||
// 流式处理
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let fullContent = '';
|
||||
let chunkCount = 0;
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
|
||||
const chunk = decoder.decode(value);
|
||||
console.log('[流式调试] 收到数据块:', chunk);
|
||||
const lines = chunk.split('\n');
|
||||
|
||||
for (const line of lines) {
|
||||
@@ -2500,14 +2281,11 @@
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(data);
|
||||
console.log('[流式调试] 解析数据:', parsed);
|
||||
if (parsed.content !== undefined) {
|
||||
if (parsed.content) {
|
||||
fullContent += parsed.content;
|
||||
chunkCount++;
|
||||
// 调用回调函数更新UI
|
||||
if (onChunk) {
|
||||
console.log('[流式调试] 调用回调函数, 当前内容长度:', fullContent.length);
|
||||
onChunk({
|
||||
content: fullContent,
|
||||
delta: parsed.content,
|
||||
@@ -2516,12 +2294,11 @@
|
||||
}
|
||||
}
|
||||
if (parsed.done) {
|
||||
console.log('[流式调试] 流式输出完成, 总块数:', chunkCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[流式调试] 解析错误:', e);
|
||||
// 忽略解析错误
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2654,8 +2431,53 @@
|
||||
tokensElement.textContent = '-';
|
||||
}
|
||||
});
|
||||
|
||||
const analysisElement = document.getElementById('comparisonAnalysis');
|
||||
if (analysisElement) {
|
||||
analysisElement.innerHTML = '<div class="text-dashboard-textLight">正在分析对比结果...</div>';
|
||||
}
|
||||
}
|
||||
|
||||
// 生成对比分析
|
||||
function generateComparisonAnalysis(modelA, modelB) {
|
||||
const analysisElement = document.getElementById('comparisonAnalysis');
|
||||
if (!analysisElement) return;
|
||||
|
||||
const analysis = [
|
||||
{
|
||||
title: '响应速度',
|
||||
content: '两个模型的响应时间对比分析'
|
||||
},
|
||||
{
|
||||
title: '回答质量',
|
||||
content: '基于内容完整性、准确性和有用性的评估'
|
||||
},
|
||||
{
|
||||
title: '语言风格',
|
||||
content: '分析两个模型的语言表达方式和风格特点'
|
||||
},
|
||||
{
|
||||
title: '详细程度',
|
||||
content: '比较回答的详细程度和信息密度'
|
||||
},
|
||||
{
|
||||
title: '总体评价',
|
||||
content: '综合两个模型在本次测试中的表现'
|
||||
}
|
||||
];
|
||||
|
||||
let analysisHTML = '';
|
||||
analysis.forEach(item => {
|
||||
analysisHTML += `
|
||||
<div class="border-l-4 border-dashboard-primary pl-4">
|
||||
<h4 class="font-semibold text-dashboard-text mb-1">${item.title}</h4>
|
||||
<p class="text-sm text-dashboard-textLight">${item.content}</p>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
analysisElement.innerHTML = analysisHTML;
|
||||
}
|
||||
|
||||
// 复制到剪贴板
|
||||
function copyToClipboard(elementId) {
|
||||
|
||||
Reference in New Issue
Block a user