chore: cerrar issue 0012 y mover a completed
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# Task 011 — Matrix Thread Support
|
||||
|
||||
## Objetivo
|
||||
|
||||
Permitir que los agentes mantengan conversaciones en threads de Matrix (`m.thread`),
|
||||
de forma que cada interaccion con un usuario pueda vivir en un hilo separado
|
||||
en lugar de la timeline principal del room.
|
||||
|
||||
## Contexto
|
||||
|
||||
Matrix soporta threads via `m.relates_to` con `rel_type: "m.thread"`.
|
||||
Un thread siempre referencia un **evento raiz** y opcionalmente incluye
|
||||
`m.in_reply_to` como fallback para clientes sin soporte de threads.
|
||||
|
||||
```json
|
||||
{
|
||||
"m.relates_to": {
|
||||
"rel_type": "m.thread",
|
||||
"event_id": "$rootEventId",
|
||||
"is_falling_back": true,
|
||||
"m.in_reply_to": {
|
||||
"event_id": "$lastEventInThread"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Prerequisito
|
||||
|
||||
- Task: Reply simple (`m.in_reply_to`) ya implementado.
|
||||
|
||||
## Plan de implementacion
|
||||
|
||||
### 1. Detectar threads entrantes en el Listener
|
||||
|
||||
- En `shell/matrix/listener.go`, al parsear el evento, extraer `m.relates_to`
|
||||
- Si `rel_type == "m.thread"`, capturar `event_id` como `ThreadRootID`
|
||||
- Propagar `ThreadRootID` en `MessageContext`
|
||||
|
||||
### 2. Extender MessageContext
|
||||
|
||||
- `pkg/decision/types.go`: anadir `ThreadRootID string` (el evento raiz del thread)
|
||||
- Esto es dato puro, no rompe la arquitectura
|
||||
|
||||
### 3. Extender ReplyAction
|
||||
|
||||
- `pkg/decision/types.go`: anadir `ThreadRootID string` a `ReplyAction`
|
||||
- El runner usara esto para decidir si enviar como thread o como mensaje normal
|
||||
|
||||
### 4. SendThreadMarkdown en Client
|
||||
|
||||
- `shell/matrix/client.go`: nuevo metodo `SendThreadMarkdown(ctx, roomID, threadRootID, inReplyTo, markdown)`
|
||||
- Construye el `m.relates_to` con `rel_type: "m.thread"` + fallback `m.in_reply_to`
|
||||
|
||||
### 5. Actualizar effects/Runner
|
||||
|
||||
- `shell/effects/runner.go`: si `ReplyAction.ThreadRootID != ""`, usar `SendThreadMarkdown`
|
||||
- Actualizar interfaz `MatrixSender` con el nuevo metodo
|
||||
|
||||
### 6. Propagacion en runtime.go
|
||||
|
||||
- Cuando el mensaje entrante ya esta en un thread (`msgCtx.ThreadRootID != ""`),
|
||||
las respuestas del bot deben continuar en ese thread
|
||||
- Cuando el usuario inicia una conversacion nueva, decidir segun config si crear thread o no
|
||||
|
||||
### 7. Configuracion por agente
|
||||
|
||||
- `internal/config/schema.go`: anadir opcion `matrix.threads.enabled: bool` y
|
||||
`matrix.threads.auto_thread: bool` (crear thread automatico por cada conversacion nueva)
|
||||
- Default: `enabled: true`, `auto_thread: false`
|
||||
|
||||
### 8. Memory por thread
|
||||
|
||||
- La window de conversacion deberia poder ser por thread en vez de por room
|
||||
- Si `ThreadRootID != ""`, usar `threadRootID` como key de la window en vez de `roomID`
|
||||
- Esto permite conversaciones paralelas en threads distintos sin mezclarse
|
||||
|
||||
### 9. Tests
|
||||
|
||||
- Unit tests para `SendThreadMarkdown` (verificar estructura JSON)
|
||||
- Test de integracion: listener detecta thread entrante y propaga ThreadRootID
|
||||
- Test: respuesta dentro de thread mantiene el thread root correcto
|
||||
|
||||
## Notas
|
||||
|
||||
- `is_falling_back: true` siempre debe estar cuando se usa thread + in_reply_to fallback
|
||||
- El `event_id` de `m.relates_to` (nivel top) siempre apunta al root del thread, nunca cambia
|
||||
- El `m.in_reply_to` dentro del thread apunta al ultimo mensaje respondido
|
||||
- Clientes sin soporte de threads ven el fallback como un reply normal
|
||||
Reference in New Issue
Block a user