import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import test from 'node:test'; import { classifyWechatIntent, isPageGenerateIntent } from './intent/classifier.mjs'; import { resolveWechatSessionAction } from './intent/session-action.mjs'; import { filterSendableHtmlArtifacts, isStubPublicHtmlContent, selectSendableHtmlArtifacts, verifyPageArtifactContent, } from './verify/page-artifact.mjs'; import { guardScheduleConfirmationReply, looksLikeScheduleConfirmation } from './handlers/schedule-guard.mjs'; import { resolvePageGenerateOutcome } from './handlers/page-generate.mjs'; import { buildGreetingText, resolveSyncReply } from './handlers/sync-replies.mjs'; import { buildWechatAgentPrompt } from './prompts/chat-general.mjs'; import { hasMindspaceCoverMeta, hasPlatformBrandMarker, hasShareDescription, verifyArtifactSharePreview, verifySharePreviewMeta, } from './verify/share-preview.mjs'; test('classifyWechatIntent detects page.generate', () => { const intent = classifyWechatIntent({ msgType: 'text', agentText: '帮我生成一个唐诗页面,放一首诗', }); assert.equal(intent.kind, 'page.generate'); assert.match(intent.topic, /唐诗页面/); assert.equal(isPageGenerateIntent({ msgType: 'text', agentText: intent.topic }), true); }); test('classifyWechatIntent detects session.reset', () => { assert.equal(classifyWechatIntent({ msgType: 'text', agentText: '换话题' }).kind, 'session.reset'); assert.equal(classifyWechatIntent({ msgType: 'text', agentText: '换新会话' }).kind, 'session.reset'); }); test('resolveWechatSessionAction recognizes natural new-session expressions', async () => { for (const text of ['换新会话', '新开一个会话', '我们重新开始吧', '从头来']) { const result = await resolveWechatSessionAction(text); assert.equal(result.action, 'reset', text); } }); test('resolveWechatSessionAction separates ignore-context from reset', async () => { assert.equal((await resolveWechatSessionAction('不要参考刚才关于医联体的内容')).action, 'ignore_previous'); assert.equal((await resolveWechatSessionAction('继续刚才的话题')).action, 'continue'); }); test('resolveWechatSessionAction uses an injected semantic classifier for unclear text', async () => { const result = await resolveWechatSessionAction('我们换个思路聊', { semanticClassifier: async () => ({ action: 'reset', confidence: 0.88, reason: '新对话意图' }), }); assert.equal(result.action, 'reset'); assert.equal(result.source, 'semantic_model'); }); test('selectSendableHtmlArtifacts never returns stub html', () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'wechat-stub-')); const stubPath = path.join(dir, 'tang-poem.html'); fs.writeFileSync( stubPath, '服务号自动补出简版页面', 'utf8', ); const realPath = path.join(dir, 'real.html'); fs.writeFileSync( realPath, `
TKMind · 智趣
' : ''; fs.writeFileSync( file, ` ${coverMeta}TKMind · 智趣
'; assert.equal(verifySharePreviewMeta(withAll).ok, true); assert.equal(verifySharePreviewMeta('').ok, false); assert.equal(hasMindspaceCoverMeta(withAll), true); assert.equal(hasShareDescription(withAll), true); assert.equal(hasPlatformBrandMarker(withAll), true); }); test('resolvePageGenerateOutcome fails when html lacks share preview meta', () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'wechat-preview-')); const file = path.join(dir, 'page.html'); writePreviewReadyHtml(file, { withCover: false }); const outcome = resolvePageGenerateOutcome({ reply: { text: '页面已生成 https://m.tkmind.cn/MindSpace/u/public/page.html' }, confirmedArtifacts: [{ localPath: file, relativePath: 'public/page.html' }], }); assert.equal(outcome.action, 'fail'); assert.equal(outcome.reason, 'missing_mindspace_cover'); assert.match(outcome.failureText, /预览元数据/); }); test('resolvePageGenerateOutcome fails when html lacks platform brand marker', () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'wechat-brand-')); const file = path.join(dir, 'page.html'); writePreviewReadyHtml(file, { withBrand: false }); const outcome = resolvePageGenerateOutcome({ reply: { text: '页面已生成' }, confirmedArtifacts: [{ localPath: file, relativePath: 'public/page.html' }], }); assert.equal(outcome.action, 'fail'); assert.equal(outcome.reason, 'missing_platform_brand'); assert.match(outcome.failureText, /平台品牌/); }); test('resolvePageGenerateOutcome sends when share preview meta is present', () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'wechat-preview-ok-')); const file = path.join(dir, 'page.html'); writePreviewReadyHtml(file); const artifact = { localPath: file, relativePath: 'public/page.html' }; assert.equal(verifyArtifactSharePreview(artifact).ok, true); const outcome = resolvePageGenerateOutcome({ reply: { text: '页面已生成' }, confirmedArtifacts: [artifact], }); assert.equal(outcome.action, 'send'); assert.equal(outcome.artifacts.length, 1); });