fix: corregir descripciones de servidores TZZR
- Añadir tabla correcta: ARCHITECT=Desarrollo, DECK=Usuario, CORP=Corporativo - Eliminar ejemplos inventados (architect_persona) - Usar ejemplos genéricos (system_rules, dev_config)
This commit is contained in:
18
README.md
18
README.md
@@ -36,13 +36,21 @@ Sistema local de gestión de contexto para IA, agnóstico al modelo.
|
|||||||
└─────────────────────────────────────────────────────────────────┘
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Servidores TZZR
|
||||||
|
|
||||||
|
| Servidor | IP | Propósito |
|
||||||
|
|----------|-----|-----------|
|
||||||
|
| ARCHITECT | 69.62.126.110 | Desarrollo |
|
||||||
|
| DECK | 72.62.1.113 | Usuario |
|
||||||
|
| CORP | 92.112.181.188 | Corporativo |
|
||||||
|
|
||||||
## Estado de Producción
|
## Estado de Producción
|
||||||
|
|
||||||
| Servidor | Estado | BD PostgreSQL | Tablas | Comandos CLI |
|
| Servidor | Estado | BD PostgreSQL | Tablas |
|
||||||
|----------|--------|---------------|--------|--------------|
|
|----------|--------|---------------|--------|
|
||||||
| DECK (72.62.1.113) | ✓ PRODUCCIÓN | Activa | 9 | Disponibles |
|
| ARCHITECT | ✓ Activo | PostgreSQL + pgvector | 9 |
|
||||||
| CORP (92.112.181.188) | ✓ PRODUCCIÓN | Activa | 9 | Disponibles |
|
| DECK | ✓ Activo | PostgreSQL + pgvector | 9 |
|
||||||
| ARCHITECT (69.62.126.110) | ✓ PRODUCCIÓN | Activa | 9 | Disponibles |
|
| CORP | ✓ Activo | PostgreSQL + pgvector | 9 |
|
||||||
|
|
||||||
### Tablas PostgreSQL (9 total)
|
### Tablas PostgreSQL (9 total)
|
||||||
1. `immutable_log` - Log blockchain-style (no editable)
|
1. `immutable_log` - Log blockchain-style (no editable)
|
||||||
|
|||||||
256
docs/CTO.md
256
docs/CTO.md
@@ -1,101 +1,209 @@
|
|||||||
# Context Manager (CTO) - Schema v1.0
|
# CTO Schema v2.0 - Context Manager
|
||||||
|
|
||||||
Sistema de gestión de contexto con embeddings para TZZR.
|
## Resumen
|
||||||
|
|
||||||
|
El schema `cto` gestiona el contexto de los agentes TZZR mediante tres tablas principales:
|
||||||
|
|
||||||
|
| Tabla | Propósito |
|
||||||
|
|-------|-----------|
|
||||||
|
| `cto.blocks` | Bloques de contexto estático (personas, reglas, conocimiento) |
|
||||||
|
| `cto.memory` | Memoria a largo plazo con embeddings |
|
||||||
|
| `cto.algorithms` | Configuración de algoritmos de selección/scoring |
|
||||||
|
|
||||||
## Tablas
|
## Tablas
|
||||||
|
|
||||||
### cto.blocks
|
### cto.blocks (23 columnas)
|
||||||
Almacena bloques de memoria extraídos de conversaciones.
|
|
||||||
|
|
||||||
| Campo | Tipo | Descripción |
|
Almacena bloques de contexto que pueden inyectarse en las conversaciones.
|
||||||
|-------|------|-------------|
|
|
||||||
| hash | CHAR(64) | SHA-256 único del contenido |
|
| Columna | Tipo | Descripción |
|
||||||
| session_hash | CHAR(64) | Sesión donde se extrajo |
|
|---------|------|-------------|
|
||||||
| owner_id | CHAR(64) | Propietario (PLY hash) |
|
| id | BIGSERIAL | PK |
|
||||||
| block_type | TEXT | fact, instruction, preference, context |
|
| hash | CHAR(64) | SHA-256 del contenido (UNIQUE) |
|
||||||
|
| code | VARCHAR(50) | Identificador legible único (ej: `system_rules`, `dev_config`) |
|
||||||
|
| name | VARCHAR(200) | Nombre descriptivo |
|
||||||
|
| session_hash | CHAR(64) | Hash de sesión (si aplica) |
|
||||||
|
| owner_id | CHAR(64) | Propietario del bloque |
|
||||||
|
| block_type | VARCHAR(50) | Tipo legacy |
|
||||||
|
| category | VARCHAR(50) | Categoría: persona, rules, capabilities, instructions, knowledge |
|
||||||
| content | TEXT | Contenido del bloque |
|
| content | TEXT | Contenido del bloque |
|
||||||
| embedding | vector(1536) | Embedding OpenAI |
|
| embedding | vector(1536) | Vector para búsqueda semántica |
|
||||||
| importance | FLOAT | Importancia 0.0-1.0 |
|
| priority | INT | Orden de inclusión (mayor = primero) |
|
||||||
| access_count | INT | Veces accedido |
|
| scope | VARCHAR(20) | Ámbito: global, server, agent, session |
|
||||||
| source_hash | CHAR(64) | Mensaje origen (log.messages) |
|
| server_code | VARCHAR(20) | Si scope=server: ARCHITECT, DECK, CORP |
|
||||||
| metadata | JSONB | Datos adicionales |
|
| agent_code | VARCHAR(50) | Si scope=agent: código del agente |
|
||||||
|
| token_count | INT | Tokens estimados |
|
||||||
|
| status | VARCHAR(20) | active, inactive, deprecated |
|
||||||
|
| created_at | TIMESTAMPTZ | Fecha creación |
|
||||||
|
| updated_at | TIMESTAMPTZ | Última modificación |
|
||||||
|
|
||||||
### cto.memory
|
**Scopes:**
|
||||||
Memoria activa por sesión - qué bloques están en contexto.
|
- `global`: Aplica a todos los agentes en todos los servidores
|
||||||
|
- `server`: Aplica solo a agentes en un servidor específico
|
||||||
|
- `agent`: Aplica solo a un agente específico
|
||||||
|
- `session`: Aplica solo a una sesión
|
||||||
|
|
||||||
| Campo | Tipo | Descripción |
|
### cto.memory (26 columnas)
|
||||||
|-------|------|-------------|
|
|
||||||
| session_hash | CHAR(64) | Sesión actual |
|
Memoria a largo plazo con scoring basado en importancia, recencia y relevancia semántica.
|
||||||
|
|
||||||
|
| Columna | Tipo | Descripción |
|
||||||
|
|---------|------|-------------|
|
||||||
|
| id | BIGSERIAL | PK |
|
||||||
|
| hash | CHAR(64) | SHA-256 único |
|
||||||
|
| session_hash | CHAR(64) | Sesión origen |
|
||||||
|
| block_hash | CHAR(64) | FK a blocks |
|
||||||
| owner_id | CHAR(64) | Propietario |
|
| owner_id | CHAR(64) | Propietario |
|
||||||
| block_hash | CHAR(64) | Referencia a cto.blocks |
|
| type | VARCHAR(20) | preference, decision, fact, entity, temporal |
|
||||||
| position | INT | Orden en contexto |
|
| content | TEXT | Contenido de la memoria |
|
||||||
| score | FLOAT | Puntuación de relevancia |
|
| summary | VARCHAR(500) | Resumen corto |
|
||||||
| token_count | INT | Tokens consumidos |
|
| importance | FLOAT | 0-1 (mayor = más importante) |
|
||||||
| included | BOOLEAN | En contexto actual |
|
| confidence | FLOAT | 0-1 (certeza) |
|
||||||
|
| embedding | vector(1536) | Vector para similitud |
|
||||||
|
| embedding_model | VARCHAR(50) | Modelo usado |
|
||||||
|
| access_count_v2 | INT | Veces accedida |
|
||||||
|
| last_access | TIMESTAMPTZ | Último acceso |
|
||||||
|
| source_hash | CHAR(64) | Memoria origen (si derivada) |
|
||||||
|
| expires_at | TIMESTAMPTZ | Expiración (para temporales) |
|
||||||
|
| status | VARCHAR(20) | active, superseded, expired, deleted |
|
||||||
|
| superseded_by | BIGINT | ID de memoria que la reemplaza |
|
||||||
|
| related_to | BIGINT[] | IDs de memorias relacionadas |
|
||||||
|
| metadata | JSONB | Metadatos adicionales |
|
||||||
|
| owner_type | VARCHAR(20) | user, agent, system |
|
||||||
|
| created_at | TIMESTAMPTZ | Fecha creación |
|
||||||
|
| updated_at | TIMESTAMPTZ | Última modificación |
|
||||||
|
|
||||||
### cto.algorithms
|
**Tipos de memoria:**
|
||||||
Configuración de algoritmos como JSONB.
|
| Tipo | Decay Rate | Descripción |
|
||||||
|
|------|------------|-------------|
|
||||||
|
| preference | 0.01 | Preferencias del usuario (decae muy lento) |
|
||||||
|
| decision | 0.05 | Decisiones tomadas |
|
||||||
|
| fact | 0.10 | Hechos aprendidos |
|
||||||
|
| entity | 0.05 | Entidades mencionadas |
|
||||||
|
| temporal | 0.50 | Info temporal (decae rápido) |
|
||||||
|
|
||||||
| Campo | Tipo | Descripción |
|
### cto.algorithms (14 columnas)
|
||||||
|-------|------|-------------|
|
|
||||||
| name | TEXT | Nombre único |
|
|
||||||
| version | TEXT | Versión |
|
|
||||||
| config | JSONB | Configuración |
|
|
||||||
| enabled | BOOLEAN | Activo |
|
|
||||||
|
|
||||||
## Algoritmos por defecto
|
Configuración de algoritmos de scoring, selección y extracción.
|
||||||
|
|
||||||
|
| Columna | Tipo | Descripción |
|
||||||
|
|---------|------|-------------|
|
||||||
|
| id | SERIAL | PK |
|
||||||
|
| code | VARCHAR(50) | Código único |
|
||||||
|
| name | VARCHAR(100) | Nombre |
|
||||||
|
| version | VARCHAR(20) | Versión |
|
||||||
|
| config | JSONB | Configuración completa |
|
||||||
|
| enabled | BOOLEAN | Legacy |
|
||||||
|
| status | VARCHAR(20) | draft, active, experiment, deprecated |
|
||||||
|
| parent_id | INT | FK a algoritmo padre (versionado) |
|
||||||
|
| metrics | JSONB | Métricas de rendimiento |
|
||||||
|
| activated_at | TIMESTAMPTZ | Fecha activación |
|
||||||
|
| deprecated_at | TIMESTAMPTZ | Fecha deprecación |
|
||||||
|
| created_at | TIMESTAMPTZ | Fecha creación |
|
||||||
|
| updated_at | TIMESTAMPTZ | Última modificación |
|
||||||
|
|
||||||
|
## Configuración del Algoritmo v2
|
||||||
|
|
||||||
### extractor
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"min_content_length": 10,
|
|
||||||
"max_block_size": 500,
|
|
||||||
"extraction_mode": "heuristic",
|
|
||||||
"patterns": ["fact", "instruction", "preference", "context"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### scorer
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"extraction": {
|
||||||
|
"enabled": true,
|
||||||
|
"async": true,
|
||||||
|
"batch_size": 10
|
||||||
|
},
|
||||||
|
"scoring": {
|
||||||
"weights": {
|
"weights": {
|
||||||
"recency": 0.3,
|
"recency": 0.20,
|
||||||
"frequency": 0.2,
|
"importance": 0.40,
|
||||||
"importance": 0.3,
|
"relevance": 0.30,
|
||||||
"similarity": 0.2
|
"frequency": 0.10
|
||||||
},
|
},
|
||||||
"decay_factor": 0.95
|
"decay_rates": {
|
||||||
|
"preference": 0.01,
|
||||||
|
"decision": 0.05,
|
||||||
|
"fact": 0.10,
|
||||||
|
"entity": 0.05,
|
||||||
|
"temporal": 0.50
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"selection": {
|
||||||
|
"strategy": "priority",
|
||||||
|
"token_budget": 8000,
|
||||||
|
"priority_order": ["system", "core", "working", "retrieved"]
|
||||||
|
},
|
||||||
|
"compression": {
|
||||||
|
"strategy": "progressive",
|
||||||
|
"keep_first": 3,
|
||||||
|
"keep_last": 10
|
||||||
|
},
|
||||||
|
"embedding": {
|
||||||
|
"provider": "openai",
|
||||||
|
"model": "text-embedding-3-small",
|
||||||
|
"dimension": 1536
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### selector
|
## Funciones
|
||||||
```json
|
|
||||||
{
|
### cto.calculate_memory_score(memory_id, query_embedding, current_time)
|
||||||
"budget_tokens": 8000,
|
|
||||||
"min_score": 0.1,
|
Calcula score combinado de una memoria:
|
||||||
"max_blocks": 50,
|
|
||||||
"strategy": "greedy"
|
```
|
||||||
}
|
score = 0.20 * recency + 0.40 * importance + 0.30 * relevance + 0.10 * frequency
|
||||||
```
|
```
|
||||||
|
|
||||||
### consolidator
|
Donde:
|
||||||
```json
|
- **recency**: Decae exponencialmente según tipo y tiempo desde último acceso
|
||||||
{
|
- **importance**: Valor 0-1 asignado al crear la memoria
|
||||||
"similarity_threshold": 0.85,
|
- **relevance**: Similitud coseno con query_embedding
|
||||||
"merge_strategy": "newest",
|
- **frequency**: Basado en access_count (normalizado 0-1)
|
||||||
"compression_ratio": 0.7
|
|
||||||
}
|
### cto.search_memories(query_embedding, owner_id, limit, min_similarity)
|
||||||
|
|
||||||
|
Busca memorias por similitud semántica:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT * FROM cto.search_memories(
|
||||||
|
'[0.1, 0.2, ...]'::vector(1536), -- embedding de la query
|
||||||
|
'owner_hash', -- propietario
|
||||||
|
20, -- límite
|
||||||
|
0.3 -- similitud mínima
|
||||||
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Despliegue
|
### cto.get_active_blocks(scope, server_code, agent_code)
|
||||||
|
|
||||||
Schema aplicado en:
|
Obtiene bloques activos filtrados por scope:
|
||||||
- ARCHITECT (69.62.126.110)
|
|
||||||
- DECK (72.62.1.113)
|
|
||||||
- CORP (92.112.181.188)
|
|
||||||
|
|
||||||
## Dependencias
|
```sql
|
||||||
|
-- Bloques globales
|
||||||
|
SELECT * FROM cto.get_active_blocks('global');
|
||||||
|
|
||||||
- PostgreSQL 14+
|
-- Bloques para un servidor específico
|
||||||
- pgvector extension
|
SELECT * FROM cto.get_active_blocks('server', 'DECK');
|
||||||
- OpenAI API (embeddings)
|
|
||||||
|
-- Bloques para un agente específico
|
||||||
|
SELECT * FROM cto.get_active_blocks('agent', NULL, 'mi_agente');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Servidores TZZR
|
||||||
|
|
||||||
|
| Servidor | IP | Propósito |
|
||||||
|
|----------|-----|-----------|
|
||||||
|
| ARCHITECT | 69.62.126.110 | Desarrollo |
|
||||||
|
| DECK | 72.62.1.113 | Usuario |
|
||||||
|
| CORP | 92.112.181.188 | Corporativo |
|
||||||
|
|
||||||
|
Schema CTO v2.0 desplegado en los 3 servidores.
|
||||||
|
|
||||||
|
## Verificar instalación
|
||||||
|
|
||||||
|
```sql
|
||||||
|
\d cto.blocks
|
||||||
|
\d cto.memory
|
||||||
|
\d cto.algorithms
|
||||||
|
SELECT code, version, status FROM cto.algorithms;
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,127 +1,305 @@
|
|||||||
-- =============================================================================
|
-- ============================================================================
|
||||||
-- Context Manager Schema (CTO) v1.0
|
-- SCHEMA CTO v2.0 - Context Manager Tables
|
||||||
-- Sistema de gestión de contexto con embeddings
|
-- ============================================================================
|
||||||
-- Requiere: pgvector extension
|
-- Servidor: ARCHITECT/DECK/CORP
|
||||||
-- =============================================================================
|
-- Dependencias: pgvector extension
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
CREATE EXTENSION IF NOT EXISTS vector;
|
|
||||||
CREATE SCHEMA IF NOT EXISTS cto;
|
CREATE SCHEMA IF NOT EXISTS cto;
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- Asegurar extensión vector
|
||||||
-- cto.blocks: Bloques de memoria con embeddings
|
CREATE EXTENSION IF NOT EXISTS vector;
|
||||||
-- -----------------------------------------------------------------------------
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- cto.blocks - Bloques de contexto estático
|
||||||
|
-- ============================================================================
|
||||||
CREATE TABLE IF NOT EXISTS cto.blocks (
|
CREATE TABLE IF NOT EXISTS cto.blocks (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
hash CHAR(64) UNIQUE NOT NULL, -- SHA-256 del contenido
|
hash CHAR(64) NOT NULL UNIQUE,
|
||||||
session_hash CHAR(64) NOT NULL, -- Sesión origen
|
code VARCHAR(50) UNIQUE,
|
||||||
owner_id CHAR(64) NOT NULL, -- Propietario (PLY hash)
|
name VARCHAR(200),
|
||||||
block_type TEXT NOT NULL DEFAULT 'fact', -- fact|instruction|preference|context
|
session_hash CHAR(64),
|
||||||
content TEXT NOT NULL, -- Contenido del bloque
|
owner_id CHAR(64),
|
||||||
embedding vector(1536), -- OpenAI text-embedding-3-small
|
block_type VARCHAR(50),
|
||||||
importance FLOAT DEFAULT 0.5, -- 0.0-1.0
|
category VARCHAR(50),
|
||||||
access_count INT DEFAULT 0, -- Frecuencia de acceso
|
content TEXT NOT NULL,
|
||||||
last_accessed TIMESTAMPTZ, -- Último acceso
|
embedding vector(1536),
|
||||||
source_hash CHAR(64), -- Mensaje origen (log.messages.hash)
|
priority INT DEFAULT 0,
|
||||||
metadata JSONB DEFAULT '{}', -- Metadatos adicionales
|
scope VARCHAR(20) DEFAULT 'global',
|
||||||
|
server_code VARCHAR(20),
|
||||||
|
agent_code VARCHAR(50),
|
||||||
|
token_count INT,
|
||||||
|
status VARCHAR(20) DEFAULT 'active',
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Índices para blocks
|
-- Índices
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_blocks_hash ON cto.blocks(hash);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_blocks_code ON cto.blocks(code);
|
||||||
CREATE INDEX IF NOT EXISTS idx_blocks_session ON cto.blocks(session_hash);
|
CREATE INDEX IF NOT EXISTS idx_blocks_session ON cto.blocks(session_hash);
|
||||||
CREATE INDEX IF NOT EXISTS idx_blocks_owner ON cto.blocks(owner_id);
|
CREATE INDEX IF NOT EXISTS idx_blocks_owner ON cto.blocks(owner_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_blocks_type ON cto.blocks(block_type);
|
CREATE INDEX IF NOT EXISTS idx_blocks_type ON cto.blocks(block_type);
|
||||||
CREATE INDEX IF NOT EXISTS idx_blocks_importance ON cto.blocks(importance DESC);
|
CREATE INDEX IF NOT EXISTS idx_blocks_category ON cto.blocks(category);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_blocks_scope ON cto.blocks(scope);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_blocks_status ON cto.blocks(status) WHERE status = 'active';
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_blocks_server ON cto.blocks(server_code) WHERE server_code IS NOT NULL;
|
||||||
CREATE INDEX IF NOT EXISTS idx_blocks_embedding ON cto.blocks USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
|
CREATE INDEX IF NOT EXISTS idx_blocks_embedding ON cto.blocks USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- Comentarios
|
||||||
-- cto.memory: Memoria activa por sesión
|
COMMENT ON TABLE cto.blocks IS 'Bloques de contexto estático (personas, reglas, conocimiento)';
|
||||||
-- -----------------------------------------------------------------------------
|
COMMENT ON COLUMN cto.blocks.code IS 'Identificador único legible (ej: system_rules, dev_config)';
|
||||||
|
COMMENT ON COLUMN cto.blocks.scope IS 'Ámbito: global, server, agent, session';
|
||||||
|
COMMENT ON COLUMN cto.blocks.priority IS 'Orden de inclusión (mayor = primero)';
|
||||||
|
COMMENT ON COLUMN cto.blocks.status IS 'Estado: active, inactive, deprecated';
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- cto.memory - Memoria a largo plazo
|
||||||
|
-- ============================================================================
|
||||||
CREATE TABLE IF NOT EXISTS cto.memory (
|
CREATE TABLE IF NOT EXISTS cto.memory (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
session_hash CHAR(64) NOT NULL, -- Sesión actual
|
hash CHAR(64) UNIQUE,
|
||||||
owner_id CHAR(64) NOT NULL, -- Propietario
|
session_hash CHAR(64),
|
||||||
block_hash CHAR(64) NOT NULL REFERENCES cto.blocks(hash),
|
block_hash CHAR(64),
|
||||||
position INT NOT NULL, -- Orden en contexto
|
owner_id CHAR(64),
|
||||||
score FLOAT DEFAULT 0.0, -- Puntuación de relevancia
|
type VARCHAR(20),
|
||||||
token_count INT DEFAULT 0, -- Tokens consumidos
|
content TEXT,
|
||||||
included BOOLEAN DEFAULT true, -- Incluido en contexto actual
|
summary VARCHAR(500),
|
||||||
|
importance FLOAT DEFAULT 0.5,
|
||||||
|
confidence FLOAT DEFAULT 0.8,
|
||||||
|
embedding vector(1536),
|
||||||
|
embedding_model VARCHAR(50) DEFAULT 'text-embedding-3-small',
|
||||||
|
access_count INT DEFAULT 0,
|
||||||
|
access_count_v2 INT DEFAULT 0,
|
||||||
|
last_access TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
source_hash CHAR(64),
|
||||||
|
expires_at TIMESTAMPTZ,
|
||||||
|
status VARCHAR(20) DEFAULT 'active',
|
||||||
|
superseded_by BIGINT,
|
||||||
|
related_to BIGINT[],
|
||||||
|
metadata JSONB DEFAULT '{}',
|
||||||
|
owner_type VARCHAR(20) DEFAULT 'user',
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
UNIQUE(session_hash, block_hash)
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
FOREIGN KEY (block_hash) REFERENCES cto.blocks(hash)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Índices para memory
|
-- Índices
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_memory_hash ON cto.memory(hash) WHERE hash IS NOT NULL;
|
||||||
CREATE INDEX IF NOT EXISTS idx_memory_session ON cto.memory(session_hash);
|
CREATE INDEX IF NOT EXISTS idx_memory_session ON cto.memory(session_hash);
|
||||||
CREATE INDEX IF NOT EXISTS idx_memory_position ON cto.memory(session_hash, position);
|
CREATE INDEX IF NOT EXISTS idx_memory_block ON cto.memory(block_hash);
|
||||||
CREATE INDEX IF NOT EXISTS idx_memory_score ON cto.memory(score DESC);
|
CREATE INDEX IF NOT EXISTS idx_memory_owner ON cto.memory(owner_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_memory_type ON cto.memory(type) WHERE type IS NOT NULL;
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_memory_status ON cto.memory(status) WHERE status = 'active';
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_memory_expires ON cto.memory(expires_at) WHERE expires_at IS NOT NULL;
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_memory_source ON cto.memory(source_hash) WHERE source_hash IS NOT NULL;
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_memory_embedding ON cto.memory USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- Comentarios
|
||||||
-- cto.algorithms: Configuración de algoritmos
|
COMMENT ON TABLE cto.memory IS 'Memoria a largo plazo con embeddings para búsqueda semántica';
|
||||||
-- -----------------------------------------------------------------------------
|
COMMENT ON COLUMN cto.memory.type IS 'Tipo: preference, decision, fact, entity, temporal';
|
||||||
|
COMMENT ON COLUMN cto.memory.importance IS 'Importancia 0-1 (mayor = más relevante)';
|
||||||
|
COMMENT ON COLUMN cto.memory.status IS 'Estado: active, superseded, expired, deleted';
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- cto.algorithms - Configuración de algoritmos
|
||||||
|
-- ============================================================================
|
||||||
CREATE TABLE IF NOT EXISTS cto.algorithms (
|
CREATE TABLE IF NOT EXISTS cto.algorithms (
|
||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
name TEXT UNIQUE NOT NULL,
|
code VARCHAR(50) UNIQUE,
|
||||||
version TEXT NOT NULL DEFAULT '1.0',
|
name VARCHAR(100) NOT NULL,
|
||||||
description TEXT,
|
version VARCHAR(20) DEFAULT '1.0',
|
||||||
config JSONB NOT NULL DEFAULT '{}',
|
config JSONB NOT NULL DEFAULT '{}',
|
||||||
enabled BOOLEAN DEFAULT true,
|
enabled BOOLEAN DEFAULT true,
|
||||||
|
status VARCHAR(20) DEFAULT 'active',
|
||||||
|
parent_id INT REFERENCES cto.algorithms(id),
|
||||||
|
metrics JSONB DEFAULT '{}',
|
||||||
|
activated_at TIMESTAMPTZ,
|
||||||
|
deprecated_at TIMESTAMPTZ,
|
||||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
);
|
);
|
||||||
|
|
||||||
-- -----------------------------------------------------------------------------
|
-- Índices
|
||||||
-- Función y triggers para updated_at
|
CREATE INDEX IF NOT EXISTS idx_algorithms_code ON cto.algorithms(code);
|
||||||
-- -----------------------------------------------------------------------------
|
CREATE INDEX IF NOT EXISTS idx_algorithms_status ON cto.algorithms(status);
|
||||||
CREATE OR REPLACE FUNCTION cto.update_timestamp()
|
CREATE INDEX IF NOT EXISTS idx_algorithms_parent ON cto.algorithms(parent_id) WHERE parent_id IS NOT NULL;
|
||||||
RETURNS TRIGGER AS $$
|
|
||||||
|
-- Comentarios
|
||||||
|
COMMENT ON TABLE cto.algorithms IS 'Configuración de algoritmos de contexto';
|
||||||
|
COMMENT ON COLUMN cto.algorithms.code IS 'Código único (ej: default_v1, experiment_a)';
|
||||||
|
COMMENT ON COLUMN cto.algorithms.status IS 'Estado: draft, active, experiment, deprecated';
|
||||||
|
COMMENT ON COLUMN cto.algorithms.parent_id IS 'Algoritmo padre (para versionado/forks)';
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Algoritmo por defecto v2
|
||||||
|
-- ============================================================================
|
||||||
|
INSERT INTO cto.algorithms (code, name, version, config, status, activated_at)
|
||||||
|
VALUES (
|
||||||
|
'default_v2',
|
||||||
|
'TZZR Context Manager v2',
|
||||||
|
'2.0.0',
|
||||||
|
'{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"name": "TZZR Context Manager v2",
|
||||||
|
"extraction": {
|
||||||
|
"enabled": true,
|
||||||
|
"async": true,
|
||||||
|
"batch_size": 10,
|
||||||
|
"filter": {
|
||||||
|
"min_length": 20,
|
||||||
|
"skip_patterns": ["ok", "gracias", "entendido"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"consolidation": {
|
||||||
|
"strategy": "heuristic_first",
|
||||||
|
"duplicate_threshold": 0.95,
|
||||||
|
"conflict_threshold": 0.85
|
||||||
|
},
|
||||||
|
"scoring": {
|
||||||
|
"strategy": "linear",
|
||||||
|
"weights": {
|
||||||
|
"recency": 0.20,
|
||||||
|
"importance": 0.40,
|
||||||
|
"relevance": 0.30,
|
||||||
|
"frequency": 0.10
|
||||||
|
},
|
||||||
|
"decay_rates": {
|
||||||
|
"preference": 0.01,
|
||||||
|
"decision": 0.05,
|
||||||
|
"fact": 0.10,
|
||||||
|
"entity": 0.05,
|
||||||
|
"temporal": 0.50
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"selection": {
|
||||||
|
"strategy": "priority",
|
||||||
|
"token_budget": 8000,
|
||||||
|
"priority_order": ["system", "core", "working", "retrieved"]
|
||||||
|
},
|
||||||
|
"compression": {
|
||||||
|
"strategy": "progressive",
|
||||||
|
"keep_first": 3,
|
||||||
|
"keep_last": 10
|
||||||
|
},
|
||||||
|
"embedding": {
|
||||||
|
"provider": "openai",
|
||||||
|
"model": "text-embedding-3-small",
|
||||||
|
"dimension": 1536
|
||||||
|
}
|
||||||
|
}'::JSONB,
|
||||||
|
'active',
|
||||||
|
NOW()
|
||||||
|
) ON CONFLICT (code) DO NOTHING;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- Funciones auxiliares
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- Calcular score de memoria
|
||||||
|
CREATE OR REPLACE FUNCTION cto.calculate_memory_score(
|
||||||
|
p_memory_id BIGINT,
|
||||||
|
p_query_embedding vector(1536) DEFAULT NULL,
|
||||||
|
p_current_time TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
) RETURNS FLOAT AS $$
|
||||||
|
DECLARE
|
||||||
|
v_memory RECORD;
|
||||||
|
v_recency FLOAT;
|
||||||
|
v_relevance FLOAT;
|
||||||
|
v_frequency FLOAT;
|
||||||
|
v_hours_elapsed FLOAT;
|
||||||
|
v_decay_rate FLOAT;
|
||||||
|
v_strength FLOAT;
|
||||||
BEGIN
|
BEGIN
|
||||||
NEW.updated_at = NOW();
|
SELECT * INTO v_memory FROM cto.memory WHERE id = p_memory_id;
|
||||||
RETURN NEW;
|
IF NOT FOUND THEN RETURN 0; END IF;
|
||||||
|
|
||||||
|
v_hours_elapsed := EXTRACT(EPOCH FROM (p_current_time - COALESCE(v_memory.last_access, v_memory.created_at))) / 3600;
|
||||||
|
v_decay_rate := CASE v_memory.type
|
||||||
|
WHEN 'preference' THEN 0.01
|
||||||
|
WHEN 'decision' THEN 0.05
|
||||||
|
WHEN 'fact' THEN 0.10
|
||||||
|
WHEN 'entity' THEN 0.05
|
||||||
|
WHEN 'temporal' THEN 0.50
|
||||||
|
ELSE 0.10
|
||||||
|
END;
|
||||||
|
v_strength := 1 + LN(1 + COALESCE(v_memory.access_count_v2, 0));
|
||||||
|
v_recency := EXP(-v_decay_rate * v_hours_elapsed / v_strength);
|
||||||
|
|
||||||
|
IF v_memory.embedding IS NOT NULL AND p_query_embedding IS NOT NULL THEN
|
||||||
|
v_relevance := 1 - (v_memory.embedding <=> p_query_embedding);
|
||||||
|
ELSE
|
||||||
|
v_relevance := 0.5;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
v_frequency := LEAST(COALESCE(v_memory.access_count_v2, 0) / 10.0, 1.0);
|
||||||
|
|
||||||
|
RETURN 0.20 * v_recency + 0.40 * COALESCE(v_memory.importance, 0.5) + 0.30 * v_relevance + 0.10 * v_frequency;
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql STABLE;
|
||||||
|
|
||||||
DROP TRIGGER IF EXISTS blocks_updated ON cto.blocks;
|
-- Buscar memorias por similitud semántica
|
||||||
DROP TRIGGER IF EXISTS algorithms_updated ON cto.algorithms;
|
CREATE OR REPLACE FUNCTION cto.search_memories(
|
||||||
|
p_query_embedding vector(1536),
|
||||||
|
p_owner_id CHAR(64),
|
||||||
|
p_limit INT DEFAULT 20,
|
||||||
|
p_min_similarity FLOAT DEFAULT 0.3
|
||||||
|
) RETURNS TABLE (
|
||||||
|
id BIGINT,
|
||||||
|
content TEXT,
|
||||||
|
type VARCHAR(20),
|
||||||
|
importance FLOAT,
|
||||||
|
similarity FLOAT,
|
||||||
|
score FLOAT
|
||||||
|
) AS $$
|
||||||
|
BEGIN
|
||||||
|
RETURN QUERY
|
||||||
|
SELECT
|
||||||
|
m.id,
|
||||||
|
m.content,
|
||||||
|
m.type,
|
||||||
|
m.importance::FLOAT,
|
||||||
|
(1 - (m.embedding <=> p_query_embedding))::FLOAT as similarity,
|
||||||
|
cto.calculate_memory_score(m.id, p_query_embedding, NOW()) as score
|
||||||
|
FROM cto.memory m
|
||||||
|
WHERE m.owner_id = p_owner_id
|
||||||
|
AND m.status = 'active'
|
||||||
|
AND m.embedding IS NOT NULL
|
||||||
|
AND (1 - (m.embedding <=> p_query_embedding)) > p_min_similarity
|
||||||
|
ORDER BY score DESC
|
||||||
|
LIMIT p_limit;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql STABLE;
|
||||||
|
|
||||||
CREATE TRIGGER blocks_updated
|
-- Obtener bloques activos por scope
|
||||||
BEFORE UPDATE ON cto.blocks
|
CREATE OR REPLACE FUNCTION cto.get_active_blocks(
|
||||||
FOR EACH ROW EXECUTE FUNCTION cto.update_timestamp();
|
p_scope VARCHAR(20) DEFAULT 'global',
|
||||||
|
p_server_code VARCHAR(20) DEFAULT NULL,
|
||||||
CREATE TRIGGER algorithms_updated
|
p_agent_code VARCHAR(50) DEFAULT NULL
|
||||||
BEFORE UPDATE ON cto.algorithms
|
) RETURNS TABLE (
|
||||||
FOR EACH ROW EXECUTE FUNCTION cto.update_timestamp();
|
code VARCHAR(50),
|
||||||
|
name VARCHAR(200),
|
||||||
-- -----------------------------------------------------------------------------
|
content TEXT,
|
||||||
-- Algoritmos por defecto
|
category VARCHAR(50),
|
||||||
-- -----------------------------------------------------------------------------
|
priority INT,
|
||||||
INSERT INTO cto.algorithms (name, version, description, config) VALUES
|
token_count INT
|
||||||
('extractor', '1.0', 'Extrae bloques de memoria de mensajes', '{
|
) AS $$
|
||||||
"min_content_length": 10,
|
BEGIN
|
||||||
"max_block_size": 500,
|
RETURN QUERY
|
||||||
"extraction_mode": "heuristic",
|
SELECT
|
||||||
"patterns": ["fact", "instruction", "preference", "context"]
|
b.code,
|
||||||
}'::jsonb),
|
b.name,
|
||||||
('scorer', '1.0', 'Calcula relevancia de bloques', '{
|
b.content,
|
||||||
"weights": {
|
b.category,
|
||||||
"recency": 0.3,
|
b.priority,
|
||||||
"frequency": 0.2,
|
b.token_count
|
||||||
"importance": 0.3,
|
FROM cto.blocks b
|
||||||
"similarity": 0.2
|
WHERE b.status = 'active'
|
||||||
},
|
AND (
|
||||||
"decay_factor": 0.95
|
b.scope = 'global'
|
||||||
}'::jsonb),
|
OR (b.scope = 'server' AND b.server_code = p_server_code)
|
||||||
('selector', '1.0', 'Selecciona bloques para contexto', '{
|
OR (b.scope = 'agent' AND b.agent_code = p_agent_code)
|
||||||
"budget_tokens": 8000,
|
)
|
||||||
"min_score": 0.1,
|
ORDER BY b.priority DESC NULLS LAST, b.created_at ASC;
|
||||||
"max_blocks": 50,
|
END;
|
||||||
"strategy": "greedy"
|
$$ LANGUAGE plpgsql STABLE;
|
||||||
}'::jsonb),
|
|
||||||
('consolidator', '1.0', 'Consolida y comprime bloques', '{
|
|
||||||
"similarity_threshold": 0.85,
|
|
||||||
"merge_strategy": "newest",
|
|
||||||
"compression_ratio": 0.7
|
|
||||||
}'::jsonb)
|
|
||||||
ON CONFLICT (name) DO UPDATE SET
|
|
||||||
config = EXCLUDED.config,
|
|
||||||
version = EXCLUDED.version,
|
|
||||||
updated_at = NOW();
|
|
||||||
|
|||||||
Reference in New Issue
Block a user