New shared package: packages/palace/ (@bytelyst/palace) Modules: - types.ts — BasePalaceWingDoc, RoomDoc, MemoryDoc, TunnelDoc, KGTripleDoc, DiaryDoc - halls.ts — HallType union, HALL_PRESETS (notelett/mindlyst/coding), hallFromLabel() - cosine.ts — cosineSimilarity(), topKByCosine(), normalizeVector() - dedup.ts — isContentDuplicate(), isExactDuplicate(), findClosestMatch() - decay.ts — computeDecayedRelevance(), boostRelevance() - extraction.ts — buildExtractionPrompt(), parseExtractionResponse(), regexFallbackExtraction() - kg.ts — findContradictions(), mergeTriples(), isTripleCurrent() - wakeup.ts — buildWakeUpLayers(), truncateToTokenBudget(), WAKEUP_PRESETS - config.ts — palaceConfigSchema (Zod) 7 test files, 91 tests passing. Consumed by NoteLett, MindLyst, and future palace-enabled products.
53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
/**
|
|
* Relevance decay for palace memories.
|
|
*
|
|
* Uses exponential half-life decay: relevance halves every N days.
|
|
* Memories that are accessed/referenced get their relevance boosted.
|
|
*/
|
|
|
|
const MS_PER_DAY = 86_400_000;
|
|
|
|
/**
|
|
* Compute decayed relevance using exponential half-life.
|
|
*
|
|
* @param originalRelevance - Initial relevance score (0-1)
|
|
* @param createdAt - ISO date string or Date when the memory was created/last accessed
|
|
* @param halfLifeDays - Number of days for relevance to halve (default: 30)
|
|
* @param asOf - Reference time for decay calculation (default: now)
|
|
* @returns Decayed relevance score (0-1)
|
|
*/
|
|
export function computeDecayedRelevance(
|
|
originalRelevance: number,
|
|
createdAt: string | Date,
|
|
halfLifeDays = 30,
|
|
asOf: Date = new Date()
|
|
): number {
|
|
if (halfLifeDays <= 0) return originalRelevance;
|
|
if (originalRelevance <= 0) return 0;
|
|
|
|
const created = typeof createdAt === 'string' ? new Date(createdAt) : createdAt;
|
|
const elapsedMs = asOf.getTime() - created.getTime();
|
|
|
|
if (elapsedMs <= 0) return Math.min(originalRelevance, 1);
|
|
|
|
const elapsedDays = elapsedMs / MS_PER_DAY;
|
|
const decayFactor = Math.pow(0.5, elapsedDays / halfLifeDays);
|
|
|
|
return Math.max(0, Math.min(1, originalRelevance * decayFactor));
|
|
}
|
|
|
|
/**
|
|
* Compute a boosted relevance for a memory that was accessed/referenced.
|
|
*
|
|
* Boost formula: new = old + (1 - old) * boostFactor
|
|
* This asymptotically approaches 1.0 without exceeding it.
|
|
*
|
|
* @param currentRelevance - Current relevance score (0-1)
|
|
* @param boostFactor - How much of the remaining gap to close (default: 0.3)
|
|
* @returns Boosted relevance score (0-1)
|
|
*/
|
|
export function boostRelevance(currentRelevance: number, boostFactor = 0.3): number {
|
|
const boosted = currentRelevance + (1 - currentRelevance) * boostFactor;
|
|
return Math.min(1, Math.max(0, boosted));
|
|
}
|