npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@engram-mem/core

v0.1.2

Published

The brain of Engram. Core memory engine with 5 cognitive systems, intent-driven retrieval, and consolidation cycles.

Readme

@engram/core

The brain of Engram. Core memory engine with 5 cognitive systems, intent-driven retrieval, and consolidation cycles.

Installation

npm install @engram/core

Requires a storage adapter. See @engram/sqlite (local) or @engram/supabase (cloud).

Quick Example

import { createMemory } from '@engram/core'
import { sqliteAdapter } from '@engram/sqlite'

const memory = createMemory({ storage: sqliteAdapter() })
await memory.initialize()

// Ingest
await memory.ingest({ role: 'user', content: 'I prefer TypeScript' })

// Recall
const result = await memory.recall('What languages do you like?')
console.log(result.formatted)

await memory.dispose()

API Reference

createMemory(options)

Factory function that creates a Memory instance.

interface MemoryOptions {
  storage: StorageAdapter           // Required: where to store memories
  intelligence?: IntelligenceAdapter // Optional: embeddings + summarization
  consolidation?: {
    schedule: 'auto' | 'manual'     // Default: 'manual'
  }
  tokenizer?: (text: string) => number  // For token budgets (optional)
}

Memory Class

initialize(): Promise<void>

Initialize storage and restore sensory buffer snapshot. Must be called before any operations.

await memory.initialize()

ingest(message): Promise<void>

Store a message. Auto-detects salience, extracts entities, creates temporal edges.

interface Message {
  sessionId?: string  // Defaults to 'default'
  role: 'user' | 'assistant' | 'system'
  content: string
  metadata?: Record<string, unknown>
}

await memory.ingest({
  role: 'user',
  content: 'My deploy target is AWS ECS',
  metadata: { source: 'slack' }
})

ingestBatch(messages): Promise<void>

Store multiple messages at once. More efficient than calling ingest repeatedly.

const messages = [
  { role: 'user', content: 'Message 1' },
  { role: 'assistant', content: 'Response 1' },
  { role: 'user', content: 'Message 2' },
]
await memory.ingestBatch(messages)

recall(query, opts?): Promise<RecallResult>

Intent-analyzed, association-walked, primed recall. The core retrieval operation.

interface RecallResult {
  memories: RetrievedMemory[]       // Directly matched memories
  associations: RetrievedMemory[]   // Found via association walk
  intent: IntentResult              // Detected intent
  primed: string[]                  // Topics now boosted for this session
  estimatedTokens: number           // Token count for assembled context
  formatted: string                 // Ready to inject into system prompt
}

interface RetrievedMemory {
  id: string
  type: 'episode' | 'digest' | 'semantic' | 'procedural'
  content: string
  relevance: number  // 0-1, including priming boost
  source: 'recall' | 'association' | 'priming'
  metadata: Record<string, unknown>
}

const result = await memory.recall('What are deployment preferences?')
console.log(`Found ${result.memories.length} direct memories`)
console.log(`Plus ${result.associations.length} associated memories`)
console.log(`Context tokens: ${result.estimatedTokens}`)

Options:

interface RecallOptions {
  embedding?: number[]    // Pre-computed embedding (skip embedding service call)
  tokenBudget?: number    // Max tokens for assembled context
}

const result = await memory.recall(query, { tokenBudget: 2000 })

expand(memoryId): Promise<{ episodes: Episode[] }>

Drill into a digest to see original episodes. Useful for understanding summarized memories.

const result = await memory.recall('deployment')
const digest = result.memories.find(m => m.type === 'digest')

if (digest) {
  const { episodes } = await memory.expand(digest.id)
  console.log(`This summary was created from ${episodes.length} original messages`)
}

consolidate(cycle?): Promise<ConsolidateResult>

Run consolidation cycles. Usually automatic, but can be called manually.

Cycles:

  • 'light' — Episodes → Digests (summaries)
  • 'deep' — Digests → Semantic & Procedural memories
  • 'dream' — Extract new associations between memories
  • 'decay' — Prune low-confidence items and stale edges
  • 'all' (default) — Run all cycles in sequence
// Run light sleep consolidation
const result = await memory.consolidate('light')
console.log(`Created ${result.digestsCreated} digests`)

// Run all cycles
const fullResult = await memory.consolidate('all')
console.log(`Promoted ${fullResult.promoted} semantic memories`)
console.log(`Created ${fullResult.procedural} procedural memories`)

stats(): Promise<MemoryStats>

Get memory statistics across all systems.

interface MemoryStats {
  episodes: number        // Raw conversation turns
  digests: number         // Session summaries
  semantic: number        // Extracted facts
  procedural: number      // Learned workflows
  associations: number    // Graph edges
}

const stats = await memory.stats()
console.log(`Memory contains ${stats.semantic} semantic facts`)

forget(query, opts?): Promise<ForgetResult>

Deprioritize memories matching a query. Lossless — memories are never deleted, only decayed below retrieval floor.

interface ForgetResult {
  count: number                   // Memories matched
  previewed: RetrievedMemory[]   // Preview without confirm
}

interface ForgetOptions {
  tier?: 'episode' | 'digest' | 'semantic' | 'procedural'  // Optional filter
  confirm?: boolean  // Default: false (preview only)
}

// Preview what would be forgotten
const preview = await memory.forget('legacy API endpoint')
console.log(`Would deprioritize ${preview.count} memories`)

// Actually apply the forgetting
const result = await memory.forget('legacy API endpoint', { confirm: true })
console.log(`Deprioritized ${result.count} memories`)

session(sessionId?): SessionHandle

Get or create a session-scoped handle. Sessions partition memories by conversation.

interface SessionHandle {
  readonly sessionId: string
  ingest(message: Omit<Message, 'sessionId'>): Promise<void>
  recall(query: string, opts?: RecallOptions): Promise<RecallResult>
}

// Auto-generate sessionId
const sess = memory.session()
console.log(`Created session: ${sess.sessionId}`)

// Or provide your own
const sess2 = memory.session('user-123-conversation-abc')

// All ingests automatically tagged with sessionId
await sess.ingest({ role: 'user', content: 'Hello' })

// Recalls are still cross-session, but primed toward this session
const result = await sess.recall('previous context?')

dispose(): Promise<void>

Release resources. Persists sensory buffer snapshot to storage for restoration on next init.

await memory.dispose()

Memory Systems Explained

Sensory Buffer (Working Memory)

In-memory store of the agent's current focus. ~100 items, volatile.

  • Items — Extracted entities, topics, decisions, preferences
  • Primed Topics — Boosted for future recalls, decay each turn
  • Active Intent — Current goal driving retrieval strategy

Saved/restored on session boundaries.

Episodic System

Lossless store of every conversation turn. Ground truth. Never deleted.

  • Includes role (user/assistant/system), content, timestamp
  • Auto-scored for salience (importance)
  • Can be marked "consolidated" but stays retrievable
  • Linked temporally to nearby episodes

Semantic System

Extracted facts and concepts. The agent's knowledge.

  • Decays by confidence score (0-1)
  • Confidence floor at 0.05 (below retrieval threshold)
  • Supersession tracking (newer facts replace older ones)
  • Reconstructed from digests during deep sleep

Procedural System

Learned workflows, preferences, habits. The agent's expertise.

  • Category: workflow, preference, habit, pattern, convention
  • Trigger: conditions that activate this procedure
  • Procedure: what to do when triggered
  • Confidence + observation count drive retrieval weight

Associative Network

Graph edges between all memories. 8 edge types:

  • temporal — Episodes that happened near in time
  • causal — One event caused another
  • topical — Share a topic/entity
  • supports — One fact supports another
  • contradicts — One fact contradicts another
  • elaborates — One fact elaborates on another
  • derives_from — Fact derives from procedure
  • co_recalled — Often retrieved together

Followed during association walk phase of recall.

Intent Types

Engram auto-detects query intent and chooses retrieval strategy:

  • TASK_START — Beginning new task (procedure-heavy)
  • TASK_CONTINUE — Continuing task (recent episodic)
  • QUESTION — Information request (semantic + associations)
  • RECALL_EXPLICIT — "Remember when..." (episodic)
  • DEBUGGING — Problem-solving (procedural + semantic)
  • PREFERENCE — User preferences (procedural)
  • REVIEW — Reviewing past work (episodic + digests)
  • CONTEXT_SWITCH — Switching topics (reset priming)
  • EMOTIONAL — Emotional expression (limited recall)
  • SOCIAL — Social interaction (limited recall)
  • INFORMATIONAL — General information (semantic)

No manual tuning needed — intent is inferred from query text.

Types Reference

See src/types.ts for full type definitions:

// Core types
export type MemoryType = 'episode' | 'digest' | 'semantic' | 'procedural'
export type EdgeType = 'temporal' | 'causal' | 'topical' | 'supports' | 'contradicts' | 'elaborates' | 'derives_from' | 'co_recalled'
export type IntentType = /* 11 types listed above */

// Memory records
export interface Episode { /* ... */ }
export interface Digest { /* ... */ }
export interface SemanticMemory { /* ... */ }
export interface ProceduralMemory { /* ... */ }
export interface Association { /* ... */ }

// Results
export interface RecallResult { /* ... */ }
export interface ConsolidateResult { /* ... */ }

// Adapters
export interface StorageAdapter { /* ... */ }
export interface IntelligenceAdapter { /* ... */ }

Performance Notes

  • SQLite backend — Single-file, no server. Great for local agents. Can handle millions of memories.
  • BM25 search — Keyword-based, instant. Embed into vectors for semantic search.
  • Intent analysis — Heuristic (fast, local). Future LLM-powered version available at Level 3.
  • Consolidation — CPU-bound. Light sleep: ~100ms per batch. Deep sleep: ~1-2s. Dream cycle: ~2-5s depending on graph size.

Troubleshooting

Q: Memory not initialized error

A: Call await memory.initialize() before any operations.

Q: No memories found on recall

A: Check that messages were ingested with matching sessionId (or default). Wait for consolidation to run to create semantic/procedural memories from episodes.

Q: High token estimate

A: Use tokenBudget option to limit results. Memories are ranked by relevance, so top results are most valuable.

Q: Sensory buffer not restored

A: Snapshot is saved on dispose(). If process crashes, snapshot is lost. Ephemeral by design.

Contributing

Contributions welcome! See CONTRIBUTING.md at repo root.

License

MIT