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:
ARCHITECT
2026-01-01 16:16:35 +00:00
parent 76c04c7255
commit 05d21976ca
3 changed files with 467 additions and 173 deletions

View File

@@ -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)

View File

@@ -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 ```json
{ {
"min_content_length": 10, "version": "2.0.0",
"max_block_size": 500, "extraction": {
"extraction_mode": "heuristic", "enabled": true,
"patterns": ["fact", "instruction", "preference", "context"] "async": true,
} "batch_size": 10
```
### scorer
```json
{
"weights": {
"recency": 0.3,
"frequency": 0.2,
"importance": 0.3,
"similarity": 0.2
}, },
"decay_factor": 0.95 "scoring": {
"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
}
} }
``` ```
### 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;
```

View File

@@ -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 $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS blocks_updated ON cto.blocks; -- Comentarios
DROP TRIGGER IF EXISTS algorithms_updated ON cto.algorithms; 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)';
CREATE TRIGGER blocks_updated -- ============================================================================
BEFORE UPDATE ON cto.blocks -- Algoritmo por defecto v2
FOR EACH ROW EXECUTE FUNCTION cto.update_timestamp(); -- ============================================================================
INSERT INTO cto.algorithms (code, name, version, config, status, activated_at)
CREATE TRIGGER algorithms_updated VALUES (
BEFORE UPDATE ON cto.algorithms 'default_v2',
FOR EACH ROW EXECUTE FUNCTION cto.update_timestamp(); 'TZZR Context Manager v2',
'2.0.0',
-- ----------------------------------------------------------------------------- '{
-- Algoritmos por defecto "version": "2.0.0",
-- ----------------------------------------------------------------------------- "name": "TZZR Context Manager v2",
INSERT INTO cto.algorithms (name, version, description, config) VALUES "extraction": {
('extractor', '1.0', 'Extrae bloques de memoria de mensajes', '{ "enabled": true,
"min_content_length": 10, "async": true,
"max_block_size": 500, "batch_size": 10,
"extraction_mode": "heuristic", "filter": {
"patterns": ["fact", "instruction", "preference", "context"] "min_length": 20,
}'::jsonb), "skip_patterns": ["ok", "gracias", "entendido"]
('scorer', '1.0', 'Calcula relevancia de bloques', '{ }
"weights": {
"recency": 0.3,
"frequency": 0.2,
"importance": 0.3,
"similarity": 0.2
}, },
"decay_factor": 0.95 "consolidation": {
}'::jsonb), "strategy": "heuristic_first",
('selector', '1.0', 'Selecciona bloques para contexto', '{ "duplicate_threshold": 0.95,
"budget_tokens": 8000, "conflict_threshold": 0.85
"min_score": 0.1, },
"max_blocks": 50, "scoring": {
"strategy": "greedy" "strategy": "linear",
}'::jsonb), "weights": {
('consolidator', '1.0', 'Consolida y comprime bloques', '{ "recency": 0.20,
"similarity_threshold": 0.85, "importance": 0.40,
"merge_strategy": "newest", "relevance": 0.30,
"compression_ratio": 0.7 "frequency": 0.10
}'::jsonb) },
ON CONFLICT (name) DO UPDATE SET "decay_rates": {
config = EXCLUDED.config, "preference": 0.01,
version = EXCLUDED.version, "decision": 0.05,
updated_at = NOW(); "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
SELECT * INTO v_memory FROM cto.memory WHERE id = p_memory_id;
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;
$$ LANGUAGE plpgsql STABLE;
-- Buscar memorias por similitud semántica
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;
-- Obtener bloques activos por scope
CREATE OR REPLACE FUNCTION cto.get_active_blocks(
p_scope VARCHAR(20) DEFAULT 'global',
p_server_code VARCHAR(20) DEFAULT NULL,
p_agent_code VARCHAR(50) DEFAULT NULL
) RETURNS TABLE (
code VARCHAR(50),
name VARCHAR(200),
content TEXT,
category VARCHAR(50),
priority INT,
token_count INT
) AS $$
BEGIN
RETURN QUERY
SELECT
b.code,
b.name,
b.content,
b.category,
b.priority,
b.token_count
FROM cto.blocks b
WHERE b.status = 'active'
AND (
b.scope = 'global'
OR (b.scope = 'server' AND b.server_code = p_server_code)
OR (b.scope = 'agent' AND b.agent_code = p_agent_code)
)
ORDER BY b.priority DESC NULLS LAST, b.created_at ASC;
END;
$$ LANGUAGE plpgsql STABLE;