# Tarea 11 — Renderizar mensajes como Markdown en Matrix ## Problema Todos los mensajes de los agentes (respuestas LLM, comandos, errores) se envían como texto plano via `SendText()`. Matrix soporta mensajes con `format: org.matrix.custom.html` + `formatted_body` para renderizar Markdown (negrita, código, listas, etc.) en clientes como Element. Existe un `SendMarkdown()` en `shell/matrix/client.go` pero tiene dos problemas: 1. Solo se usa en un único lugar (`runtime.go:617` — notificación de tool use). 2. No convierte Markdown a HTML: pone el markdown crudo en `FormattedBody`, que Matrix espera como HTML. ## Alcance ### 1. Añadir conversión Markdown → HTML (`shell/matrix/client.go`) - Añadir dependencia `github.com/yuin/goldmark` (parser Markdown → HTML estándar, muy usado en Go). - Corregir `SendMarkdown()` para que convierta el body de Markdown a HTML antes de ponerlo en `FormattedBody`. - `Body` queda como texto plano (fallback para clientes que no soportan HTML) — se puede dejar el markdown crudo ahí, que es lo estándar en Matrix. ```go func (c *Client) SendMarkdown(ctx context.Context, roomID, markdown string) error { html := mdToHTML(markdown) // nueva función interna content := event.MessageEventContent{ MsgType: event.MsgText, Body: markdown, Format: event.FormatHTML, FormattedBody: html, } _, err := c.raw.SendMessageEvent(ctx, id.RoomID(roomID), event.EventMessage, content) return err } ``` ### 2. Cambiar la interfaz `MatrixSender` para exponer `SendMarkdown` - `shell/effects/runner.go`: añadir `SendMarkdown(ctx, roomID, text) error` a la interfaz `MatrixSender`. - `tools/matrix.go`: añadir `SendMarkdown` a la interfaz `MatrixToolSender` (o como se llame). ### 3. Cambiar todos los call sites de `SendText` → `SendMarkdown` Puntos a cambiar: | Archivo | Línea(s) | Contexto | |---------|----------|----------| | `agents/runtime.go:394` | Respuesta de tarea orquestada | `SendText → SendMarkdown` | | `agents/runtime.go:456` | Reply LLM (loop) | `SendText → SendMarkdown` | | `agents/runtime.go:462` | Reply LLM (fallback) | `SendText → SendMarkdown` | | `shell/effects/runner.go:68` | Runner.executeOne (ActionKindReply) | `SendText → SendMarkdown` | | `agents/runtime.go:456` | Comando ejecutado (!xxx) | `SendText → SendMarkdown` | | `agents/runtime.go:462` | Comando desconocido | `SendText → SendMarkdown` | ### 4. Mantener `SendText` para uso interno/futuro No eliminar `SendText`, solo dejar de usarlo como canal principal de respuesta. Podría ser útil para mensajes que realmente no necesitan formato (logs internos, debugging). ### 5. Actualizar interfaz en tests/mocks Cualquier mock de `MatrixSender` que exista en tests necesitará el método `SendMarkdown`. ## Tareas ordenadas - [ ] `go get github.com/yuin/goldmark` - [ ] Crear función `mdToHTML(md string) string` en `shell/matrix/` (usa goldmark) - [ ] Corregir `SendMarkdown()` para usar `mdToHTML` - [ ] Añadir `SendMarkdown` a la interfaz `MatrixSender` en `shell/effects/runner.go` - [ ] Cambiar `runner.executeOne` (ActionKindReply) de `SendText` → `SendMarkdown` - [ ] Cambiar `runtime.go` — respuesta de comandos (!xxx) a `SendMarkdown` - [ ] Cambiar `runtime.go` — respuesta de tarea orquestada a `SendMarkdown` - [ ] Actualizar interfaz en `tools/matrix.go` si aplica - [ ] Actualizar mocks en tests - [ ] Test manual: enviar mensaje al bot y verificar que Element renderiza markdown ## Notas - goldmark es safe por defecto (escapa HTML peligroso) — no hay riesgo XSS. - El `Body` del evento Matrix queda como markdown crudo — esto es correcto según la spec de Matrix (es el fallback plaintext). - Los mensajes de error simples ("Comando desconocido: !foo") también pasan por `SendMarkdown` — no pasa nada, goldmark los deja como `
texto
` sin más.