feat: add Memory Service for DAARWIZZ

This commit is contained in:
Apple
2025-11-15 10:09:41 -08:00
parent a54a7b078c
commit 9e99c3afe2
7 changed files with 1355 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
-- Міграція для Memory Service
-- Створює таблиці: user_facts, dialog_summaries, agent_memory_events, agent_memory_facts_vector
-- Розширення для UUID та vector
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "vector";
-- ========== User Facts ==========
CREATE TABLE IF NOT EXISTS user_facts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
team_id TEXT REFERENCES teams(id) ON DELETE CASCADE,
-- Ключ факту (наприклад: "language", "is_donor", "is_validator", "top_contributor")
fact_key TEXT NOT NULL,
-- Значення факту
fact_value TEXT,
fact_value_json JSONB,
-- Метадані
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
-- Токен-гейт
token_gated BOOLEAN NOT NULL DEFAULT false,
token_requirements JSONB,
-- Таймстемпи
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ,
expires_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS idx_user_facts_user_id ON user_facts(user_id);
CREATE INDEX IF NOT EXISTS idx_user_facts_team_id ON user_facts(team_id);
CREATE INDEX IF NOT EXISTS idx_user_facts_user_key ON user_facts(user_id, fact_key);
CREATE INDEX IF NOT EXISTS idx_user_facts_token_gated ON user_facts(token_gated);
CREATE INDEX IF NOT EXISTS idx_user_facts_expires_at ON user_facts(expires_at) WHERE expires_at IS NOT NULL;
-- ========== Dialog Summaries ==========
CREATE TABLE IF NOT EXISTS dialog_summaries (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
-- Контекст діалогу
team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
channel_id TEXT REFERENCES channels(id) ON DELETE CASCADE,
agent_id TEXT REFERENCES agents(id) ON DELETE CASCADE,
user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
-- Період
period_start TIMESTAMPTZ NOT NULL,
period_end TIMESTAMPTZ NOT NULL,
-- Підсумок
summary_text TEXT NOT NULL,
summary_json JSONB,
-- Статистика
message_count INTEGER NOT NULL DEFAULT 0,
participant_count INTEGER NOT NULL DEFAULT 0,
-- Ключові теми
topics JSONB,
-- Метадані
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_team_id ON dialog_summaries(team_id);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_channel_id ON dialog_summaries(channel_id);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_agent_id ON dialog_summaries(agent_id);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_user_id ON dialog_summaries(user_id);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_team_period ON dialog_summaries(team_id, period_start, period_end);
CREATE INDEX IF NOT EXISTS idx_dialog_summaries_created_at ON dialog_summaries(created_at);
-- ========== Agent Memory Events ==========
CREATE TABLE IF NOT EXISTS agent_memory_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
channel_id TEXT REFERENCES channels(id) ON DELETE CASCADE,
user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
-- Scope: short_term, mid_term, long_term
scope TEXT NOT NULL CHECK (scope IN ('short_term', 'mid_term', 'long_term')),
-- Kind: message, fact, summary, note
kind TEXT NOT NULL CHECK (kind IN ('message', 'fact', 'summary', 'note')),
-- Тіло події
body_text TEXT,
body_json JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_agent_id ON agent_memory_events(agent_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_team_id ON agent_memory_events(team_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_channel_id ON agent_memory_events(channel_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_user_id ON agent_memory_events(user_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_agent_team_scope ON agent_memory_events(agent_id, team_id, scope);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_channel ON agent_memory_events(agent_id, channel_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_events_created_at ON agent_memory_events(created_at);
-- ========== Agent Memory Facts Vector (для RAG) ==========
CREATE TABLE IF NOT EXISTS agent_memory_facts_vector (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
fact_text TEXT NOT NULL,
embedding vector(1536), -- OpenAI ada-002 embedding size
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_agent_memory_facts_vector_agent_id ON agent_memory_facts_vector(agent_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_facts_vector_team_id ON agent_memory_facts_vector(team_id);
CREATE INDEX IF NOT EXISTS idx_agent_memory_facts_vector_agent_team ON agent_memory_facts_vector(agent_id, team_id);
-- Індекс для векторного пошуку (використовується pgvector)
-- Примітка: Створіть цей індекс після того, як у вас буде достатньо даних
-- CREATE INDEX IF NOT EXISTS idx_agent_memory_facts_vector_embedding
-- ON agent_memory_facts_vector USING ivfflat (embedding vector_cosine_ops)
-- WITH (lists = 100);