src / memory / types.ts

/**
 * @file types.ts
 * Shared type definitions for the persistent memory plugin.
 */

import type { MemoryCategory, MemoryScope } from "./constants";

/** A single memory record as stored in SQLite. */
export interface MemoryRecord {
  id: string;
  content: string;
  category: MemoryCategory;
  tags: string[];
  confidence: number; // 0.0–1.0, how confident we are in this fact
  source: string; // "user" | "ai-extracted" | "tool-call"
  scope: MemoryScope; // "global" | "project" | "session"
  project: string | null; // project name if scope="project"
  createdAt: number; // Unix timestamp ms
  updatedAt: number; // Unix timestamp ms
  lastAccessedAt: number; // Unix timestamp ms
  accessCount: number;
  supersedes: string | null; // ID of older memory this replaces
  validFrom: number | null; // Unix timestamp ms — when this fact became true (null = always)
  validTo: number | null; // Unix timestamp ms — when this fact expires (null = never)
}

/** A memory with a computed retrieval score. */
export interface ScoredMemory extends MemoryRecord {
  relevanceScore: number; // TF-IDF similarity (0–1)
  decayScore: number; // Recency decay (0–1)
  compositeScore: number; // Final blended score
}

/** TF-IDF vector: sparse representation as term→weight map. */
export type TfIdfVector = Map<string, number>;

/** Result of a search/recall operation. */
export interface RetrievalResult {
  memories: ScoredMemory[];
  totalMatched: number;
  queryTerms: string[];
  timeTakenMs: number;
}

/** Conflict detected between two memories. */
export interface MemoryConflict {
  existingId: string;
  existingContent: string;
  newContent: string;
  conflictType: "contradiction" | "update" | "duplicate";
  resolution: "keep_both" | "supersede" | "skip";
}

/** Stats returned by the Memory Status tool. */
export interface MemoryStats {
  totalMemories: number;
  byCategory: Record<string, number>;
  oldestMemory: string | null;
  newestMemory: string | null;
  mostAccessed: { content: string; accessCount: number } | null;
  totalTags: number;
  dbSizeBytes: number;
}