A personal assistant that tracks changing preferences
Use bi-temporal memory so a changed city, job, or diet supersedes the old fact instead of contradicting it.
People change. They move cities, switch jobs, go vegetarian. A personal assistant that just appends every new fact ends up holding both "lives in Lisbon" and "lives in Berlin" with no idea which is current — and contradicts itself the next time you ask.
FishMem handles this with bi-temporal facts.
When a new fact supersedes an old one, FishMem emits an UPDATE: search returns
the current truth, while the superseded fact is retained in history rather than
deleted. You get a consistent answer now and an audit trail of how it changed.
Add evolving facts over time
Scope everything to the user and let inference reconcile contradictions as they arrive.
import { FishMem } from 'fishmem';
const client = new FishMem({ apiKey: process.env.FISHMEM_API_KEY });
// Week 1
await client.add([{ role: 'user', content: 'I live in Lisbon.' }], { user_id: 'sam' });
// Week 8 — Sam moves. FishMem recognizes this supersedes the earlier fact.
const { results } = await client.add(
[{ role: 'user', content: 'I just moved to Berlin.' }],
{ user_id: 'sam' }
);
console.log(results);
// [ { id: "mem_...", memory: "Lives in Berlin", event: "UPDATE" } ]The UPDATE event tells you the move replaced an existing fact rather than
adding a new, unrelated one.
Search returns the current truth
A search for the user's location returns Berlin, not both cities. The old fact no longer competes in recall.
const { results } = await client.search('where does sam live?', {
user_id: 'sam',
top_k: 3,
});
console.log(results[0].memory); // "Lives in Berlin"History reveals the supersession
The old fact isn't lost — it's in the memory's history. Fetch it to see exactly how the fact evolved, including the previous and new values.
const { results } = await client.history('mem_...'); // the memory id from the UPDATE
for (const entry of results) {
console.log(entry.event, entry.previous_value, '->', entry.new_value, '@', entry.created_at);
}
// ADD null -> Lives in Lisbon @ 2026-04-01T...
// UPDATE Lives in Lisbon -> Lives in Berlin @ 2026-05-24T...This is the difference between valid-time (when the fact was true in the real world) and record-time (when FishMem learned it). Superseded facts are kept, so you can always reconstruct what the assistant believed at any point.