| """ |
| Mnemo Demo - Gradio Interface |
| Demonstrates smart memory injection and semantic search |
| """ |
|
|
| import gradio as gr |
| from mnemo import Mnemo, should_inject_memory |
|
|
| |
| memory = Mnemo(use_real_embeddings=True) |
|
|
| |
| EXAMPLE_MEMORIES = [ |
| "User prefers Python programming and dark mode interfaces", |
| "Project deadline is March 15th for the API redesign", |
| "Previous analysis identified gender bias in Victorian psychiatry diagnoses", |
| "Framework has 5 checkpoints: gender, class, age, occupation, marital status", |
| "User's favorite coffee is cappuccino with oat milk, no sugar", |
| "Team standup meeting every Tuesday at 2pm in conference room 401", |
| "Working on machine learning model for customer churn prediction" |
| ] |
|
|
| def initialize_demo(): |
| """Initialize with example memories""" |
| memory.clear() |
| for mem in EXAMPLE_MEMORIES: |
| memory.add(mem) |
| return f"β
Initialized with {len(EXAMPLE_MEMORIES)} example memories" |
|
|
| def add_memory(content: str): |
| """Add a new memory""" |
| if not content.strip(): |
| return "β Please enter some content", get_all_memories() |
| |
| mem_id = memory.add(content.strip()) |
| return f"β
Added memory: {mem_id}", get_all_memories() |
|
|
| def search_memories(query: str, top_k: int = 5): |
| """Search memories""" |
| if not query.strip(): |
| return "β Please enter a search query" |
| |
| results = memory.search(query.strip(), top_k=int(top_k)) |
| |
| if not results: |
| return "No memories found" |
| |
| output = [] |
| for r in results: |
| output.append(f"**[{r.id}]** (score: {r.score:.3f})") |
| output.append(f"{r.content}") |
| output.append(f"_Strategies: semantic={r.strategy_scores.get('semantic', 0):.2f}, bm25={r.strategy_scores.get('bm25', 0):.2f}, graph={r.strategy_scores.get('graph', 0):.2f}_") |
| output.append("---") |
| |
| return "\n".join(output) |
|
|
| def check_injection(query: str, context: str = ""): |
| """Check if memory should be injected""" |
| should, reason = should_inject_memory(query, context) |
| |
| status = "β
**INJECT MEMORY**" if should else "βοΈ **SKIP MEMORY**" |
| |
| return f"{status}\n\nReason: `{reason}`" |
|
|
| def get_context_for_injection(query: str, top_k: int = 3): |
| """Get formatted context for prompt injection""" |
| if not query.strip(): |
| return "β Please enter a query" |
| |
| context = memory.get_context(query.strip(), top_k=int(top_k)) |
| |
| if not context: |
| return "_No relevant context found_" |
| |
| return f"```\n{context}\n```" |
|
|
| def get_all_memories(): |
| """Get all stored memories""" |
| if len(memory) == 0: |
| return "_No memories stored_" |
| |
| output = [] |
| for mem in memory.list_all(): |
| output.append(f"β’ **{mem.id}**: {mem.content[:100]}...") |
| |
| return "\n".join(output) |
|
|
| def get_stats(): |
| """Get system statistics""" |
| stats = memory.get_stats() |
| |
| output = [] |
| for k, v in stats.items(): |
| output.append(f"β’ **{k}**: {v}") |
| |
| return "\n".join(output) |
|
|
| def clear_memories(): |
| """Clear all memories""" |
| memory.clear() |
| return "β
All memories cleared", "_No memories stored_" |
|
|
|
|
| |
| with gr.Blocks(title="Mnemo - AI Memory System", theme=gr.themes.Soft()) as demo: |
| gr.Markdown(""" |
| # π§ Mnemo - AI Memory System |
| |
| **Smart memory injection for LLMs, chatbots, and AI agents** |
| |
| > 21x faster than mem0 β’ Context-check algorithm β’ Real embeddings |
| """) |
| |
| with gr.Tab("πΎ Memory Store"): |
| gr.Markdown("### Add and view memories") |
| |
| with gr.Row(): |
| with gr.Column(scale=2): |
| memory_input = gr.Textbox( |
| label="New Memory", |
| placeholder="Enter a memory to store...", |
| lines=2 |
| ) |
| add_btn = gr.Button("β Add Memory", variant="primary") |
| add_status = gr.Markdown() |
| |
| with gr.Column(scale=3): |
| memories_display = gr.Markdown(label="Stored Memories") |
| |
| with gr.Row(): |
| init_btn = gr.Button("π Load Example Memories") |
| clear_btn = gr.Button("ποΈ Clear All") |
| |
| add_btn.click(add_memory, inputs=[memory_input], outputs=[add_status, memories_display]) |
| init_btn.click(initialize_demo, outputs=[add_status]) |
| init_btn.click(get_all_memories, outputs=[memories_display]) |
| clear_btn.click(clear_memories, outputs=[add_status, memories_display]) |
| |
| with gr.Tab("π Search"): |
| gr.Markdown("### Search stored memories") |
| |
| with gr.Row(): |
| search_input = gr.Textbox( |
| label="Search Query", |
| placeholder="Enter search query...", |
| lines=1 |
| ) |
| top_k_slider = gr.Slider( |
| minimum=1, maximum=10, value=5, step=1, |
| label="Number of Results" |
| ) |
| |
| search_btn = gr.Button("π Search", variant="primary") |
| search_results = gr.Markdown(label="Results") |
| |
| search_btn.click( |
| search_memories, |
| inputs=[search_input, top_k_slider], |
| outputs=[search_results] |
| ) |
| |
| with gr.Tab("π― Smart Injection"): |
| gr.Markdown(""" |
| ### Should memory be injected? |
| |
| The context-check algorithm detects if a query references prior context and needs memory injection. |
| |
| **Inject when:** "Based on your previous analysis...", "Compare to earlier...", "Using your framework..." |
| |
| **Skip when:** "What is Python?", "This is a NEW topic...", standalone questions |
| """) |
| |
| with gr.Row(): |
| with gr.Column(): |
| injection_query = gr.Textbox( |
| label="Query to Check", |
| placeholder="Enter a query to check...", |
| lines=2 |
| ) |
| injection_context = gr.Textbox( |
| label="Additional Context (optional)", |
| placeholder="Any additional context...", |
| lines=1 |
| ) |
| check_btn = gr.Button("π― Check Injection", variant="primary") |
| |
| with gr.Column(): |
| injection_result = gr.Markdown(label="Result") |
| |
| check_btn.click( |
| check_injection, |
| inputs=[injection_query, injection_context], |
| outputs=[injection_result] |
| ) |
| |
| gr.Markdown("### Get Context for Injection") |
| |
| with gr.Row(): |
| context_query = gr.Textbox( |
| label="Query", |
| placeholder="Enter query to get context for...", |
| lines=1 |
| ) |
| context_top_k = gr.Slider( |
| minimum=1, maximum=5, value=3, step=1, |
| label="Number of Memories" |
| ) |
| |
| context_btn = gr.Button("π Get Context") |
| context_output = gr.Markdown(label="Formatted Context") |
| |
| context_btn.click( |
| get_context_for_injection, |
| inputs=[context_query, context_top_k], |
| outputs=[context_output] |
| ) |
| |
| with gr.Tab("π Stats"): |
| gr.Markdown("### System Statistics") |
| |
| stats_btn = gr.Button("π Refresh Stats") |
| stats_display = gr.Markdown() |
| |
| stats_btn.click(get_stats, outputs=[stats_display]) |
| |
| with gr.Tab("βΉοΈ About"): |
| gr.Markdown(""" |
| ## About Mnemo |
| |
| Mnemo (named after Mnemosyne, Greek goddess of memory) is an open-source memory system for AI applications. |
| |
| ### Features |
| |
| - **π― Smart Injection** - Context-check algorithm with 90% accuracy |
| - **𧬠Real Embeddings** - sentence-transformers (with hash fallback) |
| - **π Multi-Strategy Search** - Semantic + BM25 + Knowledge Graph |
| - **π Feedback Learning** - Improves over time |
| - **β‘ Fast** - 21x faster than mem0 |
| - **π Private** - Fully local, no API keys needed |
| |
| ### Installation |
| |
| ```bash |
| pip install mnemo-memory |
| ``` |
| |
| ### Quick Start |
| |
| ```python |
| from mnemo import Mnemo |
| |
| m = Mnemo() |
| m.add("User prefers dark mode") |
| |
| if m.should_inject("Based on user preferences..."): |
| context = m.get_context("preferences") |
| # Use context in prompt |
| ``` |
| |
| ### Links |
| |
| - [HuggingFace Model](https://huggingface.co/AthelaPerk/mnemo-memory) |
| - [MCP Server](https://huggingface.co/spaces/AthelaPerk/mnemo-mcp) |
| |
| --- |
| |
| MIT License β’ Built with β€οΈ for the AI community |
| """) |
|
|
|
|
| |
| demo.load(initialize_demo) |
| demo.load(get_all_memories, outputs=[]) |
|
|
| if __name__ == "__main__": |
| demo.launch() |
|
|