Notas de versión de AgentDoc – Abril de 2026

Registro de cambios · 6 min de lectura

Una tanda breve y densa de correcciones llegó a AgentDoc (también conocido como agent doc, agentdocs, docedit) durante el último sprint. El tema esta vez es la corrección del renderizador: casos límite donde la salida de las herramientas del agente era técnicamente válida, pero la capa visual o bien descartaba información o, peor aún, fabricaba estilos que el agente en realidad no había solicitado. Cinco parches, todos puntuales, sin cambios en la API.

1. Listas anidadas: profundidad relativa conservada durante la normalización

c62928c · fix(renderer): preserve relative depth in nested-list normalization

Cuando el agente generaba listas anidadas ordenadas o sin ordenar con sangrías mixtas, la pasada de normalización del renderizador colapsaba las profundidades al nivel mínimo presente en el markdown, lo que significaba que una lista de la forma 1.1.1.1.1.1. se renderizaba como tres elementos hermanos en lugar de un árbol. La corrección cambia el normalizador de suelo absoluto a desplazamiento relativo: las diferencias de profundidad dentro del bloque se conservan y solo se normaliza la sangría global.

Por qué les importa a los agentes: muchos modelos emiten llamadas a insert_text con contenido que ha sido reformateado en la capa del LLM (por ejemplo, un modelo que aprendió la sangría con 2 espacios cuando el documento usa 4 espacios). El renderizador debe respetar la estructura, no los espacios en blanco en bruto.

2. Las clases de decoración ahora se componen en lugar de reemplazarse

ddfb64a · fix(formatting): decoration-* classes compose instead of replacing

Anteriormente, llamar a apply_decoration(target, "decoration-underline") sobre un span que ya tenía decoration-strikethrough sobrescribía la clase existente. Esta es la semántica incorrecta: las decoraciones son ortogonales (puedes subrayar y tachar el mismo token), y nuestra docstring prometía exactamente eso. El error venía de una única asignación className = en el setter de decoraciones, que reemplazamos por una gestión adecuada con classList que añade sin eliminar a los hermanos de la misma familia.

3. Las herramientas apply_* ahora tienen una semántica TOGGLE adecuada

8201f0a · fix(content_ops): implement TOGGLE on apply_* tools (matches docstrings)

La superficie de herramientas MCP anunciaba un comportamiento de alternancia en apply_bold, apply_italic, apply_underline, etc., es decir, que una segunda llamada sobre la misma selección debía eliminar el formato, no aplicarlo de nuevo. La implementación, sin embargo, siempre lo activaba. La corrección introduce una comprobación de estado sobre el span resuelto y se ramifica: si el formato ya está presente y cubre por completo la selección, se elimina; si está ausente o es parcial, se aplica de manera uniforme.

Esto importa más de lo que parece. Los flujos por voz se apoyan mucho en "en realidad, deshaz eso" como señal de rehacer; el agente que traduce eso en una segunda llamada a apply_bold ahora hace lo correcto sin necesidad de llamar a una herramienta remove_format aparte. Eliminamos dos viajes de ida y vuelta del LLM de una ruta habitual.

4. Escape de código en línea dentro de los atributos [text]{.class}

1e32d70 · fix(renderer): rewrite [text]{.class} swallowed inside inline-code

La pasada previa del renderizador para nuestra sintaxis de atributos extendida se ejecutaba antes de la etapa de markdown a HTML, lo que significaba que cadenas como `[text]{.foo}` que aparecían dentro de código en línea delimitado por comillas invertidas (es decir, documentación literal de la sintaxis) se reescribían como spans con estilo en lugar de mostrarse como código. Ahora omitimos la reescritura cuando el desplazamiento cae dentro de un span de código. Las páginas de documentación —incluida esta— vuelven a renderizarse correctamente.

5. Las clases decoration-* se aplican a cualquier elemento

a05b44c · fix(frontend): style decoration-* classes on any element, not just span

Las reglas CSS para .decoration-underline, .decoration-strikethrough, etc., estaban acotadas como span.decoration-*. Esto funcionaba en el caso común, pero fallaba cuando el agente aplicaba una decoración a un encabezado, un elemento de lista o una celda de tabla. La corrección elimina el calificador con el nombre del elemento, de modo que las decoraciones ahora son ortogonales al tipo de elemento, en consonancia con la corrección de la semántica de alternancia anterior y con la documentación.

Qué viene a continuación

El siguiente lote de trabajo está en cola en torno a los flujos de BYOK (trae tu propia clave de API de Gemini), lo que requiere enseñar al modal del frontend y a la píldora de estado de cuota a coexistir con los nuevos módulos byok_modal.js y quota_status.js. Después haremos una pasada centrada en el enrutador de chat, que ha ido acumulando ramas.

Si quieres ver el razonamiento de ingeniería detrás de las decisiones de diseño de herramientas mencionadas arriba, el artículo sobre la granularidad de herramientas cubre el marco que usamos para decidir si un comportamiento debe ser una herramienta, un argumento de herramienta o trasladarse a la capa de razonamiento del LLM.

← Granularidad de herramientas en agentes LLM Siguiente: Reconstrucción de la exportación a PDF + DOCX →