feat: Add presence heartbeat for Matrix online status

- matrix-gateway: POST /internal/matrix/presence/online endpoint
- usePresenceHeartbeat hook with activity tracking
- Auto away after 5 min inactivity
- Offline on page close/visibility change
- Integrated in MatrixChatRoom component
This commit is contained in:
Apple
2025-11-27 00:19:40 -08:00
parent 5bed515852
commit 3de3c8cb36
6371 changed files with 1317450 additions and 932 deletions

View File

@@ -0,0 +1,443 @@
# AGENTS SERVICE SPEC (PORT 7002)
# Version: 1.0.0
---
## 0. PURPOSE
`Agents Service` — це центральний сервіс текстових агентів DAGI:
- надає API для виклику Helion, Helix, Metamorph та інших текстових агентів;
- інтегрується з DAGI Router / ProjectBus / Mesh Directory;
- застосовує:
- Agent Registry,
- Context Router,
- Silence Policy,
- Throttling,
- TeamDefinition/ProjectBus контекст.
Це логічний "Runtime осередок" для текстової частини DAGI.
Порт за замовчуванням (NODE1/NODE2): **7002**.
---
## 1. HIGH-LEVEL ARCHITECTURE
```text
[ Gateway (Telegram/Web/Matrix/...) ]
[ DAGI Router (gateway.daarion.city) ]
[ Agents Service (7002) ]
[ LLM Providers / Swapper / DAGI Mesh ]
```
Agents Service отримує **RouterEvent-like** запити від DAGI Router (або внутрішніх сервісів) та:
1. Визначає, які агенти доступні (через AgentRegistry + Mesh Directory + TeamDefinition).
2. Обирає найвідповіднішого/декількох (Context Router).
3. Перевіряє Silence Policy.
4. Застосовує throttling.
5. Викликає відповідний LLM / backend агента.
6. Повертає відповідь + metadata.
---
## 2. DEPENDENCIES
### 2.1. Внутрішні модулі
Agents Service використовує:
* `configs/AGENT_REGISTRY.yaml`
* `configs/AGENT_REGISTRY_SCHEMA.yaml`
* `services/agent_registry_loader.py`
* `services/agent_context_router.py`
* `services/agent_silence_policy.py`
* `services/agent_throttle.py`
* `services/agent_mesh_directory.py`
* `configs/team_definition.yaml`
* `configs/project_bus_config.yaml`
### 2.2. Зовнішні сервіси
* **LLM Provider / Swapper Service** (NODE1/NODE2)
* **NATS** (або інший event-bus) для:
* ProjectBus,
* Mesh Directory,
* M2M-комунікації між агентами.
* **PostgreSQL / Redis** (опційно) для:
* кешу відповідей,
* logging / traces.
---
## 3. CONFIGURATION
ENV-змінні:
```env
AGENTS_SERVICE_PORT=7002
AGENT_REGISTRY_PATH=configs/AGENT_REGISTRY.yaml
AGENT_REGISTRY_SCHEMA_PATH=configs/AGENT_REGISTRY_SCHEMA.yaml
TEAM_DEFINITION_PATH=configs/team_definition.yaml
PROJECT_BUS_CONFIG_PATH=configs/project_bus_config.yaml
MESH_DIRECTORY_MODE=inprocess # "inprocess" | "nats" | "http"
MESH_DIRECTORY_NATS_SUBJECT_BASE=agent.directory
LLM_PROVIDER_BASE_URL=http://localhost:8890 # або інший super-service/swapper
AGENT_THROTTLE_LIMIT_PER_MINUTE=3
AGENT_THROTTLE_WINDOW_SECONDS=60
```
---
## 4. PUBLIC API (HTTP)
### 4.1. `POST /agents/invoke`
Основний endpoint для DAGI Router та внутрішніх сервісів.
**Request:**
```json
{
"event": {
"event_id": "tg:123",
"source": "telegram",
"chat": { "id": "123", "type": "group" },
"user": { "id": "user1", "username": "alex" },
"team_id": "team-daariandao-core",
"project_id": "proj-daariandao",
"text": "helix, перевір api",
"attachments": {
"images": [],
"docs": [],
"audio": [],
"geo": [],
"tables": []
},
"flags": {
"command": null,
"reply_to": null,
"confidential_mode": "public"
}
},
"options": {
"force_agent_id": null, // якщо заповнено, обійти context router
"allow_panel_mode": true, // дозволити кільком агентам відповісти
"max_agents": 2 // верхня межа для panel-режиму
}
}
```
**Response (успішний сценарій):**
```json
{
"status": "ok",
"replies": [
{
"agent_id": "ag_helix",
"text": "Ось аналіз API ...",
"meta": {
"model": "HELIX_ENGINEER_MODEL",
"tokens_in": 123,
"tokens_out": 256,
"latency_ms": 900
}
}
],
"context": {
"project_id": "proj-daariandao",
"team_id": "team-daariandao-core",
"reply_mode": "panel"
}
}
```
**Response (ніхто не має відповідати):**
```json
{
"status": "silent",
"reason": "no_agent_or_policy",
"context": {
"project_id": "proj-daariandao",
"team_id": "team-daariandao-core"
}
}
```
**Response (throttling):**
```json
{
"status": "throttled",
"reason": "rate_limit",
"agent_id": "ag_helion"
}
```
---
### 4.2. `GET /agents/registry`
Повертає список агентів (тільки для адміністраторів / системних агентів):
**Response:**
```json
{
"agents": [
{
"agent_id": "ag_helion",
"name": "Helion",
"role": "assistant",
"priority": 5,
"model": "HELION_TEXT_MODEL",
"skills": ["допоможи", "поясни"],
"modalities": ["text"],
"description": "Головний асистент DAARION."
}
]
}
```
---
### 4.3. `GET /agents/instances`
Проксі до Mesh Directory (видно інстанси):
```json
{
"instances": [
{
"agent_id": "ag_helion",
"instance_id": "ag_helion@noda1-01",
"node_id": "NODA1",
"status": "online",
"project_ids": ["proj-daariandao"],
"microdao_id": "microdao-root",
"last_seen": 1732450200.123
}
]
}
```
---
## 5. INTERNAL LOGIC
### 5.1. Pipeline для `/agents/invoke`
Покроковий алгоритм:
1. **Parse event**
* прийняти `event` (RouterEvent-сумісний payload),
* витягнути `project_id`, `team_id`, `chat.id`.
2. **Load TeamDefinition**
* знайти команду по `team_id` (або по `project_id` → команди, які працюють у цьому проекті),
* зчитати `reply_mode`:
* `single` / `panel` / `silent`,
* `max_agents_per_message`.
3. **Load AgentRegistry & MeshDirectory**
* завантажити список агентів із registry,
* для кожного, хто в TeamDefinition:
* перевірити, чи є онлайн інстанси (Mesh Directory).
4. **Context Router**
* побудувати `AgentDescriptor` для кожного доступного агента (з skills, priority),
* викликати `select_best_agent(event, descriptors)`:
* для `single`: обрати 1,
* для `panel`: обрати до `max_agents_per_message`,
* для `silent`: можна одразу повернути `status: silent`.
5. **Silence Policy** (per-agent)
Для кожного кандидата:
* `should_agent_reply(agent_id, event)`:
* прямі згадки,
* команди,
* приватні чати,
* контекстна релевантність.
Якщо жоден не проходить → `status: silent`.
6. **Throttling** (per-agent, per-chat)
Для кожного, хто пройшов silence policy:
* `throttle.can_reply(agent_id, chat_id)`:
* якщо ні → позначити `throttled`,
* якщо хоча б один агент може відповідати → продовжуємо.
7. **Invoke agents (LLM Provider)**
Для кожного дозволеного агента:
* сформувати system prompt (на основі `AGENT_REGISTRY`, ролі, skills),
* сформувати user/context prompt (із події),
* відправити в LLM Provider / Swapper Service:
* `POST /llm/invoke` (або NATS subject `llm.invoke`).
8. **Aggregate response**
* зібрати `replies` (до N агентів),
* зібрати `meta` (latency, tokens),
* повернути у DAGI Router HTTP-відповідь.
---
## 6. INTEGRATION WITH DAGI ROUTER
### 6.1. З боку DAGI Router
При текстовій гілці (без мультимодальності):
```python
# dagi_router.py (схематично)
resp = http.post("http://agents-service:7002/agents/invoke", json={
"event": router_event_dict,
"options": {
"force_agent_id": None,
"allow_panel_mode": True,
"max_agents": 2
}
})
```
Router далі:
* бере `resp["replies"]`,
* конвертує в повідомлення для Gateway (Telegram/Web/Matrix),
* застосовує свої policy (наприклад, фільтрацію ненормативу, якщо треба).
---
## 7. NATS / PROJECT BUS INTEGRATION
Agents Service також:
1. Слухає ProjectBus:
* `project.<project_id>.chat.mixed` (через DAGI Router),
* `project.<project_id>.tasks` (можна робити автоматичну обробку задач).
2. Може публікувати події:
* `project.<project_id>.agents` (наприклад, "Helix взяв task t123"),
* `project.<project_id>.m2m.*` (M2M/R2D2 комунікація).
Це дозволяє:
* агентам працювати в командах,
* не тільки як chatbot, а як учасники mesh-процесів.
---
## 8. HEALTHCHECK & METRICS
### 8.1. Healthcheck
`GET /healthz`:
```json
{
"status": "ok",
"registry_loaded": true,
"mesh_directory_mode": "inprocess",
"uptime_seconds": 12345
}
```
### 8.2. Prometheus метрики
* `agents_invocations_total{agent_id, project_id, status}`
* `agents_throttled_total{agent_id}`
* `agents_silent_decisions_total{reason}`
* `agents_llm_latency_ms_bucket{agent_id, le=...}`
---
## 9. LOGGING
Кожен виклик `/agents/invoke` логувати:
* `event_id`, `source`, `chat.id`, `project_id`, `team_id`,
* кандидатів агентів + scores (debug-level),
* остаточно обраних агентів,
* статус: `ok` / `silent` / `throttled` / `error`,
* latency LLM.
Формат: JSON-лог для подальшого аналізу (ELK / Loki / Grafana).
---
## 10. TEST PLAN (SHORT)
Unit-тести (pytest):
1. `test_single_agent_selection()`
* один агент у команді, простий текст, немає throttling → відповідає.
2. `test_panel_mode_two_agents()`
* `reply_mode: panel`, `max_agents_per_message: 2`,
* питання, релевантне Helix і Guardian → відповідають двоє.
3. `test_silence_policy_mentions()`
* повідомлення без згадок і без ключових слів → `status: silent`.
4. `test_throttling_per_agent()`
* 4 виклики поспіль у межах 60 сек,
* `limit_per_minute=3`,
* 4-й → `status: throttled`.
5. `test_team_definition_loading()`
* агрегація команд з `team_definition.yaml`,
* мапінг на project_id.
---
## 11. SUMMARY
Agents Service (7002) — це:
* офіційний текстовий runtime DAGI,
* точка входу для Helion/Helix/Metamorph та інших текстових агентів,
* шар, який:
* "бачить" всю конфігурацію агентів (Registry),
* "бачить" живі інстанси (Mesh Directory),
* враховує TeamDefinition/ProjectBus,
* контролює поведінку агентів у чатах (silence/panel/throttle).
Після реалізації цього сервісу DAGI Router зможе:
* делегувати всю текстову логіку в єдиний, стандартизований компонент,
* який легко масштабувати між НОДА1/НОДА2 і далі.

View File

@@ -0,0 +1,382 @@
# CITY SERVICE SPEC (PORT 7001)
# Version: 1.0.0
---
## 0. PURPOSE
`City Service` — геопросторовий та соціальний шар DAARION.city.
Цей сервіс забезпечує:
1. **Living Map** — стан міста в реальному часі:
- райони,
- локації,
- структури microDAO,
- активні агенти та користувачі.
2. **Presence System** — відстеження присутності:
- хто знаходиться в якому районі/секторі/каналі,
- статуси присутності користувачів і агентів.
3. **Geo Intelligence**:
- обробка геолокаційних даних,
- інтеграція з Geo-agent (мультимодальність),
- аналіз шляхів, зон та кластерів.
4. **Project / MicroDAO Mapping**:
- кожен microDAO має свій "віртуальний район",
- кожен проєкт — "будівлю/кластер".
5. **Integration with TeamDefinition & ProjectBus**:
- локації = канали / контексти,
- routing для комунікації між агентами у межах "районів".
Порт сервісу: **7001**.
---
## 1. FUNCTIONAL OVERVIEW
```text
[ Gateway / Web UI / Living Map UI ]
[ DAGI Router ] — (text/multimodal events)
[ City Service (7001) ]
[ PostgreSQL + NATS + Geo-agent ]
```
City Service синхронізує:
* *місто як карту* (Region/Area/Point),
* *місто як соціальну мережу* (Presence),
* *місто як структуру проектів і microDAO*.
---
## 2. CORE DATA STRUCTURES
### 2.1. Region (Регіон)
Віртуальний район DAARION.city:
```json
{
"region_id": "district-greenfood",
"name": "GREENFOOD District",
"type": "microdao", // microdao | project | custom
"microdao_id": "microdao-greenfood",
"geometry": { "type": "Polygon", "coordinates": [...] },
"meta": { "color": "#2ecc71" }
}
```
### 2.2. Area / Building / Sector
Локальні локації всередині регіонів:
```json
{
"area_id": "area-greenfood-core",
"region_id": "district-greenfood",
"name": "Core Operations",
"geometry": { "type": "Polygon", "coordinates": [...] },
"project_id": "proj-greenfood",
"meta": {}
}
```
### 2.3. Presence
Хто перебуває де:
```json
{
"subject_id": "ag_helix",
"subject_type": "agent",
"region_id": "district-greenfood",
"area_id": "area-greenfood-core",
"status": "active", // active|idle|offline
"updated_at": "2025-11-24T10:00:00Z"
}
```
### 2.4. Location Update Event
```json
{
"subject_id": "user123",
"subject_type": "user",
"geo": { "lat": 52.52, "lon": 13.40 },
"region_id": "district-greenfood",
"area_id": "area-greenfood-core"
}
```
---
## 3. DATABASE SCHEMA (PostgreSQL + PostGIS)
City Service повинен мати PostGIS.
### 3.1. regions
```sql
CREATE TABLE regions (
region_id TEXT PRIMARY KEY,
name TEXT NOT NULL,
type TEXT NOT NULL,
microdao_id TEXT,
geometry GEOMETRY(POLYGON, 4326),
meta JSONB DEFAULT '{}'::jsonb
);
```
### 3.2. areas
```sql
CREATE TABLE areas (
area_id TEXT PRIMARY KEY,
region_id TEXT REFERENCES regions(region_id),
name TEXT NOT NULL,
project_id TEXT,
geometry GEOMETRY(POLYGON, 4326),
meta JSONB DEFAULT '{}'::jsonb
);
```
### 3.3. presence
```sql
CREATE TABLE presence (
subject_id TEXT NOT NULL,
subject_type TEXT NOT NULL,
region_id TEXT NOT NULL,
area_id TEXT,
status TEXT NOT NULL,
updated_at TIMESTAMP NOT NULL DEFAULT now(),
PRIMARY KEY (subject_id, subject_type)
);
```
---
## 4. PUBLIC HTTP API (CITY SERVICE)
### 4.1. `GET /regions`
Список усіх регіонів міста.
### 4.2. `POST /regions`
Створити новий регіон (переважно для microDAO).
### 4.3. `GET /areas?region_id=...`
Список локацій у межах регіону.
### 4.4. `POST /presence/update`
Оновити присутність учасника/агента.
**Request:**
```json
{
"subject_id": "ag_helion",
"subject_type": "agent",
"geo": { "lat": 50.45, "lon": 30.52 }
}
```
Відповідь після визначення регіону/зони:
```json
{
"status": "ok",
"region_id": "district-daariandao",
"area_id": "area-governance"
}
```
### 4.5. `GET /presence?region_id=...`
Повертає, хто зараз у районі.
---
## 5. GEO-AGENT INTEGRATION
Geo-agent (мультимодальність) використовується для:
1. **Інтерпретація геоданих**:
* визначити район по координатам,
* визначити найближчу зону,
* кластеризація.
2. **Запити від користувача**:
* "Покажи активність агентів у районі GREENFOOD"
* "Яким шляхом рухається агент X?"
* "Які агенти у проекті Y зараз активні?"
3. **Генерація інсайтів**:
* heat maps,
* аномалії присутності,
* навігація робочих потоків.
City Service викликає Geo-agent через:
```
POST /multimodal/geo/infer
```
або NATS subject:
```
dagi.geo.infer
```
Payload:
```json
{
"lat": 50.45,
"lon": 30.52,
"regions": [...],
"areas": [...]
}
```
---
## 6. PROJECT BUS INTEGRATION
City Service взаємодіє з ProjectBus:
* коли створюється новий microDAO → створюється новий регіон;
* коли створюється новий проект → нова area/cluster;
* агенти/користувачі приєднуються до проектів → presence оновлюється.
Оновлення:
* `project.<id>.events` — події щодо присутності,
* `project.<id>.map.events` — події для UI living map.
Приклад події:
```json
{
"type": "presence_updated",
"project_id": "proj-greenfood",
"subject_id": "ag_helix",
"region_id": "district-greenfood",
"area_id": "area-greenfood-core",
"ts": "2025-11-24T10:10:00Z"
}
```
---
## 7. DAGI ROUTER INTEGRATION
City Service інформує DAGI Router про:
* зміни регіону/зони:
* агенти отримують контекст `region_id` / `area_id`,
* Router може маршрутизувати події за локацією,
* routing за region-каналами (геочати),
* особливі правила поведінки в певних регіонах (через TeamDefinition).
Router додає в кожен RouterEvent:
```json
{
"context": {
"region_id": "...",
"area_id": "...",
"project_id": "...",
"microdao_id": "..."
}
}
```
---
## 8. MULTINODE SUPPORT
City Service може бути:
* один на всі ноди (centralized),
* або розгорнутий на кожній НОДА:
* локальна кешована карта,
* синхронізація через NATS.
Оптимально:
```
NODE1 = primary city-service
NODE2/NODE3 = read replicas cache + local geo-routing
```
---
## 9. HEALTHCHECK & METRICS
### 9.1. `GET /healthz`
```json
{
"status": "ok",
"db": "ok",
"geo_agent": "ok",
"uptime_seconds": 21344
}
```
### 9.2. Prometheus metrics
* `presence_updates_total`
* `active_subjects{region_id}`
* `geo_queries_total`
* `geo_inference_latency_ms_bucket`
* `area_popularity{region_id, area_id}`
---
## 10. LIVING MAP UI (FUTURE)
City Service підтримує:
* API для реального часу (WebSocket/NATS),
* 2D-UI та 3D-UI клієнти:
* Three.js / Babylon.js / Unity WebGL.
Плани:
* місто як **візуальна карта** проектів,
* агентські маршрути,
* стан об'єктів, сервісів та microDAO,
* heatmap активності.
---
## 11. SUMMARY
City Service (7001):
* геопросторовий та "соціальний" шар DAARION,
* формує логіку районів microDAO та проектних зон,
* управляє присутністю користувачів і агентів,
* інтегрується з DAGI Router, Geo-agent, ProjectBus, MicroDAO Service,
* основа для 2D/3D карт та мультимодальних геоаналітик.
Це ключовий сервіс, який робить DAARION.city "живим містом", а не просто набором мікросервісів.

View File

@@ -0,0 +1,560 @@
# MICRODAO SERVICE SPEC (PORT 7004)
# Version: 1.0.0
---
## 0. PURPOSE
`MicroDAO Service` — це базовий сервіс DAO-логіки для DAARION.city:
- створення та управління microDAO (райони, команди, проєкти),
- членство, ролі та entitlements (RBAC),
- пропозиції (proposals) та голосування (voting),
- інтеграція з ProjectBus, TeamDefinition та Agents Service,
- точка правди про те, хто що може в межах кожного microDAO.
**Фокус цієї версії (MVP):**
- Off-chain governance (Postgres + NATS),
- без обов'язкового підключення до on-chain токенів (місце закладене, але може бути пустим).
Порт за замовчуванням: **7004**.
---
## 1. CORE CONCEPTS
### 1.1. MicroDAO
Легка DAO-одиниця в екосистемі DAARION:
- має `microdao_id` (наприклад, `microdao-root`, `microdao-greenfood`),
- опис, місію, набір учасників,
- пов'язане з одним або кількома `project_id`,
- має власні:
- ролі,
- entitlements (доступи, дозволи),
- voting-параметри.
### 1.2. Membership
Учасники microDAO:
- `user_id` (людина),
- `agent_id` (агент),
- `role_id` (роль у DAO),
- статус: `active`, `pending`, `banned`, `left`.
### 1.3. Roles & Entitlements
Ролі визначають, що можна робити в межах microDAO:
- `role_id`: `"owner"`, `"admin"`, `"member"`, `"observer"`, `"agent-core"`, ...
- кожна роль має набір `entitlements`:
- `can_create_proposals`,
- `can_vote`,
- `can_manage_members`,
- `can_manage_projects`,
- `can_manage_teams`,
- `can_manage_tokens` (закладка під on-chain).
### 1.4. Proposals & Voting
Пропозиції:
- створюються учасниками (люди/агенти) згідно entitlements,
- приклади:
- додати нового агента в команду,
- змінити пріоритети сервісів,
- створити новий проект,
- змінити політику доступу,
- мають статуси:
- `draft`, `open`, `accepted`, `rejected`, `expired`.
Голосування:
- голоси від учасників microDAO,
- правила підрахунку/кворуму задаються у параметрах DAO.
---
## 2. HIGH-LEVEL ARCHITECTURE
```text
[ Users / Agents / UI ]
[ Gateway (Telegram/Web/Matrix/Front) ]
[ DAGI Router ]
[ MicroDAO Service (7004) ]
[ Postgres (microdao_db) + NATS (events) + Agents Service ]
```
MicroDAO Service:
* тримає модель DAO в Postgres,
* публікує події в NATS:
* `microdao.<id>.events`,
* взаємодіє з:
* Agents Service (щоб агенти розуміли, що їм дозволено),
* ProjectBus (для створення/оновлення проектних каналів),
* Mesh Directory (через параметри доступу для агентів).
---
## 3. DATA MODEL (MVP-Рівень)
### 3.1. microdao
```sql
CREATE TABLE microdao (
microdao_id TEXT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
status TEXT NOT NULL DEFAULT 'active', -- active|archived|pending
created_at TIMESTAMP NOT NULL DEFAULT now(),
created_by TEXT NOT NULL, -- user_id/agent_id
meta JSONB DEFAULT '{}'::jsonb
);
```
### 3.2. microdao_project
```sql
CREATE TABLE microdao_project (
microdao_id TEXT NOT NULL REFERENCES microdao(microdao_id),
project_id TEXT NOT NULL,
PRIMARY KEY (microdao_id, project_id)
);
```
### 3.3. microdao_role
```sql
CREATE TABLE microdao_role (
role_id TEXT PRIMARY KEY,
microdao_id TEXT NOT NULL REFERENCES microdao(microdao_id),
name TEXT NOT NULL,
description TEXT,
entitlements JSONB NOT NULL, -- { "can_create_proposals": true, ... }
meta JSONB DEFAULT '{}'::jsonb
);
```
### 3.4. microdao_member
```sql
CREATE TABLE microdao_member (
microdao_id TEXT NOT NULL REFERENCES microdao(microdao_id),
subject_id TEXT NOT NULL, -- user_id or agent_id
subject_type TEXT NOT NULL, -- 'user' | 'agent'
role_id TEXT NOT NULL REFERENCES microdao_role(role_id),
status TEXT NOT NULL DEFAULT 'active', -- active|pending|banned|left
joined_at TIMESTAMP NOT NULL DEFAULT now(),
PRIMARY KEY (microdao_id, subject_id, subject_type)
);
```
### 3.5. microdao_proposal
```sql
CREATE TABLE microdao_proposal (
proposal_id TEXT PRIMARY KEY,
microdao_id TEXT NOT NULL REFERENCES microdao(microdao_id),
title TEXT NOT NULL,
description TEXT,
creator_id TEXT NOT NULL,
creator_type TEXT NOT NULL, -- 'user' | 'agent'
status TEXT NOT NULL DEFAULT 'open', -- draft|open|accepted|rejected|expired
created_at TIMESTAMP NOT NULL DEFAULT now(),
opens_at TIMESTAMP,
closes_at TIMESTAMP,
params JSONB DEFAULT '{}'::jsonb -- voting rules overrides, payload
);
```
### 3.6. microdao_vote
```sql
CREATE TABLE microdao_vote (
proposal_id TEXT NOT NULL REFERENCES microdao_proposal(proposal_id),
voter_id TEXT NOT NULL,
voter_type TEXT NOT NULL, -- 'user' | 'agent'
choice TEXT NOT NULL, -- 'yes'|'no'|'abstain'|custom
weight NUMERIC NOT NULL DEFAULT 1,
voted_at TIMESTAMP NOT NULL DEFAULT now(),
PRIMARY KEY (proposal_id, voter_id, voter_type)
);
```
---
## 4. CONFIGURATION
ENV:
```env
MICRODAO_SERVICE_PORT=7004
MICRODAO_DB_DSN=postgres://...
MICRODAO_NATS_URL=nats://...
PROJECT_BUS_CONFIG_PATH=configs/project_bus_config.yaml
TEAM_DEFINITION_PATH=configs/team_definition.yaml
AGENT_REGISTRY_PATH=configs/AGENT_REGISTRY.yaml
```
---
## 5. PUBLIC HTTP API
### 5.1. `POST /microdaos`
Створити новий microDAO.
**Request:**
```json
{
"microdao_id": "microdao-greenfood",
"name": "GREENFOOD DAO",
"description": "Управління екосистемою GREENFOOD AI-ERP",
"created_by": "user:owner1"
}
```
**Response:**
```json
{
"status": "ok",
"microdao": {
"microdao_id": "microdao-greenfood",
"name": "GREENFOOD DAO",
"description": "...",
"status": "active"
}
}
```
---
### 5.2. `GET /microdaos`
Список microDAO.
`GET /microdaos?status=active`
---
### 5.3. `GET /microdaos/{microdao_id}`
Деталі одного microDAO (включно з ролями/параметрами).
---
### 5.4. `POST /microdaos/{microdao_id}/members`
Додати учасника (людину/агента).
**Request:**
```json
{
"subject_id": "ag_helion",
"subject_type": "agent",
"role_id": "agent-core"
}
```
**Response:**
```json
{
"status": "ok",
"member": {
"microdao_id": "microdao-greenfood",
"subject_id": "ag_helion",
"subject_type": "agent",
"role_id": "agent-core",
"status": "active"
}
}
```
---
### 5.5. `GET /microdaos/{microdao_id}/members`
Список учасників.
---
### 5.6. `POST /microdaos/{microdao_id}/proposals`
Створити пропозицію.
**Request:**
```json
{
"title": "Додати нового агента до команди GREENFOOD",
"description": "Пропоную додати vision_agent до team-greenfood.",
"creator_id": "user:owner1",
"creator_type": "user",
"params": {
"required_quorum": 0.5,
"required_yes_ratio": 0.6
}
}
```
**Response:**
```json
{
"status": "ok",
"proposal": {
"proposal_id": "prop-123",
"status": "open"
}
}
```
---
### 5.7. `POST /proposals/{proposal_id}/votes`
Голосування.
**Request:**
```json
{
"voter_id": "user:member1",
"voter_type": "user",
"choice": "yes"
}
```
**Response:**
```json
{
"status": "ok",
"vote": {
"proposal_id": "prop-123",
"voter_id": "user:member1",
"choice": "yes",
"weight": 1
}
}
```
---
### 5.8. `GET /microdaos/{microdao_id}/proposals`
Список пропозицій DAO.
---
### 5.9. `GET /proposals/{proposal_id}`
Деталі пропозиції + поточний стан голосування.
---
## 6. EVENT BUS (NATS)
MicroDAO Service публікує події:
* `microdao.{microdao_id}.events`
Приклади payload:
### 6.1. MicroDAO Created
```json
{
"type": "microdao_created",
"microdao_id": "microdao-greenfood",
"name": "GREENFOOD DAO",
"created_by": "user:owner1",
"ts": "2025-11-24T10:00:00Z"
}
```
### 6.2. Member Added
```json
{
"type": "member_added",
"microdao_id": "microdao-greenfood",
"subject_id": "ag_helion",
"subject_type": "agent",
"role_id": "agent-core",
"ts": "2025-11-24T10:01:00Z"
}
```
### 6.3. Proposal Created
```json
{
"type": "proposal_created",
"microdao_id": "microdao-greenfood",
"proposal_id": "prop-123",
"title": "Додати vision_agent до команди GREENFOOD",
"ts": "2025-11-24T10:05:00Z"
}
```
### 6.4. Proposal Finalized
```json
{
"type": "proposal_finalized",
"microdao_id": "microdao-greenfood",
"proposal_id": "prop-123",
"final_status": "accepted",
"result": {
"yes": 10,
"no": 1,
"abstain": 2,
"quorum": 0.7
},
"ts": "2025-11-24T11:00:00Z"
}
```
---
## 7. INTEGRATION WITH OTHER SERVICES
### 7.1. Agents Service (7002)
Agents Service при кожному виклику:
* запитує MicroDAO Service (або кешує його рішення), щоб:
* перевірити, чи має агент право:
* відповідати в конкретному `project_id` / `microdao_id`,
* виконувати певні дії (наприклад, створювати команду, керувати іншими агентами).
Простий варіант: HTTP-запит:
`GET /microdaos/{microdao_id}/members?subject_id=ag_helix&subject_type=agent`
Можливий кеш у Redis.
### 7.2. ProjectBus / TeamDefinition
При створенні microDAO + прив'язці project_id MicroDAO Service може:
* генерувати (або оновлювати) записи в:
* `project_bus_config.yaml`,
* `team_definition.yaml` (або їх runtime-аналогах в БД),
* публікувати події:
* `project.<project_id>.events` про появу нового microDAO/team.
### 7.3. Mesh Directory
MicroDAO Service може:
* впливати на видимість агентів:
* наприклад, якщо агент виключений з microDAO → його інстанси в Directory позначаються з обмеженими правами в цьому проекті.
---
## 8. SECURITY / RBAC
Важливі моменти:
1. Усі операції (створення DAO, додавання членів, створення пропозицій, голосування) повинні проходити через перевірку entitlements:
* `can_create_microdao`
* `can_manage_members`
* `can_create_proposals`
* `can_vote`
2. MicroDAO Service не займається аутентифікацією — він приймає вже ідентифіковані `user_id` / `agent_id` (з gateway або auth-сервісу).
3. Системні агенти ( типу `ag_guardian`, `ag_cryptodetective` ) можуть мати особливі ролі з підвищеними entitlements (наприклад, аудит без права голосу).
---
## 9. HEALTHCHECK & METRICS
### 9.1. `GET /healthz`
```json
{
"status": "ok",
"db": "ok",
"nats": "ok",
"uptime_seconds": 1234
}
```
### 9.2. Prometheus
* `microdao_count{status}`
* `microdao_members_count{microdao_id}`
* `microdao_proposals_count{microdao_id,status}`
* `microdao_votes_total{microdao_id,proposal_id,choice}`
---
## 10. TEST PLAN (SHORT)
Unit/Integration-тести (pytest):
1. `test_create_microdao_and_get()`
* створення DAO, перевірка читання.
2. `test_add_member_and_query()`
* додати члена, перевірити список.
3. `test_create_proposal_and_vote()`
* створити пропозицію, декілька голосів, підбиття результатів.
4. `test_entitlements_block_unauthorized_actions()`
* спроба створення пропозиції користувачем без `can_create_proposals`.
5. `test_events_published_on_actions()`
* перевірити, що при створенні DAO/пропозиції/результату йдуть NATS-івенти.
---
## 11. SUMMARY
MicroDAO Service (7004):
* є "governance ядром" для DAARION.city,
* формально описує:
* хто до якого microDAO належить,
* які ролі/entitlements має,
* як приймаються рішення (proposals/voting),
* тісно інтегрований з:
* Agents Service (поведінка агентів),
* ProjectBus (потоки подій проектів),
* Mesh Directory (видимість/скили/обмеження агентів).
Цей сервіс робить всі твої фрактальні команди та мережу агентів формально керованими через DAO-рівень.

View File

@@ -0,0 +1,392 @@
# SECOND ME SERVICE SPEC (PORT 7003)
# Version: 1.0.0
---
## 0. PURPOSE
`Second Me Service` — це сервіс створення та управління **персональними цифровими двійниками** користувачів та агентів у DAARION.city.
Це ядро системи персоналізації:
- кожен користувач має SecondMe-профіль,
- SecondMe є persistent-пам'яттю,
- SecondMe може діяти як мультиагентний "асистент у тіні",
- SecondMe синхронізується з мультимодальністю (audio → текст, image → профіль),
- SecondMe допомагає іншим агентам (в т.ч. Метаморфу) адаптувати поведінку.
SecondMe працює як:
- storage (пам'ять користувача),
- continuous learning module,
- персональна reasoning-прошивка.
Порт сервісу: **7003**.
---
## 1. HIGH-LEVEL ARCHITECTURE
```text
[ User ]
/ | \
Telegram Web Matrix
\ | /
[ DAGI Router ]
[ Second Me Service (7003) ]
[ Vector DB + Redis + Postgres ]
[ Agents ]
```
SecondMe Service перехоплює:
* історію взаємодії,
* мультимодальний контент (image/audio/doc),
* профіль користувача,
* поведінкові патерни.
---
## 2. CORE RESPONSIBILITIES
### 2.1. Профіль SecondMe
Містить:
* user_id,
* персональні налаштування,
* пам'ять (context store),
* переваги, хобі, стилі,
* NFTs / achievements (майбутнє),
* зв'язки з microDAO.
### 2.2. Персональна пам'ять
SecondMe має 3 типи пам'яті:
1. **Short-term** (до 48 год, швидкий доступ)
2. **Long-term** (векторна пам'ять)
3. **Structured Memory**:
* knowledge cards,
* tasks,
* goals,
* архіви розмов.
### 2.3. Learning Pipeline
SecondMe автоматично:
* аналізує повідомлення та файли,
* перетворює їх у structured facts,
* зберігає у векторну пам'ять,
* оновлює профіль (переваги/мету/поведінку),
* генерує особисті інсайти.
### 2.4. Behavior Assistant
SecondMe допомагає іншим агентам:
* підказувати Helion/Helix, що знає про користувача,
* спрощує пояснення контексту,
* додає пам'ять у DAGI Router подіями типу:
* `user.context_update`,
* `user.preference_update`,
* `user.knowledge_card`.
---
## 3. DATA MODEL (Postgres + Vector DB)
### 3.1. Users
```sql
CREATE TABLE users (
user_id TEXT PRIMARY KEY,
created_at TIMESTAMP NOT NULL DEFAULT now(),
meta JSONB DEFAULT '{}'::jsonb
);
```
### 3.2. SecondMe Profile
```sql
CREATE TABLE secondme_profile (
user_id TEXT PRIMARY KEY,
preferences JSONB DEFAULT '{}'::jsonb,
traits JSONB DEFAULT '{}'::jsonb,
skills JSONB DEFAULT '{}'::jsonb,
settings JSONB DEFAULT '{}'::jsonb,
updated_at TIMESTAMP NOT NULL DEFAULT now()
);
```
### 3.3. Memory — Short Term
```sql
CREATE TABLE secondme_memory_short (
memory_id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
text TEXT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT now()
);
```
### 3.4. Memory — Long Term (Vector DB)
Хоститься в твоєму VectorDB (8898).
Документ:
```json
{
"id": "mem123",
"user_id": "u1",
"text": "користувач любить працювати з GREENFOOD",
"embedding": [...1024 floats...],
"metadata": {
"type": "preference",
"timestamp": "2025-11-24T12:00:00Z"
}
}
```
---
## 4. PUBLIC API (HTTP)
### 4.1. `POST /secondme/update_from_event`
Вхідна точка для DAGI Router.
**Request:**
```json
{
"event": {
"source": "telegram",
"user": { "id": "u1" },
"project_id": "proj-greenfood",
"text": "мені дуже подобається зелена аналітика",
"attachments": { "images": [], "audio": [] }
}
}
```
**Response:**
```json
{
"status": "ok",
"actions": [
"short_memory_added",
"long_memory_indexed",
"profile_trait_updated"
]
}
```
---
### 4.2. `GET /secondme/profile/{user_id}`
Отримати повний профіль користувача.
---
### 4.3. `GET /secondme/memory/{user_id}`
Повертає коротку + довгу пам'ять.
---
### 4.4. `POST /secondme/query`
Пошук у пам'яті:
**Request:**
```json
{
"user_id": "u1",
"query": "що цей користувач любить робити?"
}
```
**Response:**
```json
{
"results": [
{
"text": "користувач любить працювати з GREENFOOD",
"score": 0.92
}
]
}
```
---
### 4.5. `POST /secondme/summarize`
Генерує персональний summary користувача для агентів:
**Response:**
```json
{
"summary": "Користувач працює над GREENFOOD, любить аналітику, часто дає задачі Helix."
}
```
---
## 5. AGENT INTEGRATION
### 5.1. Helion integration
Helion отримує SecondMe-summary для:
* кращих відповідей,
* виконання задач з персональним контекстом.
### 5.2. Helix integration
SecondMe → Helix:
* історія рішень користувача,
* технічні вподобання,
* деталі проектів користувача.
### 5.3. Metamorph integration
SecondMe → Metamorph:
* персоналізація поведінки агентів,
* рекомендації по агентах, які потрібні користувачу.
### 5.4. Geo-agent
Якщо користувач дає гео-події:
* SecondMe зберігає маршрути / активність,
* може допомагати City Service сортувати події.
---
## 6. LEARNING PIPELINE
SecondMe обробляє кожну подію:
1. **Extract facts**
Визначає, чи є текст чи медіа важливим для пам'яті.
2. **Classify type**
* preference
* skill
* long-term fact
* behavioural pattern
* project affinity
3. **Embed**
* створює embedding (через твою bge-m3 модель).
4. **Index**
* зберігає у Vector DB.
5. **Profile Update**
* якщо знайдені нові патерни → оновити SecondMe Profile.
6. **Emit Events**
Публікує в NATS:
* `secondme.{user_id}.memory_added`
* `secondme.{user_id}.profile_updated`
---
## 7. INTERACTION WITH DAGI ROUTER
DAGI Router повинен:
* при кожному `RouterEvent` викликати `POST /secondme/update_from_event`,
* отримувати у відповідь:
* пам'ять-дії,
* профільні зміни.
SecondMe діє як **фонова підсистема**, що збагачує контекст.
---
## 8. PROJECT BUS INTEGRATION
SecondMe може бути підписаним на:
```
project.<project_id>.events
project.<project_id>.chat.human
```
щоб вчитися на:
* командних подіях,
* рішеннях,
* поведінці користувача всередині проекту.
---
## 9. MULTIMODAL SUPPORT
SecondMe працює з мультимодальністю:
* image → Vision-agent → SecondMe ("користувач показує X"),
* audio → STT → SecondMe (зберігає розмови і суть),
* docs → Doc-agent → SecondMe (пам'ятає PDF-документи користувача).
---
## 10. HEALTHCHECK & METRICS
### 10.1. `GET /healthz`
```json
{
"status": "ok",
"db": "ok",
"vector": "ok",
"uptime_seconds": 21344
}
```
### 10.2. Prometheus
* `secondme_events_total`
* `memory_added_total`
* `profile_updates_total`
* `embedding_latency_ms_bucket`
* `vector_search_latency_ms_bucket`
---
## 11. SUMMARY
Second Me Service (7003):
* персональна пам'ять,
* особистісний профіль,
* обробка мультимодальних подій,
* забезпечує глибинну персоналізацію системи,
* розуміє контекст користувача,
* допомагає іншим агентам приймати кращі рішення,
* працює автономно, мовчки, але є ключовим "мозком користувача".