2 Commits

Author SHA1 Message Date
egutierrez 52495af779 feat(0035e): manifest auto_group_threshold override + propagacion a Python
Manifest YAML puede declarar 'auto_group_threshold: <int>' a nivel
top-level. enrichers.cpp lo parsea y lo guarda en EnricherSpec.
jobs.cpp lo inyecta como campo opcional 'auto_group_threshold' en el
JSON stdin del subprocess. Los enrichers Python que crean Groups
(web_search, split_words, split_sentences, extract_iocs_text) leen el
campo y, si viene > 0, lo usan en lugar de su DEFAULT_GROUP_THRESHOLD.
Helper _coerce_threshold tolera int / str / None / 0 cayendo al default.
2026-05-04 14:20:52 +02:00
egutierrez 352b27d488 feat: enricher split_words para probar grouping con volumen alto
split_sentences a menudo no llega al umbral de 50 (un texto medio
tiene 5-15 frases). split_words tokeniza el mismo notes en palabras
y trivialmente lo supera con cualquier parrafo decente -> Group
visible y testeable end-to-end sin necesidad de pegar megabytes.

Diferencias respecto a split_sentences:

* Splits por regex de letras (incluye acentos espanyoles + apostrofo
  interno como "don't"). Numeros y puntuacion ignorados.
* Lowercase + filtro por min_length (default 3, filtra a/el/de/y/o).
* Param `dedupe` (default true): vocabulario unico vs cada ocurrencia.
  Con dedupe=false sirve como stress test de volumen.
* Tipo `Word` en types.yaml: amarillo, ti-letter-w, principal_field=word.
* Relacion `WORD_OF` desde cada Word al source.
* Mismo patron de grouping que split_sentences (threshold 50, K=10
  preview, batch_id en metadata, Group con count + enricher).

Tests:

* below threshold no crea Group.
* >=50 tokens unicos -> Group + 10 sueltos + resto agrupados.
* dedupe=true (default) colapsa repeticiones; dedupe=false las
  conserva como nodos separados.
* min_length filtra correctamente.
* notes prioriza sobre node_name.
* texto vacio -> exit 2.
* max_words trunca.

WSL 89 / Windows 78 + 11 skipped.
2026-05-04 00:14:57 +02:00