---
id: 0035c
title: web_search crea Group cuando excede umbral (Twitter/Reddit preview)
status: done
priority: high
created: 2026-05-03
parent: 0035
depends_on: [0035a, 0035b]
---

## Objetivo

Que `web_search` deje de vomitar 100+ Urls sueltos. Cuando el numero
de resultados excede el umbral, crea un nodo `Group` que contiene la
mayoria; los primeros K quedan sueltos como preview directo del
source.

## Cambios

1. **Threshold**: leer `auto_group_threshold` del manifest si esta
   presente; fallback a constante global `50` (hardcoded por ahora;
   settings UI viene en fase 2). Para `web_search/manifest.yaml` no
   declaramos override — usa el default.
2. **Preview K**: constante global `10` (primeros K resultados quedan
   sueltos colgando del source con `SEARCH_RESULT_OF` normal).
3. **Creacion del grupo en `run.py`**: si `len(results) >= threshold`:
   - Insertar entidad `Group` con `type_ref='Group'`,
     `name='web_search: <query> (<N>)'`, `metadata` que incluya
     `enricher='web_search'`, `query`, `count=N`, `batch_id=<UUID>`.
   - Insertar relacion `SEARCH_RESULT_OF` desde el Group al source.
   - Insertar los primeros K resultados como Urls sueltos
     (comportamiento actual, con `batch_id` en metadata).
   - Insertar los restantes N-K como Urls con `group_id=<id_group>`
     y `batch_id=<UUID>` en metadata. Cada uno mantiene su relacion
     individual `SEARCH_RESULT_OF` al source (NO al grupo — la
     procedencia es la relacion real).
4. **batch_id**: `UUID4` generado al inicio del run, compartido por
   todos los nodos creados en esa ejecucion (group + sueltos + hijos
   del grupo).

## Acceptance criteria

- `web_search` con un mock que devuelve 5 resultados: NO crea Group.
  Comportamiento actual.
- `web_search` con un mock que devuelve 100 resultados: crea 1 Group
  + 10 Urls sueltos + 90 Urls con group_id.
- Todos los nodos creados (group + sueltos + agrupados) comparten
  `metadata.batch_id`.
- En el canvas (con 0035b ya en master): aparecen 10 Urls + 1 cuadrado
  Group colgando del source. Los 90 Urls dentro del Group estan
  ocultos.
- Tests pytest nuevos:
  - `test_web_search_below_threshold_no_group`
  - `test_web_search_above_threshold_creates_group_and_preview`
  - `test_web_search_batch_id_shared_across_outputs`
- Tests existentes siguen verdes.

## TBD

Branch `issue/0035c-web-search-creates-groups`, merge `--no-ff` con
tests verdes.

## Out of scope

- Aplicar a otros enrichers (fase 2).
- Cascada multi-tipo (decision 6, fase 2).
- Regroup/promote desde tableview (fase 2).
