---
name: aggregate_extraction_results
kind: function
lang: py
domain: core
version: "1.0.0"
purity: pure
signature: "def aggregate_extraction_results(extract_results: list[dict]) -> dict"
description: "Agrega entidades y relaciones de N resultados de extraccion por chunk. Deduplica entidades por (type, name_lowercased) acumulando counts. Deduplica relaciones por (head, rel_type, tail) con Counter."
tags: [nlp, aggregation, entities, relations, deduplication, chunking, ner, re, graph]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [collections.Counter]
params:
  - name: extract_results
    desc: "Lista de resultados por chunk. Cada elemento tiene shape {'entities': {type: [name, ...]}, 'relation_extraction': {rel_type: [(head, tail), ...]}}. Es el output de extract_graph_gliner2. Claves ausentes se toleran."
output: "Dict con dos campos: 'entities' -> dict keyed por (type, name_lower) con {type, name, count}; 'relations' -> Counter (head, rel_type, tail) -> count. Listo para pasar a filter_relations_by_entity_types y merge_entity_aliases."
tested: true
tests:
  - "lista vacia retorna entities vacio y relations vacio"
  - "resultado unico se agrega correctamente"
  - "dos resultados con solapamiento acumulan counts"
  - "entidades se deduplicen case-insensitive"
test_file_path: "python/functions/core/tests/test_aggregate_extraction_results.py"
file_path: "python/functions/core/aggregate_extraction_results.py"
notes: |
  Output shape deliberado para composicion con el pipeline:
  - entities keyed por (type, name_lower) permite lookup O(1) por tipo+nombre
  - relations como Counter permite filtrar por frecuencia (count >= 2)
  No aplica coreference — eso lo hace merge_entity_aliases sobre los nombres
  canonicos despues de agregar.
---

## Ejemplo

```python
from core.aggregate_extraction_results import aggregate_extraction_results

results = [
    {"entities": {"person": ["Pablo Isla"], "organization": ["Inditex"]},
     "relation_extraction": {"ceo_of": [("Pablo Isla", "Inditex")]}},
    {"entities": {"person": ["pablo isla"], "organization": ["Inditex"]},
     "relation_extraction": {"ceo_of": [("Pablo Isla", "Inditex")]}},
]
agg = aggregate_extraction_results(results)
# agg["entities"][("person", "pablo isla")]["count"] == 2
# agg["relations"][("Pablo Isla", "ceo_of", "Inditex")] == 2
```
