File size: 2,278 Bytes
6879860
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9ee7168
6879860
 
 
 
 
 
 
4dba873
 
 
 
 
 
6879860
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4dba873
 
 
 
 
 
 
 
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
"""
Biblioteca de contenido CURADO (la fuente de la verdad, no el LLM).
Cargás JSON validado por ustedes. El motor pide content.pick(intent, edad)
y recibe un 'script' que el LLM presenta con calidez, sin inventar.
"""

import json
import os
import random


class ContentLibrary:
    def __init__(self, content_dir: str):
        self.items = {}     # intent -> list[dict]
        self.titles = {}    # content_id -> title (para armar bloques de contexto/memoria)
        for name in ("activities", "stories", "songs", "learning"):
            path = os.path.join(content_dir, f"{name}.json")
            if os.path.exists(path):
                with open(path, encoding="utf-8") as f:
                    for item in json.load(f):
                        self.items.setdefault(item["intent"], []).append(item)
                        self.titles[item["id"]] = item["title"]

        self.colors = []    # paletas para "Sofía, cambiate a <color>" (ver colors.json)
        colors_path = os.path.join(content_dir, "colors.json")
        if os.path.exists(colors_path):
            with open(colors_path, encoding="utf-8") as f:
                self.colors = json.load(f)

    def pick(self, intent: str, child_age: int, exclude_ids: set | None = None):
        """Elige un ítem curado para la edad. Si hay `exclude_ids` (contenido ya visto
        recientemente, ver ParentalStore.seen_ids), preferimos algo nuevo; si ya vio
        todo lo disponible, repetimos antes que no ofrecer nada."""
        candidates = [
            it for it in self.items.get(intent, [])
            if it.get("min_age", 0) <= child_age <= it.get("max_age", 99)
        ]
        if not candidates:
            return None
        if exclude_ids:
            fresh = [it for it in candidates if it["id"] not in exclude_ids]
            if fresh:
                candidates = fresh
        return random.choice(candidates)

    def match_color(self, message_lower: str) -> dict | None:
        """Si el mensaje menciona uno de los colores simples de colors.json,
        devuelve su entrada (script + palette curados). None si no hay match."""
        for color in self.colors:
            if any(word in message_lower for word in color["match"]):
                return color
        return None