memory / episodes.py — EpisodicMemory

Structured episodes — sequences of actions and outcomes — with optional vector search for trigger similarity.

Storage

SQLite at memory_dir/episodic_memory.db; threading.RLock guards all access.

Tables

episodes

ColumnType
idINTEGER PK
trigger / context / outcome / lesson / cluster_idTEXT
outcome_success0/1
timestampREAL
consolidated0/1

Indexes on trigger, cluster_id, timestamp.

episode_actions

ColumnType
idINTEGER PK
episode_idFK → episodes.id
action_orderINT
tool_nameTEXT
tool_argsJSON
resultTEXT
success0/1

Retention

MAX_EPISODES = 500. When exceeded the oldest non-lesson, non-consolidated episodes are deleted first. MAX_ACTIONS_PER_EPISODE = 20.

Public API

MethodEffect
record_episode(trigger, context, actions, outcome, success, lesson, cluster_id) -> intInsert episode + action rows; return id.
search_similar(trigger, limit, vector_memory=None) -> list[dict]Vector search if vector_memory available; else substring match.
search_by_outcome(success, limit)Filter by success/failure.
search_recoveries(error_context, limit, vector_memory=None)Find recovery strategies for similar past errors.
get_episode(id)Full episode + actions.
get_recent_episodes(limit)Most recent episodes (no actions).
get_episodes_by_cluster(cluster_id, limit)Cluster-grouped.
mark_consolidated(ids) / get_unconsolidated(limit)Dream-cycle markers.
format_for_context(episodes, max_chars)LLM-injection format.
count()Total episodes.