Files
bigwo/mcp-server-ssh/e2e_test.cjs

88 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const https = require('https');
const BASE = 'https://demo.tensorgrove.com.cn';
function post(path, body) {
return new Promise((resolve, reject) => {
const url = new URL(path, BASE);
const data = JSON.stringify(body);
const req = https.request(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) },
timeout: 60000,
}, (res) => {
let chunks = '';
res.on('data', (d) => chunks += d);
res.on('end', () => {
try { resolve(JSON.parse(chunks)); } catch { resolve(chunks); }
});
});
req.on('error', reject);
req.on('timeout', () => { req.destroy(); reject(new Error('timeout')); });
req.write(data);
req.end();
});
}
const TESTS = [
{ q: '我们公司的产品有哪些', expect: 'kb', desc: '泛产品查询' },
{ q: '基础三合一是什么', expect: 'kb', desc: '基础三合一' },
{ q: '火炉原理是什么', expect: 'kb', desc: '火炉原理' },
{ q: '一程系统的基础三合一是什么', expect: 'kb', desc: '一程系统基础三合一' },
{ q: '我们公司卖手机和平板吗', expect: 'chat', desc: '手机平板(应走Coze)' },
];
async function runTests() {
// Create a session first
let sessionId;
try {
const startRes = await post('/api/chat/start', { userId: 'e2e_test_' + Date.now() });
sessionId = startRes.sessionId;
console.log('Session:', sessionId);
} catch (e) {
console.error('Failed to create session:', e.message);
return;
}
const results = [];
for (const test of TESTS) {
try {
const sid = 'e2e_' + Date.now() + '_' + Math.random().toString(36).slice(2, 6);
await post('/api/chat/start', { sessionId: sid });
const res = await post('/api/chat/send', { sessionId: sid, message: test.q });
const reply = (res.data && res.data.content) || res.reply || '';
const replyShort = reply.slice(0, 100);
// Check for hallucination indicators
const hasHallucination = /(手机|平板|笔记本|智能手表|护肤品|彩妆|香水|化妆品|电视|冰箱|洗衣机)/i.test(reply);
const hasPMContent = /(PM|FitLine|细胞营养|Activize|Basics|Restorate|NTC|火炉|阿育吠陀|一成系统|基础套装|大白|小红|小白|儿童倍适|营养)/i.test(reply);
let status = '✅';
if (test.expect === 'kb' && hasHallucination) status = '❌幻觉';
else if (test.expect === 'kb' && !hasPMContent) status = '⚠无PM内容';
results.push({ desc: test.desc, q: test.q, status, reply: replyShort });
console.log(`${status} [${test.desc}] ${test.q}${replyShort}`);
} catch (e) {
results.push({ desc: test.desc, q: test.q, status: '❌ERROR', reply: e.message });
console.log(`❌ [${test.desc}] ${test.q} → ERROR: ${e.message}`);
}
}
console.log('\n=== 测试总结 ===');
const pass = results.filter(r => r.status === '✅').length;
const warn = results.filter(r => r.status.startsWith('⚠️')).length;
const fail = results.filter(r => r.status.startsWith('❌')).length;
console.log(`通过: ${pass}, 警告: ${warn}, 失败: ${fail}, 总计: ${results.length}`);
if (warn + fail > 0) {
console.log('\n=== 问题详情 ===');
results.filter(r => r.status !== '✅').forEach(r => {
console.log(`${r.status} [${r.desc}] ${r.q}`);
console.log(` 回答: ${r.reply}`);
});
}
}
runTests().catch(e => console.error('Fatal:', e));