Skip to main content

Overview

The Memory Inspector gives developers full visibility into what an AI agent has stored in Recall. You can browse individual memories, view Merkle root history, filter by time range or HNSW layer, and verify that your local state matches what’s on Solana. It ships in three forms:
  1. Rust API - collection_stats(), inspect(), get_memory(), search_with_records(), merkle_history() on HNSWIndex
  2. TypeScript SDK - MemoryInspector class via collection.inspector()
  3. Inspector UI - <veclabs-inspector> web component that embeds anywhere

Quick Start

import { SolVec } from '@veclabs/solvec';

const sv = new SolVec({ network: 'devnet' });
const collection = sv.collection('agent-memory', { dimensions: 1536 });

// Get the inspector
const inspector = collection.inspector();

// After some upserts...
await collection.upsert([
  { id: 'mem_1', values: embedding, metadata: { text: 'User prefers dark mode' } },
]);

// Check stats
const stats = await inspector.stats();
console.log(stats.totalMemories); // 1
console.log(stats.currentMerkleRoot); // 64-char hex string

// Inspect all memories
const result = await inspector.inspect();
console.log(result.memories[0].id); // "mem_1"

// Verify on-chain state
const verification = await inspector.verify();
console.log(verification.match); // true if local == on-chain

API Reference

inspector.stats()

Returns collection-level statistics without iterating through memory records.
interface InspectorCollectionStats {
  totalMemories: number;
  dimensions: number;
  currentMerkleRoot: string;
  onChainRoot: string;
  rootsMatch: boolean;
  lastWriteAt: number;       // Unix ms
  lastChainSyncAt: number;   // Unix ms
  hnswLayerCount: number;
  memoryUsageBytes: number;
  encrypted: boolean;
}

inspector.inspect(query?)

Full inspection - returns stats plus a filtered list of MemoryRecord objects.
const result = await inspector.inspect({
  writtenAfter: Date.now() - 3600_000, // last hour
  limit: 20,
  offset: 0,
});

inspector.get(id)

Returns a single MemoryRecord by ID, or null if not found.
const mem = await inspector.get('mem_42');
// mem.vector, mem.metadata, mem.writtenAt, mem.hnswLayer, etc.

inspector.searchWithRecords(vector, k)

Runs a top-K similarity search and returns full MemoryRecord objects alongside their scores.
const results = await inspector.searchWithRecords(queryEmbedding, 5);
results.forEach(({ score, memory }) => {
  console.log(`${memory.id}: ${score.toFixed(4)}`);
});

inspector.merkleHistory()

Returns the full chronological history of Merkle root changes.
const history = await inspector.merkleHistory();
// [{ root, timestamp, memoryCountAtTime, trigger }, ...]

inspector.verify()

Shorthand to check whether the local Merkle root matches the on-chain root.
const { match, localRoot, onChainRoot } = await inspector.verify();

Inspector UI Component

Installation

npm install @veclabs/inspector-ui

Usage (embedded)

<script type="module">
  import '@veclabs/inspector-ui';
</script>

<veclabs-inspector collection-name="my-collection"></veclabs-inspector>

<script>
  const el = document.querySelector('veclabs-inspector');
  el.update(inspectionData);
</script>

Usage (standalone)

<script src="https://unpkg.com/@veclabs/inspector-ui/dist/inspector.js"></script>
<veclabs-inspector></veclabs-inspector>

InspectorQuery Filters

FieldTypeDescription
metadataFilterRecord<string, unknown>Exact-match filter on metadata fields
writtenAfternumberUnix ms - only memories written after this timestamp
writtenBeforenumberUnix ms - only memories written before this timestamp
hnswLayernumberFilter to a specific HNSW layer (0 = base)
limitnumberMax results (default 50, max 500)
offsetnumberPagination offset

Reading the Merkle Timeline

The Merkle Timeline shows every root change since the collection was created. Each entry records:
  • root - The 256-bit SHA-256 Merkle root at that point in time
  • timestamp - When the change happened (Unix ms)
  • memoryCountAtTime - How many memories existed when this root was computed
  • trigger - What caused the change: "write", "delete", or "bulk_write"
Use the timeline to audit the collection’s history and detect unexpected mutations.

Verification: What rootsMatch Means

When you call inspector.verify(), the inspector computes the current Merkle root from all stored vector IDs and compares it to the root stored on Solana.
  • match: true - The local collection is in sync with the on-chain root. No vectors have been tampered with, added, or removed since the last Solana sync.
  • match: false - There’s a discrepancy. Either the collection was modified locally without syncing to Solana, or the stored vectors have been corrupted.
This is the core integrity guarantee of Recall: cryptographic proof that your agent’s memory hasn’t been tampered with.