diff --git a/prototype/kg-demo/README.md b/prototype/kg-demo/README.md new file mode 100644 index 0000000..966000d --- /dev/null +++ b/prototype/kg-demo/README.md @@ -0,0 +1,146 @@ +# 🧠 Knowledge Graph Demo: Multi-Scale Memory Organization + +## Overview + +This prototype demonstrates how **raw mementos** (unstructured observations) are transformed into a **structured knowledge graph** with hierarchy, entities, and relationships across multiple scales. + +## The WOW Factor ✨ + +This demo showcases: + +1. **Raw Mementos** → The original unstructured observations from our conversation +2. **Surgical Extraction** → Entities pulled from mementos with full traceability +3. **Multi-Scale Hierarchy** → 4 levels of abstraction (Domain → System → Component → Atomic) +4. **Rich Relationships** → 16 typed connections showing how concepts relate +5. **Full Provenance** → Every entity traces back to source mementos + +## Files Generated + +### šŸ“Š `graph.json` +Complete structured data export with: +- 15 raw mementos (the original observations) +- 14 extracted entities across 4 scale levels +- 16 relationships between entities +- Full statistics and provenance tracking + +### šŸŽØ `interactive_graph.html` +**Interactive visualization** with: +- Drag-and-drop force-directed graph +- Color-coded entity types +- Size-coded hierarchy scales +- Click nodes to see source mementos +- Physics simulation for natural layout + +**To view:** Open in any web browser + +### šŸ—‚ļø `graph.cypher` +Neo4j Cypher script for database import: +- Creates all mementos as nodes +- Creates all entities as nodes +- Establishes relationships +- Links entities back to source mementos via `EXTRACTED_TO` relationships + +**To use:** +```bash +# Option 1: Neo4j Browser +# Copy/paste into Neo4j Browser at http://localhost:7474 + +# Option 2: cypher-shell +cat graph.cypher | cypher-shell -u neo4j -p yourpassword +``` + +### šŸ“ `graph.mmd` +Mermaid diagram for quick visualization: +- Hierarchical layout +- Relationship labels +- Color-coded by entity type + +**To render:** +- GitHub/GitLab (renders automatically) +- VS Code (with Mermaid extension) +- Online: https://mermaid.live + +## Multi-Scale Architecture + +### Domain Scale (Highest Level) +- **User** - The person (you) +- **AI Memory Systems** - The broader field + +### System Scale +- **Memento Project** - The complete system being built + +### Component Scale +- **Neo4j** - Graph database +- **FastMCP** - Python framework +- **Model Context Protocol** - Integration protocol +- **Local Embeddings** - Semantic search component + +### Atomic Scale (Finest Detail) +- **Feature Branch** - Current working branch +- **Agent Isolation** - Isolation concept +- **Tasks** - Specific implementation work +- **ADR-006** - Architectural decision +- **Preferences** - Your stated preferences + +## Key Insights from the Graph + +1. **You value hierarchy and structure** - evident from preference nodes +2. **Memento uses a layered architecture** - MCP → Neo4j → Embeddings +3. **Isolation is important** - both conceptually and practically (branch) +4. **Client-side intelligence** - ADR-006 guides architectural decisions +5. **Active development** - 2 tasks in progress, building toward demo + +## Data Flow + +``` +Raw Conversation + ↓ + Mementos (m001-m015) + ↓ + Entity Extraction + ↓ + Entities (e_user, e_memento, etc.) + ↓ + Relationship Mapping + ↓ + Knowledge Graph +``` + +## Running the Demo + +```bash +# Generate all outputs +python3 knowledge_graph_demo.py + +# View interactive visualization +open interactive_graph.html + +# Or on Linux +xdg-open interactive_graph.html +``` + +## Statistics + +- **15 raw mementos** → original observations +- **14 entities** → structured concepts +- **16 relationships** → connections +- **4 scales** → levels of hierarchy +- **6 entity types** → Person, Project, Technology, Concept, Task, Preference + +## Why This Matters for Memento + +This demo proves the core concept: + +1. **Mementos are preserved** - raw data never lost +2. **Surgical extraction** - entities cleanly pulled from source +3. **Multi-scale organization** - from high-level concepts to specific details +4. **Relationship-rich** - not just facts, but how they connect +5. **Queryable at any level** - can zoom in/out through the hierarchy + +This is exactly what Memento will do for LLM memory - transform unstructured conversation into queryable knowledge graphs! + +--- + +**Generated:** 2025-11-16 +**Session:** claude/knowledge-graph-prototype-016woGkvRjndwTdvaeEGhz73 +**Isolated Environment:** āœ“ diff --git a/prototype/kg-demo/graph.cypher b/prototype/kg-demo/graph.cypher new file mode 100644 index 0000000..6adee54 --- /dev/null +++ b/prototype/kg-demo/graph.cypher @@ -0,0 +1,264 @@ +// Knowledge Graph Demo - Neo4j Cypher Script + +// Clean slate +MATCH (n) DETACH DELETE n; + +// ============ RAW MEMENTOS ============ +CREATE (:m001:Memento { + id: "m001", + content: "User is working on a project called Memento", + timestamp: datetime("2025-11-16T00:01:00Z"), + source: "conversation" +}); +CREATE (:m002:Memento { + id: "m002", + content: "Memento is an MCP server that provides persistent memory for LLMs", + timestamp: datetime("2025-11-16T00:01:30Z"), + source: "conversation" +}); +CREATE (:m003:Memento { + id: "m003", + content: "The project uses Python with FastMCP framework", + timestamp: datetime("2025-11-16T00:02:00Z"), + source: "conversation" +}); +CREATE (:m004:Memento { + id: "m004", + content: "The project uses Neo4j for graph-based vector storage", + timestamp: datetime("2025-11-16T00:02:15Z"), + source: "conversation" +}); +CREATE (:m005:Memento { + id: "m005", + content: "User is working in an isolated cloud environment", + timestamp: datetime("2025-11-16T00:03:00Z"), + source: "conversation" +}); +CREATE (:m006:Memento { + id: "m006", + content: "Current branch is claude/knowledge-graph-prototype-016woGkvRjndwTdvaeEGhz73", + timestamp: datetime("2025-11-16T00:03:15Z"), + source: "conversation" +}); +CREATE (:m007:Memento { + id: "m007", + content: "User cares about isolation from other agents", + timestamp: datetime("2025-11-16T00:04:00Z"), + source: "conversation" +}); +CREATE (:m008:Memento { + id: "m008", + content: "The project has two main tasks in progress: local embeddings and basic demo", + timestamp: datetime("2025-11-16T00:04:30Z"), + source: "conversation" +}); +CREATE (:m009:Memento { + id: "m009", + content: "User wants to see knowledge organized with hierarchy, entities, and relationships", + timestamp: datetime("2025-11-16T00:05:00Z"), + source: "conversation" +}); +CREATE (:m010:Memento { + id: "m010", + content: "User values the WOW factor in visualizations", + timestamp: datetime("2025-11-16T00:05:15Z"), + source: "conversation" +}); +CREATE (:m011:Memento { + id: "m011", + content: "The project uses sentence-transformers for local embeddings", + timestamp: datetime("2025-11-16T00:05:30Z"), + source: "conversation" +}); +CREATE (:m012:Memento { + id: "m012", + content: "User distinguishes between raw 'Mementos' and structured knowledge", + timestamp: datetime("2025-11-16T00:05:45Z"), + source: "conversation" +}); +CREATE (:m013:Memento { + id: "m013", + content: "The architecture leverages client LLM instead of server-side LLM (ADR-006)", + timestamp: datetime("2025-11-16T00:06:00Z"), + source: "conversation" +}); +CREATE (:m014:Memento { + id: "m014", + content: "Neo4j supports both graph relationships and vector embeddings in single database", + timestamp: datetime("2025-11-16T00:06:15Z"), + source: "conversation" +}); +CREATE (:m015:Memento { + id: "m015", + content: "User asked about worktrees and operating system - they are technical", + timestamp: datetime("2025-11-16T00:06:30Z"), + source: "conversation" +}); + +// ============ ENTITIES ============ +CREATE (:e_user:Person { + id: "e_user", + name: "User", + scale: "domain", + role: "developer", expertise: "technical" +}); +CREATE (:e_ai_memory:Concept { + id: "e_ai_memory", + name: "AI Memory Systems", + scale: "domain", + domain: "artificial_intelligence", subdomain: "memory" +}); +CREATE (:e_memento:Project { + id: "e_memento", + name: "Memento Project", + scale: "system", + status: "in_development", purpose: "LLM persistent memory" +}); +CREATE (:e_neo4j:Technology { + id: "e_neo4j", + name: "Neo4j", + scale: "component", + category: "database", features: "graph+vector" +}); +CREATE (:e_fastmcp:Technology { + id: "e_fastmcp", + name: "FastMCP", + scale: "component", + category: "framework", language: "python" +}); +CREATE (:e_mcp:Technology { + id: "e_mcp", + name: "Model Context Protocol", + scale: "component", + category: "protocol", purpose: "LLM tool integration" +}); +CREATE (:e_embeddings:Technology { + id: "e_embeddings", + name: "Local Embeddings", + scale: "component", + provider: "sentence-transformers", model: "all-MiniLM-L6-v2" +}); +CREATE (:e_branch:Concept { + id: "e_branch", + name: "Feature Branch", + scale: "atomic", + name: "claude/knowledge-graph-prototype-016woGkvRjndwTdvaeEGhz73" +}); +CREATE (:e_isolation:Concept { + id: "e_isolation", + name: "Agent Isolation", + scale: "atomic", + importance: "high", reason: "prevent interference" +}); +CREATE (:e_task_embeddings:Task { + id: "e_task_embeddings", + name: "Implement Local Embeddings", + scale: "atomic", + status: "in_progress", epic: "core_components" +}); +CREATE (:e_task_demo:Task { + id: "e_task_demo", + name: "Basic Demo", + scale: "atomic", + status: "in_progress", epic: "core_components" +}); +CREATE (:e_adr006:Concept { + id: "e_adr006", + name: "ADR-006: Leverage Client LLM", + scale: "atomic", + decision: "use_client_llm", principle: "YAGNI" +}); +CREATE (:e_pref_hierarchy:Preference { + id: "e_pref_hierarchy", + name: "Preference: Hierarchical Organization", + scale: "atomic", + valued: "hierarchy, entities, relationships" +}); +CREATE (:e_pref_wow:Preference { + id: "e_pref_wow", + name: "Preference: WOW Factor", + scale: "atomic", + valued: "impressive visualizations" +}); + +// ============ RELATIONSHIPS ============ +MATCH (s:e_user), (t:e_memento) +CREATE (s)-[:WORKS_ON {role: "creator"}]->(t); +MATCH (s:e_user), (t:e_isolation) +CREATE (s)-[:VALUES {priority: "high"}]->(t); +MATCH (s:e_user), (t:e_pref_hierarchy) +CREATE (s)-[:HAS_PREFERENCE]->(t); +MATCH (s:e_user), (t:e_pref_wow) +CREATE (s)-[:HAS_PREFERENCE]->(t); +MATCH (s:e_memento), (t:e_ai_memory) +CREATE (s)-[:BELONGS_TO_DOMAIN]->(t); +MATCH (s:e_memento), (t:e_mcp) +CREATE (s)-[:IMPLEMENTS {role: "server"}]->(t); +MATCH (s:e_memento), (t:e_fastmcp) +CREATE (s)-[:USES {purpose: "framework"}]->(t); +MATCH (s:e_memento), (t:e_neo4j) +CREATE (s)-[:USES {purpose: "storage"}]->(t); +MATCH (s:e_memento), (t:e_embeddings) +CREATE (s)-[:USES {purpose: "semantic_search"}]->(t); +MATCH (s:e_neo4j), (t:e_embeddings) +CREATE (s)-[:STORES {data_type: "vector_embeddings"}]->(t); +MATCH (s:e_adr006), (t:e_memento) +CREATE (s)-[:GUIDES {aspect: "architecture"}]->(t); +MATCH (s:e_task_embeddings), (t:e_memento) +CREATE (s)-[:CONTRIBUTES_TO {phase: "1"}]->(t); +MATCH (s:e_task_demo), (t:e_memento) +CREATE (s)-[:CONTRIBUTES_TO {phase: "1"}]->(t); +MATCH (s:e_task_embeddings), (t:e_embeddings) +CREATE (s)-[:IMPLEMENTS]->(t); +MATCH (s:e_branch), (t:e_isolation) +CREATE (s)-[:PROVIDES {mechanism: "git_branch"}]->(t); +MATCH (s:e_user), (t:e_branch) +CREATE (s)-[:WORKS_IN {environment: "cloud"}]->(t); + +// ============ MEMENTO -> ENTITY EXTRACTION ============ +MATCH (m:m001), (e:e_user) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m007), (e:e_user) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m009), (e:e_user) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m015), (e:e_user) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m002), (e:e_ai_memory) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m012), (e:e_ai_memory) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m001), (e:e_memento) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m002), (e:e_memento) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m003), (e:e_memento) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m004), (e:e_neo4j) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m014), (e:e_neo4j) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m003), (e:e_fastmcp) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m002), (e:e_mcp) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m008), (e:e_embeddings) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m011), (e:e_embeddings) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m006), (e:e_branch) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m005), (e:e_isolation) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m007), (e:e_isolation) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m008), (e:e_task_embeddings) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m008), (e:e_task_demo) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m013), (e:e_adr006) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m009), (e:e_pref_hierarchy) +CREATE (m)-[:EXTRACTED_TO]->(e); +MATCH (m:m010), (e:e_pref_wow) +CREATE (m)-[:EXTRACTED_TO]->(e); \ No newline at end of file diff --git a/prototype/kg-demo/graph.json b/prototype/kg-demo/graph.json new file mode 100644 index 0000000..5ab5efe --- /dev/null +++ b/prototype/kg-demo/graph.json @@ -0,0 +1,477 @@ +{ + "mementos": [ + { + "id": "m001", + "content": "User is working on a project called Memento", + "timestamp": "2025-11-16T00:01:00Z", + "source": "conversation" + }, + { + "id": "m002", + "content": "Memento is an MCP server that provides persistent memory for LLMs", + "timestamp": "2025-11-16T00:01:30Z", + "source": "conversation" + }, + { + "id": "m003", + "content": "The project uses Python with FastMCP framework", + "timestamp": "2025-11-16T00:02:00Z", + "source": "conversation" + }, + { + "id": "m004", + "content": "The project uses Neo4j for graph-based vector storage", + "timestamp": "2025-11-16T00:02:15Z", + "source": "conversation" + }, + { + "id": "m005", + "content": "User is working in an isolated cloud environment", + "timestamp": "2025-11-16T00:03:00Z", + "source": "conversation" + }, + { + "id": "m006", + "content": "Current branch is claude/knowledge-graph-prototype-016woGkvRjndwTdvaeEGhz73", + "timestamp": "2025-11-16T00:03:15Z", + "source": "conversation" + }, + { + "id": "m007", + "content": "User cares about isolation from other agents", + "timestamp": "2025-11-16T00:04:00Z", + "source": "conversation" + }, + { + "id": "m008", + "content": "The project has two main tasks in progress: local embeddings and basic demo", + "timestamp": "2025-11-16T00:04:30Z", + "source": "conversation" + }, + { + "id": "m009", + "content": "User wants to see knowledge organized with hierarchy, entities, and relationships", + "timestamp": "2025-11-16T00:05:00Z", + "source": "conversation" + }, + { + "id": "m010", + "content": "User values the WOW factor in visualizations", + "timestamp": "2025-11-16T00:05:15Z", + "source": "conversation" + }, + { + "id": "m011", + "content": "The project uses sentence-transformers for local embeddings", + "timestamp": "2025-11-16T00:05:30Z", + "source": "conversation" + }, + { + "id": "m012", + "content": "User distinguishes between raw 'Mementos' and structured knowledge", + "timestamp": "2025-11-16T00:05:45Z", + "source": "conversation" + }, + { + "id": "m013", + "content": "The architecture leverages client LLM instead of server-side LLM (ADR-006)", + "timestamp": "2025-11-16T00:06:00Z", + "source": "conversation" + }, + { + "id": "m014", + "content": "Neo4j supports both graph relationships and vector embeddings in single database", + "timestamp": "2025-11-16T00:06:15Z", + "source": "conversation" + }, + { + "id": "m015", + "content": "User asked about worktrees and operating system - they are technical", + "timestamp": "2025-11-16T00:06:30Z", + "source": "conversation" + } + ], + "entities": [ + { + "id": "e_user", + "name": "User", + "type": "Person", + "properties": { + "role": "developer", + "expertise": "technical" + }, + "scale": "domain", + "extracted_from": [ + "m001", + "m007", + "m009", + "m015" + ] + }, + { + "id": "e_ai_memory", + "name": "AI Memory Systems", + "type": "Concept", + "properties": { + "domain": "artificial_intelligence", + "subdomain": "memory" + }, + "scale": "domain", + "extracted_from": [ + "m002", + "m012" + ] + }, + { + "id": "e_memento", + "name": "Memento Project", + "type": "Project", + "properties": { + "status": "in_development", + "purpose": "LLM persistent memory" + }, + "scale": "system", + "extracted_from": [ + "m001", + "m002", + "m003" + ] + }, + { + "id": "e_neo4j", + "name": "Neo4j", + "type": "Technology", + "properties": { + "category": "database", + "features": "graph+vector" + }, + "scale": "component", + "extracted_from": [ + "m004", + "m014" + ] + }, + { + "id": "e_fastmcp", + "name": "FastMCP", + "type": "Technology", + "properties": { + "category": "framework", + "language": "python" + }, + "scale": "component", + "extracted_from": [ + "m003" + ] + }, + { + "id": "e_mcp", + "name": "Model Context Protocol", + "type": "Technology", + "properties": { + "category": "protocol", + "purpose": "LLM tool integration" + }, + "scale": "component", + "extracted_from": [ + "m002" + ] + }, + { + "id": "e_embeddings", + "name": "Local Embeddings", + "type": "Technology", + "properties": { + "provider": "sentence-transformers", + "model": "all-MiniLM-L6-v2" + }, + "scale": "component", + "extracted_from": [ + "m008", + "m011" + ] + }, + { + "id": "e_branch", + "name": "Feature Branch", + "type": "Concept", + "properties": { + "name": "claude/knowledge-graph-prototype-016woGkvRjndwTdvaeEGhz73" + }, + "scale": "atomic", + "extracted_from": [ + "m006" + ] + }, + { + "id": "e_isolation", + "name": "Agent Isolation", + "type": "Concept", + "properties": { + "importance": "high", + "reason": "prevent interference" + }, + "scale": "atomic", + "extracted_from": [ + "m005", + "m007" + ] + }, + { + "id": "e_task_embeddings", + "name": "Implement Local Embeddings", + "type": "Task", + "properties": { + "status": "in_progress", + "epic": "core_components" + }, + "scale": "atomic", + "extracted_from": [ + "m008" + ] + }, + { + "id": "e_task_demo", + "name": "Basic Demo", + "type": "Task", + "properties": { + "status": "in_progress", + "epic": "core_components" + }, + "scale": "atomic", + "extracted_from": [ + "m008" + ] + }, + { + "id": "e_adr006", + "name": "ADR-006: Leverage Client LLM", + "type": "Concept", + "properties": { + "decision": "use_client_llm", + "principle": "YAGNI" + }, + "scale": "atomic", + "extracted_from": [ + "m013" + ] + }, + { + "id": "e_pref_hierarchy", + "name": "Preference: Hierarchical Organization", + "type": "Preference", + "properties": { + "valued": "hierarchy, entities, relationships" + }, + "scale": "atomic", + "extracted_from": [ + "m009" + ] + }, + { + "id": "e_pref_wow", + "name": "Preference: WOW Factor", + "type": "Preference", + "properties": { + "valued": "impressive visualizations" + }, + "scale": "atomic", + "extracted_from": [ + "m010" + ] + } + ], + "relationships": [ + { + "source": "e_user", + "target": "e_memento", + "type": "WORKS_ON", + "properties": { + "role": "creator" + }, + "extracted_from": [ + "m001" + ] + }, + { + "source": "e_user", + "target": "e_isolation", + "type": "VALUES", + "properties": { + "priority": "high" + }, + "extracted_from": [ + "m007" + ] + }, + { + "source": "e_user", + "target": "e_pref_hierarchy", + "type": "HAS_PREFERENCE", + "properties": {}, + "extracted_from": [ + "m009" + ] + }, + { + "source": "e_user", + "target": "e_pref_wow", + "type": "HAS_PREFERENCE", + "properties": {}, + "extracted_from": [ + "m010" + ] + }, + { + "source": "e_memento", + "target": "e_ai_memory", + "type": "BELONGS_TO_DOMAIN", + "properties": {}, + "extracted_from": [ + "m002" + ] + }, + { + "source": "e_memento", + "target": "e_mcp", + "type": "IMPLEMENTS", + "properties": { + "role": "server" + }, + "extracted_from": [ + "m002" + ] + }, + { + "source": "e_memento", + "target": "e_fastmcp", + "type": "USES", + "properties": { + "purpose": "framework" + }, + "extracted_from": [ + "m003" + ] + }, + { + "source": "e_memento", + "target": "e_neo4j", + "type": "USES", + "properties": { + "purpose": "storage" + }, + "extracted_from": [ + "m004" + ] + }, + { + "source": "e_memento", + "target": "e_embeddings", + "type": "USES", + "properties": { + "purpose": "semantic_search" + }, + "extracted_from": [ + "m011" + ] + }, + { + "source": "e_neo4j", + "target": "e_embeddings", + "type": "STORES", + "properties": { + "data_type": "vector_embeddings" + }, + "extracted_from": [ + "m014" + ] + }, + { + "source": "e_adr006", + "target": "e_memento", + "type": "GUIDES", + "properties": { + "aspect": "architecture" + }, + "extracted_from": [ + "m013" + ] + }, + { + "source": "e_task_embeddings", + "target": "e_memento", + "type": "CONTRIBUTES_TO", + "properties": { + "phase": "1" + }, + "extracted_from": [ + "m008" + ] + }, + { + "source": "e_task_demo", + "target": "e_memento", + "type": "CONTRIBUTES_TO", + "properties": { + "phase": "1" + }, + "extracted_from": [ + "m008" + ] + }, + { + "source": "e_task_embeddings", + "target": "e_embeddings", + "type": "IMPLEMENTS", + "properties": {}, + "extracted_from": [ + "m008", + "m011" + ] + }, + { + "source": "e_branch", + "target": "e_isolation", + "type": "PROVIDES", + "properties": { + "mechanism": "git_branch" + }, + "extracted_from": [ + "m006", + "m007" + ] + }, + { + "source": "e_user", + "target": "e_branch", + "type": "WORKS_IN", + "properties": { + "environment": "cloud" + }, + "extracted_from": [ + "m005", + "m006" + ] + } + ], + "hierarchy": {}, + "statistics": { + "total_mementos": 15, + "total_entities": 14, + "total_relationships": 16, + "entities_by_type": { + "Person": 1, + "Concept": 4, + "Project": 1, + "Technology": 4, + "Task": 2, + "Preference": 2 + }, + "entities_by_scale": { + "domain": 2, + "system": 1, + "component": 4, + "atomic": 7 + } + } +} \ No newline at end of file diff --git a/prototype/kg-demo/graph.mmd b/prototype/kg-demo/graph.mmd new file mode 100644 index 0000000..8643c17 --- /dev/null +++ b/prototype/kg-demo/graph.mmd @@ -0,0 +1,58 @@ +graph TB + + %% === RAW MEMENTOS (Foundation Layer) === + %% DOMAIN SCALE + e_user["User"] + e_ai_memory["AI Memory Systems"] + + %% SYSTEM SCALE + e_memento["Memento Project"] + + %% COMPONENT SCALE + e_neo4j["Neo4j"] + e_fastmcp["FastMCP"] + e_mcp["Model Context Protocol"] + e_embeddings["Local Embeddings"] + + %% ATOMIC SCALE + e_branch["Feature Branch"] + e_isolation["Agent Isolation"] + e_task_embeddings["Implement Local Embeddings"] + e_task_demo["Basic Demo"] + e_adr006["ADR-006: Leverage Client LLM"] + e_pref_hierarchy["Preference: Hierarchical Organization"] + e_pref_wow["Preference: WOW Factor"] + + %% === RELATIONSHIPS === + e_user -->|WORKS ON| e_memento + e_user -->|VALUES| e_isolation + e_user -->|HAS PREFERENCE| e_pref_hierarchy + e_user -->|HAS PREFERENCE| e_pref_wow + e_memento -->|BELONGS TO DOMAIN| e_ai_memory + e_memento -->|IMPLEMENTS| e_mcp + e_memento -->|USES| e_fastmcp + e_memento -->|USES| e_neo4j + e_memento -->|USES| e_embeddings + e_neo4j -->|STORES| e_embeddings + e_adr006 -->|GUIDES| e_memento + e_task_embeddings -->|CONTRIBUTES TO| e_memento + e_task_demo -->|CONTRIBUTES TO| e_memento + e_task_embeddings -->|IMPLEMENTS| e_embeddings + e_branch -->|PROVIDES| e_isolation + e_user -->|WORKS IN| e_branch + + %% === STYLING === + style e_user fill:#e1f5fe + style e_ai_memory fill:#e8f5e9 + style e_memento fill:#f3e5f5 + style e_neo4j fill:#fff3e0 + style e_fastmcp fill:#fff3e0 + style e_mcp fill:#fff3e0 + style e_embeddings fill:#fff3e0 + style e_branch fill:#e8f5e9 + style e_isolation fill:#e8f5e9 + style e_task_embeddings fill:#fff9c4 + style e_task_demo fill:#fff9c4 + style e_adr006 fill:#e8f5e9 + style e_pref_hierarchy fill:#fce4ec + style e_pref_wow fill:#fce4ec \ No newline at end of file diff --git a/prototype/kg-demo/interactive_graph.html b/prototype/kg-demo/interactive_graph.html new file mode 100644 index 0000000..92942c0 --- /dev/null +++ b/prototype/kg-demo/interactive_graph.html @@ -0,0 +1,340 @@ + + + + Knowledge Graph: Multi-Scale Memory Organization + + + + + + +
+
+ +
+ + + + diff --git a/prototype/kg-demo/knowledge_graph_demo.py b/prototype/kg-demo/knowledge_graph_demo.py new file mode 100644 index 0000000..a2b33f0 --- /dev/null +++ b/prototype/kg-demo/knowledge_graph_demo.py @@ -0,0 +1,393 @@ +#!/usr/bin/env python3 +""" +Knowledge Graph Demo: Multi-Scale Memory Organization +Demonstrates raw mementos → structured knowledge graph with hierarchy +""" + +import json +from dataclasses import dataclass, asdict +from typing import List, Dict, Set +from datetime import datetime +from collections import defaultdict + +# ============================================================================ +# LAYER 1: RAW MEMENTOS (Original Unstructured Data) +# ============================================================================ + +@dataclass +class Memento: + """Raw memory - the original unstructured observation""" + id: str + content: str + timestamp: str + source: str = "conversation" + +MEMENTOS = [ + Memento("m001", "User is working on a project called Memento", "2025-11-16T00:01:00Z"), + Memento("m002", "Memento is an MCP server that provides persistent memory for LLMs", "2025-11-16T00:01:30Z"), + Memento("m003", "The project uses Python with FastMCP framework", "2025-11-16T00:02:00Z"), + Memento("m004", "The project uses Neo4j for graph-based vector storage", "2025-11-16T00:02:15Z"), + Memento("m005", "User is working in an isolated cloud environment", "2025-11-16T00:03:00Z"), + Memento("m006", "Current branch is claude/knowledge-graph-prototype-016woGkvRjndwTdvaeEGhz73", "2025-11-16T00:03:15Z"), + Memento("m007", "User cares about isolation from other agents", "2025-11-16T00:04:00Z"), + Memento("m008", "The project has two main tasks in progress: local embeddings and basic demo", "2025-11-16T00:04:30Z"), + Memento("m009", "User wants to see knowledge organized with hierarchy, entities, and relationships", "2025-11-16T00:05:00Z"), + Memento("m010", "User values the WOW factor in visualizations", "2025-11-16T00:05:15Z"), + Memento("m011", "The project uses sentence-transformers for local embeddings", "2025-11-16T00:05:30Z"), + Memento("m012", "User distinguishes between raw 'Mementos' and structured knowledge", "2025-11-16T00:05:45Z"), + Memento("m013", "The architecture leverages client LLM instead of server-side LLM (ADR-006)", "2025-11-16T00:06:00Z"), + Memento("m014", "Neo4j supports both graph relationships and vector embeddings in single database", "2025-11-16T00:06:15Z"), + Memento("m015", "User asked about worktrees and operating system - they are technical", "2025-11-16T00:06:30Z"), +] + +# ============================================================================ +# LAYER 2: ENTITIES (Extracted Structured Concepts) +# ============================================================================ + +@dataclass +class Entity: + """Structured entity extracted from mementos""" + id: str + name: str + type: str # Person, Project, Technology, Concept, Task + properties: Dict + scale: str # atomic, component, system, domain + extracted_from: List[str] # memento IDs + +@dataclass +class Relationship: + """Connection between entities""" + source: str + target: str + type: str + properties: Dict + extracted_from: List[str] + +class KnowledgeGraph: + """Multi-scale knowledge graph with hierarchy""" + + def __init__(self): + self.mementos: List[Memento] = [] + self.entities: Dict[str, Entity] = {} + self.relationships: List[Relationship] = [] + self.hierarchy: Dict[str, List[str]] = defaultdict(list) + + def add_memento(self, memento: Memento): + """Add raw memento""" + self.mementos.append(memento) + + def add_entity(self, entity: Entity): + """Add extracted entity""" + self.entities[entity.id] = entity + + def add_relationship(self, rel: Relationship): + """Add relationship between entities""" + self.relationships.append(rel) + + def add_hierarchy(self, parent: str, child: str): + """Add hierarchical relationship""" + self.hierarchy[parent].append(child) + + def to_mermaid(self) -> str: + """Generate Mermaid diagram""" + lines = ["graph TB"] + lines.append("") + lines.append(" %% === RAW MEMENTOS (Foundation Layer) ===") + + # Add entities by scale + scales = ["domain", "system", "component", "atomic"] + colors = { + "Person": "#e1f5fe", + "Project": "#f3e5f5", + "Technology": "#fff3e0", + "Concept": "#e8f5e9", + "Task": "#fff9c4", + "Preference": "#fce4ec" + } + + for scale in scales: + entities_in_scale = [e for e in self.entities.values() if e.scale == scale] + if entities_in_scale: + lines.append(f" %% {scale.upper()} SCALE") + for entity in entities_in_scale: + label = entity.name.replace('"', "'") + lines.append(f' {entity.id}["{label}"]') + lines.append("") + + # Add relationships + lines.append(" %% === RELATIONSHIPS ===") + for rel in self.relationships: + label = rel.type.replace("_", " ") + lines.append(f' {rel.source} -->|{label}| {rel.target}') + + lines.append("") + lines.append(" %% === STYLING ===") + for eid, entity in self.entities.items(): + color = colors.get(entity.type, "#ffffff") + lines.append(f" style {eid} fill:{color}") + + return "\n".join(lines) + + def to_neo4j_cypher(self) -> str: + """Generate Neo4j Cypher script""" + lines = ["// Knowledge Graph Demo - Neo4j Cypher Script", ""] + lines.append("// Clean slate") + lines.append("MATCH (n) DETACH DELETE n;") + lines.append("") + + # Create mementos + lines.append("// ============ RAW MEMENTOS ============") + for m in self.mementos: + content = m.content.replace('"', '\\"') + lines.append(f'CREATE (:{m.id}:Memento {{') + lines.append(f' id: "{m.id}",') + lines.append(f' content: "{content}",') + lines.append(f' timestamp: datetime("{m.timestamp}"),') + lines.append(f' source: "{m.source}"') + lines.append('});') + + lines.append("") + lines.append("// ============ ENTITIES ============") + for e in self.entities.values(): + props = ", ".join([f'{k}: "{v}"' for k, v in e.properties.items()]) + lines.append(f'CREATE (:{e.id}:{e.type} {{') + lines.append(f' id: "{e.id}",') + lines.append(f' name: "{e.name}",') + lines.append(f' scale: "{e.scale}",') + lines.append(f' {props}') + lines.append('});') + + lines.append("") + lines.append("// ============ RELATIONSHIPS ============") + for rel in self.relationships: + rel_type = rel.type.upper().replace(" ", "_") + props = ", ".join([f'{k}: "{v}"' for k, v in rel.properties.items()]) + props_str = f' {{{props}}}' if props else '' + lines.append(f'MATCH (s:{rel.source}), (t:{rel.target})') + lines.append(f'CREATE (s)-[:{rel_type}{props_str}]->(t);') + + lines.append("") + lines.append("// ============ MEMENTO -> ENTITY EXTRACTION ============") + for e in self.entities.values(): + for memento_id in e.extracted_from: + lines.append(f'MATCH (m:{memento_id}), (e:{e.id})') + lines.append(f'CREATE (m)-[:EXTRACTED_TO]->(e);') + + return "\n".join(lines) + + def to_json(self) -> str: + """Export as JSON for analysis""" + return json.dumps({ + "mementos": [asdict(m) for m in self.mementos], + "entities": [asdict(e) for e in self.entities.values()], + "relationships": [asdict(r) for r in self.relationships], + "hierarchy": dict(self.hierarchy), + "statistics": { + "total_mementos": len(self.mementos), + "total_entities": len(self.entities), + "total_relationships": len(self.relationships), + "entities_by_type": self._count_by_type(), + "entities_by_scale": self._count_by_scale() + } + }, indent=2) + + def _count_by_type(self) -> Dict[str, int]: + counts = defaultdict(int) + for e in self.entities.values(): + counts[e.type] += 1 + return dict(counts) + + def _count_by_scale(self) -> Dict[str, int]: + counts = defaultdict(int) + for e in self.entities.values(): + counts[e.scale] += 1 + return dict(counts) + + def print_summary(self): + """Print beautiful ASCII summary""" + print("\n" + "="*80) + print("🧠 KNOWLEDGE GRAPH DEMO: Multi-Scale Memory Organization") + print("="*80) + + print(f"\nšŸ“ RAW MEMENTOS: {len(self.mementos)} unstructured observations") + print("-" * 80) + for m in self.mementos[:5]: + print(f" [{m.id}] {m.content}") + if len(self.mementos) > 5: + print(f" ... and {len(self.mementos) - 5} more") + + print(f"\nšŸŽÆ EXTRACTED ENTITIES: {len(self.entities)} structured concepts") + print("-" * 80) + + # Group by scale + for scale in ["domain", "system", "component", "atomic"]: + entities = [e for e in self.entities.values() if e.scale == scale] + if entities: + print(f"\n {scale.upper()} SCALE ({len(entities)} entities):") + for e in entities: + sources = f"from {len(e.extracted_from)} mementos" + print(f" • {e.name} ({e.type}) - {sources}") + + print(f"\nšŸ”— RELATIONSHIPS: {len(self.relationships)} connections") + print("-" * 80) + for rel in self.relationships[:10]: + src = self.entities[rel.source].name + tgt = self.entities[rel.target].name + print(f" {src} --[{rel.type}]--> {tgt}") + if len(self.relationships) > 10: + print(f" ... and {len(self.relationships) - 10} more") + + print("\n" + "="*80) + + +# ============================================================================ +# BUILD THE KNOWLEDGE GRAPH +# ============================================================================ + +def build_demo_graph() -> KnowledgeGraph: + """Construct the knowledge graph from conversation""" + kg = KnowledgeGraph() + + # Add all mementos + for m in MEMENTOS: + kg.add_memento(m) + + # DOMAIN SCALE: Highest level concepts + kg.add_entity(Entity("e_user", "User", "Person", + {"role": "developer", "expertise": "technical"}, + "domain", ["m001", "m007", "m009", "m015"])) + + kg.add_entity(Entity("e_ai_memory", "AI Memory Systems", "Concept", + {"domain": "artificial_intelligence", "subdomain": "memory"}, + "domain", ["m002", "m012"])) + + # SYSTEM SCALE: Major projects/systems + kg.add_entity(Entity("e_memento", "Memento Project", "Project", + {"status": "in_development", "purpose": "LLM persistent memory"}, + "system", ["m001", "m002", "m003"])) + + # COMPONENT SCALE: Architectural components + kg.add_entity(Entity("e_neo4j", "Neo4j", "Technology", + {"category": "database", "features": "graph+vector"}, + "component", ["m004", "m014"])) + + kg.add_entity(Entity("e_fastmcp", "FastMCP", "Technology", + {"category": "framework", "language": "python"}, + "component", ["m003"])) + + kg.add_entity(Entity("e_mcp", "Model Context Protocol", "Technology", + {"category": "protocol", "purpose": "LLM tool integration"}, + "component", ["m002"])) + + kg.add_entity(Entity("e_embeddings", "Local Embeddings", "Technology", + {"provider": "sentence-transformers", "model": "all-MiniLM-L6-v2"}, + "component", ["m008", "m011"])) + + # ATOMIC SCALE: Specific implementation details + kg.add_entity(Entity("e_branch", "Feature Branch", "Concept", + {"name": "claude/knowledge-graph-prototype-016woGkvRjndwTdvaeEGhz73"}, + "atomic", ["m006"])) + + kg.add_entity(Entity("e_isolation", "Agent Isolation", "Concept", + {"importance": "high", "reason": "prevent interference"}, + "atomic", ["m005", "m007"])) + + kg.add_entity(Entity("e_task_embeddings", "Implement Local Embeddings", "Task", + {"status": "in_progress", "epic": "core_components"}, + "atomic", ["m008"])) + + kg.add_entity(Entity("e_task_demo", "Basic Demo", "Task", + {"status": "in_progress", "epic": "core_components"}, + "atomic", ["m008"])) + + kg.add_entity(Entity("e_adr006", "ADR-006: Leverage Client LLM", "Concept", + {"decision": "use_client_llm", "principle": "YAGNI"}, + "atomic", ["m013"])) + + kg.add_entity(Entity("e_pref_hierarchy", "Preference: Hierarchical Organization", "Preference", + {"valued": "hierarchy, entities, relationships"}, + "atomic", ["m009"])) + + kg.add_entity(Entity("e_pref_wow", "Preference: WOW Factor", "Preference", + {"valued": "impressive visualizations"}, + "atomic", ["m010"])) + + # RELATIONSHIPS - Multi-scale connections + + # User relationships + kg.add_relationship(Relationship("e_user", "e_memento", "WORKS_ON", + {"role": "creator"}, ["m001"])) + kg.add_relationship(Relationship("e_user", "e_isolation", "VALUES", + {"priority": "high"}, ["m007"])) + kg.add_relationship(Relationship("e_user", "e_pref_hierarchy", "HAS_PREFERENCE", + {}, ["m009"])) + kg.add_relationship(Relationship("e_user", "e_pref_wow", "HAS_PREFERENCE", + {}, ["m010"])) + + # Project composition + kg.add_relationship(Relationship("e_memento", "e_ai_memory", "BELONGS_TO_DOMAIN", + {}, ["m002"])) + kg.add_relationship(Relationship("e_memento", "e_mcp", "IMPLEMENTS", + {"role": "server"}, ["m002"])) + kg.add_relationship(Relationship("e_memento", "e_fastmcp", "USES", + {"purpose": "framework"}, ["m003"])) + kg.add_relationship(Relationship("e_memento", "e_neo4j", "USES", + {"purpose": "storage"}, ["m004"])) + kg.add_relationship(Relationship("e_memento", "e_embeddings", "USES", + {"purpose": "semantic_search"}, ["m011"])) + + # Architectural relationships + kg.add_relationship(Relationship("e_neo4j", "e_embeddings", "STORES", + {"data_type": "vector_embeddings"}, ["m014"])) + kg.add_relationship(Relationship("e_adr006", "e_memento", "GUIDES", + {"aspect": "architecture"}, ["m013"])) + + # Task relationships + kg.add_relationship(Relationship("e_task_embeddings", "e_memento", "CONTRIBUTES_TO", + {"phase": "1"}, ["m008"])) + kg.add_relationship(Relationship("e_task_demo", "e_memento", "CONTRIBUTES_TO", + {"phase": "1"}, ["m008"])) + kg.add_relationship(Relationship("e_task_embeddings", "e_embeddings", "IMPLEMENTS", + {}, ["m008", "m011"])) + + # Development environment + kg.add_relationship(Relationship("e_branch", "e_isolation", "PROVIDES", + {"mechanism": "git_branch"}, ["m006", "m007"])) + kg.add_relationship(Relationship("e_user", "e_branch", "WORKS_IN", + {"environment": "cloud"}, ["m005", "m006"])) + + return kg + + +# ============================================================================ +# GENERATE WOW FACTOR OUTPUTS +# ============================================================================ + +if __name__ == "__main__": + print("\nšŸš€ Building Knowledge Graph from Conversation...") + kg = build_demo_graph() + + # Print summary + kg.print_summary() + + # Save outputs + print("\nšŸ’¾ Generating output files...") + + with open("/home/user/memento/prototype/kg-demo/graph.json", "w") as f: + f.write(kg.to_json()) + print(" āœ“ Saved: graph.json (structured data)") + + with open("/home/user/memento/prototype/kg-demo/graph.cypher", "w") as f: + f.write(kg.to_neo4j_cypher()) + print(" āœ“ Saved: graph.cypher (Neo4j visualization script)") + + with open("/home/user/memento/prototype/kg-demo/graph.mmd", "w") as f: + f.write(kg.to_mermaid()) + print(" āœ“ Saved: graph.mmd (Mermaid diagram)") + + print("\n✨ Knowledge Graph Demo Complete!") + print("\nšŸ“Š Next steps:") + print(" • View graph.json for full structured data") + print(" • Load graph.cypher into Neo4j for interactive exploration") + print(" • Render graph.mmd with Mermaid for quick visualization") + print() diff --git a/prototype/kg-demo/mobile.html b/prototype/kg-demo/mobile.html new file mode 100644 index 0000000..d823d29 --- /dev/null +++ b/prototype/kg-demo/mobile.html @@ -0,0 +1,590 @@ + + + + + + + + Knowledge Graph - Mobile + + + +
+
+

🧠 Knowledge Graph

+
Touch & drag to explore
+
+ +
+
+
15
+
Mementos
+
+
+
14
+
Entities
+
+
+
16
+
Links
+
+
+ +
+
Person
+
Project
+
Tech
+
Concept
+
Task
+
Pref
+
+ +
+ +
+ +
+ +
+ +
+
+ Node Details + +
+
+ Tap a node to see details +
+
+
+ + + +