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
| Antes | Después |
|---|---|
| 3 chips visibles en el dropdown | Sin 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
| Elemento | Antes | Después |
|---|---|---|
.search-inline-dropdown max-height | 520px fijo | min(82vh, 800px) |
.search-inline-oracle-chat max-height | 380px fijo | min(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
| Archivo | Tipo de cambio |
|---|---|
src/components/shell/SearchInline.tsx | Lógica: eliminación de state mode, simplificación de shouldAskOracle, refactor del useEffect de scroll |
src/styles/globals.css | CSS: 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/askno cambia. - Sin cambios en el search index: Fuse.js y
/search-index.jsonintactos. - 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]]