feat(memory-v2): close Phase A with auto-review, product events, and H5 recall UI.
Add candidate auto-review pipeline, shadow audit tooling, admin metrics page, and user-visible memory recall hints in chat with phase-a readiness checks. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
export function summarizePersonalMemoryObservation(observation) {
|
||||
if (!observation || observation.skipped || !observation.enabled) {
|
||||
return { savedPreviews: [], autoReviewed: 0, pendingReview: 0 };
|
||||
}
|
||||
const savedPreviews = (observation.results ?? [])
|
||||
.filter((item) => item?.accepted && item?.candidate?.status === 'accepted')
|
||||
.map((item) => ({
|
||||
preview: String(item.candidate.content ?? '').slice(0, 60),
|
||||
policyReason: String(item.candidate.policyReason ?? ''),
|
||||
memoryType: String(item.candidate.memoryType ?? ''),
|
||||
}))
|
||||
.slice(0, 3);
|
||||
return {
|
||||
savedPreviews,
|
||||
autoReviewed: Number(observation.autoReviewed ?? 0),
|
||||
pendingReview: Number(observation.pendingReview ?? 0),
|
||||
};
|
||||
}
|
||||
|
||||
export function formatPersonalMemorySavedNotice(summary) {
|
||||
if (!summary?.savedPreviews?.length) return null;
|
||||
const preview = summary.savedPreviews[0]?.preview;
|
||||
if (!preview) return null;
|
||||
return `已记住:${preview}${preview.length >= 60 ? '…' : ''}`;
|
||||
}
|
||||
|
||||
export function formatMemoryRecallNotice(count) {
|
||||
const safeCount = Number(count ?? 0);
|
||||
if (!Number.isFinite(safeCount) || safeCount <= 0) return null;
|
||||
return `参考了你的 ${safeCount} 条记忆`;
|
||||
}
|
||||
|
||||
const INTERNAL_MEMORY_PREVIEW_RES = [
|
||||
/^\[Memory Context\]/i,
|
||||
/^\[用户身份\]/,
|
||||
/^【TKMind 路由提示】/,
|
||||
/^【Memind 任务编排】/,
|
||||
/^\[MindSpace 上下文\]/,
|
||||
];
|
||||
|
||||
export function buildMemoryRecallPreviews(memories, { limit = 5, maxLength = 80 } = {}) {
|
||||
if (!Array.isArray(memories)) return [];
|
||||
const previews = [];
|
||||
for (const item of memories) {
|
||||
const raw = String(item?.text ?? item?.content ?? '').trim();
|
||||
if (!raw) continue;
|
||||
if (INTERNAL_MEMORY_PREVIEW_RES.some((pattern) => pattern.test(raw))) continue;
|
||||
if (/\[Memory Context\]/i.test(raw)) continue;
|
||||
const clipped = raw.slice(0, maxLength);
|
||||
previews.push(clipped.length < raw.length ? `${clipped}…` : clipped);
|
||||
if (previews.length >= limit) break;
|
||||
}
|
||||
return previews;
|
||||
}
|
||||
Reference in New Issue
Block a user