# Project export: memory-manager

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: UC Berkeley AI Hackathon 2025
- Tagline: this memory solution for AI chatbots with a visualization is a dynamic data structure for human-like accessing of relevant memories, boosting productivity and enhancing results from using chatbots.
- Devpost: https://devpost.com/software/memory-manager
- GitHub: https://github.com/KomalKaur0/memory-manager
- Team: 3 GitHub contributor(s) — max-raney (28 commits), Komal Kaur (19 commits), Claude (14 commits)

## Devpost submission (written by the team)

### Inspiration

AI chatbots have a memory to streamline conversations and draw context across conversations to make interactions more effective. These memory systems are similar to having someone use a Google Search to find a memory with keywords, but cannot go deeper than that about how the memories connect and fit together. The Problem with Current Memory Approaches Traditional Vector Search (The "Google Search" Problem): Stores memories as isolated embeddings in vector space Retrieval is based purely on semantic similarity to query No understanding of relationships between stored memories Results are ranked by distance metrics, not contextual relevance Cannot leverage connection patterns to improve accuracy over time Treats each piece of information as independent We believe we can combine the embedding space's ability to store ideas and use a graph to draw connections between them. In essence, we are inspired by the human mind to create a memory solution that can dynamically use nodes in a graph like neurons in a brain.

### What it does

Our solution has the following key components: Dynamic Weighted Graph Memory: where the edge weight depends on the usage and relevance to the current node. Dual Storage Strategy: Neo4j Graph Database - Stores memories and their relationships with rich metadata. Weaviate Vector Store - Enables fast semantic similarity search. Hybrid Queries - Combines semantic search with graph traversal for superior results. Dual Storage Strategy: Neo4j Graph Database - Stores memories and their relationships with rich metadata. Weaviate Vector Store - Enables fast semantic similarity search. Hybrid Queries - Combines semantic search with graph traversal for superior results. Learning Connection Weights: Edges start at weight = 0 and strengthen through usage (neural-like plasticity). Connection types between nodes are causation, temporal sequence, similarity, contrast, generalization. Usage patterns influence future retrieval relevance. Learning Connection Weights: Edges start at weight = 0 and strengthen through usage (neural-like plasticity). Connection types between nodes are causation, temporal sequence, similarity, contrast, generalization. Usage patterns influence future retrieval relevance. What it all does Connection-Aware Retrieval: Instead of just finding semantically similar content, the system: Generates a hypothetical ideal response embedding Finds candidate memories through vector similarity Traverses the connection graph to discover related concepts Uses an AI filter agent to evaluate contextual relevance Returns curated results with provenance and reasoning Frontend Interface: Interact with a chatbot and use the 3D visualizer tool to see the dynamic memory graph in action. View memory nodes See access patterns Understand how the chatbot is using the memories it knows Why This Matters For AI Systems: More accurate retrieval that improves with usage Contextual understanding beyond keyword matching Reduced hallucination through connection-based validation Emergent knowledge discovery through graph patterns For Real Applications: Personal AI assistants that truly "remember" your conversations Educational systems that understand knowledge prerequisites Research tools that can discover non-obvious connections Customer service that learns relationship patterns in problems Company storage and access to knowledge and papers

### How we built it

We came up with the full idea using experience from various coursework and used Claude Code to help build it.

### Challenges we ran into

Time restriction Limitations on RAM

### Accomplishments we're proud of

We are proud of having come up with this idea and building both a front and back end for it to make it as interactive and intuitive as possible.

### What we learned

We learned about implementations of the embedding space and how to use React.js for visualizations. We learned about existing memory management techniques and their drawbacks.

### What's next

We would like to improve the visualization's 3D capabilities by exploring other implementations.

## README (from the GitHub repository)

## Inspiration
AI chatbots have a memory to streamline conversations and draw context across conversations to make interactions more effective. These memory systems are similar to having someone use a Google Search to find a memory with keywords, but cannot go deeper than that about how the memories connect and fit together. 
The Problem with Current Memory Approaches
Traditional Vector Search (The "Google Search" Problem):

- Stores memories as isolated embeddings in vector space
- Retrieval is based purely on semantic similarity to query
- No understanding of relationships between stored memories
- Results are ranked by distance metrics, not contextual relevance
- Cannot leverage connection patterns to improve accuracy over time
- Treats each piece of information as independent

We believe we can combine the embedding space's ability to store ideas and use a graph to draw connections between them. In essence, we are inspired by the human mind to create a memory solution that can dynamically use nodes in a graph like neurons in a brain.

## What it does

Our solution has the following key components:
- Dynamic Weighted Graph Memory:

```
Memories as Nodes: {concept, content, keywords, tags, connections}
Relationships as Edges: {connection_type, weight, usage_history}
```

where the edge weight depends on the usage and relevance to the current node.

- Dual Storage Strategy: Neo4j Graph Database - Stores memories and their relationships with rich metadata. 
Weaviate Vector Store - Enables fast semantic similarity search.
Hybrid Queries - Combines semantic search with graph traversal for superior results.

- Learning Connection Weights: Edges start at weight = 0 and strengthen through usage (neural-like plasticity). Connection types between nodes are causation, temporal sequence, similarity, contrast, generalization. Edge weights are based purely on access frequency and relative recency — measured by system activity, not wall-clock time — so frequently co-accessed memories develop stronger connections over time.
- 
**What it all does**
Connection-Aware Retrieval:

Instead of just finding semantically similar content, the system:

- Generates a hypothetical ideal response embedding
- Finds candidate memories through vector similarity
- Traverses the connection graph to discover related concepts
- Uses an AI filter agent to evaluate contextual relevance
- Returns curated results with provenance and reasoning

Frontend Interface:

Interact with a chatbot and use the 3D visualizer tool to see the dynamic memory graph in action.

- View memory nodes
- See access patterns
- Understand how the chatbot is using the memories it knows

**Why This Matters**
For AI Systems:

- More accurate retrieval that improves with usage
- Contextual understanding beyond keyword matching
- Reduced hallucination through connection-based validation
- Emergent knowledge discovery through graph patterns

For Real Applications:

- Personal AI assistants that truly "remember" your conversations
- Educational systems that understand knowledge prerequisites
- Research tools that can discover non-obvious connections
- Customer service that learns relationship patterns in problems
- Company storage and access to knowledge and papers

## How we built it

We came up with the full idea using experience from various coursework and used Claude Code to help build it.

## Challenges we ran into

- Time restriction
- Limitations on RAM

## Accomplishments that we're proud of

We are proud of having come up with this idea and building both a front and back end for it to make it as interactive and intuitive as possible.

## What we learned

We learned about implementations of the embedding space and how to use React.js for visualizations. We learned about existing memory management techniques and their drawbacks.

## What's next for memory-manager

We would like to improve the visualization's 3D capabilities by exploring other implementations.


## Detected evidence (automated analysis)

Indexed codebase: 119 recognized source files, 1196 KB.
- Anthropic (technology) — detected in the code
- FastAPI (technology) — detected in the code
- HTML (language) — detected in the code
- Hugging Face (technology) — detected in the code
- JavaScript (language) — detected in the code
- Python (language) — detected in the code
- PyTorch (technology) — detected in the code
- React (technology) — detected in the code
- TypeScript (language) — detected in the code
- Google Gemini (technology) — claimed on Devpost, not found in the code
- AI coding agent: Claude Code — evidence: commit authorship or trailers

## Codebase structure (from repository index)

### Files (120 of 132)

```
.gitignore
check_network.py
config/__init__.py
config/database_config.yaml
config/database.py
config/settings.py
docs/api_reference.md
docs/architecture.md
docs/getting_started.md
docs/visualization_guide.md
enhanced_benchmark_search_performance_20250621_235904.json
enhanced_benchmark_small_20250621_235839.json
ENVIRONMENT_SETUP.md
example_complete_agent_system.py
examples/conversation_sim.py
examples/example_agent_usage.py
examples/example_complete_agent_system.py
examples/example_must_keep_demo.py
examples/knowledge_base_migration.py
frontend/.env.backup
frontend/.gitignore
frontend/app.json
frontend/App.tsx
frontend/index.ts
frontend/package.json
frontend/README.md
frontend/src/components/Chat/ChatBubble.tsx
frontend/src/components/Chat/ChatInput.tsx
frontend/src/components/Chat/TypingIndicator.tsx
frontend/src/components/Connection/ConnectionStatus.tsx
frontend/src/components/Debug/ConnectionDebug.tsx
frontend/src/components/Debug/DebugFloatingButton.tsx
frontend/src/components/Memory3D/MemoryConnection3D.tsx
frontend/src/components/Memory3D/MemoryGraph3D.tsx
frontend/src/components/Memory3D/MemoryGraphOverlay.tsx
frontend/src/components/Memory3D/MemoryNode3D.tsx
frontend/src/components/Memory3D/SimpleTest3D.tsx
frontend/src/components/MemoryOverlay/MemoryVisualizationOverlay.tsx
frontend/src/config/api.ts
frontend/src/hooks/useBackendConnection.ts
frontend/src/navigation/AppNavigator.tsx
frontend/src/screens/ChatScreen.tsx
frontend/src/screens/MemoryVisualizationScreen.tsx
frontend/src/services/apiService.ts
frontend/src/stores/chatStore.ts
frontend/src/stores/memoryStore.ts
frontend/src/types/memory.ts
frontend/src/utils/connectionTest.ts
frontend/src/utils/memoryLayout.ts
frontend/tsconfig.json
main.py
MUST_KEEP_FEATURE_SUMMARY.md
README.md
requirements.in
requirements.txt
scripts/benchmark_config.py
scripts/benchmark_performance.py
scripts/enhanced_benchmark.py
scripts/import_data.py
scripts/memory_app.py
scripts/populate_demo_data.py
scripts/README.md
scripts/setup_database.py
scripts/simple_benchmark.py
setup_tunnel_auto.sh
setup_tunnel.sh
setup.py
simple_benchmark_results_20250621_235350.json
src/__init__.py
src/agents/__init__.py
src/agents/connection_agent.py
src/agents/filter_agent.py
src/agents/mock_claude_client.py
src/agents/relevance_agent.py
src/api/__init__.py
src/api/admin_api.py
src/api/analytics_api.py
src/api/chat_api.py
src/api/memory_api.py
src/api/search_api.py
src/api/websocket_manager.py
src/core/__init__.py
src/core/edge_manager.py
src/core/memory_graph.py
src/core/memory_node.py
src/core/weight_calculator.py
src/learning/__init__.py
src/learning/adaptive_weights.py
src/learning/connection_builder.py
src/learning/temporal_decay.py
src/learning/usage_tracker.py
src/retrieval/__init__.py
src/retrieval/embedding_search_mock.py
src/retrieval/embedding_search_simple.py
src/retrieval/embedding_search.py
src/retrieval/graph_traversal.py
src/retrieval/hybrid_retriever_simple.py
src/retrieval/hybrid_retriever.py
src/retrieval/search_strategies.py
src/storage/__init__.py
src/storage/graph_database.py
src/storage/memory_importer.py
src/storage/migration_tools.py
src/storage/vector_store.py
src/visualization/__init__.py
src/visualization/analytics_dashboard.py
src/visualization/graph_renderer.py
src/visualization/interactive_explorer.py
src/visualization/spatial_layout.py
start_development.sh
start_server.sh
test_chat_integration.py
test_claude_fallback_logging.py
test_conversation_history_config.py
test_frontend_backend.html
test_frontend_env.js
test_integration.py
tests/__init__.py
tests/conftest.py
tests/fixtures/sample_memories.json
[12 more files omitted for size]
```

### Dependencies

- frontend/package.json: @babel/core@^7.25.2, @expo/metro-runtime@~5.0.4, @react-navigation/bottom-tabs@^7.3.17, @react-navigation/native@^7.1.13, @types/react@~19.0.10, expo@~53.0.12, expo-blur@^14.1.5, expo-status-bar@~2.2.3, react@^19.0.0, react-dom@19.0.0, react-native@0.79.4, react-native-gesture-handler@~2.24.0, react-native-reanimated@~3.17.4, react-native-safe-area-context@^5.4.0, react-native-screens@^4.11.1, react-native-svg@^15.12.0, react-native-web@^0.20.0, typescript@~5.8.3, zustand@^5.0.5
- requirements.txt: annotated-types@==0.7.0, anthropic, anyio@==4.9.0, certifi@==2025.6.15, charset-normalizer@==3.4.2, fastapi@==0.115.13, filelock@==3.18.0, fsspec@==2025.5.1, hf-xet@==1.1.5, huggingface-hub@==0.33.0, idna@==3.10, iniconfig@==2.1.0, jinja2@==3.1.6, joblib@==1.5.1, markupsafe@==3.0.2, mpmath@==1.3.0, neo4j@==5.28.1, networkx@==3.5, numpy@==2.3.1, packaging@==25.0, pillow@==11.2.1, pluggy@==1.6.0, pydantic@==2.11.7, pydantic-core@==2.33.2, pygments@==2.19.2, pytest@==8.4.1, python-dotenv, pytz@==2025.2, pyyaml@==6.0.2, regex@==2024.11.6, requests@==2.32.4, safetensors@==0.5.3, scikit-learn@==1.7.0, scipy@==1.15.3, sentence-transformers@==4.1.0, sniffio@==1.3.1, starlette@==0.46.2, sympy@==1.14.0, threadpoolctl@==3.6.0, tokenizers@==0.21.1, torch@==2.7.1, tqdm@==4.67.1, transformers@==4.52.4, typing-extensions@==4.14.0, typing-inspection@==0.4.1, urllib3@==2.5.0

### Recent commits (newest first)

- add paper via upload
- Clarify learning connection weights in README
- Enhance chatbot to use Claude with retrieved memories for intelligent responses
- Merge pull request #4 from KomalKaur0/backend/0.00.04
- Fix crashes in chat memory visualization overlay
- Fix crash when expanding node info in memory visualization
- Complete chatbot integration with real backend memory system
- Fix memory connection visualization in 3D graph
- readme
- readme
- Merge branch 'backend/0.00.04' into integration
- Server tunnel setup
- mesh backend files
- Add comprehensive demo data with 12 realistic memory clusters
- Implement comprehensive frontend-backend integration with collapsible debug panel
- Merge backend/memory-architecture-update into development
- Complete co-access connection learning system and comprehensive testing
- Early benchmark examples and tests
- Merge pull request #3 from KomalKaur0/backend/0.00.03
- Add support for loading API keys for voyager and claude from a .env file

## Key source files (fetched from GitHub, selected and truncated for size)

### MUST_KEEP_FEATURE_SUMMARY.md

```markdown
# Must-Keep Flagging System & Generous Memory Limits

## Overview
Enhanced the AI Memory System agents with a sophisticated "must-keep" flagging system that allows the AI to bypass all filtering constraints for absolutely critical memories, plus made memory limits much more generous across the board.

## 🔒 Must-Keep Flagging System

### Purpose
When the AI evaluates memory relevance, it can now flag certain memories as "must-keep" that will bypass ALL filtering constraints including:
- Relevance thresholds
- Redundancy removal
- Diversity optimization
- Platform constraints
- User preferences
- Count limits

### Must-Keep Criteria
A memory gets flagged as must-keep if it meets ANY of these criteria:

1. **Exceptional Overall Relevance**: >= 0.9 overall score with >= 0.8 confidence
2. **Perfect Semantic Match**: >= 0.95 semantic score with >= 0.7 context relevance
3. **Critical Domain Knowledge**: >= 0.8 importance score + >= 0.9 topical score, OR >= 0.95 importance
4. **Recently Accessed with Strong Relevance**: >= 5 access count + >= 0.7 overall score
5. **Critical Tags**: Memory tagged with "critical", "important", "essential", "key", "core", "fundamental"
6. **Multi-Dimensional Excellence**: >= 0.9 confidence + 2+ dimensions >= 0.8 + >= 0.75 overall
7. **Exact Concept Match**: 2+ matching words between query and concept + >= 0.6 overall

### How It Works
```python
# RelevanceAgent evaluates and flags
score = relevance_agent.evaluate_relevance(memory, query, context)
if score.must_keep:
    print("🔒 This memory will bypass all filters!")

# FilterAgent respects must-keep flags
result = filter_agent.filter_for_response(memories, scores, preferences, context)
# Must-keep memories are ALWAYS included, even if they violate constraints
```

### Example Output
```
Memory 1: Python async programming fundamentals 🔒 MUST-KEEP
  Relevance Score: 0.586
  Must-Keep Flag: True
  Reasoning: Critical memory (flagged as must-keep). MUST-KEEP, Moderate semantic match...
```

## 📈 More Generous Memory Limits

### Updated Defaults
| Setting | Old Value | New Value | Change |
|---------|-----------|-----------|---------|
| Default max_memories | 5 | 10 | +100% |
| Default relevance_threshold | 0.5 | 0.3 | -40% (more inclusive) |
| Mobile platform limit | 2 | 5 | +150% |
| Web platform limit | 5 | 15 | +200% |
| API platform limit | 10 | 25 | +150% |

### Platform-Specific Limits
```python
platform_limits = {
    'mobile': {'max_memories': 5},    # Was 2
    'web': {'max_memories': 15},      # Was 5  
    'api': {'max_memories': 25}       # Was 10
}
```

### Backward Compatibility
All changes maintain backward compatibility. Existing code continues to work, just with more generous defaults.

## 🎯 Benefits

### For AI Decision Making
- **Critical Knowledge Protection**: Important memories can't be accidentally filtered out
- **Intelligent Override**: AI can recognize when something is too important to lose
- **Context Awareness**: Must-keep decisions factor in 
[truncated — 1646 more characters]
```

### ENVIRONMENT_SETUP.md

```markdown
# 🌐 Environment Setup Guide

This guide explains how to configure the frontend to connect to the backend using environment variables, including tunnel support.

## 📁 Frontend Environment Configuration

The frontend uses environment variables to determine which backend URL to connect to. This allows easy switching between local development and tunnel URLs.

### Environment Variables

Create or edit `frontend/.env`:

```bash
# Primary backend URL - the main URL to use
EXPO_PUBLIC_API_BASE_URL=https://your-tunnel-url.ngrok.io

# Local development fallback
EXPO_PUBLIC_LOCAL_URL=http://localhost:8000

# Tunnel URL (for reference)
TUNNEL_URL=https://your-tunnel-url.ngrok.io

# Development settings
EXPO_PUBLIC_DEBUG_MODE=true
EXPO_PUBLIC_AUTO_CONNECT=true

# Fallback URLs (comma-separated, tried in order)
EXPO_PUBLIC_FALLBACK_URLS=https://your-tunnel-url.ngrok.io,http://localhost:8000,http://127.0.0.1:8000,http://192.168.156.157:8000
```

## 🚀 Quick Setup Scripts

### 1. Auto Setup with Tunnel

```bash
./setup_tunnel_auto.sh
```

This script:
- ✅ Checks if backend is running (starts if needed)
- ✅ Verifies ngrok installation
- ✅ Starts ngrok tunnel
- ✅ Auto-detects tunnel URL
- ✅ Updates frontend `.env` file
- ✅ Tests the connection

### 2. Manual URL Update

```bash
./update_tunnel_url.sh https://abc123.ngrok.io
```

Updates the frontend configuration with a specific tunnel URL.

### 3. Test Configuration

```bash
node test_frontend_env.js
```

Validates environment configuration and tests URLs.

## 🔧 Manual Setup

### Step 1: Start Backend

```bash
# Start backend server
source .env
source .venv/bin/activate
python -m uvicorn main:app --host 0.0.0.0 --port 8000 --reload
```

### Step 2: Create Tunnel (if needed)

```bash
# Install ngrok (if not installed)
# Visit: https://ngrok.com/download

# Start tunnel
ngrok http 8000
```

Copy the `https://` URL from ngrok output.

### Step 3: Update Frontend Config

```bash
# Method 1: Use script
./update_tunnel_url.sh https://abc123.ngrok.io

# Method 2: Edit manually
nano frontend/.env
```

### Step 4: Start Frontend

```bash
cd frontend
npm start
# Press 'w' for web browser
```

## 🧪 Testing Connection

### 1. Manual URL Test

```bash
# Test backend directly
curl https://your-tunnel-url.ngrok.io/health

# Expected response:
# {"status":"healthy","components":{"memory_graph":"healthy","embedding_search":"healthy"}}
```

### 2. Frontend Debug Panel

The app includes a **ConnectionDebug** component with a collapsible interface:

**Features:**
- ✅ Current environment configuration display
- ✅ Real-time connection status
- ✅ "Run Full Test" for comprehensive API testing
- ✅ Dynamic URL input and testing
- ✅ Floating button in top-left (debug mode only)
- ✅ Keyboard shortcut: `Ctrl+D` or `Cmd+D` (web)

**Access:**
- Click the floating debug button (top-left corner)
- Keyboard shortcut: `Ctrl+D` / `Cmd+D` (web only)
- Only visible when `EXPO_PUBLIC_DEBUG_MODE=true`

### 3. Browser Console

Check browser develop
[truncated — 2324 more characters]
```

### requirements.txt

```
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
#    pip-compile
#
annotated-types==0.7.0
    # via pydantic
anyio==4.9.0
    # via starlette
certifi==2025.6.15
    # via requests
charset-normalizer==3.4.2
    # via requests
fastapi==0.115.13
    # via -r requirements.in
filelock==3.18.0
    # via
    #   huggingface-hub
    #   torch
    #   transformers
fsspec==2025.5.1
    # via
    #   huggingface-hub
    #   torch
hf-xet==1.1.5
    # via huggingface-hub
huggingface-hub==0.33.0
    # via
    #   sentence-transformers
    #   tokenizers
    #   transformers
idna==3.10
    # via
    #   anyio
    #   requests
iniconfig==2.1.0
    # via pytest
jinja2==3.1.6
    # via torch
joblib==1.5.1
    # via scikit-learn
markupsafe==3.0.2
    # via jinja2
mpmath==1.3.0
    # via sympy
neo4j==5.28.1
    # via -r requirements.in
networkx==3.5
    # via torch
numpy==2.3.1
    # via
    #   -r requirements.in
    #   scikit-learn
    #   scipy
    #   transformers
packaging==25.0
    # via
    #   huggingface-hub
    #   pytest
    #   transformers
pillow==11.2.1
    # via sentence-transformers
pluggy==1.6.0
    # via pytest
pydantic==2.11.7
    # via
    #   -r requirements.in
    #   fastapi
pydantic-core==2.33.2
    # via pydantic
pygments==2.19.2
    # via pytest
pytest==8.4.1
    # via -r requirements.in
pytz==2025.2
    # via neo4j
pyyaml==6.0.2
    # via
    #   huggingface-hub
    #   transformers
regex==2024.11.6
    # via transformers
requests==2.32.4
    # via
    #   huggingface-hub
    #   transformers
safetensors==0.5.3
    # via transformers
scikit-learn==1.7.0
    # via sentence-transformers
scipy==1.15.3
    # via
    #   scikit-learn
    #   sentence-transformers
sentence-transformers==4.1.0
    # via -r requirements.in
sniffio==1.3.1
    # via anyio
starlette==0.46.2
    # via fastapi
sympy==1.14.0
    # via torch
threadpoolctl==3.6.0
    # via scikit-learn
tokenizers==0.21.1
    # via transformers
torch==2.7.1
    # via sentence-transformers
tqdm==4.67.1
    # via
    #   huggingface-hub
    #   sentence-transformers
    #   transformers
transformers==4.52.4
    # via sentence-transformers
typing-extensions==4.14.0
    # via
    #   anyio
    #   fastapi
    #   huggingface-hub
    #   pydantic
    #   pydantic-core
    #   sentence-transformers
    #   torch
    #   typing-inspection
typing-inspection==0.4.1
    # via pydantic
urllib3==2.5.0
    # via requests
python-dotenv
anthropic

# The following packages are considered to be unsafe in a requirements file:
# setuptools

```

### frontend/package.json

```
{
  "name": "ai-memory-frontend",
  "version": "1.0.0",
  "main": "index.ts",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@react-navigation/bottom-tabs": "^7.3.17",
    "@react-navigation/native": "^7.1.13",
    "expo": "~53.0.12",
    "expo-blur": "^14.1.5",
    "expo-status-bar": "~2.2.3",
    "react": "^19.0.0",
    "react-native": "0.79.4",
    "react-native-gesture-handler": "~2.24.0",
    "react-native-reanimated": "~3.17.4",
    "react-native-safe-area-context": "^5.4.0",
    "react-native-screens": "^4.11.1",
    "react-native-svg": "^15.12.0",
    "zustand": "^5.0.5",
    "react-dom": "19.0.0",
    "react-native-web": "^0.20.0",
    "@expo/metro-runtime": "~5.0.4"
  },
  "devDependencies": {
    "@babel/core": "^7.25.2",
    "@types/react": "~19.0.10",
    "typescript": "~5.8.3"
  },
  "private": true
}

```

### main.py

```python
"""
FastAPI main application for AI Memory System
"""
import logging
from contextlib import asynccontextmanager
from typing import AsyncGenerator
import os
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse

from src.api.memory_api import memory_router
from src.api.search_api import search_router
from src.api.admin_api import admin_router
from src.api.chat_api import chat_router
from src.api.analytics_api import analytics_router
from src.core.memory_graph import MemoryGraph
from src.retrieval.embedding_search_mock import EmbeddingSearch
from src.retrieval.hybrid_retriever_simple import HybridRetriever
from src.agents.relevance_agent import get_claude_client_from_env
from src.agents.connection_agent import ConnectionAgent
from src.retrieval.embedding_search import get_embedding_config_from_env
from src.api.websocket_manager import websocket_manager
from src.visualization.spatial_layout import SpatialLayoutEngine
from src.core.memory_node import MemoryNode, ConnectionType

# Load environment variables from .env file
load_dotenv()

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Global instances
memory_graph: MemoryGraph = None
embedding_search: EmbeddingSearch = None
hybrid_retriever: HybridRetriever = None

@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator:
    """Initialize and cleanup application resources"""
    global memory_graph, embedding_search, hybrid_retriever
    
    logger.info("Starting AI Memory System...")
    
    # Initialize core components
    memory_graph = MemoryGraph(decay_rate=0.01)
    
    # Initialize embedding search with API key from .env
    embedding_config = get_embedding_config_from_env()
    embedding_search = EmbeddingSearch(embedding_config)
    await embedding_search.initialize()
    
    hybrid_retriever = HybridRetriever(
        memory_graph=memory_graph,
        embedding_search=embedding_search
    )
    
    # Initialize connection agent for co-access tracking
    connection_agent = ConnectionAgent(memory_graph=memory_graph)
    
    # Initialize Claude client with API key from .env
    claude_client = get_claude_client_from_env()
    
    # Initialize spatial layout engine
    spatial_layout_engine = SpatialLayoutEngine()
    
    # Create demo data if memory graph is empty
    if len(memory_graph.nodes) == 0:
        logger.info("Creating demo memory data...")
        await create_demo_memory_data(memory_graph, spatial_layout_engine, hybrid_retriever)
    
    # Store instances in app state for access in routes
    app.state.memory_graph = memory_graph
    app.state.embedding_search = embedding_search
    app.state.hybrid_retriever = hybrid_retriever
    app.state.connection_agent = connection_agent
    app.state.claude_client = claude_client
    app.state.websocket_manager = websocket_manager
    app.state.spatial_layout_engine = spatial_layout_engine
    
    logger.info("AI Memory System initialized successfully")
    
    yield
    
    logger.info("Shutting down AI Memory System...")
    if embedding_search:
        await embedding_search.cleanup()

# Create FastAPI application
app = FastAPI(
    title="AI Memory System API",
    description="Adaptive graph-based memory system for AI with semantic similarity and learned associations",
    version="1.0.0",
    lifespan=lifespan
)

# Configure CORS for frontend access
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "http://localhost:8081",  # Expo dev server
        "http://localhost:19006", # Expo web dev server  
        "http://127.0.0.1:8081",  # Alternative localhost
        "http://127.0.0.1:19006", # Alternative localhost
        "*",  # Allow all for development
    ],
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    allow_headers=["*"],
)

# Include API routers
app.include_router(memory_router, prefix="/api/memory", tags=["memory"])
app.include_router(search_router, prefix="/api/search", tags=["search"])
app.include_router(admin_router, prefix="/api/admin", tags=["admin"])
app.include_router(chat_router, prefix="/api/chat", tags=["chat"])
app.include_router(analytics_router, prefix="/api/analytics", tags=["analytics"])

@app.get("/")
async def root():
    """Root endpoint with system information"""
    return {
        "message": "AI Memory System API",
        "version": "1.0.0",
        "status": "running",
        "docs": "/docs"
    }

@app.get("/health")
async def health_check():
    """Health check endpoint"""
    try:
        # Basic health checks
        graph_healthy = app.state.memory_graph is not None
        embedding_healthy = app.state.embedding_search is not None and app.state.embedding_search.is_ready()
        
        return {
            "status": "healthy" if graph_healthy and embedding_healthy else "degraded",
            "components": {
                "memory_graph": "healthy" if graph_healthy else "unhealthy",
                "embedding_search": "healthy" if embedding_healthy else "unhealthy"
            }
        }
    except Exception as e:
        logger.error(f"Health check failed: {e}")
        return JSONResponse(
            status_code=503,
            content={"status": "unhealthy", "error": str(e)}
        )

@app.exception_handler(404)
async def not_found_handler(request, exc):
    return JSONResponse(
        status_code=404,
        content={"error": "Endpoint not found", "message": str(exc)}
    )

@app.exception_handler(500)
async def internal_error_handler(request, exc):
    logger.error(f"Internal server error: {exc}")
    return JSONResponse(
        status_code=500,
        content={"error": "Internal server error", "message": "An unexpected error occurred"}
    )

async def create_demo_memory_data(memory_graph, layout_engine, hy
[truncated — 6572 more characters]
```

### frontend/index.ts

```typescript
import { registerRootComponent } from 'expo';

import App from './App';

// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
// the environment is set up appropriately
registerRootComponent(App);

```

### frontend/App.tsx

```typescript
import React, { useEffect } from 'react';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { AppNavigator } from './src/navigation/AppNavigator';
import { useMemoryStore } from './src/stores/memoryStore';

export default function App() {
  const { generateMockData, nodes } = useMemoryStore();

  // Generate mock data on app start
  useEffect(() => {
    if (Object.keys(nodes).length === 0) {
      generateMockData();
    }
  }, [generateMockData, nodes]);

  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <AppNavigator />
    </GestureHandlerRootView>
  );
}

```

### start_server.sh

```shell
#!/bin/bash

# Load environment variables from .env file
if [ -f .env ]; then
    export $(cat .env | xargs)
fi

# Activate virtual environment and start server
source .venv/bin/activate
python -m uvicorn main:app --host 0.0.0.0 --port 8000 --reload
```

### update_tunnel_url.sh

```shell
#!/bin/bash

# Script to update frontend .env with new tunnel URL

if [ -z "$1" ]; then
    echo "🚇 Update Frontend Tunnel URL"
    echo "============================"
    echo ""
    echo "Usage: $0 <tunnel-url>"
    echo ""
    echo "Example:"
    echo "  $0 https://abc123.ngrok.io"
    echo ""
    echo "Current .env configuration:"
    if [ -f "frontend/.env" ]; then
        echo "---"
        cat frontend/.env | grep -E "(API_BASE_URL|TUNNEL_URL|FALLBACK_URLS)"
        echo "---"
    else
        echo "  No frontend/.env file found"
    fi
    echo ""
    exit 1
fi

TUNNEL_URL="$1"

# Validate URL format
if [[ ! $TUNNEL_URL =~ ^https?:// ]]; then
    echo "❌ Invalid URL format. Please include https:// or http://"
    exit 1
fi

echo "🔄 Updating frontend .env with tunnel URL: $TUNNEL_URL"

# Create backup
if [ -f "frontend/.env" ]; then
    cp frontend/.env frontend/.env.backup
    echo "📋 Backup created: frontend/.env.backup"
fi

# Update the .env file
cat > frontend/.env << EOF
# AI Memory System Frontend Configuration

# Backend API URL - Primary URL to use
EXPO_PUBLIC_API_BASE_URL=${TUNNEL_URL}

# Local development fallback
EXPO_PUBLIC_LOCAL_URL=http://localhost:8000

# Tunnel URL (ngrok)
TUNNEL_URL=${TUNNEL_URL}

# Development settings
EXPO_PUBLIC_DEBUG_MODE=true
EXPO_PUBLIC_AUTO_CONNECT=true

# Fallback URLs (comma-separated)
EXPO_PUBLIC_FALLBACK_URLS=${TUNNEL_URL},http://localhost:8000,http://127.0.0.1:8000,http://192.168.156.157:8000
EOF

echo "✅ Frontend .env updated successfully!"
echo ""
echo "📋 New configuration:"
echo "---"
cat frontend/.env
echo "---"
echo ""
echo "🔄 Next steps:"
echo "1. Restart your frontend development server"
echo "2. The app will automatically use the new URL"
echo "3. Check the ConnectionDebug component to verify connection"
echo ""
echo "💡 To test the connection:"
echo "   curl ${TUNNEL_URL}/health"
```

### setup_tunnel.sh

```shell
#!/bin/bash

echo "🚇 Setting up ngrok tunnel for AI Memory System"
echo "=============================================="

# Check if ngrok is installed
if ! command -v ngrok &> /dev/null; then
    echo "❌ ngrok not found. Installing..."
    
    # Download and install ngrok
    if [[ "$OSTYPE" == "linux-gnu"* ]]; then
        echo "📥 Downloading ngrok for Linux..."
        curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null
        echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | sudo tee /etc/apt/sources.list.d/ngrok.list
        sudo apt update && sudo apt install ngrok
    elif [[ "$OSTYPE" == "darwin"* ]]; then
        echo "📥 Installing ngrok via Homebrew..."
        brew install ngrok/ngrok/ngrok
    else
        echo "❌ Unsupported OS. Please install ngrok manually: https://ngrok.com/download"
        exit 1
    fi
fi

# Check if backend is running
echo "🩺 Checking if backend is running..."
if curl -s http://localhost:8000/health > /dev/null; then
    echo "✅ Backend is running on localhost:8000"
else
    echo "❌ Backend not running. Start it first:"
    echo "   source .venv/bin/activate && python main.py"
    exit 1
fi

# Start ngrok tunnel
echo "🚀 Starting ngrok tunnel..."
echo "   This will create a public URL for your backend"
echo "   Use Ctrl+C to stop the tunnel"
echo ""

# Start ngrok in background and capture URL
ngrok http 8000 --log=stdout | while read line; do
    if [[ $line == *"url=https://"* ]]; then
        url=$(echo $line | grep -o 'url=https://[^[:space:]]*' | cut -d= -f2)
        echo "🌐 Tunnel URL: $url"
        echo ""
        echo "📝 Update your frontend config:"
        echo "   BASE_URL: '$url'"
        echo ""
        echo "   Or use the ConnectionStatus component to update the URL dynamically"
        echo ""
    fi
    echo "$line"
done
```

[84 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]