"""Configurazione statica del Memory Gateway letta dall'ambiente.""" from __future__ import annotations import logging import os from collections import Counter from typing import Any QDRANT_URL = os.environ.get("QDRANT_URL", "http://127.0.0.1:6333") QDRANT_API_KEY = os.environ.get("QDRANT_API_KEY", "") EMBED_API = os.environ.get("EMBED_API", "ollama") EMBED_URL = os.environ.get("EMBED_URL", os.environ.get("OLLAMA_URL", "http://127.0.0.1:11434")) EMBED_MODEL = os.environ.get("EMBED_MODEL", "bge-m3") EMBED_API_KEY = os.environ.get("EMBED_API_KEY", "") EMBED_DIM = int(os.environ.get("EMBED_DIM", "1024")) # Catena di fallback per gli embedding (JSON, formato RERANK_CHAIN + campo "api"). # Vuota โ†’ comportamento legacy: endpoint singolo da EMBED_API/EMBED_URL/EMBED_API_KEY. EMBED_CHAIN = os.environ.get("EMBED_CHAIN", "") EMBED_TIMEOUT_MS = int(os.environ.get("EMBED_TIMEOUT_MS", "30000")) EMBED_RETRY_COOLDOWN_S = int(os.environ.get("EMBED_RETRY_COOLDOWN_S", "60")) # Retry transiente per le chiamate Qdrant (store/search inclusi) QDRANT_RETRIES = int(os.environ.get("QDRANT_RETRIES", "3")) COLLECTION = os.environ.get("COLLECTION", "memories") API_KEYS: set[str] = {k.strip() for k in os.environ.get("API_KEYS", "").split(",") if k.strip()} RATE_LIMIT_PER_MIN = int(os.environ.get("RATE_LIMIT_PER_MIN", "120")) MAX_TEXT_LEN = int(os.environ.get("MAX_TEXT_LEN", "8000")) GUARDRAIL_ENABLED = os.environ.get("GUARDRAIL_ENABLED", "true").lower() == "true" GUARDRAIL_BLOCK_THRESHOLD = float(os.environ.get("GUARDRAIL_BLOCK_THRESHOLD", "0.85")) GUARDRAIL_WARN_THRESHOLD = float(os.environ.get("GUARDRAIL_WARN_THRESHOLD", "0.70")) GUARDRAIL_VERSION = "similarity-v2" # Strato 3 del guardrail: cross-encoder (richiede catena rerank attiva) GUARDRAIL_RERANK = os.environ.get("GUARDRAIL_RERANK", "false").lower() == "true" GUARDRAIL_RERANK_BLOCK = float(os.environ.get("GUARDRAIL_RERANK_BLOCK", "0.90")) GUARDRAIL_RERANK_SUGGEST = float(os.environ.get("GUARDRAIL_RERANK_SUGGEST", "0.85")) # Verifica supersede: cross-score (nuovo, vecchio) sotto soglia โ†’ warning non bloccante GUARDRAIL_SUPERSEDE_CHECK = os.environ.get("GUARDRAIL_SUPERSEDE_CHECK", "false").lower() == "true" GUARDRAIL_SUPERSEDE_MIN = float(os.environ.get("GUARDRAIL_SUPERSEDE_MIN", "0.50")) # Score composito: rerank + importance + recency + authority (post-rerank) SCORE_W_RELEVANCE = float(os.environ.get("SCORE_W_RELEVANCE", "0.55")) SCORE_W_IMPORTANCE = float(os.environ.get("SCORE_W_IMPORTANCE", "0.20")) SCORE_W_RECENCY = float(os.environ.get("SCORE_W_RECENCY", "0.15")) SCORE_W_AUTHORITY = float(os.environ.get("SCORE_W_AUTHORITY", "0.10")) SCORE_DECAY_HALF_LIFE_DAYS = float(os.environ.get("SCORE_DECAY_HALF_LIFE_DAYS", "180")) GIT_COMMIT = os.environ.get("GIT_COMMIT", "unknown").strip() GATEWAY_VERSION = os.environ.get("GATEWAY_VERSION", "2.11.0").strip() VM_PUSH_URL = os.environ.get("VM_PUSH_URL", "http://host.docker.internal:8428/api/v1/import/prometheus") VM_PUSH_INTERVAL = int(os.environ.get("VM_PUSH_INTERVAL", "30")) METRICS_ENABLED = os.environ.get("METRICS_ENABLED", "true").lower() == "true" logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") log = logging.getLogger("memory-gateway") SPARSE_VECTOR_NAME = "bm25" # Re-ranking: catena di fallback resiliente (frigate โ†’ brain locale). # Il default nel codice รจ OFF; il deploy imposta RERANK_ENABLED=true e la catena. RERANK_ENABLED = os.environ.get("RERANK_ENABLED", "false").lower() == "true" RERANK_MODEL = os.environ.get("RERANK_MODEL", "bge-reranker-v2-m3") RERANK_CANDIDATES = int(os.environ.get("RERANK_CANDIDATES", "16")) RERANK_MAX_DOC_CHARS = int(os.environ.get("RERANK_MAX_DOC_CHARS", "800")) RERANK_TIMEOUT_MS = int(os.environ.get("RERANK_TIMEOUT_MS", "10000")) RERANK_RETRY_COOLDOWN_S = int(os.environ.get("RERANK_RETRY_COOLDOWN_S", "60")) RERANK_CHAIN = os.environ.get("RERANK_CHAIN", "") _metrics: dict[str, Any] = { "requests": Counter(), "duration_sum": Counter(), "duration_count": Counter(), "errors": Counter(), "search_queries": 0, "search_hits": 0, "rerank_calls": Counter(), "rerank_duration_sum": Counter(), "embed_calls": Counter(), "embed_duration_sum": Counter(), "qdrant_retries": 0, }