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
+35 -2
View File
@@ -1,7 +1,8 @@
import crypto from 'node:crypto';
import { loadMindSpaceConfig } from './mindspace-config.mjs';
export const DEFAULT_SPACE_QUOTA_BYTES = 5 * 1024 * 1024;
export const DEFAULT_MAX_FILE_BYTES = 2 * 1024 * 1024;
export const DEFAULT_MAX_FILE_BYTES = 5 * 1024 * 1024;
export const SYSTEM_CATEGORIES = Object.freeze([
{
@@ -141,8 +142,17 @@ export async function ensureDefaultSpaces(pool, options = {}) {
export function createMindSpaceService(pool, options = {}) {
const maxFileBytes = Number(options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES);
const aiDailyLimit = Number(options.aiDailyLimit ?? 10);
const publicPageLimit = Number(options.publicPageLimit ?? 5);
const publicPageLimitFallback = Number(options.publicPageLimit ?? 5);
const monthlyViewLimit = Number(options.monthlyViewLimit ?? 1000);
const scheduleService = options.scheduleService ?? null;
const resolvePublicPageLimit = async () => {
try {
const config = await loadMindSpaceConfig(pool);
return Number(config.publicPageLimit ?? publicPageLimitFallback);
} catch {
return publicPageLimitFallback;
}
};
const getSpace = async (userId) => {
const [spaces] = await pool.query(
@@ -190,6 +200,28 @@ export function createMindSpaceService(pool, options = {}) {
FROM h5_publish_records WHERE user_id = ?`,
[Date.now() - 30 * 24 * 60 * 60 * 1000, userId],
);
const publicPageLimit = await resolvePublicPageLimit();
let schedule = null;
if (scheduleService) {
try {
const [todayTodoItems, digestSubscriptions] = await Promise.all([
typeof scheduleService.listTodayTodoItems === 'function'
? scheduleService.listTodayTodoItems({ userId })
: Promise.resolve([]),
typeof scheduleService.listDigestSubscriptions === 'function'
? scheduleService.listDigestSubscriptions({
userId,
digestType: 'todo_day',
status: ['active', 'locked'],
limit: 10,
})
: Promise.resolve([]),
]);
schedule = { todayTodoItems, digestSubscriptions };
} catch {
schedule = null;
}
}
return {
id: row.id,
userId: row.user_id,
@@ -211,6 +243,7 @@ export function createMindSpaceService(pool, options = {}) {
categories: categories.map(categoryResponse),
createdAt: asNumber(row.created_at),
updatedAt: asNumber(row.updated_at),
schedule,
};
};