Configuration

On this page

All tunables live on the single MemoryConfig dataclass (memory.core.config.MemoryConfig). Pass an instance to AIMemoryManager(config=...), or build one individual memory class at a time with its own constructor arguments (most classes don't read MemoryConfig directly — see the per-class API pages for which constructor args map to which config fields).

Full field reference

FieldTypeDefaultPurpose
max_short_termint1000Validated (≥ 1) capacity hint for short-term memory. Not actually enforced by ShortTermMemory — that class takes its own window_size constructor argument instead (see ShortTermMemory). Only consumed by MemoryType.SHORT_TERM.default_capacity.
max_long_termint1000Read by AIMemoryManager.run_maintenance() to decide when to trigger LTM compression (ltm_count > max_long_term * 0.8).
max_workingint1000Passed as WorkingMemory(capacity=...) inside _TenantBundle.
max_episodicint1000Only consumed by MemoryType.EPISODIC.default_capacity — no EpisodicMemory class exists in this package.
max_semanticint1000Only consumed by MemoryType.SEMANTIC.default_capacity. Not enforced by SemanticMemory (unbounded growth).
max_procedralint1000Typo for "procedural" — only consumed by MemoryType.PROCEDURAL.default_capacity. No ProceduralMemory class exists.
importance_thresholdfloat0.7Validated (0–1). Used by AIMemoryManager.save_interaction() to decide whether to promote an entry to LTM.
similarity_thresholdfloat0.85Validated (0–1). Documented for memory consolidation; not read by any class in this source tree.
retrieval_limitint10Validated (≥ 1). Passed as SelectionConfig(top_k=...) when AIMemoryManager builds its shared MemorySelector.
embedding_modelstr"all-MiniLM-L6-v2"Passed to SemanticMemory(model_name=...). Only takes effect if sentence-transformers is installed.
embedding_batch_sizeint32Documented; not read by SemanticMemory or _EmbeddingModel (batching uses whatever list size you pass to embed_batch).
embedding_cache_sizeint1000Passed as SemanticMemory(cache_size=...) → _EmbeddingModel's LRU embedding cache size.
normalize_textboolFalseDocumented; not read anywhere in this source tree.
preserve_caseboolTrueDocumented; not read anywhere in this source tree.
remove_duplicatesboolTrueDocumented; not read anywhere in this source tree — see MemoryCompressor.merge_duplicates for the actual dedup mechanism, which is unconditional and independently configured.
enable_persistenceboolTrueRead by AIMemoryManager.__init__ to decide whether UserProfileManager gets a persist_dir (JSON-file profile persistence). Does not gate LongTermMemory, which always persists to SQLite regardless of this flag.
persistence_pathstr"./memory_storage"Base directory. AIMemoryManager derives {persistence_path}/{tenant_id}_ltm.db for each tenant's SQLite file and {persistence_path}/profiles for profile JSON files.
auto_save_intervalint300Documented ("5 minutes"); no scheduler or timer reads this field anywhere in this source tree — there is no auto-save loop.
return_messagesboolFalseForwarded as the return_messages constructor arg default for ConversationBufferMemory/ConversationBufferWindowMemory only if you pass config.return_messages explicitly — the memory classes' own constructors default this independently to False and do not read MemoryConfig themselves.
input_key / output_key / memory_keystr"input" / "output" / "history"Same caveat as above — these are the default values baked into the memory class constructors, not values sourced from a MemoryConfig instance at runtime.
max_token_limitint2000Used as the class-level default for ConversationSummaryMemory.__init__'s max_token_limit parameter (memory_config.max_token_limit, evaluated once at import time against MemoryConfig's own class attribute — see Known Issues).
window_sizeint5Same pattern — read once as MemoryConfig's class attribute for _TenantBundle.stm = ShortTermMemory(window_size=config.window_size, ...). This one is correctly read from your actual config instance because _TenantBundle passes config.window_size explicitly, unlike the class-default cases above.
enable_decayboolTrueValidated (decay_rate range checked only if this is True). Documented; AIMemoryManager always applies decay in run_maintenance() regardless of this flag's value — it is not actually checked before decay is applied.
decay_ratefloat0.1Validated (0–1 if enable_decay). Passed to ShortTermMemory.apply_decay(), LongTermMemory.apply_global_decay(), and as ForgettingConfig.base_decay_rate.
min_importancefloat0.1Passed to ShortTermMemory.evict_below(), LongTermMemory.delete_below_importance(), and as ForgettingConfig.min_importance / deletion_threshold.
enable_consolidationboolTrueDocumented; not read anywhere in this source tree.
consolidation_intervalint3600Documented; not read anywhere in this source tree — there is no scheduler.
max_tokensint2000Passed as both WorkingMemory(token_budget=...) and ContextBuilder(total_token_budget=...) inside AIMemoryManager.__init__.
log_levelstr"INFO"Documented; not read anywhere in this source tree — configure Python logging yourself.
enable_statsboolTrueDocumented; not read anywhere in this source tree.

[!WARNING] Several fields are documented but unused As flagged inline above, a substantial number of MemoryConfig fields (similarity_threshold, embedding_batch_size, normalize_text, preserve_case, remove_duplicates, auto_save_interval, enable_consolidation, consolidation_interval, log_level, enable_stats, max_short_term, max_episodic, max_semantic, max_procedral, enable_decay) are declared and validated but not read by any class in this source tree. This was confirmed by grepping every reference to config.<field> and self.config.<field> across the package. Don't assume setting them changes runtime behavior unless you've verified it against your actual installed version.

Validation rules

MemoryConfig.__post_init__ calls _validate(), which raises ValueError if:

  • max_short_term < 1
  • importance_threshold is outside [0, 1]
  • similarity_threshold is outside [0, 1]
  • retrieval_limit < 1
  • enable_decay is True and decay_rate is outside [0, 1]

No other fields are validated — e.g. max_working, max_long_term, min_importance, and all string fields accept any value including negative numbers or empty strings without error.

Loading from environment variables

Python · 3 lines
from zerda.memory import MemoryConfig

config = MemoryConfig.from_env()

from_env() only maps five environment variables — every other field falls back to its dataclass default even if you have other MEMORY_* variables set:

Env varMaps to
MEMORY_MAX_SHORT_TERMmax_short_term (default 100 here, not 1000 — from_env's own fallback differs from the dataclass field default)
MEMORY_MAX_LONG_TERMmax_long_term
MEMORY_EMBEDDING_MODELembedding_model
MEMORY_PERSISTENCE_PATHpersistence_path
MEMORY_ENABLE_PERSISTENCEenable_persistence (compared case-insensitively against the literal string "true")

Serializing configuration

MemoryConfig.to_dict() returns only 10 of the 32 declared fields (max_short_term, max_long_term, max_working, max_episodic, importance_threshold, similarity_threshold, retrieval_limit, embedding_model, enable_persistence, enable_decay). If you need a complete snapshot for logging or persistence, use dataclasses.asdict(config) instead:

Python · 6 lines
from dataclasses import asdict
from zerda.memory import MemoryConfig

config = MemoryConfig()
full_dict = asdict(config)   # all 32 fields
partial_dict = config.to_dict()  # only 10 fields

Related pages