Retrieval¶
Use retrieve() for normal recall and retrieve_with_explanations() when you need
ranking-time introspection.
The stable explainability surface is:
EmotionalMemory.retrieve_with_explanations()AsyncEmotionalMemory.retrieve_with_explanations()RetrievalSignalsRetrievalBreakdownRetrievalExplanation
These models describe the ranking plan before retrieval-side mutation. The returned
Memory objects may already reflect post-retrieval updates such as reconsolidation.
Lower-level helpers in emotional_memory.retrieval are documented here because they
shape the scoring model, but they are not all promoted as stable top-level API. In
particular, build_retrieval_plan() remains an engine helper rather than a supported
root import.
emotional_memory.retrieval.RetrievalConfig
¶
Bases: BaseModel
Parameters for multi-signal retrieval scoring.
adaptive_weights_config: AdaptiveWeightsConfig = AdaptiveWeightsConfig()
class-attribute
instance-attribute
¶
Parameters for smooth mood-modulated weight adjustment.
ape_threshold: float = 0.3
class-attribute
instance-attribute
¶
Affective Prediction Error threshold to trigger reconsolidation.
base_weights: list[float] = [0.35, 0.25, 0.15, 0.1, 0.1, 0.05]
class-attribute
instance-attribute
¶
Weights for [semantic, mood_congruence, affect_proximity, momentum_alignment, recency, resonance_boost]. Must have exactly 6 elements.
candidate_multiplier: int = 3
class-attribute
instance-attribute
¶
Pre-filter multiplier: when the store has > top_k * candidate_multiplier entries, use search_by_embedding to fetch top_k * candidate_multiplier candidates before full multi-signal scoring.
query_classifier: QueryClassifierConfig | None = None
class-attribute
instance-attribute
¶
Per-query-type weight routing. None = disabled (default behaviour).
reconsolidation_learning_rate: float = 0.2
class-attribute
instance-attribute
¶
Alpha for tag update on reconsolidation. Max shift = 50%.
reconsolidation_window_seconds: float = 300.0
class-attribute
instance-attribute
¶
Seconds after retrieval during which the tag remains labile.
emotional_memory.retrieval.QueryClassifierConfig
¶
Bases: BaseModel
Configuration for per-query-type retrieval weight routing.
Set mode to 'heuristic' to activate the built-in regex classifier at
zero latency overhead, or 'llm' to use an external QueryClassifier
instance passed to the engine constructor. 'disabled' (default) leaves
weight routing inactive and preserves existing behaviour.
routed_weights maps query-type labels to 6-element weight vectors (same
order as RetrievalConfig.base_weights). LOCOMO_ROUTING from
emotional_memory.query_classifier is a ready-to-use routing table.
Routing selects the starting weights, it does not bypass adaptive
weighting: the routed vector replaces base_weights and is then still
modulated by the current mood via adaptive_weights() (and by the
ablation mask). A routed [1, 0, 0, 0, 0, 0] therefore yields a
pure-semantic ranking only under a neutral/calm mood; to gate signals off
unconditionally, disable them via the enable_* ablation flags or route
in front of the engine instead.
default_type: str = 'default'
class-attribute
instance-attribute
¶
Fallback key when the classified type has no entry in routed_weights.
mode: Literal['disabled', 'heuristic', 'llm'] = 'disabled'
class-attribute
instance-attribute
¶
'heuristic' — auto-create HeuristicQueryClassifier; 'llm' — use the QueryClassifier instance supplied to the engine constructor; 'disabled' — off.
routed_weights: dict[str, list[float]] = Field(default_factory=dict)
class-attribute
instance-attribute
¶
Per-type weight override. Unknown types fall back to default_type.
emotional_memory.retrieval.AdaptiveWeightsConfig
¶
Bases: BaseModel
Parameters for smooth mood-modulated retrieval weight adjustment.
Each of the three psychological conditions (negative mood, high arousal, calm/neutral) is modelled as a continuous sigmoid or Gaussian gate rather than a hard threshold, eliminating discontinuities in retrieval behaviour.
sharpness controls how step-like the transition is: a value of ~50
approximates the old hard-threshold behaviour; the default of 5.0 produces
a smooth transition centred at the given point.
emotional_memory.retrieval.RetrievalSignals
¶
Bases: BaseModel
Named retrieval signal values for explainability.
The six fields map directly to the composite scorer
semantic_similarity mood_congruence affect_proximity momentum_alignment recency resonance
total() -> float
¶
Return the sum of all six signals.
emotional_memory.retrieval.RetrievalBreakdown
¶
Bases: BaseModel
Structured decomposition of one retrieval score.
emotional_memory.retrieval.RetrievalExplanation
¶
Bases: BaseModel
One retrieved memory plus the score decomposition that ranked it.
score and breakdown describe the ranking-time score before any
side effects of retrieval (for example reconsolidation or Hebbian
strengthening) are applied. memory is the post-retrieval memory state.
emotional_memory.retrieval.retrieval_score(query_embedding: list[float], query_affect: CoreAffect, current_mood: MoodField, current_momentum: AffectiveMomentum, memory: Memory, activation_map: dict[str, float], now: datetime, decay_config: DecayConfig, retrieval_config: RetrievalConfig, precomputed_weights: NDArray[np.float64] | None = None) -> float
¶
Compute the composite retrieval score for a single memory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
activation_map
|
dict[str, float]
|
Pre-computed spreading activation levels from
|
required |
precomputed_weights
|
NDArray[float64] | None
|
Pre-computed adaptive weights from |
None
|
Source code in src/emotional_memory/retrieval.py
emotional_memory.retrieval.retrieval_breakdown(query_embedding: list[float], query_affect: CoreAffect, current_mood: MoodField, current_momentum: AffectiveMomentum, memory: Memory, activation_map: dict[str, float], now: datetime, decay_config: DecayConfig, retrieval_config: RetrievalConfig, precomputed_weights: NDArray[np.float64] | None = None) -> RetrievalBreakdown
¶
Return the full score decomposition for one memory.
This is the explainable counterpart to retrieval_score() and uses the
exact same scoring path.
Source code in src/emotional_memory/retrieval.py
emotional_memory.retrieval.adaptive_weights(mood: MoodField, base: list[float], config: AdaptiveWeightsConfig | None = None) -> NDArray[np.float64]
¶
Return retrieval weights modulated by current mood state.
Mood acts as a weight modulator — not a hard filter but a continuous shaping of what signals dominate retrieval (inspired by mood-congruent recall research, Bower 1981).
Three conditions are applied as smooth continuous functions (tanh / Gaussian) rather than hard thresholds, eliminating discontinuities at boundary values while preserving the same directional intent: - Negative mood → emotional signals dominate (s2, s3 ↑, s1 ↓) - High arousal → momentum alignment dominates (s4 ↑, s1 ↓) - Calm/neutral → semantic retrieval dominates (s1 ↑, s2, s3 ↓)
Source code in src/emotional_memory/retrieval.py
emotional_memory.retrieval.reconsolidate(tag: EmotionalTag, current_affect: CoreAffect, ape: float, learning_rate: float) -> EmotionalTag
¶
Update the tag's core_affect proportionally to the APE.
alpha = min(ape * learning_rate, 0.5) — linearly scaled, capped at 50% per retrieval. Pearce-Hall associability (large errors increase the learning rate) is handled separately by update_prediction(). Only core_affect is updated; all other fields remain unchanged. reconsolidation_count is incremented.
Source code in src/emotional_memory/retrieval.py
emotional_memory.retrieval.compute_ape(tag: EmotionalTag, observed: CoreAffect) -> float
¶
Compute Affective Prediction Error for a memory tag.
Uses tag.expected_affect as the reference point when set; otherwise
falls back to tag.core_affect (i.e. the encoding-time affect).
The APE is the Euclidean distance in affect space between the expected and observed affect (Pearce & Hall, 1980).
Source code in src/emotional_memory/retrieval.py
emotional_memory.retrieval.update_prediction(tag: EmotionalTag, observed: CoreAffect, ape: float) -> EmotionalTag
¶
Update the tag's expected_affect via Pearce-Hall associability learning.
The learning rate is adaptive: large APE increases the rate (fast relearning after surprise), small APE decreases it (stable predictions need less updating).
Learning-rate update (Pearce-Hall: associability tracks prediction error): target_lr = clamp(ape, 0.05, 0.80) # the APE magnitude is the attractor new_lr = current_lr + 0.2 * (target_lr - current_lr) # smooth adaptation new_lr = clamp(new_lr, 0.05, 0.80)
The new expected_affect is an EMA blend
new_expected = lerp(current_expected, observed, new_lr)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tag
|
EmotionalTag
|
The tag whose prediction should be updated. |
required |
observed
|
CoreAffect
|
The affect observed at retrieval time. |
required |
ape
|
float
|
The pre-computed APE (from compute_ape). |
required |
Returns:
| Type | Description |
|---|---|
EmotionalTag
|
Updated tag with new |
EmotionalTag
|
All other fields are unchanged. |
References¶
Pearce, J. M., & Hall, G. (1980). A model for Pavlovian learning: Variations in the effectiveness of conditioned but not of unconditioned stimuli. Psychological Review, 87(6), 532-552.