diff --git a/docs/cookbooks/frameworks/mirofish-swarm-memory.mdx b/docs/cookbooks/frameworks/mirofish-swarm-memory.mdx
new file mode 100644
index 000000000..94135def9
--- /dev/null
+++ b/docs/cookbooks/frameworks/mirofish-swarm-memory.mdx
@@ -0,0 +1,766 @@
+---
+title: MiroFish Swarm Memory
+description: "Build a multi-agent swarm simulation with graph-powered memory using Mem0 and MiroFish patterns."
+---
+
+
+
+Build a multi-agent swarm simulation with graph-powered memory using Mem0 OSS and [MiroFish](https://github.com/666ghj/MiroFish) patterns. MiroFish is a graph-centric system — it extracts entities and relationships from documents, builds a knowledge graph, and queries it throughout its pipeline. Mem0's Graph Memory is a natural replacement for its Zep Cloud integration.
+
+
+ This cookbook demonstrates the **core memory patterns** using a simplified simulation. MiroFish's actual architecture uses a factory pattern (`memory_factory.py`) with abstract providers, batch buffering with retries in `ZepGraphMemoryUpdater`, and IPC-based agent interviews. This cookbook focuses on the Mem0 API integration points — wrap these calls in your own retry/batch logic for production use.
+
+
+## Overview
+
+This cookbook implements a **Housing Policy Prediction Simulation** following MiroFish's five-stage workflow:
+
+1. **Graph Building** — Ingest seed documents, extract entities and relationships
+2. **Environment Setup** — Query the knowledge graph to enrich agent profiles
+3. **Simulation** — Track agent interactions with per-agent memory isolation
+4. **Report Generation** — Semantic search + graph traversal for analysis
+5. **Deep Interaction** — Query post-simulation memory and relationships (MiroFish also supports live agent interviews via IPC — not covered here)
+
+Three agents debate a housing policy reform:
+- **Mayor Chen** — Policy advocate pushing for zoning reform
+- **Wang (Homeowner)** — Opposition leader organizing resistance
+- **Professor Li** — Academic providing data-driven analysis
+
+## Prerequisites
+
+```bash
+pip install "mem0ai[graph]"
+```
+
+You need a graph backend. Choose one:
+
+| Backend | Setup | Best for |
+|---|---|---|
+| **Neo4j Aura** (free tier) | [Sign up](https://neo4j.com/product/auradb/), get Bolt URI | Production, closest to Zep |
+| **Neo4j Docker** | `docker run -p 7687:7687 -e NEO4J_AUTH=neo4j/password neo4j:5` | Local development |
+| **Kuzu** (embedded) | No setup needed — runs in-process | Quick testing, zero dependencies |
+
+```bash
+export OPENAI_API_KEY="sk-..."
+
+# Option A: Neo4j Docker (local development)
+docker run -p 7687:7687 -e NEO4J_AUTH=neo4j/password neo4j:5
+export NEO4J_URL="neo4j://localhost:7687"
+export NEO4J_USERNAME="neo4j"
+export NEO4J_PASSWORD="password"
+
+# Option B: Neo4j Aura (production — free tier available)
+export NEO4J_URL="neo4j+s://.databases.neo4j.io"
+export NEO4J_USERNAME="neo4j"
+export NEO4J_PASSWORD="your-aura-password"
+
+# Option C: Kuzu (zero setup — auto-detected when NEO4J_URL is not set)
+# No exports needed
+```
+
+## Complete Implementation
+
+```python
+"""
+MiroFish Swarm Prediction Simulation with Mem0 Graph Memory
+
+MiroFish uses Zep Cloud as its knowledge graph backend. This implementation
+replaces Zep with Mem0 OSS Graph Memory, which provides:
+- Automatic entity extraction from text
+- Relationship mining (source → relationship → destination triples)
+- Combined vector + graph search returning memories AND relations
+- Per-agent isolation via run_id
+- Self-hosted with no node caps
+
+Follows MiroFish's 5-stage pipeline:
+1. Graph Building - Ingest seed documents, extract entities
+2. Environment Setup - Query graph to enrich agent profiles
+3. Simulation - Track agent actions with per-agent isolation
+4. Report Generation - Semantic + graph search for analysis
+5. Deep Interaction - Query post-simulation knowledge graph
+
+Run:
+ export OPENAI_API_KEY="sk-..."
+ export NEO4J_URL="neo4j://localhost:7687"
+ export NEO4J_USERNAME="neo4j"
+ export NEO4J_PASSWORD="password"
+ python mirofish_swarm_memory.py
+"""
+
+import os
+import time
+from mem0 import Memory
+
+
+# ======================================================================
+# MiroFish Agent Action Types (matches OASIS simulation output)
+# ======================================================================
+
+# Twitter actions
+TWITTER_ACTIONS = [
+ "CREATE_POST", "LIKE_POST", "REPOST", "FOLLOW",
+ "DO_NOTHING", "QUOTE_POST",
+]
+
+# Reddit actions (superset — includes moderation + discovery)
+REDDIT_ACTIONS = [
+ "LIKE_POST", "DISLIKE_POST", "CREATE_POST", "CREATE_COMMENT",
+ "LIKE_COMMENT", "DISLIKE_COMMENT", "SEARCH_POSTS", "SEARCH_USER",
+ "TREND", "REFRESH", "DO_NOTHING", "FOLLOW", "MUTE",
+]
+
+# Combined (DO_NOTHING is skipped during memory storage)
+MIROFISH_ACTIONS = list(set(TWITTER_ACTIONS + REDDIT_ACTIONS) - {"DO_NOTHING"})
+
+
+# ======================================================================
+# Graph Memory Configuration
+# ======================================================================
+
+def build_config():
+ """Build Mem0 config with Graph Memory.
+
+ Uses Neo4j if credentials are set, otherwise falls back to Kuzu (embedded).
+ """
+ neo4j_url = os.environ.get("NEO4J_URL")
+
+ # Shared config for LLM, embedder, and vector store
+ base = {
+ "llm": {
+ "provider": "openai",
+ "config": {"model": "gpt-4o-mini", "temperature": 0.1}
+ },
+ "embedder": {
+ "provider": "openai",
+ "config": {"model": "text-embedding-3-small", "embedding_dims": 1536}
+ },
+ "vector_store": {
+ "provider": "qdrant",
+ "config": {
+ "collection_name": "mirofish",
+ "embedding_model_dims": 1536,
+ }
+ },
+ }
+
+ custom_prompt = (
+ "Extract all people, organizations, policies, locations, "
+ "and their relationships. Capture support/opposition stances, "
+ "affiliations, and quantitative claims."
+ )
+
+ if neo4j_url:
+ base["graph_store"] = {
+ "provider": "neo4j",
+ "config": {
+ "url": neo4j_url,
+ "username": os.environ.get("NEO4J_USERNAME", "neo4j"),
+ "password": os.environ.get("NEO4J_PASSWORD", "password"),
+ },
+ "custom_prompt": custom_prompt,
+ }
+ else:
+ # Fallback: Kuzu embedded (no external services needed)
+ print(" NEO4J_URL not set — using Kuzu (embedded) graph store")
+ base["graph_store"] = {
+ "provider": "kuzu",
+ "config": {"db": "/tmp/mirofish_graph.kuzu"},
+ "custom_prompt": custom_prompt,
+ }
+
+ return base
+
+
+# ======================================================================
+# Simulation Engine
+# ======================================================================
+
+class MiroFishSimulation:
+ """
+ Multi-agent simulation with graph-powered memory.
+
+ Uses Mem0 Graph Memory to replace MiroFish's Zep Cloud integration:
+ - Entities and relationships are extracted automatically from text
+ - search() returns both semantic memories AND graph relations
+ - Per-agent isolation via run_id
+ - Project isolation via user_id
+ """
+
+ def __init__(self, project_id: str, config: dict):
+ self.project_id = project_id
+ self.memory = Memory.from_config(config)
+ self.stats = {
+ "documents_ingested": 0,
+ "activities_recorded": 0,
+ "rounds_completed": 0,
+ }
+
+ # ------------------------------------------------------------------
+ # Stage 1: Graph Building — Seed Document Ingestion
+ # ------------------------------------------------------------------
+
+ def ingest_documents(self, documents: list[str]):
+ """Ingest seed documents and extract entities + relationships.
+
+ MiroFish equivalent: GraphBuilderService.build_graph()
+ Zep equivalent: graph.add_batch() with episode polling
+
+ With Mem0 Graph Memory, each document is processed by the LLM
+ to extract entities (people, orgs, policies) and relationships
+ (supports, opposes, filed). These become nodes and edges in the
+ graph store, alongside vector embeddings for semantic search.
+ """
+ print(" Ingesting documents and building knowledge graph...")
+ for i, doc in enumerate(documents):
+ result = self.memory.add(
+ [{"role": "user", "content": doc}],
+ user_id=self.project_id,
+ metadata={"stage": "graph_building", "source": "seed_document", "chunk_index": i}
+ )
+ # Graph Memory returns extracted relations
+ relations = result.get("relations", {})
+ added = relations.get("added_entities", [])
+ if added:
+ print(f" Doc {i}: extracted {len(added)} entities/relations")
+
+ self.stats["documents_ingested"] = len(documents)
+ print(f" Ingested {len(documents)} documents")
+
+ # ------------------------------------------------------------------
+ # Stage 2: Environment Setup — Agent Profile Enrichment
+ # ------------------------------------------------------------------
+
+ def enrich_agent_profile(self, agent_name: str, persona_query: str) -> dict:
+ """Search memory + graph for context relevant to an agent's persona.
+
+ MiroFish equivalent: OasisProfileGenerator using graph.search()
+
+ Returns both semantic memories and graph relations that can be
+ injected into the agent's system prompt.
+ """
+ results = self.memory.search(
+ persona_query,
+ user_id=self.project_id,
+ limit=10
+ )
+ facts = [r["memory"] for r in results.get("results", [])]
+ relations = results.get("relations", [])
+
+ print(f" {agent_name}: {len(facts)} facts, {len(relations)} relations")
+ return {"facts": facts, "relations": relations}
+
+ # ------------------------------------------------------------------
+ # Stage 3: Simulation — Agent Activity Tracking
+ # ------------------------------------------------------------------
+
+ def record_action(self, agent_id: str, agent_name: str,
+ action_type: str, content: str,
+ platform: str, round_num: int):
+ """Record a single agent action as a memory with graph extraction.
+
+ MiroFish equivalent: ZepGraphMemoryUpdater.add_activity()
+ Zep equivalent: graph.add(type="text", data=episode_text)
+
+ Agent memories use run_id to group by agent (no assistant
+ memories involved). Graph Memory extracts entities/relationships
+ from the action content automatically.
+ """
+ formatted = f"{agent_name} [{action_type}]: {content}"
+
+ self.memory.add(
+ [{"role": "user", "content": formatted}],
+ run_id=agent_id,
+ metadata={
+ "action_type": action_type,
+ "platform": platform,
+ "round": round_num,
+ "agent_name": agent_name,
+ }
+ )
+ self.stats["activities_recorded"] += 1
+
+ def run_round(self, round_num: int, activities: list[tuple]):
+ """Execute one simulation round."""
+ print(f" Round {round_num}: {len(activities)} actions")
+ for agent_id, agent_name, action_type, content, platform in activities:
+ self.record_action(agent_id, agent_name, action_type, content, platform, round_num)
+ self.stats["rounds_completed"] = max(self.stats["rounds_completed"], round_num)
+
+ def recall_agent_memory(self, agent_id: str, query: str) -> dict:
+ """Agent recalls its own memories mid-simulation.
+
+ Searches by run_id to match the scope used during add().
+ """
+ results = self.memory.search(
+ query,
+ run_id=agent_id,
+ limit=5
+ )
+ return {
+ "memories": [r["memory"] for r in results.get("results", [])],
+ "relations": results.get("relations", []),
+ }
+
+ # ------------------------------------------------------------------
+ # Stage 4: Report Generation — Semantic + Graph Retrieval
+ # ------------------------------------------------------------------
+
+ def quick_search(self, query: str, limit: int = 10) -> dict:
+ """Semantic search + graph relations across all agents.
+
+ MiroFish equivalent: ZepToolsService.quick_search()
+ Returns both vector-matched memories and related graph triples.
+ """
+ results = self.memory.search(
+ query,
+ user_id=self.project_id,
+ limit=limit
+ )
+ return {
+ "memories": [r["memory"] for r in results.get("results", [])],
+ "relations": results.get("relations", []),
+ }
+
+ def panorama_search(self) -> dict:
+ """Retrieve all memories + all graph relations.
+
+ MiroFish equivalent: ZepToolsService.panorama_search()
+ Returns the complete knowledge state for report generation.
+ """
+ results = self.memory.get_all(user_id=self.project_id)
+ return {
+ "memories": [r["memory"] for r in results.get("results", [])],
+ "relations": results.get("relations", []),
+ }
+
+ def agent_search(self, agent_id: str, query: str, limit: int = 10) -> dict:
+ """Search within a single agent's memory space."""
+ results = self.memory.search(
+ query,
+ run_id=agent_id,
+ limit=limit
+ )
+ return {
+ "memories": [r["memory"] for r in results.get("results", [])],
+ "relations": results.get("relations", []),
+ }
+
+ # ------------------------------------------------------------------
+ # Cleanup
+ # ------------------------------------------------------------------
+
+ def cleanup(self):
+ """Delete all memories and graph data for this simulation."""
+ self.memory.delete_all(user_id=self.project_id)
+ print(f" Cleaned up all memories for {self.project_id}")
+
+
+# ======================================================================
+# Run the full 5-stage pipeline
+# ======================================================================
+
+def main():
+ project_id = f"mirofish_housing_{int(time.time())}"
+ config = build_config()
+ sim = MiroFishSimulation(project_id=project_id, config=config)
+
+ # ==================================================================
+ # STAGE 1: Graph Building — Ingest seed documents
+ # ==================================================================
+ print("=" * 60)
+ print("STAGE 1: Graph Building")
+ print("=" * 60)
+
+ sim.ingest_documents([
+ "The city council proposed a new zoning reform allowing higher "
+ "density housing in suburban areas. Mayor Chen expressed strong "
+ "support, citing a 40% housing shortage affecting young professionals. "
+ "The reform would allow buildings up to 8 stories in previously "
+ "restricted 3-story zones.",
+
+ "Local homeowners association president Wang opposes the reform, "
+ "arguing it will decrease property values by 15-20%. The association "
+ "represents 5,000 homeowners in the affected districts. Wang has "
+ "organized three community meetings and collected 2,000 signatures.",
+
+ "Professor Li from Beijing University published research showing "
+ "similar reforms in Shenzhen led to 15% price drops in existing "
+ "homes but created 30% more affordable housing units within 3 years. "
+ "The study covered 12 districts and 50,000 housing units.",
+ ])
+
+ # ==================================================================
+ # STAGE 2: Environment Setup — Enrich agent profiles
+ # ==================================================================
+ print("\n" + "=" * 60)
+ print("STAGE 2: Environment Setup")
+ print("=" * 60)
+
+ mayor_context = sim.enrich_agent_profile(
+ "Mayor Chen",
+ "Mayor Chen housing reform zoning policy"
+ )
+ wang_context = sim.enrich_agent_profile(
+ "Wang",
+ "Wang homeowner opposition property values petition"
+ )
+ li_context = sim.enrich_agent_profile(
+ "Professor Li",
+ "Professor Li research housing data Shenzhen"
+ )
+
+ print("\n Example profile context for Mayor Chen:")
+ for fact in mayor_context["facts"][:3]:
+ print(f" Fact: {fact}")
+ for rel in mayor_context["relations"][:3]:
+ src = rel.get("source", "?")
+ edge = rel.get("relationship", "?")
+ dst = rel.get("destination", rel.get("target", "?"))
+ print(f" Relation: {src} --[{edge}]--> {dst}")
+
+ # ==================================================================
+ # STAGE 3: Simulation — Run agent interactions
+ # ==================================================================
+ print("\n" + "=" * 60)
+ print("STAGE 3: Simulation")
+ print("=" * 60)
+
+ # Round 1: Opening statements
+ sim.run_round(1, [
+ ("mayor_chen", "Mayor Chen", "CREATE_POST",
+ "This reform will create 10,000 new housing units by 2028. "
+ "Young families deserve affordable homes. #HousingForAll",
+ "twitter"),
+
+ ("wang_homeowner", "Wang", "CREATE_POST",
+ "Our property values will plummet! The council ignores the "
+ "voices of 5,000 homeowners. #StopTheReform",
+ "twitter"),
+
+ ("prof_li", "Professor Li", "CREATE_POST",
+ "New analysis: Shenzhen zoning data shows net positive outcomes "
+ "after 3 years. Short-term pain, long-term gain for housing equity.",
+ "twitter"),
+ ])
+
+ # Round 2: Debate and interaction
+ sim.run_round(2, [
+ ("wang_homeowner", "Wang", "CREATE_COMMENT",
+ "Replied to Professor Li: 'Shenzhen is a tier-1 city with "
+ "completely different dynamics. Your comparison is misleading.'",
+ "twitter"),
+
+ ("mayor_chen", "Mayor Chen", "LIKE_POST",
+ "Liked Professor Li's post about Shenzhen housing data.",
+ "twitter"),
+
+ ("prof_li", "Professor Li", "CREATE_COMMENT",
+ "Replied to Wang: 'The methodology controls for city tier "
+ "and population density. I invite you to review the full dataset.'",
+ "twitter"),
+
+ ("mayor_chen", "Mayor Chen", "CREATE_POST",
+ "Data from @ProfLi confirms what we've been saying: zoning "
+ "reform works. Let's move forward with evidence, not fear.",
+ "twitter"),
+ ])
+
+ # Round 3: Escalation and platform expansion
+ sim.run_round(3, [
+ ("wang_homeowner", "Wang", "CREATE_POST",
+ "Filing formal petition with 3,000 signatures against the "
+ "zoning reform. Council meeting next Tuesday. All homeowners "
+ "must attend!",
+ "reddit"),
+
+ ("mayor_chen", "Mayor Chen", "CREATE_POST",
+ "Announcing public town hall on zoning reform this Saturday. "
+ "All voices welcome. Data-driven decisions benefit everyone.",
+ "twitter"),
+
+ ("prof_li", "Professor Li", "CREATE_POST",
+ "Published full dataset and methodology on my university page. "
+ "Transparency is essential for informed public debate.",
+ "twitter"),
+
+ ("wang_homeowner", "Wang", "FOLLOW",
+ "Followed @MayorChen to monitor policy updates.",
+ "twitter"),
+ ])
+
+ # Mid-simulation: agent recalls own memory + graph
+ print("\n Mid-simulation recall for Mayor Chen:")
+ mayor_recall = sim.recall_agent_memory(
+ "mayor_chen",
+ "What positions have I taken on housing reform?"
+ )
+ for mem in mayor_recall["memories"]:
+ print(f" Memory: {mem}")
+ for rel in mayor_recall["relations"][:3]:
+ src = rel.get("source", "?")
+ edge = rel.get("relationship", "?")
+ dst = rel.get("destination", rel.get("target", "?"))
+ print(f" Relation: {src} --[{edge}]--> {dst}")
+
+ # ==================================================================
+ # STAGE 4: Report Generation — Retrieve memories + graph for analysis
+ # ==================================================================
+ print("\n" + "=" * 60)
+ print("STAGE 4: Report Generation")
+ print("=" * 60)
+
+ # Quick search: targeted query
+ print("\n Quick Search: 'opposition to housing reform'")
+ opposition = sim.quick_search("opposition to housing reform", limit=5)
+ for mem in opposition["memories"]:
+ print(f" Memory: {mem}")
+ for rel in opposition["relations"][:3]:
+ src = rel.get("source", "?")
+ edge = rel.get("relationship", "?")
+ dst = rel.get("destination", rel.get("target", "?"))
+ print(f" Relation: {src} --[{edge}]--> {dst}")
+
+ # Agent-specific search
+ print("\n Agent Search: Wang's activities")
+ wang_activities = sim.agent_search("wang_homeowner", "all actions and statements")
+ for mem in wang_activities["memories"]:
+ print(f" Memory: {mem}")
+
+ # Panorama: full overview
+ print("\n Panorama Search: all memories + relations")
+ panorama = sim.panorama_search()
+ print(f" Total memories: {len(panorama['memories'])}")
+ print(f" Total relations: {len(panorama['relations'])}")
+ for mem in panorama["memories"][:5]:
+ print(f" Memory: {mem}")
+ if len(panorama["memories"]) > 5:
+ print(f" ... and {len(panorama['memories']) - 5} more")
+ for rel in panorama["relations"][:5]:
+ src = rel.get("source", "?")
+ edge = rel.get("relationship", "?")
+ dst = rel.get("destination", rel.get("target", "?"))
+ print(f" Relation: {src} --[{edge}]--> {dst}")
+
+ # ==================================================================
+ # STAGE 5: Deep Interaction — Post-simulation queries
+ # ==================================================================
+ print("\n" + "=" * 60)
+ print("STAGE 5: Deep Interaction")
+ print("=" * 60)
+
+ queries = [
+ "How did the debate evolve across the three rounds?",
+ "What evidence was cited by each side?",
+ "Who supports and who opposes the reform?",
+ ]
+
+ for query in queries:
+ print(f"\n Query: '{query}'")
+ results = sim.quick_search(query, limit=3)
+ for mem in results["memories"][:2]:
+ print(f" Memory: {mem}")
+ for rel in results["relations"][:2]:
+ src = rel.get("source", rel.get("source_node", "?"))
+ edge = rel.get("relationship", rel.get("relation", "?"))
+ dst = rel.get("destination", rel.get("destination_node", "?"))
+ print(f" Relation: {src} --[{edge}]--> {dst}")
+
+ # ==================================================================
+ # Summary
+ # ==================================================================
+ print("\n" + "=" * 60)
+ print("SIMULATION COMPLETE")
+ print("=" * 60)
+ print(f" Project ID: {project_id}")
+ print(f" Documents ingested: {sim.stats['documents_ingested']}")
+ print(f" Activities tracked: {sim.stats['activities_recorded']}")
+ print(f" Rounds completed: {sim.stats['rounds_completed']}")
+ print(f" Total memories: {len(panorama['memories'])}")
+ print(f" Total relations: {len(panorama['relations'])}")
+
+ # Cleanup (uncomment to delete all memories + graph data)
+ # sim.cleanup()
+
+
+if __name__ == "__main__":
+ print("MiroFish Swarm Prediction Simulation powered by Mem0 Graph Memory\n")
+ main()
+```
+
+## How It Works
+
+### Graph Memory: The Right Fit for MiroFish
+
+MiroFish's entire pipeline revolves around a **knowledge graph** — it extracts entities from documents, builds relationships, and queries the graph throughout simulation and reporting. Mem0's Graph Memory provides the same capabilities:
+
+| MiroFish needs | Zep Cloud | Mem0 Graph Memory |
+|---|---|---|
+| **Entity extraction** | Built-in via Zep API | Automatic via LLM extraction |
+| **Relationship mining** | Graph edges | `(source) --[relationship]--> (destination)` triples |
+| **Semantic + keyword search** | Semantic + BM25 | Vector similarity + graph relation retrieval |
+| **Graph traversal** | Node/edge queries | `relations` array in search results |
+| **Per-agent isolation** | Single shared graph in MiroFish | Native `run_id` scoping |
+| **Self-hosting** | No (cloud only) | Yes — Neo4j, Memgraph, Kuzu, Neptune |
+| **Node/memory limits** | Capped on free tier | Unlimited (self-hosted) |
+
+### How search() Returns Both Memories and Relations
+
+When Graph Memory is enabled, every `search()` call returns two arrays:
+
+```python
+results = memory.search("housing reform", user_id="my_sim")
+
+# Vector-matched memories (ordered by similarity)
+results["results"] # [{"memory": "...", "score": 0.85, ...}, ...]
+
+# Graph relations connected to query entities
+results["relations"] # [{"source": "mayor_chen", "relationship": "supports", "destination": "zoning_reform"}, ...]
+```
+
+This is what makes Mem0 Graph Memory a natural replacement for Zep — you get semantic search AND structured graph data in a single call.
+
+### Per-Agent Memory Isolation
+
+`user_id` scopes the simulation project. `run_id` tags individual agent actions at storage time (we use `run_id` instead of `agent_id` since no assistant memories are involved). Searches use `user_id` for project-wide retrieval:
+
+```python
+# Store project-level memories (seed documents)
+memory.add(
+ [{"role": "user", "content": "Mayor Chen supports the zoning reform."}],
+ user_id="my_sim"
+)
+
+# Store agent-specific memories (simulation actions)
+memory.add(
+ [{"role": "user", "content": "Mayor Chen [CREATE_POST]: Reform works!"}],
+ run_id="mayor_chen"
+)
+
+# Search project-level memories (seed docs)
+memory.search("housing reform", user_id="my_sim")
+
+# Search agent-specific memories (actions stored with run_id)
+memory.search("housing reform", run_id="mayor_chen")
+
+# Get all project-level memories + graph relations
+memory.get_all(user_id="my_sim")
+```
+
+
+ Use `user_id` for project-level data (seed documents) and `run_id` for agent actions — both for `add()` and `search()`. Always match the scope: if you `add()` with `run_id`, `search()` with `run_id`. Use the message list format `[{"role": "user", "content": "..."}]` for all `add()` calls — it works on both OSS and Cloud.
+
+
+### Stage Mapping
+
+| MiroFish Stage | What Happens | Mem0 Graph Memory Call |
+|---|---|---|
+| **1. Graph Building** | Ingest docs, extract entities | `memory.add(doc, user_id=project)` — entities/relations extracted automatically |
+| **2. Environment Setup** | Enrich agent personas from graph | `memory.search(query, user_id=project)` — returns facts + relations |
+| **3. Simulation** | Track per-agent actions | `memory.add(messages, run_id=agent)` |
+| **3. Simulation** | Mid-round recall | `memory.search(query, run_id=agent)` |
+| **4. Report Generation** | Targeted analysis | `memory.search(query, user_id=project)` — memories + graph |
+| **4. Report Generation** | Full overview | `memory.get_all(user_id=project)` — all memories + all relations |
+| **5. Deep Interaction** | Follow-up queries | `memory.search(query, user_id=project)` |
+
+### Zep-to-Mem0 Migration Reference
+
+For developers replacing MiroFish's Zep integration. Note that Mem0 Graph Memory covers the core graph operations but some Zep features have no direct equivalent — see caveats below.
+
+| MiroFish Service | Zep Call | Mem0 Graph Memory Equivalent | Caveat |
+|---|---|---|---|
+| GraphBuilderService | `client.graph.create()` | Implicit on first `memory.add()` | |
+| GraphBuilderService | `client.graph.set_ontology()` | `custom_prompt` in graph_store config | Freeform text, not a typed schema like Zep's `EntityModel`/`EdgeModel` |
+| GraphBuilderService | `client.graph.add_batch(episodes)` | `memory.add()` per chunk | No batch API — call per chunk |
+| GraphBuilderService | `client.graph.episode.get(uuid)` | Not needed (add is synchronous in OSS) | |
+| GraphBuilderService | `client.graph.delete(id)` | `memory.delete_all(user_id=...)` | |
+| ZepEntityReader | `client.graph.node.get_by_graph_id()` | `memory.get_all(user_id=...)` → `relations` | |
+| ZepEntityReader | `client.graph.node.get(uuid)` | `memory.search(entity_name, user_id=...)` | Semantic search, not exact ID lookup |
+| ZepEntityReader | `client.graph.node.get_entity_edges()` | `memory.search(entity_name, user_id=...)` → `relations` | Returns all matching relations, not edges for a specific node |
+| ZepGraphMemoryUpdater | `client.graph.add(type="text")` | `memory.add(messages, run_id=...)` | No batch buffering or retry — implement in your wrapper |
+| ZepToolsService | `search_graph(query, scope)` | `memory.search(query, user_id=...)` → memories + relations | |
+| ZepToolsService | `get_entities()` | `memory.get_all(user_id=...)` → `relations` | |
+| ZepToolsService | Panorama (all nodes + edges) | `memory.get_all(user_id=...)` | No temporal fact separation (active vs historical) |
+| ZepToolsService | InsightForge (multi-query decomposition) | Not available | Implement LLM-driven sub-query decomposition in your own ReportAgent |
+| OasisProfileGenerator | `client.graph.search()` | `memory.search(query, user_id=...)` | |
+
+
+ **What Mem0 Graph Memory does not cover**: Zep's typed ontology schemas (`EntityModel`, `EdgeModel`), temporal fact lifecycle (`valid_at`/`invalid_at`/`expired_at`), single-node-by-ID lookup, and InsightForge's multi-query decomposition. For InsightForge-like functionality, implement sub-query logic in your own ReportAgent using `memory.search()` as the retrieval primitive.
+
+
+### Custom Extraction Prompts
+
+Guide what entities and relationships Mem0 extracts — analogous to (but less structured than) Zep's `set_ontology()`:
+
+```python
+config = {
+ "graph_store": {
+ "provider": "neo4j",
+ "config": {"url": "...", "username": "...", "password": "..."},
+ "custom_prompt": (
+ "Extract all people, organizations, policies, locations, "
+ "and their relationships. Capture support/opposition stances, "
+ "affiliations, and quantitative claims."
+ ),
+ }
+}
+```
+
+### Action Types
+
+MiroFish's OASIS engine produces these agent action types. Format them as natural language when storing. Skip `DO_NOTHING` actions (no memory value). `TREND` and `REFRESH` are Reddit-only discovery actions — store if you want to track browsing behavior.
+
+| Action Type | Platform | Example Memory Content |
+|---|---|---|
+| `CREATE_POST` | Both | `"Mayor Chen [CREATE_POST]: This reform will create 10,000 units"` |
+| `CREATE_COMMENT` | Reddit | `"Wang [CREATE_COMMENT]: Replied to Prof Li: 'Your data is misleading'"` |
+| `LIKE_POST` | Both | `"Mayor Chen [LIKE_POST]: Liked Prof Li's post about Shenzhen data"` |
+| `REPOST` | Twitter | `"Prof Li [REPOST]: Reposted Mayor Chen's town hall announcement"` |
+| `FOLLOW` | Both | `"Wang [FOLLOW]: Followed @MayorChen"` |
+| `QUOTE_POST` | Twitter | `"Mayor Chen [QUOTE_POST]: 'Data confirms reform works' quoting Prof Li"` |
+| `DISLIKE_POST` | Reddit | `"Wang [DISLIKE_POST]: Downvoted Mayor Chen's reform post"` |
+| `TREND` | Reddit | `"Prof Li [TREND]: Browsed trending topics"` |
+| `DO_NOTHING` | Both | Skip — no memory value |
+
+## Running the Example
+
+```bash
+# Option A: Neo4j (production)
+export OPENAI_API_KEY="sk-..."
+export NEO4J_URL="neo4j://localhost:7687"
+export NEO4J_USERNAME="neo4j"
+export NEO4J_PASSWORD="password"
+python mirofish_swarm_memory.py
+
+# Option B: Kuzu (zero dependencies, just need OpenAI key)
+export OPENAI_API_KEY="sk-..."
+python mirofish_swarm_memory.py # auto-detects missing NEO4J_URL, uses Kuzu
+```
+
+
+Exact output varies as Mem0 automatically extracts and deduplicates entities. The specific relations and memory counts depend on LLM extraction quality.
+
+
+## Best Practices
+
+1. **Unique `user_id` per simulation** — Use timestamps or UUIDs (e.g., `mirofish_housing_1742198400`) to prevent memory collisions between runs
+2. **Always set `run_id` for agent actions** — Per-agent isolation prevents memory cross-contamination between agents
+3. **Use `custom_prompt`** — Guide entity extraction to capture domain-specific relationships (people, policies, stances)
+4. **Format actions as natural language** — `"Mayor Chen [CREATE_POST]: content"` extracts better entities than raw JSON
+5. **Query relations for reports** — The `relations` array in search results gives structured `(source, relationship, destination)` triples for building analytical reports
+6. **Cleanup old simulations** — Call `delete_all(user_id=...)` when a simulation run is no longer needed
+
+## Resources
+
+- [MiroFish GitHub](https://github.com/666ghj/MiroFish) — Source code and setup guide
+- [MiroFish Documentation](https://deepwiki.com/666ghj/MiroFish) — Full framework docs
+- [Mem0 Graph Memory](/open-source/features/graph-memory) — Graph Memory documentation
+- [Mem0 Documentation](https://docs.mem0.ai/) — Full API reference
+
+
+
+ Full Graph Memory documentation with provider setup.
+
+
+ MiroFish source code and setup guide.
+
+
diff --git a/docs/docs.json b/docs/docs.json
index 6a93f7ee5..a3628d264 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -375,7 +375,8 @@
"cookbooks/frameworks/multimodal-retrieval",
"cookbooks/frameworks/eliza-os-character",
"cookbooks/frameworks/chrome-extension",
- "cookbooks/frameworks/gemini-3-with-mem0-mcp"
+ "cookbooks/frameworks/gemini-3-with-mem0-mcp",
+ "cookbooks/frameworks/mirofish-swarm-memory"
]
}
]
@@ -401,6 +402,7 @@
"integrations/autogen",
"integrations/agno",
"integrations/camel-ai",
+ "integrations/mirofish",
"integrations/openclaw",
"integrations/openai-agents-sdk",
"integrations/google-ai-adk",