Skip to content

Episodic Memory

IntaGrin's memory system has three tiers already: working memory (checkpointed conversation history, memory.max_messages sliding-window eviction), long-term memory (a single evolving prose summary, state["long_term_memory"], regenerated by an LLM call whenever eviction happens — see 04_Shared_State_Redux.md), and semantic/knowledge memory (rag: — document/knowledge-base retrieval, unrelated to agent experience). episodic_memory: adds the fourth: discrete, structured, individually queryable event records — "user prefers window seats," "booking BK-4471 failed: card declined" — as opposed to the single blended long_term_memory prose summary, which can't be filtered or reliably retrieved for one specific fact.

(Procedural memory — learned skills/code — isn't included; it doesn't map onto this framework's declarative YAML/tool model.)

Episodic memory here is explicit and tool-driven, not automatic per-turn logging: an agent calls remember_episode when something notable happens, and later calls recall_episodes to look it back up.

yaml
memory:
  type: "sqlite"   # or "postgres" — episodic_memory is a no-op for redis/sliding_window/buffer/custom

episodic_memory:
  embedding_model: "text-embedding-3-small"  # defaults to match rag.embedding_model's default
  scope: "session"                            # "session" (default) | "tenant" | "global"
  default_limit: 5

Setting episodic_memory: auto-registers two tools on every agent — the same "presence triggers registration" pattern rag: uses for search_knowledge_base:

  • remember_episode(event_type, content, tags=None) — records one event. event_type is a short label you choose (e.g. "preference", "failure", "booking") used later to filter recall_episodes. tags are optional free-form labels for finer-grained filtering.
  • recall_episodes(query=None, event_type=None, tags=None, limit=None) — recalls previously recorded episodes. Omit query for a cheap structured lookup by event_type/tags/recency alone (no embedding call); pass query for embedding-based semantic similarity search over episode content. tags, if given, requires every tag to be present (AND, not OR).

Scope

episodic_memory.scope is independent of memory.shared_scope — a project might want the long_term_memory summary private per-session while episodic events are shared globally, or vice versa.

  • "session" (default): only this session_id's own episodes.
  • "tenant": shared across every session under the same authenticated caller/tenant prefix (same convention as memory.shared_scope: tenant).
  • "global": shared across every session in the project, any tenant.

Storage

Episodes are stored in a sqlite/postgres episodes table — the same self-managing-schema convention shared_memory/run_logs already use, living in the same database as checkpoints. Unlike shared_memory's single row per scope (last-write-wins), the episodes table is append-only: remember_episode always inserts a new row, so nothing is ever silently overwritten.

Limitations

There is no retention or pruning policy in this version — episodes accumulate indefinitely for a scope. For a long-running, high-frequency use of remember_episode, plan for unbounded row growth the same way you would for any other unbounded application table.

Released under the Apache 2.0 License.