Problem
add() embeds one string at a time. fastembed's embed() takes an iterable and batches internally, so storing 1,000 memories one by one pays per-call overhead a thousand times over.
This blocks bulk import (#20) from being usable at any real size, and makes the benchmark harness (#21) slow to set up.
What to build
MemoryStore.add_many(items: Sequence[MemoryInput]) -> list[Memory]
One embedding call for the whole batch, one transaction for the inserts.
Acceptance criteria
Notes
Deliberately library-only for now — no MCP tool. An agent storing memories one at a time is the normal case, and a bulk tool invites an agent to dump a conversation into memory wholesale, which is exactly the low-value noise that degrades search. Bulk import is a human operation.
Pointers
src/localmem_mcp/store.py — add(); note self.embedder.embed() already accepts a sequence
- The
_lock and with self._conn transaction pattern in add()
Problem
add()embeds one string at a time. fastembed'sembed()takes an iterable and batches internally, so storing 1,000 memories one by one pays per-call overhead a thousand times over.This blocks bulk import (#20) from being usable at any real size, and makes the benchmark harness (#21) slow to set up.
What to build
One embedding call for the whole batch, one transaction for the inserts.
Acceptance criteria
embed()call for the batch, not one per itemMemoryrecords in input order, with their idsadd(): empty content rejected, tags normalizedadd(), posted on the issuedocs/guide/python-library.mdplusCHANGELOG.mdNotes
Deliberately library-only for now — no MCP tool. An agent storing memories one at a time is the normal case, and a bulk tool invites an agent to dump a conversation into memory wholesale, which is exactly the low-value noise that degrades search. Bulk import is a human operation.
Pointers
src/localmem_mcp/store.py—add(); noteself.embedder.embed()already accepts a sequence_lockandwith self._conntransaction pattern inadd()