# 🧠 Модуль Пам'яті для Агента Sofiia на NODA2

## 📊 Архітектура Пам'яті DAARION

### Трирівнева система пам'яті:

```
┌─────────────────────────────────────────────────────────────┐
│                     SOFIIA MEMORY STACK                     │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐     │
│  │   Qdrant     │  │  PostgreSQL  │  │    Neo4j     │     │
│  │   (Vector)   │  │ (Relational) │  │   (Graph)    │     │
│  └──────────────┘  └──────────────┘  └──────────────┘     │
│        │                  │                  │             │
│        └──────────────────┼──────────────────┘             │
│                           │                                │
│                  ┌────────▼────────┐                      │
│                  │ Memory Service  │                      │
│                  │    (:8000)      │                      │
│                  └─────────────────┘                      │
│                           │                                │
│                  ┌────────▼────────┐                      │
│                  │  Sofiia Agent   │                      │
│                  │   (OpenClaw)    │                      │
│                  └─────────────────┘                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

---

## 1. Векторна Пам'ять (Qdrant)

### Колекції для Sofiia:

| Колекція | Призначення | Dimension |
|----------|-------------|-----------|
| `sofiia_messages` | Історія повідомлень діалогів | 1024 |
| `sofiia_docs` | Документи та knowledge base | 1024 |
| `sofiia_memory_items` | Long-term memory items | 1024 |
| `sofiia_user_context` | Контекст користувачів | 1024 |

**Embedding model:** Cohere embed-multilingual-v3.0 (1024 dimensions)

### Що зберігається:
- Повідомлення користувачів та відповіді Sofiia
- Документація проектів
- Контекстні дані про користувачів
- Long-term memories (важливі факти, рішення)

---

## 2. Реляційна Пам'ять (PostgreSQL)

### Таблиця `user_facts`:

| Поле | Тип | Опис |
|------|-----|------|
| `fact_id` | UUID | Унікальний ID |
| `user_id` | String | ID користувача |
| `team_id` | String | ID команди/DAO |
| `agent_id` | String | **"sofiia"** |
| `fact_key` | String | Ключ факту |
| `fact_value` | Text | Текстове значення |
| `fact_value_json` | JSONB | Структуровані дані |

### Приклади фактів:
- `name`: "Олександр"
- `preferences`: {"language": "uk", "style": "formal"}
- `chat_event:2026-02-22`: "Обговорювали архітектуру DAARION"

---

## 3. Графова Пам'ять (Neo4j)

### Node types:
- `Agent` - Sofiia
- `User` - Користувачі
- `Channel` - Telegram, Slack, etc.
- `Message` - Повідомлення
- `Topic` - Теми розмов
- `Project` - Проєкти (DAARION, NODA2, etc.)

### Relationships:
```
(User)-[:SENT]->(Message)
(Sofiia)-[:RESPONDED]->(Message)
(Message)-[:IN_CHANNEL]->(Telegram)
(Message)-[:ABOUT]->(Architecture)
(Message)-[:REFERENCES]->(Project:DAARION)
```

### Що дає:
- Зв'язки між користувачами та темами
- Історія розмов по проектах
- Виявлення залежностей

---

## 🎯 Варіанти налаштування на NODA2:

### Варіант A: Локальна пам'ять (ПОВНА НЕЗАЛЕЖНІСТЬ) ✨

**Переваги:**
- ✅ Повна ізоляція від NODA1
- ✅ Швидкий доступ (локально)
- ✅ Можна тестувати без впливу на прод
- ✅ Dev-середовище

**Недоліки:**
- ❌ Не бачить пам'ять з NODA1
- ❌ Потрібно більше ресурсів
- ❌ Окремі дані для dev

**Що потрібно:**
```yaml
services:
  # Qdrant для векторної пам'яті
  qdrant-node2:
    image: qdrant/qdrant:latest
    container_name: dagi-qdrant-node2
    ports:
      - "6333:6333"
      - "6334:6334"
    volumes:
      - ./data/qdrant-node2:/qdrant/storage
    environment:
      - QDRANT__SERVICE__HOST=0.0.0.0

  # PostgreSQL для реляційної пам'яті
  postgres-node2:
    image: postgres:16
    container_name: dagi-postgres-node2
    ports:
      - "5433:5432"
    environment:
      - POSTGRES_DB=daarion_memory
      - POSTGRES_USER=daarion
      - POSTGRES_PASSWORD=daarion_secret
    volumes:
      - ./data/postgres-node2:/var/lib/postgresql/data

  # Neo4j для графової пам'яті (опціонально)
  neo4j-node2:
    image: neo4j:5.15
    container_name: dagi-neo4j-node2
    ports:
      - "7474:7474"
      - "7687:7687"
    environment:
      - NEO4J_AUTH=neo4j/daarion_secret
    volumes:
      - ./data/neo4j-node2:/data

  # Memory Service
  memory-service-node2:
    build: ./services/memory-service
    container_name: dagi-memory-service-node2
    ports:
      - "8000:8000"
    environment:
      - QDRANT_HOST=qdrant-node2
      - QDRANT_PORT=6333
      - DATABASE_URL=postgresql://daarion:daarion_secret@postgres-node2:5432/daarion_memory
      - NEO4J_URI=bolt://neo4j-node2:7687
      - COHERE_API_KEY=${COHERE_API_KEY}
    depends_on:
      - qdrant-node2
      - postgres-node2
```

---

### Варіант B: Підключення до NODA1 (РЕПЛІКА) 🔄

**Переваги:**
- ✅ Бачить пам'ять з NODA1
- ✅ Економія ресурсів
- ✅ Read-replica для аналітики
- ✅ Реальний прод-контекст

**Недоліки:**
- ❌ Залежність від NODA1
- ❌ Мережева затримка
- ❌ Не можна писати (read-only)

**Що потрібно:**
```yaml
services:
  # Memory Service підключається до NODA1
  memory-service-node2:
    build: ./services/memory-service
    container_name: dagi-memory-service-node2
    ports:
      - "8000:8000"
    environment:
      # Підключення до NODA1 Qdrant
      - QDRANT_HOST=144.76.224.179
      - QDRANT_PORT=6333
      
      # Підключення до NODA1 PostgreSQL (read replica)
      - DATABASE_URL=postgresql://daarion_reader:***@144.76.224.179:5432/daarion_memory
      
      # Підключення до NODA1 Neo4j (read replica)
      - NEO4J_URI=bolt://144.76.224.179:7687
      
      - READ_ONLY_MODE=true
      - COHERE_API_KEY=${COHERE_API_KEY}
```

---

### Варіант C: Гібридний (РЕКОМЕНДОВАНО) ⭐

**Переваги:**
- ✅ Локальна пам'ять для dev/test
- ✅ Можливість підключитись до NODA1 за потреби
- ✅ Гнучкість
- ✅ Повна ізоляція для експериментів

**Архітектура:**
```
NODA2 (Development)
├── Local Memory Stack
│   ├── Qdrant (:6333)
│   ├── PostgreSQL (:5433)
│   └── Memory Service (:8000)
│
└── Optional: Remote NODA1 Access
    └── Environment variable switch
```

---

## 🚀 Рекомендація: Почати з Варіанту C

### Крок 1: Створити docker-compose.memory-node2.yml

```bash
cd /Users/apple/github-projects/microdao-daarion
```

Файл: `docker-compose.memory-node2.yml`

### Крок 2: Отримати Cohere API Key

Для embedding моделі потрібен ключ:
1. Зайти на https://cohere.ai
2. Зареєструватись
3. Отримати API Key

### Крок 3: Запустити Memory Stack

```bash
# Додати Cohere API Key в .env
echo "COHERE_API_KEY=your_cohere_key_here" >> .env

# Запустити
docker-compose -f docker-compose.memory-node2.yml up -d

# Перевірити
docker ps | grep -E "memory|qdrant|postgres"
```

### Крок 4: Налаштувати Sofiia для використання пам'яті

В OpenClaw конфігурації додати:

```json
{
  "agents": {
    "list": [
      {
        "id": "sofiia",
        "model": {
          "primary": "xai/grok-4-1-fast-reasoning"
        },
        "memory": {
          "enabled": true,
          "serviceUrl": "http://localhost:8000",
          "collections": {
            "messages": "sofiia_messages",
            "docs": "sofiia_docs",
            "memory": "sofiia_memory_items",
            "context": "sofiia_user_context"
          }
        }
      }
    ]
  }
}
```

---

## 📝 Приклад використання пам'яті Sofiia:

### Збереження повідомлення:
```python
await memory_client.save_memory(
    agent_id="sofiia",
    user_id="telegram:123456",
    channel_id="telegram:sofiia",
    content="User asked about DAARION architecture",
    role="user",
    metadata={
        "topic": "architecture",
        "intent": "question",
        "project": "DAARION"
    }
)
```

### Отримання контексту:
```python
context = await memory_client.get_context(
    agent_id="sofiia",
    user_id="telegram:123456",
    query="архітектура",
    limit=10
)
```

### Збереження факту:
```python
await memory_client.save_fact(
    agent_id="sofiia",
    user_id="telegram:123456",
    fact_key="preferences",
    fact_value_json={
        "language": "uk",
        "style": "technical",
        "projects": ["DAARION", "NODA2"]
    }
)
```

---

## 📊 Статистика пам'яті (для моніторингу):

```sql
-- Кількість фактів для Sofiia
SELECT COUNT(*) FROM user_facts WHERE agent_id = 'sofiia';

-- Останні повідомлення
SELECT * FROM user_facts 
WHERE agent_id = 'sofiia' 
ORDER BY created_at DESC 
LIMIT 10;
```

---

## 🎯 Наступні кроки:

1. ✅ Ознайомитись з архітектурою пам'яті (готово!)
2. ⏳ Отримати Cohere API Key
3. ⏳ Створити docker-compose.memory-node2.yml
4. ⏳ Запустити Memory Stack
5. ⏳ Налаштувати OpenClaw для підключення
6. ⏳ Протестувати збереження та пошук

---

**Який варіант цікавить вас більше? Можу допомогти з реалізацією! 🚀**
