core.memory

Memory vector recall: semantic search over PermanentHistory turns.

Tier 1 primitives:

  • TurnHit — ranked result returned by search.

  • Entry — storage tuple yielded by TurnVectorStore.iter_entries.

  • TurnVectorStore — in-memory append-only vector store with cosine-similarity search.

L2 adds:

  • Memory — facade combining an Embeddings backend with a TurnVectorStore for high-level index_turn / search / reindex operations.

L3 adds:

  • persist_store() / load_store() — Parquet persistence for the in-memory store.

Memory vector recall: semantic search over PermanentHistory turns.

Tier 1 primitives:

  • TurnHit — ranked result returned by search.

  • Entry — storage tuple yielded by TurnVectorStore.iter_entries.

  • TurnVectorStore — in-memory append-only vector store with cosine-similarity search.

L2 adds:

  • Memory — facade combining an Embeddings backend with a TurnVectorStore for high-level index_turn / search / reindex operations.

L3 adds:

class Entry(text, embedding, turn, metadata)[source]

Bases: NamedTuple

Storage tuple yielded by TurnVectorStore.iter_entries.

Fields mirror what was passed to add() at index time. Used by Memory.reindex() (L2) and persist_store() (L3) to read the store’s full contents without reaching into private state.

Parameters:
text

The plain text that was embedded.

Type:

str

embedding

The float vector returned by the embedding backend.

Type:

list[float]

turn

The raw turn dict.

Type:

dict[str, Any]

metadata

The caller-provided metadata dict.

Type:

dict[str, Any]

text: str

Alias for field number 0

embedding: list[float]

Alias for field number 1

turn: dict[str, Any]

Alias for field number 2

metadata: dict[str, Any]

Alias for field number 3

class Memory(embeddings, store=None)[source]

Bases: object

Semantic recall over completed conversation turns.

Wraps an EmbeddingBackend and a TurnVectorStore. Provides two indexing entry points:

  • index_turn() / aindex_turn() — extract text from a structured turn dict via turn["content"][0]["text"].

  • index_turn_text() / aindex_turn_text() — embed an arbitrary caller-supplied string while still storing the structured turn dict alongside. Used by HistoryRecorder (L4) to embed the Q+A pair (f"{prompt}\n{response}") rather than just the response.

Parameters:
  • embeddings (EmbeddingBackend) – Embedding backend (LiteLLM API model or local local/... model). Any object implementing EmbeddingBackend is accepted.

  • store (TurnVectorStore | None) – Optional TurnVectorStore. Defaults to a fresh instance. Public and settable so callers can swap in a store loaded from Parquet (L3).

index_turn(turn, metadata=None)[source]

Embed turn["content"][0]["text"] and store the turn.

Parameters:
  • turn (dict[str, Any]) – Turn dict mirroring PermanentHistory shape. Must contain content[0]["text"].

  • metadata (dict[str, Any] | None) – Optional caller metadata. Defaults to empty dict.

Returns:

The integer index of the stored entry.

Return type:

int

index_turn_text(text, turn, metadata=None)[source]

Embed an arbitrary text and store the structured turn.

Use this when the embedded text differs from turn["content"][0]["text"] — e.g., when embedding the Q+A pair (f"{prompt}\n{response}") while still storing the response as the canonical turn content.

Parameters:
  • text (str) – The plain text to embed.

  • turn (dict[str, Any]) – The structured turn dict to store alongside.

  • metadata (dict[str, Any] | None) – Optional caller metadata.

Returns:

The integer index of the stored entry.

Return type:

int

async aindex_turn(turn, metadata=None)[source]

Async variant of index_turn().

Parameters:
Return type:

int

async aindex_turn_text(text, turn, metadata=None)[source]

Async variant of index_turn_text().

Parameters:
Return type:

int

search(query, top_k=5, threshold=None)[source]

Embed query and return ranked hits from the store.

Parameters:
  • query (str) – Plain-text query.

  • top_k (int) – Maximum hits to return.

  • threshold (float | None) – Optional minimum cosine similarity.

Returns:

List of TurnHit sorted by score descending.

Return type:

list

async asearch(query, top_k=5, threshold=None)[source]

Async variant of search().

Parameters:
Return type:

list

reindex(new_embeddings)[source]

Re-embed all stored texts with a new embedding model.

Reads all entries via TurnVectorStore.iter_entries(), clears the store, and re-adds each entry with the new embedding. The turn dicts and metadata are preserved verbatim. After reindexing, self._embeddings is updated so subsequent search() calls embed queries with the new model.

Parameters:

new_embeddings (EmbeddingBackend) – The new embedding backend to use.

Return type:

None

count()[source]

Number of turns currently indexed.

Return type:

int

clear()[source]

Remove all indexed turns.

Return type:

None

class TurnHit(score, turn, turn_index, text, metadata)[source]

Bases: object

A single ranked result returned by TurnVectorStore.search.

Parameters:
score

Cosine similarity in [-1.0, 1.0] between the query embedding and the stored turn’s embedding. Sorted descending by search().

Type:

float

turn

The raw turn dict stored at index time. Mirrors the PermanentHistory turn shape: {"role": str, "content": [{"type": "text", "text": str}], "timestamp": float, "metadata": dict}.

Type:

dict[str, Any]

turn_index

Position of the entry in TurnVectorStore at the time of the search. Stable within a single search() call for a given store; may shift after clear().

Type:

int

text

Pre-extracted plain text (typically the Q+A pair) that was embedded. Equal to the string passed to add(text=...).

Type:

str

metadata

Caller-provided metadata attached at index time. Always present (possibly empty dict). Tier 2 will populate user_id / session_id / agent_id here.

Type:

dict[str, Any]

score: float
turn: dict[str, Any]
turn_index: int
text: str
metadata: dict[str, Any]
class TurnVectorStore[source]

Bases: object

Append-only in-memory store of embedded turns with cosine search.

Entries are stored in four parallel lists keyed by an integer index. add() returns the index of the appended entry; that index is preserved on the corresponding TurnHit returned by search().

Search is O(N) over all stored entries. Adequate for Tier 1 scale; a vector-index backend (Chroma/Qdrant) is a future concern.

add(text, embedding, turn, metadata=None)[source]

Append an entry and return its integer index.

Parameters:
  • text (str) – Plain text that was embedded.

  • embedding (list[float]) – Float vector returned by the embedding backend.

  • turn (dict[str, Any]) – Raw turn dict (mirrors PermanentHistory turn shape).

  • metadata (dict[str, Any] | None) – Caller metadata. Defaults to an empty dict.

Returns:

The integer index of the newly appended entry.

Return type:

int

search(query_embedding, top_k=5, threshold=None)[source]

Return up to top_k turns ranked by cosine similarity.

Parameters:
  • query_embedding (list[float]) – Embedded query vector.

  • top_k (int) – Maximum hits to return.

  • threshold (float | None) – Optional minimum cosine similarity. Hits below this score are excluded. None means no floor.

Returns:

Hits sorted by score descending. Empty list if the store is empty or all hits fall below threshold.

Return type:

list[TurnHit]

iter_entries()[source]

Yield all entries as Entry tuples in insertion order.

Used by Memory.reindex() and persist_store() to read the store’s full contents without exposing the underlying lists.

Return type:

Iterator[Entry]

count()[source]

Number of entries currently in the store.

Return type:

int

clear()[source]

Remove all entries. Subsequent count() returns 0.

Return type:

None

cosine_similarity(a, b)[source]

Cosine similarity between two equal-length float vectors.

Thin wrapper around Embeddings.cosine_similarity() so that turn_store consumers don’t need to import the Embeddings class just to compute similarity. Returns 0.0 when either vector has zero magnitude.

Parameters:
  • a (list[float]) – First vector.

  • b (list[float]) – Second vector. Must be the same length as a.

Returns:

Cosine similarity in [-1.0, 1.0].

Return type:

float

load_store(path)[source]

Load a Parquet file written by persist_store() into a fresh store.

Parameters:

path (str) – Source file path.

Returns:

A new TurnVectorStore whose entries and ordering match what was persisted.

Raises:
Return type:

TurnVectorStore

persist_store(store, path)[source]

Write all entries in store to a Parquet file at path.

Overwrites any existing file. Empty stores produce a valid zero-row Parquet file.

Parameters:
  • store (TurnVectorStore) – The TurnVectorStore to serialize.

  • path (str) – Destination file path. Parent directories are created.

Return type:

None

Classes

class Entry(text, embedding, turn, metadata)[source]

Bases: NamedTuple

Storage tuple yielded by TurnVectorStore.iter_entries.

Fields mirror what was passed to add() at index time. Used by Memory.reindex() (L2) and persist_store() (L3) to read the store’s full contents without reaching into private state.

Parameters:
text

The plain text that was embedded.

Type:

str

embedding

The float vector returned by the embedding backend.

Type:

list[float]

turn

The raw turn dict.

Type:

dict[str, Any]

metadata

The caller-provided metadata dict.

Type:

dict[str, Any]

text: str

Alias for field number 0

embedding: list[float]

Alias for field number 1

turn: dict[str, Any]

Alias for field number 2

metadata: dict[str, Any]

Alias for field number 3

count(value, /)

Return number of occurrences of value.

index(value, start=0, stop=9223372036854775807, /)

Return first index of value.

Raises ValueError if the value is not present.

class Memory(embeddings, store=None)[source]

Bases: object

Semantic recall over completed conversation turns.

Wraps an EmbeddingBackend and a TurnVectorStore. Provides two indexing entry points:

  • index_turn() / aindex_turn() — extract text from a structured turn dict via turn["content"][0]["text"].

  • index_turn_text() / aindex_turn_text() — embed an arbitrary caller-supplied string while still storing the structured turn dict alongside. Used by HistoryRecorder (L4) to embed the Q+A pair (f"{prompt}\n{response}") rather than just the response.

Parameters:
  • embeddings (EmbeddingBackend) – Embedding backend (LiteLLM API model or local local/... model). Any object implementing EmbeddingBackend is accepted.

  • store (TurnVectorStore | None) – Optional TurnVectorStore. Defaults to a fresh instance. Public and settable so callers can swap in a store loaded from Parquet (L3).

index_turn(turn, metadata=None)[source]

Embed turn["content"][0]["text"] and store the turn.

Parameters:
  • turn (dict[str, Any]) – Turn dict mirroring PermanentHistory shape. Must contain content[0]["text"].

  • metadata (dict[str, Any] | None) – Optional caller metadata. Defaults to empty dict.

Returns:

The integer index of the stored entry.

Return type:

int

index_turn_text(text, turn, metadata=None)[source]

Embed an arbitrary text and store the structured turn.

Use this when the embedded text differs from turn["content"][0]["text"] — e.g., when embedding the Q+A pair (f"{prompt}\n{response}") while still storing the response as the canonical turn content.

Parameters:
  • text (str) – The plain text to embed.

  • turn (dict[str, Any]) – The structured turn dict to store alongside.

  • metadata (dict[str, Any] | None) – Optional caller metadata.

Returns:

The integer index of the stored entry.

Return type:

int

async aindex_turn(turn, metadata=None)[source]

Async variant of index_turn().

Parameters:
Return type:

int

async aindex_turn_text(text, turn, metadata=None)[source]

Async variant of index_turn_text().

Parameters:
Return type:

int

search(query, top_k=5, threshold=None)[source]

Embed query and return ranked hits from the store.

Parameters:
  • query (str) – Plain-text query.

  • top_k (int) – Maximum hits to return.

  • threshold (float | None) – Optional minimum cosine similarity.

Returns:

List of TurnHit sorted by score descending.

Return type:

list

async asearch(query, top_k=5, threshold=None)[source]

Async variant of search().

Parameters:
Return type:

list

reindex(new_embeddings)[source]

Re-embed all stored texts with a new embedding model.

Reads all entries via TurnVectorStore.iter_entries(), clears the store, and re-adds each entry with the new embedding. The turn dicts and metadata are preserved verbatim. After reindexing, self._embeddings is updated so subsequent search() calls embed queries with the new model.

Parameters:

new_embeddings (EmbeddingBackend) – The new embedding backend to use.

Return type:

None

count()[source]

Number of turns currently indexed.

Return type:

int

clear()[source]

Remove all indexed turns.

Return type:

None

class TurnHit(score, turn, turn_index, text, metadata)[source]

Bases: object

A single ranked result returned by TurnVectorStore.search.

Parameters:
score

Cosine similarity in [-1.0, 1.0] between the query embedding and the stored turn’s embedding. Sorted descending by search().

Type:

float

turn

The raw turn dict stored at index time. Mirrors the PermanentHistory turn shape: {"role": str, "content": [{"type": "text", "text": str}], "timestamp": float, "metadata": dict}.

Type:

dict[str, Any]

turn_index

Position of the entry in TurnVectorStore at the time of the search. Stable within a single search() call for a given store; may shift after clear().

Type:

int

text

Pre-extracted plain text (typically the Q+A pair) that was embedded. Equal to the string passed to add(text=...).

Type:

str

metadata

Caller-provided metadata attached at index time. Always present (possibly empty dict). Tier 2 will populate user_id / session_id / agent_id here.

Type:

dict[str, Any]

score: float
turn: dict[str, Any]
turn_index: int
text: str
metadata: dict[str, Any]
class TurnVectorStore[source]

Bases: object

Append-only in-memory store of embedded turns with cosine search.

Entries are stored in four parallel lists keyed by an integer index. add() returns the index of the appended entry; that index is preserved on the corresponding TurnHit returned by search().

Search is O(N) over all stored entries. Adequate for Tier 1 scale; a vector-index backend (Chroma/Qdrant) is a future concern.

add(text, embedding, turn, metadata=None)[source]

Append an entry and return its integer index.

Parameters:
  • text (str) – Plain text that was embedded.

  • embedding (list[float]) – Float vector returned by the embedding backend.

  • turn (dict[str, Any]) – Raw turn dict (mirrors PermanentHistory turn shape).

  • metadata (dict[str, Any] | None) – Caller metadata. Defaults to an empty dict.

Returns:

The integer index of the newly appended entry.

Return type:

int

search(query_embedding, top_k=5, threshold=None)[source]

Return up to top_k turns ranked by cosine similarity.

Parameters:
  • query_embedding (list[float]) – Embedded query vector.

  • top_k (int) – Maximum hits to return.

  • threshold (float | None) – Optional minimum cosine similarity. Hits below this score are excluded. None means no floor.

Returns:

Hits sorted by score descending. Empty list if the store is empty or all hits fall below threshold.

Return type:

list[TurnHit]

iter_entries()[source]

Yield all entries as Entry tuples in insertion order.

Used by Memory.reindex() and persist_store() to read the store’s full contents without exposing the underlying lists.

Return type:

Iterator[Entry]

count()[source]

Number of entries currently in the store.

Return type:

int

clear()[source]

Remove all entries. Subsequent count() returns 0.

Return type:

None

Functions

cosine_similarity(a, b)[source]

Cosine similarity between two equal-length float vectors.

Thin wrapper around Embeddings.cosine_similarity() so that turn_store consumers don’t need to import the Embeddings class just to compute similarity. Returns 0.0 when either vector has zero magnitude.

Parameters:
  • a (list[float]) – First vector.

  • b (list[float]) – Second vector. Must be the same length as a.

Returns:

Cosine similarity in [-1.0, 1.0].

Return type:

float

load_store(path)[source]

Load a Parquet file written by persist_store() into a fresh store.

Parameters:

path (str) – Source file path.

Returns:

A new TurnVectorStore whose entries and ordering match what was persisted.

Raises:
Return type:

TurnVectorStore

persist_store(store, path)[source]

Write all entries in store to a Parquet file at path.

Overwrites any existing file. Empty stores produce a valid zero-row Parquet file.

Parameters:
  • store (TurnVectorStore) – The TurnVectorStore to serialize.

  • path (str) – Destination file path. Parent directories are created.

Return type:

None