Saltar al contenido
EspañolEnglish

Interfaces de IA y editor de texto

Las piezas de una interfaz de asistente salen del chat del asistente de AMSET, que las usa a diario: la caja de entrada, los mensajes, el razonamiento, las llamadas a herramientas, el registro de lo que hace un agente, los ficheros que genera y el selector de modelo. Son 12, sin dependencias, con un CSS por componente y todo dicho con texto además de con color.

Los componentes

Adjunto

Attachment

Un fichero adjunto a un mensaje.
La barra de buscar DENTRO de algo -una conversación larga, un documento-.
La caja donde se escribe a un asistente.
Una llamada a una herramienta.

Mensaje de chat

ChatMessage

Un mensaje de un chat con un asistente.

Razonamiento

Reasoning

El razonamiento de un modelo, plegado.
El registro de lo que está haciendo un agente.

Selector de motor

ModelSelector

Con qué se atiende lo siguiente.

Sugerencias

Suggestions

Las respuestas rápidas que propone un asistente.
Un fichero que ha generado un asistente, con su vista previa a un clic.

Uso y coste

UsageBadge

Cuánto ha costado una respuesta.

Visor de imagen

ImageViewer

El visor de una imagen a pantalla casi completa.
  • PromptInput crece con el texto hasta un tope, envía con Intro y baja de línea con Mayús+Intro (sin enviar mientras se compone con un IME), recupera lo último con la flecha arriba y admite ficheros pegados, arrastrados o elegidos. Con busyModes se puede seguir escribiendo mientras responde: añadir al turno, parar y corregir o encolar.
  • ChatMessage trae copiar, regenerar y editar en la misma burbuja, y acciones propias.
  • ActivityLog sigue el final solo si ya estabas abajo y junta los eventos repetidos; con group, un historial de varias tareas.
  • FindBar busca dentro de una conversación larga, donde el buscador del navegador no ve lo que no se ha cargado.
  • ArtifactFrame aísla el HTML que genera un asistente con sandbox="allow-scripts", nunca con allow-same-origin.

Editor de texto enriquecido

@amset/ui no trae un editor de texto ni depende de uno. Trae lo que tiene que verse y comportarse como el resto de la biblioteca —la barra, sus paneles de enlace e imagen y los estilos de la zona de escritura— y deja el motor a tu aplicación. Hay dos recetas completas, una para Tiptap y otra para Lexical, compiladas y comprobadas en el repositorio de la biblioteca.

SentidoPropQué lleva
editor → barrastateLo que hay puesto donde está el cursor (active), lo que no se puede usar ahora (unavailable) y el enlace del cursor (link).
barra → editoronCommandLa orden: 'bold', 'heading2', 'bulletList', 'undo', 'clearFormatting'…
barra → editoronLinkChange{ href, newTab } ya comprobado, o null para quitarlo.
barra → editoronImageInsert{ src, alt } ya comprobado; alt solo va vacío si la imagen se marca como decorativa.
aplicación → barrashortcutsLos atajos del editor (Mod+B), que la barra anuncia y enseña en su ayuda. Los escucha el editor, no la barra.
  • Una sola parada del tabulador para toda la barra, flechas entre botones y memoria del foco al volver.
  • Cada formato es un ToggleButton con aria-pressed; pulsarlo con el ratón no le quita el foco al editor, así que la selección se queda donde estaba.
  • Los paneles de enlace e imagen solo se montan al abrirlos y no son un <form>: la barra vale dentro del formulario de tu aplicación.
  • Las direcciones se comprueban con normalizeLinkHref y normalizeImageSrc (lista blanca de esquemas: un javascript: o un data: no pasan). La barra no limpia lo que guarda el editor: ese HTML se sanea en el servidor antes de guardarlo o pintarlo.

Las recetas de Tiptap y Lexical

Se instala en tu aplicación el editor que elijas; la biblioteca no necesita nada nuevo. Las recetas van sobre el núcleo de cada editor, sin @tiptap/react ni @lexical/react: esos paquetes arrastran código de menús flotantes que no hace falta para esta barra.

Instalar el editor
# Tiptapnpm install @tiptap/core @tiptap/pm @tiptap/starter-kit @tiptap/extension-image # Lexicalnpm install lexical @lexical/rich-text @lexical/list @lexical/link @lexical/history @lexical/selection @lexical/utils
Las hojas, si importas los estilos por componente
import '@amset/ui/styles/rich-text.css'import '@amset/ui/styles/toggle-button.css'
El marco y la zona de escritura
<span id={labelId}>Product description</span><div className="amset-richtext__frame">  <RichTextToolbar label="Description formatting" aria-controls={editorId} variant="flat" {...toolbarProps} />  <div ref={hostRef} /></div>

Código de la guía de la biblioteca (docs/rich-text-editor.md, revisión 3bb3996d), comprobado allí por el compilador.

Cada receta es un hook de React que monta el editor en un <div>, mantiene state al día en cada cambio y traduce cada orden a la API del editor. Es todo el pegamento que hay. Con otro editor basta con contestar a lo mismo: qué está activo en el cursor, qué no se puede usar ahora, y cómo se ejecuta cada orden.