// exe-engine/tests/smoke/exe-engine-p1.test.js // EXE-Engine · Phase 1 冒烟测试 // PRJ-EXE-001 · Phase 1 · ZY-EXE-P1 // 版权:国作登字-2026-A-00037559 'use strict'; const { createEngine, ContextManager, Session, MultiModelExecutor, SchedulerV2, MonitorDashboard, QwenAdapter } = require('../../src/index'); let passed = 0; let failed = 0; function assert(condition, message) { if (condition) { passed++; // eslint-disable-next-line no-console console.log(` ✅ ${message}`); } else { failed++; // eslint-disable-next-line no-console console.error(` ❌ ${message}`); } } // eslint-disable-next-line no-console console.log('🔧 EXE-Engine Phase 1 冒烟测试\n'); const engine = createEngine(); // ── 测试 1: Phase 1 模块导出 ── // eslint-disable-next-line no-console console.log('── 测试 1: Phase 1 模块导出 ──'); assert(typeof ContextManager === 'function', 'ContextManager 是构造函数'); assert(typeof Session === 'function', 'Session 是构造函数'); assert(typeof MultiModelExecutor === 'function', 'MultiModelExecutor 是构造函数'); assert(typeof SchedulerV2 === 'function', 'SchedulerV2 是构造函数'); assert(typeof MonitorDashboard === 'function', 'MonitorDashboard 是构造函数'); assert(engine.contextManager instanceof ContextManager, 'engine.contextManager 已创建'); assert(engine.session instanceof Session, 'engine.session 已创建'); assert(engine.multiModelExecutor instanceof MultiModelExecutor, 'engine.multiModelExecutor 已创建'); assert(engine.scheduler instanceof SchedulerV2, 'engine.scheduler 已创建'); assert(engine.monitor instanceof MonitorDashboard, 'engine.monitor 已创建'); // ── 测试 2: ContextManager ── // eslint-disable-next-line no-console console.log('\n── 测试 2: ContextManager 上下文管理 ──'); const cm = engine.contextManager; const ctxId = cm.createContext('AG-ZY-01', 'sess-test-001', { repo: 'guanghulab' }); assert(typeof ctxId === 'string' && ctxId.startsWith('ctx-'), `创建上下文返回 ID: ${ctxId}`); const ctx = cm.getContext(ctxId); assert(ctx !== null, '获取上下文成功'); assert(ctx.agentId === 'AG-ZY-01', '上下文 agentId 正确'); assert(ctx.sessionId === 'sess-test-001', '上下文 sessionId 正确'); assert(ctx.data.repo === 'guanghulab', '上下文初始数据正确'); assert(ctx.status === 'active', '上下文初始状态为 active'); assert(Array.isArray(ctx.messages), '上下文 messages 是数组'); const updateOk = cm.updateContext(ctxId, { branch: 'main' }); assert(updateOk === true, '更新上下文成功'); assert(cm.getContext(ctxId).data.branch === 'main', '更新后数据正确'); const addMsgOk = cm.addMessage(ctxId, 'user', '你好'); assert(addMsgOk === true, '添加消息成功'); assert(cm.getContext(ctxId).messages.length === 1, '消息数量正确'); assert(cm.getContext(ctxId).messages[0].role === 'user', '消息角色正确'); const expireOk = cm.expireContext(ctxId); assert(expireOk === true, '过期上下文成功'); assert(cm.getContext(ctxId).status === 'expired', '过期后状态正确'); const contexts = cm.listContexts('AG-ZY-01'); assert(contexts.length >= 1, 'listContexts 返回结果'); cm.setGridDBPersistence({ mock: true }); assert(cm._gridDB !== null, 'Grid-DB 预留接口设置成功'); const notFoundCtx = cm.getContext('ctx-nonexistent'); assert(notFoundCtx === null, '不存在的上下文返回 null'); // ── 测试 3: Session 会话管理 ── // eslint-disable-next-line no-console console.log('\n── 测试 3: Session 会话管理 ──'); const sess = engine.session; const { sessionId, contextId } = sess.createSession('AG-ZY-01', { topic: '代码审查' }); assert(typeof sessionId === 'string' && sessionId.startsWith('sess-'), `创建会话: ${sessionId}`); assert(typeof contextId === 'string' && contextId.startsWith('ctx-'), `关联上下文: ${contextId}`); const sessObj = sess.getSession(sessionId); assert(sessObj !== null, '获取会话成功'); assert(sessObj.agentId === 'AG-ZY-01', '会话 agentId 正确'); assert(sessObj.status === 'active', '会话初始状态 active'); assert(sessObj.metadata.topic === '代码审查', '会话元数据正确'); const turnOk = sess.addTurn(sessionId, '帮我看看这段代码', '代码看起来没问题'); assert(turnOk === true, '添加轮次成功'); sess.addTurn(sessionId, '还有优化建议吗', '建议使用 const 替代 let'); const history = sess.getHistory(sessionId, 1); assert(history.length === 1, 'getHistory limit=1 返回 1 条'); assert(history[0].user === '还有优化建议吗', '历史最后一条消息正确'); const fullHistory = sess.getHistory(sessionId); assert(fullHistory.length === 2, '完整历史 2 条'); const endOk = sess.endSession(sessionId); assert(endOk === true, '结束会话成功'); assert(sess.getSession(sessionId).status === 'ended', '结束后状态为 ended'); const addAfterEnd = sess.addTurn(sessionId, 'test', 'test'); assert(addAfterEnd === false, '结束后不能添加轮次'); const sessions = sess.listSessions('AG-ZY-01'); assert(sessions.length >= 1, 'listSessions 返回结果'); // ── 测试 4: MultiModelExecutor ── // eslint-disable-next-line no-console console.log('\n── 测试 4: MultiModelExecutor 多模型执行器 ──'); const mme = engine.multiModelExecutor; const availModels = mme.getAvailableModels(); assert(Array.isArray(availModels), 'getAvailableModels 返回数组'); assert(availModels.length === 4, `可用模型 4 个 (实际: ${availModels.length})`); assert(availModels.includes('deepseek-v3'), '包含 deepseek-v3'); assert(availModels.includes('qwen-max'), '包含 qwen-max'); // ── 测试 5: SchedulerV2 ── // eslint-disable-next-line no-console console.log('\n── 测试 5: SchedulerV2 调度器 ──'); const sched = engine.scheduler; const t1 = sched.enqueue({ agentId: 'AG-ZY-01', priority: 'high', payload: { action: 'build' } }); assert(typeof t1 === 'string', `入队高优先级任务: ${t1}`); const t2 = sched.enqueue({ agentId: 'AG-ZY-01', priority: 'low', payload: { action: 'lint' } }); const t3 = sched.enqueue({ agentId: 'AG-SY-01', priority: 'normal', payload: { action: 'review' } }); const queue = sched.getQueue(); assert(queue.length === 3, '队列中 3 个任务'); assert(queue[0].priority === 'high', '高优先级排在前面'); const dequeued = sched.dequeue(); assert(dequeued !== null, '出队成功'); assert(dequeued.priority === 'high', '出队的是高优先级任务'); sched.complete(dequeued.taskId, { success: true }); const status = sched.getStatus(); assert(status.completed === 1, '已完成 1 个'); assert(status.pending === 2, '待处理 2 个'); // 依赖测试 const t4 = sched.enqueue({ taskId: 'task-dep-1', agentId: 'AG-ZY-01', priority: 'high', dependsOn: ['task-not-done'], payload: { action: 'deploy' } }); const depDequeue = sched.dequeue(); assert(depDequeue?.taskId !== 'task-dep-1', '依赖未满足的任务不出队'); // 标记失败测试 sched.fail('task-fail-test', '测试失败'); assert(sched.getStatus().failed === 1, 'fail 记录成功'); // ── 测试 6: MonitorDashboard ── // eslint-disable-next-line no-console console.log('\n── 测试 6: MonitorDashboard 监控仪表盘 ──'); const mon = engine.monitor; mon.recordMetric('request_count', 1, { model: 'deepseek-v3' }); mon.recordMetric('request_count', 1, { model: 'qwen-max' }); mon.recordMetric('latency_ms', 150, { model: 'deepseek-v3' }); mon.recordMetric('latency_ms', 200, { model: 'qwen-max' }); mon.recordMetric('tokens_used', 1500, {}); mon.recordMetric('error_count', 0, {}); const reqMetrics = mon.getMetrics('request_count'); assert(reqMetrics.length === 2, '获取 request_count 指标 2 条'); const latMetrics = mon.getMetrics('latency_ms'); assert(latMetrics.length === 2, '获取 latency_ms 指标 2 条'); const snapshot = mon.getSnapshot(); assert(typeof snapshot.qps === 'number', 'snapshot 包含 qps'); assert(typeof snapshot.avgLatency === 'number', 'snapshot 包含 avgLatency'); assert(typeof snapshot.totalTokens === 'number', 'snapshot 包含 totalTokens'); assert(typeof snapshot.errorRate === 'number', 'snapshot 包含 errorRate'); assert(snapshot.totalTokens === 1500, `totalTokens = 1500 (实际: ${snapshot.totalTokens})`); assert(snapshot.metricsCount === 6, `metricsCount = 6 (实际: ${snapshot.metricsCount})`); mon.resetMetrics(); assert(mon.getMetrics('request_count').length === 0, 'resetMetrics 清除成功'); // ── 测试 7: HLI Persona 路由 ── // eslint-disable-next-line no-console console.log('\n── 测试 7: HLI Persona 路由(Phase 1 实装) ──'); (async () => { const loadResult = await engine.router.handleStubRoute('/hli/persona/load'); assert(loadResult.statusCode === 200 || loadResult.statusCode === 400, `persona/load 返回 ${loadResult.statusCode}`); // 带参数调用 const personaStubs = engine.router.getHLIStubs().filter(s => s.path === '/hli/persona/load'); const loadHandler = personaStubs[0].handler; const loadRes = await loadHandler({ body: { persona_id: 'PER-ZY-01' } }); assert(loadRes.statusCode === 200, 'persona/load 加载铸渊成功'); assert(loadRes.body.persona_id === 'PER-ZY-01', '返回正确的 persona_id'); assert(loadRes.body.status === 'loaded', '状态为 loaded'); assert(loadRes.body.name === '铸渊', '人格体名称正确'); const switchStubs = engine.router.getHLIStubs().filter(s => s.path === '/hli/persona/switch'); const switchHandler = switchStubs[0].handler; const switchRes = await switchHandler({ body: { from_persona_id: 'PER-ZY-01', to_persona_id: 'PER-SY-01' } }); assert(switchRes.statusCode === 200, 'persona/switch 切换成功'); assert(switchRes.body.active_persona_id === 'PER-SY-01', '活跃人格体切换正确'); assert(switchRes.body.status === 'switched', '状态为 switched'); // ── 测试 8: HLI Dialogue 路由 ── // eslint-disable-next-line no-console console.log('\n── 测试 8: HLI Dialogue 路由(Phase 1 实装) ──'); const dialogueStubs = engine.router.getHLIStubs(); const sendHandler = dialogueStubs.find(s => s.path === '/hli/dialogue/send').handler; const sendRes = await sendHandler({ body: { session_id: 'test-sess', message: '你好', persona_id: 'PER-ZY-01' } }); assert(sendRes.statusCode === 200, 'dialogue/send 发送成功'); assert(typeof sendRes.body.reply === 'string', '返回 reply 字符串'); assert(sendRes.body.session_id === 'test-sess', '返回正确的 session_id'); assert(typeof sendRes.body.turn_id === 'string', '返回 turn_id'); const histHandler = dialogueStubs.find(s => s.path === '/hli/dialogue/history').handler; const histRes = await histHandler({ body: { session_id: 'test-sess' } }); assert(histRes.statusCode === 200, 'dialogue/history 查询成功'); assert(Array.isArray(histRes.body.turns), '返回 turns 数组'); assert(histRes.body.total >= 1, `历史记录 total >= 1 (实际: ${histRes.body.total})`); const streamHandler = dialogueStubs.find(s => s.path === '/hli/dialogue/stream').handler; const streamRes = await streamHandler({ body: { session_id: 'test-sess' } }); assert(streamRes.statusCode === 200, 'dialogue/stream 返回 200'); assert(streamRes.body.type === 'stream', 'stream 类型正确'); // ── 测试 9: HLI User 路由 ── // eslint-disable-next-line no-console console.log('\n── 测试 9: HLI User 路由(Phase 1 实装) ──'); const profileHandler = dialogueStubs.find(s => s.path === '/hli/user/profile').handler; const profileRes = await profileHandler({ body: { user_id: 'USR-001' } }); assert(profileRes.statusCode === 200, 'user/profile 查询成功'); assert(profileRes.body.user_id === 'USR-001', '返回正确的 user_id'); assert(profileRes.body.name === '冰朔', '用户名正确'); const updateHandler = dialogueStubs.find(s => s.path === '/hli/user/profile/update').handler; const updateRes = await updateHandler({ body: { user_id: 'USR-001', updates: { role: 'superadmin' } } }); assert(updateRes.statusCode === 200, 'user/profile/update 更新成功'); assert(updateRes.body.role === 'superadmin', '角色更新正确'); const notFoundRes = await profileHandler({ body: { user_id: 'USR-NONEXIST' } }); assert(notFoundRes.statusCode === 404, '不存在的用户返回 404'); const newUserRes = await updateHandler({ body: { user_id: 'USR-NEW', updates: { name: '新用户' } } }); assert(newUserRes.statusCode === 200, '更新不存在的用户自动创建'); assert(newUserRes.body.name === '新用户', '新用户名称正确'); // ── 测试 10: Qwen Adapter executeStream ── // eslint-disable-next-line no-console console.log('\n── 测试 10: QwenAdapter executeStream ──'); const qwAdapter = engine.adapters.get('qwen-max'); assert(typeof qwAdapter.executeStream === 'function', 'executeStream 方法存在'); // 验证 _resolveModel 增强 assert(qwAdapter._resolveModel('code_generation') === 'qwen-coder-plus-latest', '_resolveModel code_generation 正确'); assert(qwAdapter._resolveModel('text_processing') === 'qwen-max-latest', '_resolveModel text_processing 正确'); assert(qwAdapter._resolveModel('reasoning') === 'qwen-max', '_resolveModel reasoning 正确'); // ── 测试结果汇总 ── // eslint-disable-next-line no-console console.log('\n══════════════════════════════════════'); // eslint-disable-next-line no-console console.log(`🔧 EXE-Engine Phase 1 冒烟测试完成`); // eslint-disable-next-line no-console console.log(` ✅ 通过: ${passed}`); // eslint-disable-next-line no-console console.log(` ❌ 失败: ${failed}`); // eslint-disable-next-line no-console console.log(` 📊 总计: ${passed + failed}`); // eslint-disable-next-line no-console console.log('══════════════════════════════════════\n'); if (failed > 0) { process.exit(1); } })();