Spaces:
Running
Running
File size: 14,275 Bytes
28a08e7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | -- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-- AGENTE AI β Schema Supabase completo
-- Incolla questo file nel SQL Editor: Dashboard β SQL Editor β New query β Run
-- Tutti gli statement sono idempotenti (IF NOT EXISTS / CREATE OR REPLACE).
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-- ββ 0. Estensioni βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
CREATE EXTENSION IF NOT EXISTS vector;
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-- 1. MEMORIA EPISODICA β tabella episodes
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
CREATE TABLE IF NOT EXISTS public.episodes (
id BIGSERIAL PRIMARY KEY,
type TEXT NOT NULL,
task TEXT NOT NULL,
output TEXT,
success INTEGER DEFAULT 1,
ts TEXT NOT NULL,
tags TEXT DEFAULT '[]'
);
CREATE INDEX IF NOT EXISTS idx_episodes_type ON public.episodes (type);
CREATE INDEX IF NOT EXISTS idx_episodes_ts ON public.episodes (ts);
ALTER TABLE public.episodes ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename='episodes' AND policyname='anon full access') THEN
CREATE POLICY "anon full access" ON public.episodes FOR ALL TO anon USING (true) WITH CHECK (true);
END IF;
END $$;
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-- 2. MEMORIA SEMANTICA β tabella semantic_memory + pgvector
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
CREATE TABLE IF NOT EXISTS public.semantic_memory (
id TEXT PRIMARY KEY,
content TEXT NOT NULL,
metadata JSONB DEFAULT '{}'
);
ALTER TABLE public.semantic_memory
ADD COLUMN IF NOT EXISTS embedding vector(384);
ALTER TABLE public.semantic_memory ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename='semantic_memory' AND policyname='anon full access') THEN
CREATE POLICY "anon full access" ON public.semantic_memory FOR ALL TO anon USING (true) WITH CHECK (true);
END IF;
END $$;
CREATE OR REPLACE FUNCTION match_semantic_memory(
query_embedding vector(384),
match_count int DEFAULT 5,
match_threshold float DEFAULT 0.2
)
RETURNS TABLE (id text, content text, metadata jsonb, similarity float)
LANGUAGE sql STABLE AS $$
SELECT id, content, metadata,
(1 - (embedding <=> query_embedding))::float AS similarity
FROM public.semantic_memory
WHERE embedding IS NOT NULL
AND (1 - (embedding <=> query_embedding)) > match_threshold
ORDER BY embedding <=> query_embedding
LIMIT match_count;
$$;
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-- 3. MEMORIA AGENTE β tabella agent_memory (incident registry + decision memory)
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
CREATE TABLE IF NOT EXISTS public.agent_memory (
key TEXT PRIMARY KEY,
value TEXT NOT NULL DEFAULT '{}',
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
ALTER TABLE public.agent_memory ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename='agent_memory' AND policyname='anon full access') THEN
CREATE POLICY "anon full access" ON public.agent_memory FOR ALL TO anon USING (true) WITH CHECK (true);
END IF;
END $$;
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-- 4. TASK AGENTE β tabelle agent_tasks + agent_task_events
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
CREATE TABLE IF NOT EXISTS public.agent_tasks (
task_id TEXT PRIMARY KEY,
goal TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'QUEUED',
max_steps INTEGER NOT NULL DEFAULT 8,
context TEXT NOT NULL DEFAULT '[]',
created_at BIGINT NOT NULL DEFAULT 0,
updated_at BIGINT NOT NULL DEFAULT 0
);
CREATE TABLE IF NOT EXISTS public.agent_task_events (
id BIGSERIAL PRIMARY KEY,
task_id TEXT NOT NULL REFERENCES public.agent_tasks(task_id) ON DELETE CASCADE,
event_index INTEGER NOT NULL,
event_data TEXT NOT NULL,
created_at BIGINT NOT NULL DEFAULT 0,
UNIQUE (task_id, event_index)
);
CREATE INDEX IF NOT EXISTS idx_agent_task_events_lookup
ON public.agent_task_events (task_id, event_index ASC);
ALTER TABLE public.agent_tasks ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.agent_task_events ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename='agent_tasks' AND policyname='anon full access') THEN
CREATE POLICY "anon full access" ON public.agent_tasks FOR ALL TO anon USING (true) WITH CHECK (true);
CREATE POLICY "anon full access" ON public.agent_task_events FOR ALL TO anon USING (true) WITH CHECK (true);
END IF;
END $$;
CREATE OR REPLACE FUNCTION purge_old_agent_tasks() RETURNS void
LANGUAGE plpgsql AS $$
DECLARE cutoff BIGINT := (EXTRACT(EPOCH FROM NOW()) * 1000 - 7 * 86400000)::BIGINT;
BEGIN DELETE FROM public.agent_tasks WHERE updated_at < cutoff; END;
$$;
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-- 5. SKILL TRACKER β tabelle skill_stats + skill_patterns
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
CREATE OR REPLACE FUNCTION _touch_updated_at()
RETURNS TRIGGER LANGUAGE plpgsql AS $$
BEGIN NEW.updated_at = now(); RETURN NEW; END;
$$;
CREATE TABLE IF NOT EXISTS public.skill_stats (
session_id TEXT NOT NULL,
tool_name TEXT NOT NULL,
success_count INTEGER NOT NULL DEFAULT 0,
fail_count INTEGER NOT NULL DEFAULT 0,
last_used DOUBLE PRECISION NOT NULL DEFAULT 0,
total_latency_ms DOUBLE PRECISION NOT NULL DEFAULT 0,
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (session_id, tool_name)
);
CREATE INDEX IF NOT EXISTS idx_skill_stats_session ON public.skill_stats (session_id);
ALTER TABLE public.skill_stats ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename='skill_stats' AND policyname='anon full access') THEN
CREATE POLICY "anon full access" ON public.skill_stats FOR ALL TO anon USING (true) WITH CHECK (true);
END IF;
END $$;
DROP TRIGGER IF EXISTS trg_skill_stats_updated_at ON public.skill_stats;
CREATE TRIGGER trg_skill_stats_updated_at BEFORE UPDATE ON public.skill_stats
FOR EACH ROW EXECUTE FUNCTION _touch_updated_at();
CREATE TABLE IF NOT EXISTS public.skill_patterns (
id TEXT PRIMARY KEY,
task_signature TEXT NOT NULL,
tool_sequence TEXT[] NOT NULL,
success_count INTEGER NOT NULL DEFAULT 0,
total_count INTEGER NOT NULL DEFAULT 0,
last_used BIGINT NOT NULL DEFAULT 0,
confidence DOUBLE PRECISION NOT NULL DEFAULT 0,
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_skill_patterns_confidence ON public.skill_patterns (confidence DESC);
CREATE INDEX IF NOT EXISTS idx_skill_patterns_last_used ON public.skill_patterns (last_used DESC);
ALTER TABLE public.skill_patterns ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename='skill_patterns' AND policyname='anon full access') THEN
CREATE POLICY "anon full access" ON public.skill_patterns FOR ALL TO anon USING (true) WITH CHECK (true);
END IF;
END $$;
DROP TRIGGER IF EXISTS trg_skill_patterns_updated_at ON public.skill_patterns;
CREATE TRIGGER trg_skill_patterns_updated_at BEFORE UPDATE ON public.skill_patterns
FOR EACH ROW EXECUTE FUNCTION _touch_updated_at();
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-- 6. FILE SYSTEM VIRTUALE β tabella vfs_files
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
CREATE TABLE IF NOT EXISTS public.vfs_files (
id TEXT PRIMARY KEY,
path TEXT NOT NULL,
content TEXT NOT NULL DEFAULT '',
mime_type TEXT NOT NULL DEFAULT 'text/plain',
size BIGINT NOT NULL DEFAULT 0,
created_at BIGINT NOT NULL DEFAULT 0,
updated_at BIGINT NOT NULL DEFAULT 0
);
ALTER TABLE public.vfs_files ADD COLUMN IF NOT EXISTS version BIGINT NOT NULL DEFAULT 0;
CREATE INDEX IF NOT EXISTS idx_vfs_files_path ON public.vfs_files (path);
CREATE INDEX IF NOT EXISTS vfs_files_version_idx ON public.vfs_files (id, version);
ALTER TABLE public.vfs_files ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename='vfs_files' AND policyname='anon full access') THEN
CREATE POLICY "anon full access" ON public.vfs_files FOR ALL TO anon USING (true) WITH CHECK (true);
END IF;
END $$;
CREATE OR REPLACE FUNCTION public._vfs_bump_version()
RETURNS TRIGGER LANGUAGE plpgsql AS $$
BEGIN NEW.version = OLD.version + 1; RETURN NEW; END;
$$;
DROP TRIGGER IF EXISTS trg_vfs_version ON public.vfs_files;
CREATE TRIGGER trg_vfs_version BEFORE UPDATE ON public.vfs_files
FOR EACH ROW EXECUTE FUNCTION public._vfs_bump_version();
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-- 7. TOKEN OAUTH β tabelle managed_tokens + oauth_states
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
CREATE TABLE IF NOT EXISTS public.managed_tokens (
user_id TEXT NOT NULL DEFAULT 'default',
provider TEXT NOT NULL,
access_token TEXT NOT NULL DEFAULT '',
refresh_token TEXT NOT NULL DEFAULT '',
expires_at BIGINT NOT NULL DEFAULT 0,
scope TEXT NOT NULL DEFAULT '',
raw_meta TEXT NOT NULL DEFAULT '{}',
created_at BIGINT NOT NULL DEFAULT 0,
updated_at BIGINT NOT NULL DEFAULT 0,
UNIQUE (user_id, provider)
);
CREATE INDEX IF NOT EXISTS managed_tokens_user_idx ON public.managed_tokens (user_id, provider);
ALTER TABLE public.managed_tokens ENABLE ROW LEVEL SECURITY;
DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE tablename='managed_tokens' AND policyname='service only') THEN
CREATE POLICY "service only" ON public.managed_tokens FOR ALL TO service_role USING (true) WITH CHECK (true);
END IF;
END $$;
CREATE TABLE IF NOT EXISTS public.oauth_states (
state TEXT PRIMARY KEY,
provider TEXT NOT NULL,
user_id TEXT NOT NULL DEFAULT 'default',
created_at BIGINT NOT NULL DEFAULT 0
);
CREATE OR REPLACE FUNCTION public._purge_oauth_states() RETURNS void
LANGUAGE plpgsql AS $$
BEGIN
DELETE FROM public.oauth_states
WHERE created_at < (EXTRACT(EPOCH FROM NOW()) * 1000 - 600000)::BIGINT;
END;
$$;
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-- FINE β Verifica eseguendo:
-- SELECT table_name FROM information_schema.tables
-- WHERE table_schema = 'public' ORDER BY table_name;
-- ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|