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

recallite

v0.0.3

Published

SQLite memory for agents that learn from outcomes.

Readme

Recallite 🧠⚡

SQLite memory for agents that learn from outcomes.

Recallite gives Node.js AI agents, automations, and self-improving applications persistent memory, hybrid retrieval, and outcome-aware learning in a single SQLite database.


License: MIT TypeScript Node.js


What Recallite Is

Recallite is an opinionated, lightweight memory layer for Node.js AI agents built on top of SQLite (FTS5 full-text search + Float32 BLOB vector storage).

Unlike basic vector stores that only perform static semantic similarity searches, Recallite tracks the real-world outcomes of past agent actions and reinforces or weakens memory usefulness over time:

$$\text{Remember} \longrightarrow \text{Retrieve} \longrightarrow \text{Act} \longrightarrow \text{Observe Outcome} \longrightarrow \text{Reinforce / Weaken} \longrightarrow \text{Recall Better Next Time}$$

  • Vector Storage & Engine: Float32 vectors are stored in SQLite BLOB columns and searched using Recallite's exact cosine-similarity engine (InlineScalarEngine or WorkerBlobScanEngine).

What Recallite Is Not

[!IMPORTANT] Recallite does not retrain language models. It improves future agent decision-making by dynamically updating memory confidence, usefulness scores, lifecycle states, and hybrid retrieval ranking signals.


🎯 Which API Mode Should You Use?

Recallite supports both a Lite API for fast, simple SQLite memory and an Outcome-Aware API for complex AI agents:

| Goal / Scenario | Recommended Mode | Key Methods | Runnable Example | | :--- | :--- | :--- | :--- | | Personal AI Assistant / Chatbot | Lite API | createRecallite(), add(), context() | npm run example:lite | | Self-Improving Support / Coding Bot | Outcome API | remember(), recall(), feedback() | npm run example:outcome | | Policy Enforcement & Safety Rules | Safety API | type: 'constraint', relate('contradicts') | npm run example:safety | | Autonomous Admin Agent / Ops | Full Agent API | defineProfile(), consolidate(), explainRecall() | npm run example:admin | | Claude / Antigravity / Cursor IDE | MCP Server | npx recallite-mcp --db ./memory.db | npm run mcp |


⚡ Quick Start: Lite API (5 Seconds)

For chatbots, personal assistants, or CLI tools where you just want a clean SQLite memory store without boilerplate:

import { createRecallite } from 'recallite';

// 1. Connect in 1 line (pass DB path or omit for in-memory SQLite)
const memory = await createRecallite('./my-bot.db');

// 2. Add memories with plain text strings
await memory.add("User prefers dark mode UI and concise Markdown explanations.");
await memory.add("User works as a Senior Software Engineer specializing in Node.js.");

// 3. Get ready-to-inject LLM prompt context in 1 line
const promptContext = await memory.context("User preferences");

console.log(promptContext);
// Output:
// [OBSERVATION] User prefers dark mode UI and concise Markdown explanations.
// User prefers dark mode UI and concise Markdown explanations.

🔌 Model Context Protocol (MCP) Server

Recallite includes a zero-dependency, stdio-based MCP Server (recallite-mcp) allowing AI tools (Claude Desktop, Antigravity IDE, Cursor, Windsurf, etc.) to plug into Recallite as an external persistent memory engine.

Quick Launch via CLI

# Run MCP server against local SQLite database
npx recallite-mcp --db ./agent-memory.db

IDE / Claude Desktop Configuration

Add the following to your MCP client config (e.g. claude_desktop_config.json or Antigravity MCP settings):

{
  "mcpServers": {
    "recallite": {
      "command": "npx",
      "args": ["recallite-mcp", "--db", "./agent-memory.db"]
    }
  }
}

Exposed MCP Tools

| Tool Name | Description | Key Arguments | | :--- | :--- | :--- | | recallite_remember | Store a new memory into SQLite | content, title, type, metadata | | recallite_recall | Perform hybrid keyword + vector search | query, limit, profile | | recallite_context | Get ready-to-inject LLM prompt context | query, format (markdown/compact) | | recallite_feedback | Submit outcome feedback (success/failure) | retrievalId, outcome, score, usedMemoryIds | | recallite_stats | Retrieve system health, memory metrics & prompt optimization token savings | format (summary/json) | | recallite_explain | Inspect RRF score breakdown for a recall session | retrievalId |


🔄 MCP Agent Lifecycle (Kullanım Döngüsü)

When integrating Recallite MCP Server into AI agent workflows (Cursor, Claude, Antigravity, AutoGPT), agents follow a 4-stage autonomous memory loop:

graph TD
    A[1. Task Starts] --> B[2. Auto-Recall: call recallite_context]
    B --> C[3. Agent Executes Task with Context]
    C --> D{New Rule / Solution Learned?}
    D -- Yes --> E[4. Auto-Remember: call recallite_remember]
    D -- No --> F[5. Task Finish]
    E --> F
    F --> G[6. Outcome Feedback: call recallite_feedback]
  1. Context Retrieval (recallite_context): At task initialization, the agent retrieves relevant rules, constraints, and past bug fixes formatted into a token-budgeted prompt context.
  2. Task Execution: The agent performs code generation or planning adhering to retrieved constraints.
  3. Memory Capture (recallite_remember): If a new rule, user preference, or bug solution is discovered, the agent automatically persists it into SQLite.
  4. Outcome Learning (recallite_feedback): The agent submits execution feedback (success or failure), dynamically boosting or weakening memory scores for future sessions.

📋 Example .agents / System Prompt Configurations

To make your AI agent automatically use Recallite MCP without manual prompting, add one of the following prompt snippets to your project:

Option 1: .agents/AGENTS.md (or Cursor .cursorrules / Antigravity)

Create a file at .agents/AGENTS.md (see template in examples/mcp-agent-rules.md):

# Persistent Memory Rules (Recallite MCP)

You are connected to the Recallite MCP memory server. Follow these rules for all tasks:

## 1. Task Initialization (Auto-Recall)
- **Rule**: At the start of any non-trivial task, always execute `recallite_context` with your task query.
- **Goal**: Inject relevant user preferences, coding guidelines, and past bug fixes into your working context before writing code.

## 2. Automatic Knowledge Capture (Auto-Remember)
- **Rule**: Automatically call `recallite_remember` whenever you discover or create:
  - User Preferences -> `type: "observation"`
  - Hard Constraints & Safety Rules -> `type: "constraint"`
  - Bug Fixes & Lessons -> `type: "lesson"`
  - Reusable Procedures -> `type: "procedure"`

## 3. Outcome Feedback (Auto-Feedback)
- **Rule**: After completing a task or when a test/build fails, invoke `recallite_feedback`:
  - Success: `outcome: "success"`, `score: 0.9` -> Reinforces helpful memories.
  - Failure: `outcome: "failure"`, `score: 0.1` -> Weakens incorrect or outdated memories.

Option 2: Claude Desktop / System Prompt Snippet

You have access to the Recallite MCP server tools:
- recallite_context: Call this FIRST at the start of any conversation to retrieve user preferences and past project lessons.
- recallite_remember: Call this whenever you learn a new preference, constraint, or solution during the chat.
- recallite_feedback: Call this to reinforce memories when a task succeeds or fails.
- recallite_stats: Call this to check memory health and prompt token savings metrics.

🚀 Advanced Quick Start: Outcome-Aware AI Agent

For autonomous agents that generate solutions and need to learn from real-world execution results (success vs. failure):

import { createRecallite } from 'recallite';

// 1. Initialize Recallite with embedding function
const recallite = await createRecallite({
  database: './agent-memory.db',
  dimensions: 1536,
  embed: async (texts) => await myEmbeddingProvider.embed(texts),
});

// 2. Remember an episode or solution
const episode = await recallite.remember({
  type: 'episode',
  title: 'Public Guestbook Spam Fix',
  content: 'Public guestbook feature received high spam and was reverted after 3 days.',
  source: { type: 'system-event', id: 'deployment-42' },
  metadata: { category: 'moderation', outcome: 'reverted' },
});

// 3. Recall relevant memories for a new task
const result = await recallite.recall('Add user public comments', {
  profile: 'planner',
  types: ['lesson', 'procedure', 'episode'],
  limit: 5,
});

// 4. Format recalled memories directly into LLM context snippet
const contextPrompt = recallite.formatContext(result, {
  maxTokens: 2000,
  format: 'markdown',
});

// 5. Outcome feedback with explicit memory attribution
// Real-world execution succeeded -> Boost memory usefulness score!
await recallite.feedback(result.retrievalId, {
  outcome: 'success',
  score: 0.9,
  usedMemoryIds: [result.memories[0].memory.id],
  reason: 'Prevented repeated security issue by enforcing moderation',
});

How Retrieval & Scoring Work

Recallite uses Reciprocal Rank Fusion (RRF) to combine FTS5 full-text search, Float32 BLOB vector similarity, and metadata filters.

RRF Formula

$$RRFScore = \frac{w_{fts}}{60 + Rank_{fts}} + \frac{w_{vec}}{60 + Rank_{vec}}$$

If a memory is only matched in FTS or only in Vector search, the un-matched channel contribution is $0$.

Final Scoring Formula

To ensure brand-new memories (with default 0.5 confidence and 0.5 usefulness) get retrieved, tested, and reinforced without collapsing to zero, Recallite uses an additive quality multiplier:

$$QualityMultiplier = 0.45 + 0.25 \times Confidence + 0.20 \times Usefulness + 0.10 \times Importance$$

$$FinalScore = RRFScore \times StatusMultiplier \times ProfileMultiplier \times QualityMultiplier \times ContradictionMultiplier$$


Memory Reliability & Metrics

Recallite does not trust generated memories automatically.

  • usefulnessScore: Updated dynamically via outcome feedback (reinforce / feedback).
  • confidence: Updated when evidence is attached, validation occurs (validate), or contradiction state changes.
  • evidenceCount: Derived automatically from unique supports and derived_from relations.
  • contradictionCount: Derived automatically from active contradicts relations.

[!NOTE] Confidence and relevance are separate concepts. A memory may be highly reliable but irrelevant to the current task. Feedback events never automatically alter a memory's lifecycle status.


Memory Lifecycle & Source Trust Policy

flowchart TD
    Candidate["candidate (LLM Generated / Draft)"]
    Validated["validated (Verified / Approved)"]
    Active["active (Participating in Default Retrieval)"]
    Deprecated["deprecated (Soft Deleted / Excluded)"]
    Superseded["superseded (Replaced by Newer Memory)"]

    Candidate -->|validate| Validated
    Candidate -->|deprecate| Deprecated
    Validated -->|activate| Active
    Active -->|deprecate| Deprecated
    Active -->|supersede| Superseded

Source Trust Level Policy

Memory lifecycle status is determined by evaluating both memory type and source trust level:

| Source Trust Level | Memory Types | Default Status | Rationale | | :--- | :--- | :--- | :--- | | Trusted Sourceshuman, system, system-event, system-metric | episode, observation, constraint, procedure | active | Ground-truth facts, metrics, human rules, and real execution events. | | Trusted Sources | lesson, reflection | candidate | Requires validation before participating in default active retrieval. | | Untrusted Sourcesllm, imported, unknown | episode, observation, lesson, procedure, reflection, constraint | candidate | Generated/unverified items are held in draft state (candidate) until validated. | | All Sources | exemplar | validated | Pre-approved gold-standard benchmark examples. |

Safety Guard for Status Overrides

If an untrusted source (llm or imported) attempts to force status: 'active', Recallite safety guards force the status to 'candidate' unless explicitly overridden with allowUnsafeStatusOverride: true:

// Safely defaults to 'candidate' status
await recallite.remember({
  type: 'constraint',
  title: 'No CAPTCHA on checkout',
  content: 'CAPTCHA drops conversion',
  source: { type: 'llm' }, // Untrusted LLM source -> candidate status
});

// Explicit unsafe override (requires permission flag)
await recallite.remember({
  type: 'constraint',
  title: 'Force active rule',
  content: 'Direct rule enforcement',
  source: { type: 'llm' },
  status: 'active',
  allowUnsafeStatusOverride: true, // Express permission required
});

Outcome Feedback & Contradiction Warnings

Contradiction Expansion & Warnings

Contradiction expansion does not consume the primary result quota. When a recalled memory conflicts with another memory via a contradicts relation, Recallite attaches a warning while preserving your primary result count limit:

const result = await recallite.recall("Animations UI optimization");

console.log(result.memories[0]);
/*
{
  memory: { title: "Animations boost user engagement", ... },
  score: 0.78,
  reasons: ["semantic-match", "validated-memory"],
  warnings: [
    {
      type: "contradiction",
      memoryId: "mem_42",
      summary: "Contradicts memory \"Animations increase mobile CPU usage\""
    }
  ]
}
*/

Contradictions Rendered in LLM Context

When using formatContext(), contradiction warnings are rendered directly into the prompt string so LLMs receive explicit warning signals:

[LESSON] Animations boost user engagement (85% conf)
Content: Animations increase user retention by 15%.
⚠️ Contradiction: Contradicts memory "Animations increase mobile CPU usage"

API at a Glance

| Method | Purpose | | :--- | :--- | | remember(input) | Store a new memory with source metadata | | rememberMany(inputs) | Bulk insert memories in a single SQLite transaction | | recall(query, options) | Retrieve RRF-ranked memories returning RecallResponse (supports signal for AbortSignal) | | formatContext(response, options) | Format a recall response directly into prompt context | | feedback(retrievalId, options) | Record outcome feedback with explicit memory attribution | | reinforce(memoryId, options) | Update score for a single specific memory directly | | relate(sourceId, targetId, options) | Create evidence (supports) or contradicts links | | consolidate(options) | Group experiences & synthesize candidate lessons | | validate(memoryId) | Mark a candidate memory as verified | | activate(memoryId) | Include a validated memory in default active retrieval | | supersede(oldId, newId) | Atomically replace an old memory with a new rule | | explainRecall(retrievalId) | Debug tool returning detailed selection reasons and vector execution info | | health() | Inspect SQLite integrity, FTS sync, and vector dimensions | | prune(options) | Clean up old deprecated memories safely (dryRun supported) | | close(options) | Gracefully drain worker pool (drainTimeout: 5000) and close SQLite connection cleanly |


Performance, Workers & Concurrency Model

For high-throughput AI agents and server backends, Recallite decouples single-threaded SQLite write transactions on the main application thread from CPU-intensive Float32 vector scans using a dedicated Worker Thread Pool.

sequenceDiagram
    autonumber
    actor Agent as AI Agent / Orchestrator
    participant Main as Main Thread (Recallite)
    participant Embed as Application Embedding API
    participant Worker as Worker Thread Pool (WorkerBlobScanEngine)
    participant DB as SQLite DB (WAL Mode)

    Agent->>Main: recall("Add user comments", { profile: "planner", signal })
    Main->>Embed: embed(["Add user comments"])
    Embed-->>Main: Return Query Vector [Float32Array]
    Main->>DB: Execute FTS5 Keyword Search (bm25)
    DB-->>Main: Return FTS Candidate Ranks

    alt Total Vectors >= minVectorCount OR Scan Ops >= minScanOperations
        Main->>Worker: Dispatch vector-search task (queryVector, dbPath)
        Worker->>DB: Open Read-Only DB Handle (query_only = ON) & Scan Float32 BLOBs
        DB-->>Worker: Return Raw BLOB Rows
        Worker-->>Main: Return Top-50 Memory IDs + Cosine Scores
    else Small Vector Store (Inline Execution)
        Main->>DB: Execute InlineScalarEngine (cosine_similarity C Function)
        DB-->>Main: Return Top-50 Ranks
    end

    Main->>Main: Compute RRF Fusion, Status & Contradiction Multipliers
    Main-->>Agent: Return Ranked Memories & Contradiction Warnings

Worker Concurrency Model

  • Main Thread Write Ownership: The main application thread retains exclusive ownership of all SQLite write operations (INSERT, UPDATE, DELETE, lifecycle transitions, relations, and migrations).
  • Independent Read Connections: Each worker thread opens its own separate read-only connection (readonly: true, query_only = ON, busy_timeout = 5000) to a database already configured in WAL mode by the main connection.
  • Task-Level Parallelism: Worker pool offloads full recall vector scans for concurrent requests across workers. Individual vector queries are not split across worker shards.
  • Scan Concurrency Control: maxConcurrentVectorScans (default: 2) prevents excessive simultaneous BLOB scans from overwhelming CPU bandwidth.
  • Non-Blocking WAL Reads: SQLite WAL mode permits worker read scans to run concurrently while the main thread executes short write transactions.

Worker Configuration & Capping

Worker options can be configured as a boolean, 'auto' string, or detailed options object:

const recallite = await createRecallite({
  database: './memory.db',
  workers: {
    enabled: true,
    size: 'auto',                  // Capped: min(max(1, availableParallelism - 1), 4)
    minVectorCount: 2000,          // Offload threshold by vector count
    minScanOperations: 1000000,     // Offload threshold by estimated operations (count * dimensions)
    maxConcurrentVectorScans: 2,   // Scan concurrency semaphore
    taskTimeout: 10000,            // 10s task execution timeout
    maxQueueSize: 100,             // Queue capacity limit
    fallback: 'error',             // 'error' (default) throws RECALLITE_WORKER_TIMEOUT; 'inline' enables main thread fallback
  },
});

[!IMPORTANT] size: "auto" is capped to a maximum of 4 workers (Math.min(Math.max(1, availableParallelism() - 1), 4)) to prevent excessive parallel read scans against the same SQLite database file.

Worker Failure Behavior & Cancellation

Worker mode prevents CPU-heavy exact vector scans from blocking the Node.js event loop and improves responsiveness under concurrent workloads.

  • Task Timeout: Tasks exceeding taskTimeout fail with RECALLITE_WORKER_TIMEOUT. Main-thread inline fallback is disabled by default (fallback: 'error') to prevent event-loop freezing after timeouts.
  • Queue Overflow: Requests exceeding maxQueueSize fail with RECALLITE_WORKER_QUEUE_FULL.
  • Query Cancellation: Passing signal: AbortSignal to recall() immediately cancels queued or active worker scans and rejects with RECALLITE_ABORTED.
  • Graceful Teardown: recallite.close({ drainTimeout: 5000 }) drains pending active tasks before terminating worker pool threads.

📚 Runnable Scenario Examples

Recallite includes 4 complete, self-contained, real-world scenario examples in examples/:

1. Lite API Mode (Personal AI Chatbot Memory)

Demonstrates 1-line setup, plain text string memory addition, and 1-line LLM prompt context injection.

npm run example:lite

2. Outcome-Aware Agent Mode (Self-Improving Support Bot)

Demonstrates recording troubleshooting solutions, calling feedback() on real-world outcomes, and observing how successful fixes get automatically boosted for future queries.

npm run example:outcome

3. Policy & Safety Enforcement Mode (Contradiction Warnings)

Demonstrates enforcing system constraints, linking conflicting legacy vs. updated rules via relate('contradicts'), and detecting contradiction warnings during retrieval.

npm run example:safety

4. Production Autonomous Admin Agent (Full Architecture)

Demonstrates a production-grade Marketplace Moderation & Operations Admin Agent with two-stage retrieval, precise attribution, multi-factor decision logic, and experience consolidation (consolidate()).

# Run in Inline Engine Mode
npm run example:admin

# Run in Multi-Core Worker Pool Mode
npm run example:admin -- --worker

Performance Benchmarks

Run benchmarks anytime using npm run bench:

📌 Benchmark Environment & Hardware Context:
 - Hardware: Apple Silicon (M-series Mac)
 - Node.js: v23.1.0 | SQLite Driver: better-sqlite3
 - Vector Storage: Float32 BLOB columns in SQLite
 - Vector Engine: Recallite exact cosine-similarity engine (Float32 BLOB scalar calculation)
 - Search Mode: Exact k-NN Search (O(N) linear scan)
 - Cache Mode: Warm Cache (SQLite WAL + MMAP enabled)
 - Worker Pool: Enabled (Pool size: 2, minVectorCount: 2000, minScanOperations: 1,000,000)
 - Benchmark Vector Dimensions: 128

==================================================================================================================================
| Operation                              |     Count |   Total Time |  Batch Throughput |   Item Throughput |    Avg Latency |    p95 Latency |
==================================================================================================================================
| remember (single item insert)          |      50 ops |    108.81 ms |       459.5 batch/s |       459.5 items/s |     2.176 ms/op |     9.288 ms p95 |
| rememberMany (100 items/batch)         |      10 ops |    302.40 ms |        33.1 batch/s |      3306.8 items/s |    30.240 ms/op |    70.451 ms p95 |
| recall @ 10,000 memories (InlineScalarEngine) |      10 ops |   2443.25 ms |         4.1 batch/s |         4.1 items/s |   244.325 ms/op |   421.661 ms p95 |
| recall @ 10,000 memories (WorkerBlobScanEngine) |      10 ops |   1732.37 ms |         5.8 batch/s |         5.8 items/s |   173.237 ms/op |   327.841 ms p95 |
| recall @ 10,000 memories (10 Concurrent Requests) |       2 ops |   3162.90 ms |         0.6 batch/s |         6.3 items/s |  1581.449 ms/op |  1639.192 ms p95 |
| formatContext (Markdown format)        |     100 ops |      2.35 ms |     42630.3 batch/s |     42630.3 items/s |     0.023 ms/op |     0.055 ms p95 |
| reinforce (score update)               |     300 ops |   1292.22 ms |       232.2 batch/s |       232.2 items/s |     4.307 ms/op |     7.826 ms p95 |
==================================================================================================================================

Project Status

| Feature / Subsystem | Status | Description | | :--- | :--- | :--- | | SQLite Persistence & WAL | 🟢 Stable | Production ready with parameterized security. | | FTS5 Full-Text Retrieval | 🟢 Stable | BM25 keyword matching with sanitization. | | Lifecycle & Status Tools | 🟢 Stable | Candidate, Validated, Active, Deprecated, Superseded. | | Outcome Reinforcement | 🟢 Stable | Non-linear EMA score updates and attribution. | | Worker Thread Vector Engine | 🟢 Stable | Off-main-thread vector scans maintaining event-loop responsiveness under load. | | Exact Vector Search Engine | 🟢 Stable (Small/Medium Stores) | Exact $O(N)$ linear scan benchmarked at ~115ms for 3,000 memories with Worker Pool. Practical up to tens of thousands of memories depending on hardware and latency tolerance. | | Automated LLM Consolidation | 🟡 Beta | Requires external LLM callback & candidate validation. |


Limitations

  • Recallite does not retrain language models.
  • The default vector engine performs exact search ($O(N)$) and is intended for small-to-medium local memory collections. Large-scale collections (>50,000 memories) may require a custom approximate vector-search adapter.
  • Retrieval quality depends on the embedding provider.
  • Automatic consolidation requires validation.
  • SQLite is best suited for local and single-node deployments.
  • Semantic similarity does not guarantee factual correctness.

📜 License

MIT License © 2026 Ahmet & Recallite Contributors.