js/ai/memory
js/ai/memory.ts
fino:ai/memory — durable, cross-session semantic memory for agents.
Memory stores embedding-backed facts and behaviours, not conversation
history. SqliteMemory supplies durable storage, uses sqlite-vec for scoped
cosine search when available, and falls back to an exact scan otherwise.
agentMemory() adds recall policy, labels, bounded utility evidence,
optional reinforcement, and optional forgetting. Controllers sharing a
namespace and store see the same committed memories, including from
concurrent sessions.
Signals and storage
Recall records exposure but does not assume a hit was useful. Applications can complete a returned selection with an eval score, or set stronger memory-specific manual feedback. The store keeps aggregates and bounded, short-lived selection receipts rather than prompts or an evidence ledger.
Conversation history and summarization remain in fino:ai/context and
fino:ai/session. See Agent Memory for the full
usage and lifecycle guide.
import { agentMemory, memoryTool, SqliteMemory } from 'fino:ai/memory';
const store = await SqliteMemory.open({ path: './memory.db', embedder });
const memory = agentMemory({ store, namespace: 'engineering' });
const remember = memoryTool(memory, { sessionId: 'debugging' });
await remember.run({ text: 'Prefer narrow root-cause fixes.', durability: 'shared' });
const selection = await memory.recall({ text: 'How should I fix this?' });
await memory.complete(selection.selectionId, { score: .9 });Interfaces
interface Embedder {
Minimal embedding provider required by semantic memory.
Methods
embed(texts: string[]): Promise<Float32Array[]>
Embed texts in input order. Every vector must have dimensions values.
Readonly Properties
readonly dimensions: number
Fixed width of vectors produced by embed(). Must be positive.
interface ContextualMemoryUtility {
One compact utility aggregate for a label context.
Properties
key: string
Stable normalized representation of the context labels.
evalCount: number
Number of eval outcomes aggregated into this context.
evalSum: number
Sum of conservatively distributed eval scores.
updatedAt: number
Last update time in milliseconds since the Unix epoch.
interface MemoryUtility {
Compact evidence retained for one memory. No raw messages are stored.
Properties
exposures: number
Number of times this memory was returned by recall.
lastExposedAt: number | null
Last exposure time, or null before first recall.
evalCount: number
Number of eval bundles contributing to this memory.
evalSum: number
Sum of conservatively distributed eval scores.
manual: number | null
Mutable manual value in [-1, 1], or null when unset.
manualUpdatedAt: number | null
Last manual feedback time, or null.
reinforcedAt: number | null
Last positive reinforcement time, or null.
contexts: ContextualMemoryUtility[]
Bounded utility summaries for relevant label contexts.
interface MemoryRecord {
A stored semantic memory.
Properties
id: string
Stable store-assigned identifier.
text: string
Text embedded and returned to an agent when recalled.
scope: MemoryScope
Explicit access scope.
labels: MemoryLabels
Normalized descriptive labels.
metadata?: Record<string, unknown>
Optional application metadata, not interpreted by memory policy.
importance: number
Base retention importance in [0, 1]. Defaults to .5.
createdAt: number
Creation time in milliseconds since the Unix epoch.
updatedAt: number
Last mutation time in milliseconds since the Unix epoch.
expiresAt: number | null
Expiry time for semi-ephemeral entries, or null.
utility: MemoryUtility
Compact mutable utility state.
interface MemoryCandidate extends MemoryRecord {
Candidate returned by a MemoryStore before controller policy reranking.
Properties
similarity: number
Embedding similarity, where larger values are more relevant.
interface MemoryStoreInput {
Input accepted by the durable store. Controllers normally construct this.
Properties
text: string
scope: MemoryScope
labels: MemoryLabels
metadata?: Record<string, unknown>
importance: number
createdAt: number
expiresAt: number | null
embedding: Float32Array
interface MemorySelectionReceipt {
Short-lived receipt connecting an eval outcome to an exact recall bundle.
Properties
id: string
namespace: string
memoryIds: string[]
contextKey: string
createdAt: number
interface MemoryStore {
Durable mechanism used by AgentMemoryController.
Implementations must make consumeSelection() single-use and atomically
apply its aggregate updates. Store values are plain structured data so the
interface can be adapted across Realm boundaries.
Readonly Properties
readonly semanticAvailable: boolean
Whether embeddings can be searched.
Methods
embed(texts: string[]): Promise<Float32Array[]>
Embed query or entry text using the store's compatible embedding model.
put(input: MemoryStoreInput): Promise<MemoryRecord>
Persist one fully-scoped entry.
setLabels(id: string, labels: MemoryLabels, updatedAt: number): Promise<MemoryRecord | null>
Replace labels after best-effort automatic classification.
get(id: string): Promise<MemoryRecord | null>
Return one memory by id, including currently suppressed entries.
search(input: {
namespace: string;
sessionId?: string;
embedding: Float32Array;
limit: number;
}): Promise<MemoryCandidate[]>
Search shared and optionally matching session entries by embedding.
recordSelection(receipt: MemorySelectionReceipt, maxSelections: number): Promise<void>
Record exposures and a bounded selection receipt.
consumeSelection(input: {
selectionId: string;
score: number;
now: number;
maxContexts: number;
reinforce: boolean;
}): Promise<boolean>
Consume one receipt and apply an eval contribution exactly once.
setManual(
id: string,
value: number | null,
now: number,
reinforce: boolean,
): Promise<MemoryRecord | null>
Replace or clear memory-specific manual feedback.
close(): Promise<void>
Release owned storage resources. Repeated calls are harmless.
interface MemoryLabelInput {
Input supplied to a configurable lightweight label classifier.
Properties
text: string
Text or summary being classified.
source: 'memory' | 'message' | 'session'
Classification moment, allowing different prompts or rules.
interface MemoryLabeler {
Optional classifier used to infer bounded labels.
Methods
label(input: MemoryLabelInput): Promise<MemoryLabels>
Return proposed labels. Errors are treated as best-effort failures.
interface MemoryLabelRules {
Rules controlling automatic and explicit label cardinality.
Properties
allowed?: Record<string, string[]>
Allowed keys and, when non-empty, allowed values for each key.
maxPerKey?: number
Maximum retained values per key. Defaults to 3.
interface RememberMemoryInput {
Input for creating a memory directly or through the creation tool.
Properties
text: string
Text to embed and remember.
scope?: MemoryRememberScope
Shared by default; session scope requires an explicit session id.
labels?: MemoryLabels
Explicit labels committed with the entry.
metadata?: Record<string, unknown>
Application metadata copied to the entry.
importance?: number
Base importance in [0, 1]. Defaults to .5.
expiresAt?: number
Optional expiry time in milliseconds since the Unix epoch.
interface MemoryQuery {
Query for semantic recall.
Properties
text: string
Natural-language text to embed.
topK?: number
Maximum returned hits. Defaults to 5.
sessionId?: string
Include session-scoped memories for this session in addition to shared memories.
runId?: string
Optional run identifier retained only by the caller, not as evidence.
labels?: MemoryLabels
Message or session labels used for boosts and contextual utility.
filter?: { labels?: MemoryLabels; metadata?: Record<string, unknown> }
Explicit hard filters.
interface RecallHit extends MemoryRecord {
A recalled entry with semantic and policy ranking details.
Properties
similarity: number
Raw embedding similarity.
score: number
Final controller score after bounded boosts and optional utility.
retention: number
Current retention multiplier; 1 when forgetting is disabled.
citation: { id: string; metadata?: Record<string, unknown> }
Source attribution suitable for model context or UI.
interface MemorySelection {
Immutable result of one recall operation.
Properties
selectionId: string
Single-use id accepted by complete().
labels: MemoryLabels
Normalized labels describing this work chunk.
hits: RecallHit[]
Ranked semantic hits.
interface MemoryForgettingOptions {
Optional exponential retention policy.
Properties
halfLifeMs: number
Base half-life in milliseconds before importance and utility adjustments.
suppressBelow?: number
Suppress hits below this retention multiplier. Defaults to .05.
interface AgentMemoryOptions {
Controller construction options.
Properties
store: MemoryStore
Durable shared store.
namespace: string
Access namespace bound to this controller.
labeler?: MemoryLabeler
Optional lightweight automatic classifier.
labelRules?: MemoryLabelRules
Label normalization and vocabulary rules.
reinforcement?: boolean
Whether utility affects ranking and retention. Defaults to false.
forgetting?: false | MemoryForgettingOptions
Exponential forgetting policy, or false to disable it. Defaults to false.
maxContexts?: number
Maximum contextual summaries retained per memory. Defaults to 8.
maxSelections?: number
Maximum outstanding selection receipts per namespace. Defaults to 256.
overfetch?: number
Semantic candidates considered per requested hit. Defaults to 4.
minSimilarity?: number
Minimum semantic similarity admitted to policy ranking. Defaults to .01.
now?: () => number
Injected clock used by all lifecycle policy. Defaults to Date.now.
interface Retriever {
Narrow semantic retrieval adapter for RAG call sites.
Methods
retrieve(text: string, opts?: Omit<MemoryQuery, 'text'>): Promise<RecallHit[]>
Return recalled hits for text, with call options overriding defaults.
interface SqliteMemoryOptions {
Options for opening the sqlite-backed durable memory store.
Properties
path: string
Filesystem path of the database, created when absent.
embedder: Embedder
Embedding model defining the store's vector space.
fs?: object
Optional filesystem provider forwarded to sqlite.
interface MemoryToolOptions {
Options binding namespace-safe authority into memoryTool().
Properties
sessionId?: string
Session id allowed for session-durability writes.
name?: string
Model-visible tool name. Defaults to remember.
Types
type MemoryScope =
| { type: 'shared'; namespace: string }
| { type: 'session'; namespace: string; sessionId: string }
A durable shared scope or a semi-ephemeral session scope.
type MemoryLabels = Record<string, string[]>
Bounded, normalized labels used for filtering, ranking, and utility context.
type MemoryRememberScope = { type: 'shared' } | { type: 'session'; sessionId: string }
Caller-facing scope. Namespace authority is bound by the controller.
type MemoryOptions = Omit<AgentMemoryOptions, 'store'> & SqliteMemoryOptions
Options for opening sqlite storage and constructing a controller at once.
Classes
class SqliteMemory implements MemoryStore {
Sqlite implementation of the durable MemoryStore contract.
Getters
get semanticAvailable(): boolean
Embedding search is available whenever the configured dimension is positive.
Methods
embed(texts: string[]): Promise<Float32Array[]>
Embed text with the model that defines this store's vector space.
put(input: MemoryStoreInput): Promise<MemoryRecord>
Persist one memory after validating its embedding width.
setLabels(id: string, labels: MemoryLabels, updatedAt: number): Promise<MemoryRecord | null>
Replace labels for an existing memory.
async get(id: string): Promise<MemoryRecord | null>
Load a memory by id.
async search(input: {
namespace: string;
sessionId?: string;
embedding: Float32Array;
limit: number;
}): Promise<MemoryCandidate[]>
Search embeddings in the shared namespace and one optional session scope.
recordSelection(receipt: MemorySelectionReceipt, maxSelections: number): Promise<void>
Atomically record aggregate exposure and retain a bounded selection receipt.
consumeSelection(input: {
selectionId: string;
score: number;
now: number;
maxContexts: number;
reinforce: boolean;
}): Promise<boolean>
Consume a selection once and aggregate its observational eval score.
setManual(
id: string,
value: number | null,
now: number,
reinforce: boolean,
): Promise<MemoryRecord | null>
Replace or clear the compact manual value for one memory.
async close(): Promise<void>
Close the sqlite connection.
Static Methods
static async open(opts: SqliteMemoryOptions): Promise<SqliteMemory>
Open a sqlite memory store, creating its versioned schema when needed.
The optional fs is forwarded to Database.open().
class AgentMemoryController {
Stateful policy coordinator over a durable, concurrently shared store.
The controller has no ambient current-session slot. Every session-specific operation carries an explicit session id, so one controller can safely be shared by simultaneous agent sessions.
Constructors
constructor(opts: AgentMemoryOptions)
Create a controller. Prefer the agentMemory() factory.
Getters
get namespace(): string
Namespace bound to this controller.
Methods
labels(input: MemoryLabelInput): Promise<MemoryLabels>
Classify a message, memory candidate, or session summary with the configured bounded label rules. Returns an empty object on classifier failure or when no labeler is configured.
async remember(input: RememberMemoryInput): Promise<MemoryRecord>
Embed, commit, and optionally auto-label one durable memory.
async recall(query: MemoryQuery): Promise<MemorySelection>
Recall semantic memories and record bounded exposure evidence.
complete(selectionId: string, outcome: { score: number }): Promise<boolean>
Apply one observational eval score to a returned selection.
async feedback(
memoryId: string,
feedback: { value: number | null },
): Promise<MemoryRecord | null>
Set, replace, or clear the strongest memory-specific utility signal.
get(memoryId: string): Promise<MemoryRecord | null>
Inspect one entry without applying recall policy or exposure.
close(): Promise<void>
Close the owned or injected store. Repeated calls are delegated safely.
Functions
function agentMemory(opts: AgentMemoryOptions): AgentMemoryController
Create a policy controller over a shared durable memory store.
function retriever(
memory: AgentMemoryController,
defaults: Omit<MemoryQuery, 'text'> = {},
): Retriever
Create a narrow semantic retriever over an agent-memory controller.
function memoryTool(
memory: AgentMemoryController,
opts: MemoryToolOptions = {},
): Tool<
{
text: string;
durability?: 'shared' | 'session';
labels?: MemoryLabels;
importance?: number;
expiresAt?: number;
},
{ content: string }
>
Create an opt-in validated tool for memory creation.
Namespace is always bound by the controller. A session write is rejected unless the tool factory was given a session id, preventing model arguments from selecting arbitrary scopes.
async function memory(opts: MemoryOptions): Promise<AgentMemoryController>
Convenience factory that opens a sqlite store and binds a controller.