🚀 Matrix Gateway: базова реалізація v1

- Matrix Client (підключення та синхронізація)
- RBAC Checker (перевірка прав через Postgres)
- Job Creator (створення jobs з команд)
- NATS Publisher (публікація jobs у streams)
- K8s deployment
- README з документацією

Команди: !embed, !retrieve, !summarize

TODO: Реальна інтеграція з Matrix homeserver, статуси результатів
This commit is contained in:
Apple
2026-01-10 10:40:18 -08:00
parent a001636c11
commit a0c3c0cbb5
10 changed files with 714 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
"""
NATS Publisher — публікація jobs у NATS JetStream
"""
from typing import Optional, Dict, Any
from nats.aio.client import Client as NATS
from nats.js import JetStreamContext
class NATSPublisher:
def __init__(self, nats_url: str):
self.nats_url = nats_url
self.nc: Optional[NATS] = None
self.js: Optional[JetStreamContext] = None
async def connect(self):
"""Підключення до NATS"""
try:
self.nc = NATS()
await self.nc.connect(self.nats_url)
self.js = self.nc.jetstream()
print(f"✅ Підключено до NATS: {self.nats_url}")
except Exception as e:
print(f"❌ Помилка підключення до NATS: {e}")
raise
async def disconnect(self):
"""Відключення від NATS"""
if self.nc:
await self.nc.close()
print("✅ Відключено від NATS")
async def publish_job(self, job: Dict[str, Any]):
"""Публікація job у NATS stream"""
if not self.js:
raise RuntimeError("NATS не підключено")
job_type = job.get("type", "unknown")
priority = job.get("priority", "offline")
# Визначення subject залежно від типу та пріоритету
if priority == "online":
if job_type == "embed":
subject = "mm.embed.online"
elif job_type == "retrieve":
subject = "mm.retrieve.online"
elif job_type == "summarize":
subject = "mm.summarize.online"
else:
subject = f"mm.{job_type}.online"
else:
if job_type == "embed":
subject = "mm.embed.offline"
elif job_type == "index":
subject = "mm.index.offline"
elif job_type == "backfill":
subject = "mm.backfill.offline"
else:
subject = f"mm.{job_type}.offline"
# Публікація
import json
job_json = json.dumps(job).encode()
ack = await self.js.publish(subject, job_json)
print(f"📤 Job опубліковано: {subject} (seq: {ack.seq})")
return ack