Plan de Enlace de Sesión Independiente del Canal
Descripción general
Este documento define el modelo de enlace de sesión independiente del canal a largo plazo y el alcance concreto para la próxima iteración de implementación. Objetivo:
- convertir el enrutamiento de sesiones enlazadas a subagentes en una capacidad central
- mantener el comportamiento específico del canal en los adaptadores
- evitar regresiones en el comportamiento normal de Discord
Por qué existe esto
El comportamiento actual mezcla:
- política de contenido de finalización
- política de enrutamiento de destino
- detalles específicos de Discord
Esto causó casos extremos como:
- entrega duplicada en el canal principal y en el hilo bajo ejecuciones concurrentes
- uso de tokens obsoletos en gestores de enlace reutilizados
- falta de contabilidad de actividad para envíos mediante webhook
Alcance de la iteración 1
Esta iteración está intencionalmente limitada.
1. Agregar interfaces centrales independientes del canal
Agregar tipos centrales e interfaces de servicio para enlaces y enrutamiento. Tipos centrales propuestos:
export type BindingTargetKind = "subagent" | "session";
export type BindingStatus = "active" | "ending" | "ended";
export type ConversationRef = {
channel: string;
accountId: string;
conversationId: string;
parentConversationId?: string;
};
export type SessionBindingRecord = {
bindingId: string;
targetSessionKey: string;
targetKind: BindingTargetKind;
conversation: ConversationRef;
status: BindingStatus;
boundAt: number;
expiresAt?: number;
metadata?: Record<string, unknown>;
};
Contrato del servicio central:
export interface SessionBindingService {
bind(input: {
targetSessionKey: string;
targetKind: BindingTargetKind;
conversation: ConversationRef;
metadata?: Record<string, unknown>;
ttlMs?: number;
}): Promise<SessionBindingRecord>;
listBySession(targetSessionKey: string): SessionBindingRecord[];
resolveByConversation(ref: ConversationRef): SessionBindingRecord | null;
touch(bindingId: string, at?: number): void;
unbind(input: {
bindingId?: string;
targetSessionKey?: string;
reason: string;
}): Promise<SessionBindingRecord[]>;
}
2. Agregar un enrutador de entrega central para finalizaciones de subagentes
Agregar una única ruta de resolución de destino para eventos de finalización. Contrato del enrutador:
export interface BoundDeliveryRouter {
resolveDestination(input: {
eventKind: "task_completion";
targetSessionKey: string;
requester?: ConversationRef;
failClosed: boolean;
}): {
binding: SessionBindingRecord | null;
mode: "bound" | "fallback";
reason: string;
};
}
Para esta iteración:
- solo
task_completionse enruta a través de esta nueva ruta - las rutas existentes para otros tipos de eventos permanecen como están
3. Mantener Discord como adaptador
Discord sigue siendo la primera implementación de adaptador. Responsabilidades del adaptador:
- crear/reutilizar conversaciones de hilo
- enviar mensajes enlazados mediante webhook o envío de canal
- validar el estado del hilo (archivado/eliminado)
- mapear metadatos del adaptador (identidad del webhook, ids de hilo)
4. Corregir problemas de corrección actualmente conocidos
Requerido en esta iteración:
- actualizar el uso del token al reutilizar un gestor de enlace de hilo existente
- registrar actividad saliente para envíos de Discord basados en webhook
- detener la vuelta al canal principal implícita cuando se selecciona un destino de hilo enlazado para la finalización en modo sesión
5. Preservar los valores predeterminados actuales de seguridad en tiempo de ejecución
Sin cambios de comportamiento para usuarios con la generación de hilos enlazados deshabilitada. Los valores predeterminados permanecen:
channels.discord.threadBindings.spawnSubagentSessions = false
Resultado:
- los usuarios normales de Discord mantienen el comportamiento actual
- la nueva ruta central afecta solo al enrutamiento de finalización de sesión enlazada donde esté habilitado
No incluido en la iteración 1
Explícitamente diferido:
- destinos de enlace ACP (
targetKind: "acp") - nuevos adaptadores de canal más allá de Discord
- reemplazo global de todas las rutas de entrega (
spawn_ack, futurosubagent_message) - cambios a nivel de protocolo
- rediseño de migración/versionado del almacén para toda la persistencia de enlaces
Notas sobre ACP:
- el diseño de la interfaz deja espacio para ACP
- la implementación de ACP no se inicia en esta iteración
Invariantes de enrutamiento
Estas invariantes son obligatorias para la iteración 1.
- la selección de destino y la generación de contenido son pasos separados
- si la finalización en modo sesión resuelve a un destino enlazado activo, la entrega debe apuntar a ese destino
- no hay redirección oculta desde el destino enlazado al canal principal
- el comportamiento de vuelta atrás debe ser explícito y observable
Compatibilidad y despliegue
Objetivo de compatibilidad:
- sin regresión para usuarios con la generación de hilos enlazados desactivada
- sin cambios para canales que no sean Discord en esta iteración
Despliegue:
- Implementar interfaces y enrutador detrás de las puertas de características actuales.
- Enrutar las entregas enlazadas en modo de finalización de Discord a través del enrutador.
- Mantener la ruta heredada para flujos no enlazados.
- Verificar con pruebas específicas y registros de tiempo de ejecución en canary.
Pruebas requeridas en la iteración 1
Cobertura de unidad e integración requerida:
- la rotación de tokens del gestor utiliza el token más reciente después de reutilizar el gestor
- los envíos mediante webhook actualizan las marcas de tiempo de actividad del canal
- dos sesiones enlazadas activas en el mismo canal del solicitante no se duplican en el canal principal
- la finalización para una ejecución en modo sesión enlazada resuelve solo al destino del hilo
- la bandera de generación deshabilitada mantiene el comportamiento heredado sin cambios
Archivos de implementación propuestos
Central:
src/infra/outbound/session-binding-service.ts(nuevo)src/infra/outbound/bound-delivery-router.ts(nuevo)src/agents/subagent-announce.ts(integración de resolución de destino de finalización)
Adaptador de Discord y tiempo de ejecución:
src/discord/monitor/thread-bindings.manager.tssrc/discord/monitor/reply-delivery.tssrc/discord/send.outbound.ts
Pruebas:
src/discord/monitor/provider*.test.tssrc/discord/monitor/reply-delivery.test.tssrc/agents/subagent-announce.format.test.ts
Criterios de finalización para la iteración 1
- las interfaces centrales existen y están conectadas para el enrutamiento de finalizaciones
- las correcciones de exactitud anteriores están fusionadas con pruebas
- no hay entrega de finalización duplicada en el canal principal y el hilo en ejecuciones enlazadas en modo sesión
- sin cambios de comportamiento para despliegues con generación enlazada deshabilitada
- ACP permanece explícitamente diferido
Plan de Supervisión de PTY y ProcesosInvestigación sobre Memoria del Espacio de Trabajo