Add smart ACK provider for WeChat MP replies

Replace fixed ackText with a rule-based AckProvider that picks
response templates by message type and intent (translate, summary,
rewrite, poster, ppt, mindmap, code, search, schedule). Pure sync,
zero I/O, auto-falls back to config.ackText on any error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
john
2026-06-26 15:19:03 +08:00
parent 9ed4fd48d7
commit 9b4a25799f
162 changed files with 17276 additions and 2054 deletions
+60
View File
@@ -1,4 +1,7 @@
import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import test from 'node:test';
import { publicationInternals } from './mindspace-publications.mjs';
@@ -135,3 +138,60 @@ test('publicHomepageResponse summarizes public cards and total views', () => {
assert.equal(result.pageCount, 2);
assert.equal(result.pages[0].publicUrl, '/u/john/pages/one');
});
test('buildPublicationThumbnailFallback points private resources at the public page thumbnail', () => {
assert.equal(
publicationInternals.buildPublicationThumbnailFallback('john', 'page-037d497f'),
'/u/john/pages/page-037d497f.thumbnail.png',
);
assert.equal(
publicationInternals.buildPublicationThumbnailFallback('木子', 'demo-page'),
'/u/%E6%9C%A8%E5%AD%90/pages/demo-page.thumbnail.png',
);
});
test('prepareHtmlPublishContent inlines owned private image assets before scanning', async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'mindspace-publish-'));
const storageKey = 'users/user-1/assets/asset-1/current.png';
await fs.mkdir(path.dirname(path.join(root, storageKey)), { recursive: true });
await fs.writeFile(path.join(root, storageKey), Buffer.from('png-bytes'));
const pool = {
async query(sql, params) {
assert.match(sql, /h5_assets/);
assert.equal(params[0], 'user-1');
assert.deepEqual(params[1], ['asset-1']);
return [
[
{
id: 'asset-1',
mime_type: 'image/png',
storage_key: storageKey,
},
],
];
},
};
try {
const html = '<!doctype html><img src="/api/mindspace/v1/assets/asset-1/download?inline=1&v=1">';
const prepared = await publicationInternals.prepareHtmlPublishContent({
pool,
userId: 'user-1',
html,
ownerSlug: 'john',
urlSlug: 'korean-daily-look',
absoluteStoragePath: (key) => path.join(root, key),
});
assert.match(prepared, /src="data:image\/png;base64,/);
assert.doesNotMatch(prepared, /\/api\/mindspace\/v1\/assets\//);
const scan = publicationInternals.scanContent(prepared, { format: 'html' });
assert.equal(
scan.findings.some((finding) => finding.type === 'private_resource_reference'),
false,
);
} finally {
await fs.rm(root, { recursive: true, force: true });
}
});