package ar.com.companeros.memory; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.UUID; import net.minecraft.core.GlobalPos; /** Recuerdo inmutable con fecha, lugar, procedencia y evidencia verificable. */ public record MemoryRecord(UUID id, UUID agentId, UUID worldId, GlobalPos location, long occurredAtUtc, long gameTime, MemoryType type, double importance, double confidence, long lastVerifiedAtUtc, long lastVerifiedGameTime, MemoryOrigin origin, String sourceId, List evidenceIds, String content, Set keywords, Set relatedAgents, UUID supersedes, boolean pinned) { public static final int MAX_CONTENT_CHARS = 2048; public MemoryRecord { Objects.requireNonNull(id, "id"); Objects.requireNonNull(agentId, "agentId"); Objects.requireNonNull(worldId, "worldId"); Objects.requireNonNull(type, "type"); Objects.requireNonNull(origin, "origin"); Objects.requireNonNull(content, "content"); Objects.requireNonNull(sourceId, "sourceId"); if (content.isBlank() || content.length() > MAX_CONTENT_CHARS || sourceId.length() > 128) throw new IllegalArgumentException("Texto de recuerdo fuera de límite"); if (occurredAtUtc < 0 || gameTime < 0 || lastVerifiedAtUtc < 0 || lastVerifiedGameTime < 0 || !Double.isFinite(importance) || importance < 0 || importance > 1 || !Double.isFinite(confidence) || confidence < 0 || confidence > 1) throw new IllegalArgumentException("Metadatos de recuerdo inválidos"); if (id.equals(supersedes)) throw new IllegalArgumentException("Un recuerdo no se reemplaza a sí mismo"); evidenceIds = List.copyOf(evidenceIds); keywords = Set.copyOf(keywords); relatedAgents = Set.copyOf(relatedAgents); if (evidenceIds.size() > 32 || keywords.size() > 32 || relatedAgents.size() > 32 || keywords.stream().anyMatch(key -> key.isBlank() || key.length() > 64)) throw new IllegalArgumentException("Índices de recuerdo fuera de límite"); if (location != null) location = GlobalPos.of(location.dimension(), location.pos().immutable()); } public boolean protectedFromEviction() { return pinned || importance >= .8; } public MemoryRecord verified(double newConfidence, long nowUtc, long nowGameTime) { return new MemoryRecord(id, agentId, worldId, location, occurredAtUtc, gameTime, type, importance, newConfidence, nowUtc, nowGameTime, origin, sourceId, evidenceIds, content, keywords, relatedAgents, supersedes, pinned); } }