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, /签合同/); });