| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- 'use strict';
- const assert = require('assert/strict');
- const fs = require('fs');
- const os = require('os');
- const path = require('path');
- const { AgentWorkbenchDb } = require('../mcp/src/core/agent-workbench-db');
- const { AgentWorkbenchService } = require('../mcp/src/core/agent-workbench-service');
- const output = () => ({
- content: '已收到,我先按当前信息整理下一步。',
- confidence: 0.96,
- intent: '信息确认',
- reason: '恢复测试固定输出。',
- requiresHuman: false,
- profileUpdates: {},
- tasks: [],
- alerts: [],
- citations: [],
- toolTrace: [],
- });
- async function main() {
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'qiwei-generation-recovery-'));
- const db = new AgentWorkbenchDb(path.join(dir, 'workbench.db'), { globalPaused: false, defaultMode: 'autopilot' });
- let calls = 0;
- const sent = [];
- const service = new AgentWorkbenchService({
- db,
- agent: {
- modelClient: { isConfigured: () => true },
- async run() {
- calls += 1;
- if (calls === 1) throw new Error('fixture fatal generation failure');
- return output();
- },
- },
- qiwei: {
- isConfigured: () => true,
- async sendText(contactId, content) {
- sent.push({ contactId, content });
- return { isSendSuccess: true, msgServerId: `recovery-out-${sent.length}` };
- },
- },
- config: {
- accountKey: 'generation-recovery-fixture',
- agent: {
- provider: 'fixture', model: 'fixture', apiKey: 'fixture', generationRetryAttempts: 1, generationRetryBaseMs: 0, qualityPassScore: 60,
- generationRecovery: { pendingAgeMs: 5000, retryCooldownMs: 5000, maxAgeMs: 3600000 },
- },
- qiwei: { allowedSenders: ['recovery-contact'] },
- memory: { enabled: false },
- },
- });
- try {
- const queued = await service.ingestInbound({
- externalId: 'generation-recovery-in-1',
- contactId: 'recovery-contact',
- contactName: '恢复测试',
- content: '请介绍一下服务',
- }, { awaitGeneration: false, allowAutoSend: true });
- assert.equal(queued.status, 'generation_queued');
- for (let i = 0; i < 50 && !db.listAudit(100).some(item => item.action === 'agent_failed'); i += 1) {
- await new Promise(resolve => setTimeout(resolve, 5));
- }
- const conversation = db.getConversationByContactId('recovery-contact');
- const inbound = db.getLatestInbound(conversation.id);
- assert.equal(inbound.status, 'generation_failed', '后台失败必须留下可恢复状态');
- assert.equal(sent.length, 0);
- const recovered = await service.recoverPendingGenerations('smoke:recovery');
- assert.equal(recovered.recovered, 1, '下一轮恢复必须认领并处理失败入站');
- assert.equal(sent.length, 1, '恢复成功后必须只发送一次');
- assert.equal(db.getMessage(inbound.id).status, 'reply_sent');
- assert.equal(db.listAudit(100).some(item => item.action === 'agent_generation_recovery_attempt'), true);
- assert.equal(db.listAudit(100).some(item => item.action === 'agent_generation_recovery_completed'), true);
- process.stdout.write(JSON.stringify({ status: 'passed', checks: [
- '异步生成失败持久化为 generation_failed',
- '下一轮恢复扫描重新生成并自动发送',
- '恢复链路保持单次出站与审计记录',
- ] }, null, 2) + '\n');
- } finally {
- service.stopBackgroundWorkers();
- db.close();
- fs.rmSync(dir, { recursive: true, force: true });
- }
- }
- main().catch(error => {
- process.stderr.write(JSON.stringify({ status: 'failed', message: error.message, stack: error.stack }, null, 2) + '\n');
- process.exitCode = 1;
- });
|