CreaRack-SL

Oráculo de EL — UX s78: eliminación de chips de modo, scroll inteligente y ventana más alta

Oráculo de EL — UX s78: eliminación de chips de modo, scroll inteligente y ventana más alta

Tres mejoras de UX aplicadas al componente SearchInline del workspace (Oráculo de EL) tras feedback de Edu en la sesión 78. El cambio se desplegó en el commit c1c7bd7 del 2026-05-21.


Contexto

El Oráculo de EL es la caja de búsqueda híbrida del workspace CreaRack Pro. Combina búsqueda fuzzy local (Fuse.js sobre /search-index.json) con un chat multi-turno vía POST /api/oraculo/ask. La detección automática de modo (shouldAskOracle) determina si una query debe ir al backend LLM o resolverse localmente.

Antes de este cambio, la interfaz exponía tres chips manuales — Auto, Buscar, Preguntar — que permitían al usuario forzar un modo. El estado mode: SearchMode (‘auto’ | ‘search’ | ‘oracle’) se propagaba a shouldAskOracle(query, mode).


Mejoras implementadas

1. Erradicación de chips Auto / Buscar / Preguntar

AntesDespués
3 chips visibles en el dropdownSin chips; decisión 100 % automática
type SearchMode = 'auto' | 'search' | 'oracle'Tipo eliminado
const [mode, setMode] = useState<SearchMode>('auto')State eliminado
shouldAskOracle(query, mode)shouldAskOracle(query)

La heurística shouldAskOracle cubre el 95 % de los casos de uso reales:

  • q.length < 8 → fuzzy search.
  • Termina en ? o ¿ → oráculo.
  • ≥ 4 palabras → oráculo.
  • Empieza por palabra interrogativa (qué, cómo, dónde, por qué, cuál, quién, cuándo, what, how, where, why, which, who, when) → oráculo.
  • En cualquier otro caso → fuzzy search.

Los chips eran ruido cognitivo: añadían fricción visual y path de error (usuario en modo ‘search’ preguntando al oráculo sin saberlo) sin aportar valor real.

2. Scroll automático al inicio del último turno assistant

Comportamiento anterior: node.scrollTop = node.scrollHeight → siempre al fondo del contenedor.

Comportamiento nuevo (implementado en el useEffect sobre [turns.length, pending]):

const assistants = node.querySelectorAll<HTMLElement>(
  '.search-inline-oracle-turn.assistant:not(.pending)',
);
const last = assistants[assistants.length - 1];
if (last) {
  // Scroll para que el TOP del turno quede en lo alto del contenedor
  const containerTop = node.getBoundingClientRect().top;
  const itemTop = last.getBoundingClientRect().top;
  node.scrollTop = node.scrollTop + (itemTop - containerTop);
} else {
  // Sin respuesta aún (solo turn user o spinner pending) → fondo
  node.scrollTop = node.scrollHeight;
}

Rationale: las respuestas del LLM pueden ser largas (varios párrafos de markdown). Si el scroll va al final, el usuario ve el pie de la respuesta y tiene que hacer scroll manual hacia arriba para leer desde el inicio. Con este cambio, el inicio de la respuesta queda en la parte superior del viewport del chat desde el primer render.

El fallback al fondo preserva la experiencia durante el estado pending (“El Oráculo está pensando…”), garantizando que el indicador de carga sea siempre visible.

3. Ventana más alta: dropdown y chat

ElementoAntesDespués
.search-inline-dropdown max-height520px fijomin(82vh, 800px)
.search-inline-oracle-chat max-height380px fijomin(70vh, 660px)

Los valores fijos cortaban respuestas largas en monitores de alta resolución (27”+ habituales en el equipo). Los nuevos valores con min() se adaptan al viewport:

  • Portátiles pequeños (768px height): dropdown ~630px, chat ~538px.
  • Monitores grandes (1440px+ height): dropdown cap 800px, chat cap 660px.

Archivos modificados

ArchivoTipo de cambio
src/components/shell/SearchInline.tsxLógica: eliminación de state mode, simplificación de shouldAskOracle, refactor del useEffect de scroll
src/styles/globals.cssCSS: max-height dinámicos para .search-inline-dropdown y .search-inline-oracle-chat

Impacto funcional

  • Sin breaking changes de API: el endpoint POST /api/oraculo/ask no cambia.
  • Sin cambios en el search index: Fuse.js y /search-index.json intactos.
  • Conversación efímera preservada: no se añade persistencia; la sesión sigue siendo por pestaña.
  • Accesibilidad: se eliminan 3 botones de la UI → menos elementos focusables, menor ruido para lectores de pantalla.

Véase también

  • [[feature—workspace—oraculo-el]]
  • [[incident—20260519—oraculo-hardening-v1]]