src / constants.ts

/**
 * @file constants.ts
 * Single source of truth for every tunable parameter.
 * Grouped by subsystem for easy discovery.
 */

export const DB_FILENAME = "memory.db";
export const MAX_MEMORIES_TOTAL = 10_000;
export const MAX_MEMORY_CONTENT_LENGTH = 4_000;
export const MAX_TAGS_PER_MEMORY = 10;
export const MAX_TAG_LENGTH = 50;
export const MAX_CATEGORY_LENGTH = 30;

/** Default number of memories injected into prompt context. */
export const DEFAULT_CONTEXT_MEMORIES = 5;
/** Maximum memories that can be injected per prompt. */
export const MAX_CONTEXT_MEMORIES = 15;
/** Default number returned by explicit Recall/Search tools. */
export const DEFAULT_SEARCH_RESULTS = 8;
/** Maximum results from a single search/recall. */
export const MAX_SEARCH_RESULTS = 25;
/** Minimum TF-IDF similarity score to surface a memory (0–1). */
export const MIN_RELEVANCE_THRESHOLD = 0.05;
/** Minimum query length (chars) for semantic search. */
export const MIN_QUERY_LENGTH = 2;

/** Stop words excluded from TF-IDF indexing. */
export const STOP_WORDS = new Set([
  "the",
  "a",
  "an",
  "is",
  "in",
  "of",
  "and",
  "or",
  "for",
  "to",
  "how",
  "what",
  "why",
  "when",
  "does",
  "with",
  "from",
  "its",
  "that",
  "this",
  "are",
  "was",
  "were",
  "be",
  "been",
  "being",
  "have",
  "has",
  "had",
  "do",
  "did",
  "will",
  "would",
  "could",
  "should",
  "may",
  "might",
  "shall",
  "can",
  "it",
  "he",
  "she",
  "they",
  "we",
  "you",
  "i",
  "me",
  "my",
  "your",
  "our",
  "his",
  "her",
  "their",
  "not",
  "no",
  "but",
  "if",
  "so",
  "at",
  "by",
  "on",
  "up",
  "out",
  "about",
  "into",
  "over",
  "after",
  "before",
  "between",
  "under",
  "again",
  "then",
  "here",
  "there",
  "all",
  "each",
  "every",
  "both",
  "few",
  "more",
  "most",
  "other",
  "some",
  "such",
  "than",
  "too",
  "very",
  "just",
  "also",
  "now",
]);
/** Minimum term length for TF-IDF indexing. */
export const MIN_TERM_LENGTH = 2;
/** Maximum vocabulary size for the TF-IDF index. */
export const MAX_VOCAB_SIZE = 50_000;
/** How many top terms per document to keep for scoring. */
export const MAX_TERMS_PER_DOC = 200;

/** Half-life of memory relevance decay in days. */
export const DECAY_HALF_LIFE_DAYS = 45;
/** Weight of recency in the composite retrieval score (0–1). */
export const DECAY_WEIGHT = 0.2;
/** Weight of access frequency in the composite retrieval score (0–1). */
export const FREQUENCY_WEIGHT = 0.1;
/** Weight of TF-IDF similarity in the composite retrieval score (0–1). */
export const SIMILARITY_WEIGHT = 0.55;
/** Weight of stored confidence score in the composite retrieval score (0–1). */
export const CONFIDENCE_WEIGHT = 0.15;

/** Max tokens for AI fact extraction calls. */
export const AI_EXTRACT_MAX_TOKENS = 800;
/** Temperature for AI fact extraction (low = factual). */
export const AI_EXTRACT_TEMPERATURE = 0.1;
/** Timeout for AI calls in ms. */
export const AI_CALL_TIMEOUT_MS = 12_000;
/** Max tokens for AI relevance scoring. */
export const AI_RELEVANCE_MAX_TOKENS = 200;
/** Temperature for relevance scoring. */
export const AI_RELEVANCE_TEMPERATURE = 0.05;
/** Max tokens for AI conflict detection. */
export const AI_CONFLICT_MAX_TOKENS = 400;
/** Temperature for conflict detection. */
export const AI_CONFLICT_TEMPERATURE = 0.1;

export const VALID_SCOPES = ["global", "project", "session"] as const;
export type MemoryScope = (typeof VALID_SCOPES)[number];
/** Max project name length. */
export const MAX_PROJECT_NAME_LENGTH = 60;
/** Max session memories (in-memory only, never persisted). */
export const MAX_SESSION_MEMORIES = 200;

export const VALID_CATEGORIES = [
  "fact",
  "preference",
  "project",
  "note",
  "instruction",
  "relationship",
  "context",
] as const;
export type MemoryCategory = (typeof VALID_CATEGORIES)[number];

/** Max chars of injected memory context (to avoid blowing up prompts). */
export const MAX_INJECTED_CONTEXT_CHARS = 3_000;
/** Separator between injected memories. */
export const MEMORY_SEPARATOR = "\n• ";