Skip to main content

Memory

WASP keeps state in three locations: PostgreSQL (durable), Redis (fast/cached), and the filesystem (/data/memory/ for backups, /data/screenshots/ for visual artifacts). Ten primary memory layers persist across restarts.

Layer overview

LayerBackingPurposeImproves with use?
EpisodicMemoryEntry (Postgres)Conversation history, file referencesYes — every turn appends
Semantic / vectorMemoryEmbedding (Postgres, JSONB)Embedding-based similarity retrievalYes — embeddings on promotion
Knowledge graphKnowledgeNode, KnowledgeRelation (Postgres) + kg:node:* (Redis)Entities, relations, preferencesYes — extracted from conversations
ProceduralProceduralMemory (Postgres)Multi-step procedures abstracted from successful runsYes — learned from execution
BehavioralBehavioralRule (Postgres)Rules learned from user correctionsYes — corrections trigger learning
Learning examplesLearningExample (Postgres)Positive/negative few-shotsYes — feedback adds examples
VisualVisualMemory (Postgres)Indexed screenshots with metadataYes — every browser capture
Goal-scopedGoalMemory (Postgres)Per-goal observations during executionYes — bounded to goal lifetime
Temporal world modelWorldTimeline, EntityState, StatePrediction (Postgres)Time-series of entities (prices, system metrics)Yes — extracted from skill outputs
Ranking(computed)Composite retrieval scoringNo — algorithm

Each layer has a dedicated topic page in Cognitive Systems. This page focuses on the foundational layers (episodic, semantic, ranking) and the global picture.

Episodic memory

memory/index.py, memory/store.py.

Every chat turn writes a MemoryEntry row:

id (UUID), memory_type (enum), project_id, chat_id,
file_path, tags (JSONB), content_summary, content_hash,
importance, access_count, created_at, version

MemoryManager.add_episodic() inserts; query_episodic() retrieves with ranking.

PromotionEngine scans episodic entries and promotes those that recur or have high importance into semantic memory. Runs on a schedule (promotion job, 12 h) plus inside the dream cycle.

ForgettingCurve decays stale entries; MemoryCleanupJob (daily) drops entries below the importance floor.

Semantic / vector memory

memory/vector_memory.py, memory/embeddings/*.py.

Embeddings are stored as MemoryEmbedding rows with the embedding as JSONB float32. Three embedding backends:

BackendWhenFile
OpenAIIf OPENAI_API_KEY present and EMBEDDING_PROVIDER=openaiembeddings/openai.py
OllamaIf --profile local-llm is upembeddings/ollama.py
Hash fallbackAlways available; deterministic SHA-512 vectorembeddings/hash_fallback.py

Cosine similarity search (vector_search(query, top_k)) is the primary retrieval. The Vector Index Job (vector_index, default 600 s) backfills missing embeddings.

Ranking

memory/ranking.py.

Composite relevance scoring:

score = 0.5 × similarity + 0.3 × recency + 0.2 × importance

_recency_score() is exponential decay (half_life_hours = 24).

Applied to retrieved memories before injection.

Memory injection budget

The Context Builder injects memory into every prompt with caps to control cost:

LayerCap
Episodicadaptive (last N exchanges, sized to remaining budget)
Semantic / vector5 entries
Procedural3 procedures
Goal-scoped5 observations
Knowledge graph(compact format, varies)
Behavioral rulesall active rules
Self-modelstrengths + known failures + active preferences
Epistemic statehigh/medium/low summary
Temporalrecent observations relevant to current text

Total memory block typically 2–8 KB. Progressive truncation when approaching model context window: full → 4 exchanges → 2 → 1, system prompt always preserved. Logged as model_manager.overflow_recovered.

Auxiliary state

Two agent-state Redis keys complement the SQL layers:

KeyModulePurpose
agent:self_model (+ :version)agent/self_model.pyStrengths, known failures, user preferences, weekly stats; file backup at /data/memory/self_model.json
agent:epistemicagent/epistemic.pyPer-domain confidence; symmetric ±0.015 calibration on skill success/failure
agent:cpi (+ :cpi_high)agent/cpi.pyComposite cognitive pressure 0–100

Resetting memory

Three escalation levels:

LevelAction
Per-chat/wipe_all Telegram command — drops episodic + flow lock for the current chat
Per-layerSQL DELETE from a specific table; or dashboard /memory, /behavioral-rules, /knowledge-graph per-row delete
Full resetDashboard /reset (Panic Reset) — wipes 17 tables + 12+ Redis key patterns + agent identity, runs VACUUM FULL

Panic Reset never erases: API keys, Docker volumes, custom Python skills, subscriptions, prime.md, /data/src_patches/ backups.

See also