Added
- feat: add `RecordMemoryError` to error hierarchy (`TaskHandlerError` subclass) (601)
- feat: add `TaskHandler.record_memory(result, error)` — builds and persists an `Episode` before resolving the Future, so `await agent.run(task)` returns only after memory is written (601)
- feat: add `Episode.error: Exception | None` field; `Episode.result` is now optional (601)
- feat: add `template` param to `reflective_memory()` for custom reflection prompts (600)
- feat: add `Memory.summary()` delegating to `store.summary()` (595)
- feat: add `memory/recipes.py` with `recency_memory()`, `similarity_memory()`, `reflective_memory()` factory functions (593)
- feat: `Memory.key_fn` is now optional, defaulting to `lambda ep: ep.task.instruction` (593)
- feat: add `recall_mode` (`RecallMode` enum) to `BaseMemoryStore` — `RecallMode.RECENT` delegates `search()` to `read_recent()`; `RecallMode.SEARCH` performs similarity lookup (590)
- feat: add `RecallMode(str, Enum)` to `data_structures.memory` (590)
- feat: add `id_` UUID field to `Episode` (588)
Changed
- refactor: remove `BaseMemory` ABC and legacy strategy classes (`RecencyMemory`, `SimilarityMemory`, `ReflectiveMemory`); `LLMAgent` and `LLMAgentBuilder` now accept `list[Memory]` directly (602)
- refactor: move `BaseMemoryStore` to `base/memory_store.py`; `base/memory.py` now contains only `BaseMemory` (587)
- refactor: move store implementations into new `memory_stores/` package — `json.py`, `qdrant/store.py`, `qdrant/utils.py` (587)
- refactor: introduce `Memory` concrete class with `key_fn` + `metadata_fns`; replaces `BaseMemory` hierarchy (586)
- refactor: `Episode.additional_data` renamed to `metadata` (`dict[str, str]`, non-optional, default `{}`) (586)
- refactor: `BaseMemoryStore.write()` `embedded_text` param renamed to `key` (586)
- refactor: `BaseMemoryStore.search()` `k` param removed; stores use `self.max_results` set at construction (586)
- refactor: `BaseMemoryStore` gains `max_results: int = 5` init param (586)