Files
memind/temporal-recall-service/recall.test.mjs
T
john 212ff3ff80 Add User Model Service and Temporal Recall for MeMind V0.1.
Introduce UMS ingest/snapshot pipeline, Context Planner with multi-source recall, runtime context injection, canonical user mapping, and session snapshot loading on auth/me.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-03 23:25:18 +08:00

89 lines
2.9 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { buildContextPlan } from '../temporal-recall-service/context-planner.mjs';
import { parseTimeScope } from '../temporal-recall-service/time-parser.mjs';
import { dedupeTimelineItems } from '../temporal-recall-service/dedupe.mjs';
import { formatTemporalRecallBlock } from '../temporal-recall-service/runtime-context.mjs';
test('parseTimeScope resolves yesterday', () => {
const now = new Date('2026-09-03T12:00:00+08:00');
const scope = parseTimeScope('我昨天有什么重要的事', now);
assert.equal(scope.relative_label, 'yesterday');
const startLocal = new Date(scope.mention_range.start);
assert.ok(startLocal.getTime() < now.getTime());
assert.ok(new Date(scope.mention_range.end).getTime() <= now.getTime());
});
test('buildContextPlan includes calendar for schedule questions', () => {
const plan = buildContextPlan({
query: '我今天有什么行程安排?',
user_id: 'user-1',
now: new Date('2026-09-03T12:00:00+08:00'),
});
assert.ok(plan.sources.calendar >= 0.5);
assert.ok(plan.retrievals.some((r) => r.source === 'calendar'));
});
test('buildContextPlan produces multi-source retrievals', () => {
const plan = buildContextPlan({
query: '我昨天有什么重要的事情安排吗?',
user_id: 'user-1',
now: new Date('2026-09-03T12:00:00+08:00'),
});
assert.equal(plan.query_type, 'personal_temporal_recall');
assert.equal(plan.context_needs.temporal_recall, 'REQUIRED');
assert.ok(plan.retrievals.length >= 2);
assert.ok(plan.sources.meinput > 0.5);
assert.ok(plan.sources.chat > 0.5);
});
test('dedupe merges similar items', () => {
const items = dedupeTimelineItems([
{
timeline_item_id: 'a',
title: '明天下午三点签合同',
content: '明天下午三点去签合同',
observed_time: '2026-09-02T10:00:00+08:00',
event_time: null,
source_ref: 'meinput:1',
recall_score: 0.8,
importance: 0.8,
confidence: 0.9,
},
{
timeline_item_id: 'b',
title: '明天下午三点去签合同',
content: '明天下午三点去跟张总签合同',
observed_time: '2026-09-02T10:05:00+08:00',
event_time: null,
source_ref: 'chat:1',
recall_score: 0.75,
importance: 0.75,
confidence: 0.85,
},
]);
assert.equal(items.length, 1);
assert.equal(items[0].merged_from?.length, 2);
});
test('formatTemporalRecallBlock renders grouped items', () => {
const block = formatTemporalRecallBlock({
groups: [
{
label: 'mentioned_or_planned',
items: [
{
source: 'meinput',
observed_time: '2026-09-02T10:00:00+08:00',
title: '明天下午三点签合同',
recall_score: 0.81,
},
],
},
],
});
assert.match(block, /时间范围回忆/);
assert.match(block, /meinput/);
assert.match(block, /签合同/);
});