create-bk-agent 0.22.0 → 0.22.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/index.js +3 -1
- package/dist/src/prompts.js +5 -0
- package/package.json +39 -39
- package/templates/.codex-manifest.json +529 -0
- package/templates/base/orchestrator/soporte/flows/atencion-ticket.yaml +159 -0
- package/templates/base/orchestrator/soporte/flows/incidente-critico.yaml +218 -0
- package/templates/base/orchestrator/soporte/orchestrator.yaml +98 -0
- package/templates/base/orchestrator/soporte/test-flow.mjs +210 -0
- package/templates/base/orchestrator/soporte/vault/comunicacion/plantillas.md +211 -0
- package/templates/base/orchestrator/soporte/vault/lecciones/.gitkeep +0 -0
- package/templates/base/orchestrator/soporte/vault/procesos/escalacion.md +106 -0
- package/templates/base/orchestrator/soporte/vault/procesos/manejo-de-tickets.md +101 -0
- package/templates/base/orchestrator/soporte/vault/productos/coberturas-de-soporte.md +94 -0
- package/templates/base/orchestrator/soporte/vault/sla/niveles-de-servicio.md +104 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
id: atencion-ticket
|
|
3
|
+
name: "Atención de Ticket — {{payload.ticket_id}}"
|
|
4
|
+
description: >
|
|
5
|
+
Pipeline completo de atención a un ticket de soporte: triage y priorización,
|
|
6
|
+
resolución L1 con la base de conocimiento, comunicación al cliente con gate de
|
|
7
|
+
aprobación, y registro de aprendizajes en la KB.
|
|
8
|
+
|
|
9
|
+
steps:
|
|
10
|
+
- id: s1-triage
|
|
11
|
+
agent: triage-agent
|
|
12
|
+
depends_on: []
|
|
13
|
+
task: |
|
|
14
|
+
Clasificar y priorizar el siguiente ticket de soporte entrante.
|
|
15
|
+
|
|
16
|
+
DATOS DEL TICKET:
|
|
17
|
+
- ID: {{payload.ticket_id}}
|
|
18
|
+
- Cliente: {{payload.cliente}}
|
|
19
|
+
- Plan/Tier: {{payload.plan}}
|
|
20
|
+
- Canal de entrada: {{payload.canal}}
|
|
21
|
+
- Asunto: {{payload.asunto}}
|
|
22
|
+
- Descripción del problema: {{payload.descripcion}}
|
|
23
|
+
- Información del entorno (si la proporcionó): {{payload.entorno}}
|
|
24
|
+
|
|
25
|
+
Producir el triage completo:
|
|
26
|
+
|
|
27
|
+
1. PRIORIDAD
|
|
28
|
+
- P1 Crítico: sistema caído, impacto en producción, sin workaround
|
|
29
|
+
- P2 Alto: funcionalidad core degradada, impacto en operaciones
|
|
30
|
+
- P3 Medio: bug con workaround disponible o feature parcialmente afectada
|
|
31
|
+
- P4 Bajo: consulta, mejora sugerida o cosmético
|
|
32
|
+
|
|
33
|
+
2. TIPO DE ISSUE
|
|
34
|
+
- Bug / Error técnico
|
|
35
|
+
- Consulta / "How to"
|
|
36
|
+
- Solicitud de feature / mejora
|
|
37
|
+
- Problema de rendimiento / performance
|
|
38
|
+
- Acceso / permisos / facturación
|
|
39
|
+
- Integración con terceros
|
|
40
|
+
|
|
41
|
+
3. ÁREA DE PRODUCTO AFECTADA
|
|
42
|
+
Identificar qué módulo, API o componente está involucrado basándose en la descripción.
|
|
43
|
+
|
|
44
|
+
4. NIVEL DE SOPORTE REQUERIDO
|
|
45
|
+
- L1: resoluble con documentación existente o procedimiento estándar
|
|
46
|
+
- L2: requiere investigación técnica, acceso a logs o análisis de código
|
|
47
|
+
- L3: requiere escalación a ingeniería, posible bug en producción
|
|
48
|
+
|
|
49
|
+
5. SLA APLICABLE
|
|
50
|
+
Tiempo de respuesta y resolución según prioridad y plan del cliente.
|
|
51
|
+
|
|
52
|
+
6. INFORMACIÓN FALTANTE
|
|
53
|
+
Lista de datos adicionales que necesitamos del cliente para resolver más rápido
|
|
54
|
+
(si aplica).
|
|
55
|
+
|
|
56
|
+
7. CONTEXTO PARA EL AGENTE DE SOPORTE
|
|
57
|
+
Resumen ejecutivo de 3-4 líneas con lo que sabe el siguiente agente para arrancar.
|
|
58
|
+
|
|
59
|
+
- id: s2-resolucion
|
|
60
|
+
agent: support-agent
|
|
61
|
+
depends_on: [s1-triage]
|
|
62
|
+
task: |
|
|
63
|
+
Resolver el ticket de soporte usando la base de conocimiento.
|
|
64
|
+
|
|
65
|
+
TRIAGE DEL TICKET:
|
|
66
|
+
{{steps.s1-triage.output}}
|
|
67
|
+
|
|
68
|
+
TICKET ORIGINAL:
|
|
69
|
+
- Cliente: {{payload.cliente}} (Plan: {{payload.plan}})
|
|
70
|
+
- Asunto: {{payload.asunto}}
|
|
71
|
+
- Descripción: {{payload.descripcion}}
|
|
72
|
+
- Entorno: {{payload.entorno}}
|
|
73
|
+
|
|
74
|
+
Produce la respuesta de soporte L1:
|
|
75
|
+
|
|
76
|
+
1. DIAGNÓSTICO
|
|
77
|
+
Qué está causando el problema según la descripción y la base de conocimiento.
|
|
78
|
+
|
|
79
|
+
2. SOLUCIÓN PASO A PASO
|
|
80
|
+
Instrucciones claras y numeradas para que el cliente resuelva el problema.
|
|
81
|
+
Si hay un workaround mientras se investiga la causa raíz, indicarlo primero.
|
|
82
|
+
|
|
83
|
+
3. VERIFICACIÓN
|
|
84
|
+
Cómo sabe el cliente que el problema se resolvió (qué debe ver/comprobar).
|
|
85
|
+
|
|
86
|
+
4. ESTADO DE RESOLUCIÓN
|
|
87
|
+
- RESUELTO: el problema tiene solución documentada y completa
|
|
88
|
+
- NECESITA_INFO: falta información del cliente para continuar
|
|
89
|
+
- ESCALAR_L2: el issue supera el alcance de L1, necesita investigación técnica
|
|
90
|
+
- WORKAROUND: hay solución temporal pero el root cause requiere L2
|
|
91
|
+
|
|
92
|
+
5. ARTÍCULOS DE KB UTILIZADOS
|
|
93
|
+
Lista de artículos o secciones de la documentación consultados (para tracking).
|
|
94
|
+
|
|
95
|
+
- id: s3-comunicacion
|
|
96
|
+
agent: communication-agent
|
|
97
|
+
depends_on: [s1-triage, s2-resolucion]
|
|
98
|
+
gate: true
|
|
99
|
+
gate_criteria:
|
|
100
|
+
- "La respuesta es clara y accionable — el cliente sabe exactamente qué hacer"
|
|
101
|
+
- "El tono es empático sin ser condescendiente"
|
|
102
|
+
- "Si el issue no se resuelve completamente, se explica el próximo paso y el tiempo estimado"
|
|
103
|
+
- "No se incluye jerga interna ni información confidencial"
|
|
104
|
+
task: |
|
|
105
|
+
Redactar la respuesta al cliente para el ticket {{payload.ticket_id}}.
|
|
106
|
+
|
|
107
|
+
TRIAGE:
|
|
108
|
+
{{steps.s1-triage.output}}
|
|
109
|
+
|
|
110
|
+
RESOLUCIÓN L1:
|
|
111
|
+
{{steps.s2-resolucion.output}}
|
|
112
|
+
|
|
113
|
+
DATOS DEL CLIENTE:
|
|
114
|
+
- Nombre: {{payload.cliente}}
|
|
115
|
+
- Canal: {{payload.canal}}
|
|
116
|
+
- Plan: {{payload.plan}}
|
|
117
|
+
|
|
118
|
+
Redactar la comunicación completa:
|
|
119
|
+
|
|
120
|
+
## Asunto del email / título de la respuesta
|
|
121
|
+
Claro, específico, que transmita que estamos trabajando en ello.
|
|
122
|
+
|
|
123
|
+
## Cuerpo de la respuesta
|
|
124
|
+
- Apertura: reconocer el problema con empatía (1-2 líneas, sin excesos)
|
|
125
|
+
- Diagnóstico explicado en términos del cliente (no jerga técnica interna)
|
|
126
|
+
- Solución o próximos pasos numerados y claros
|
|
127
|
+
- Tiempo estimado si el problema no está completamente resuelto
|
|
128
|
+
- Cierre: cómo contactarnos si la solución no funciona o hay preguntas
|
|
129
|
+
|
|
130
|
+
## Notas internas (no van al cliente)
|
|
131
|
+
- Información de contexto para el agente que haga seguimiento
|
|
132
|
+
- Acciones pendientes del equipo de soporte
|
|
133
|
+
|
|
134
|
+
- id: s4-kb
|
|
135
|
+
agent: knowledge-agent
|
|
136
|
+
depends_on: [s2-resolucion, s3-comunicacion]
|
|
137
|
+
task: |
|
|
138
|
+
Analizar el ticket resuelto y proponer mejoras a la base de conocimiento.
|
|
139
|
+
|
|
140
|
+
TICKET: {{payload.asunto}}
|
|
141
|
+
TRIAGE: {{steps.s1-triage.output}}
|
|
142
|
+
RESOLUCIÓN: {{steps.s2-resolucion.output}}
|
|
143
|
+
|
|
144
|
+
Evaluar:
|
|
145
|
+
|
|
146
|
+
1. ¿EXISTE ARTÍCULO EN LA KB?
|
|
147
|
+
- SÍ, está actualizado → no se requiere acción
|
|
148
|
+
- SÍ, pero está desactualizado o incompleto → proponer actualización
|
|
149
|
+
- NO → proponer nuevo artículo
|
|
150
|
+
|
|
151
|
+
2. PROPUESTA DE CONTENIDO (si aplica)
|
|
152
|
+
Si se necesita crear o actualizar un artículo, redactar el borrador completo
|
|
153
|
+
siguiendo la estructura: título + descripción del problema + causa + solución
|
|
154
|
+
paso a paso + verificación + casos relacionados.
|
|
155
|
+
|
|
156
|
+
3. MEJORAS AL PROCESO
|
|
157
|
+
Si este ticket reveló un gap en el proceso de atención (pregunta frecuente no
|
|
158
|
+
documentada, procedimiento ambiguo, criterio de escalación poco claro), proponer
|
|
159
|
+
la mejora específica.
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
id: incidente-critico
|
|
3
|
+
name: "Incidente Crítico — {{payload.incidente_id}}"
|
|
4
|
+
description: >
|
|
5
|
+
Gestión de incidentes P1/P2: confirmación y escalación con gate, diagnóstico
|
|
6
|
+
técnico profundo, plan de resolución con gate de aprobación, comunicado externo
|
|
7
|
+
al cliente y postmortem para prevenir recurrencias.
|
|
8
|
+
|
|
9
|
+
steps:
|
|
10
|
+
- id: s1-confirmacion
|
|
11
|
+
agent: triage-agent
|
|
12
|
+
depends_on: []
|
|
13
|
+
gate: true
|
|
14
|
+
gate_criteria:
|
|
15
|
+
- "La prioridad P1/P2 está correctamente justificada con el impacto real"
|
|
16
|
+
- "El alcance del incidente está definido (cuántos clientes, qué funcionalidades)"
|
|
17
|
+
- "Se identificó el canal de comunicación de crisis y los responsables en guardia"
|
|
18
|
+
- "Hay un War Room o canal de coordinación definido"
|
|
19
|
+
task: |
|
|
20
|
+
Confirmar y documentar el incidente crítico para activar el protocolo de respuesta.
|
|
21
|
+
|
|
22
|
+
DATOS DEL INCIDENTE:
|
|
23
|
+
- ID: {{payload.incidente_id}}
|
|
24
|
+
- Reportado por: {{payload.reportado_por}}
|
|
25
|
+
- Fecha/hora de detección: {{payload.hora_deteccion}}
|
|
26
|
+
- Descripción inicial: {{payload.descripcion}}
|
|
27
|
+
- Sistemas afectados: {{payload.sistemas_afectados}}
|
|
28
|
+
- Clientes impactados (estimado): {{payload.clientes_impactados}}
|
|
29
|
+
- Síntomas observados: {{payload.sintomas}}
|
|
30
|
+
|
|
31
|
+
Producir el documento de apertura del incidente:
|
|
32
|
+
|
|
33
|
+
1. CLASIFICACIÓN
|
|
34
|
+
- Prioridad confirmada: P1 / P2 con justificación
|
|
35
|
+
- Tipo de incidente: outage total / degradación / pérdida de datos / seguridad / rendimiento
|
|
36
|
+
- Sistemas afectados con nivel de impacto por sistema
|
|
37
|
+
|
|
38
|
+
2. ALCANCE DEL IMPACTO
|
|
39
|
+
- Clientes afectados (cantidad y segmento)
|
|
40
|
+
- Funcionalidades no disponibles o degradadas
|
|
41
|
+
- Impacto en negocio estimado (revenue, operaciones, reputación)
|
|
42
|
+
|
|
43
|
+
3. HIPÓTESIS INICIALES
|
|
44
|
+
3 hipótesis de causa raíz ordenadas por probabilidad.
|
|
45
|
+
|
|
46
|
+
4. PLAN DE RESPUESTA INMEDIATA
|
|
47
|
+
- Acciones en las próximas 15 minutos
|
|
48
|
+
- Responsable de cada acción (rol)
|
|
49
|
+
- Canal de coordinación del equipo (War Room)
|
|
50
|
+
|
|
51
|
+
5. COMUNICACIÓN INICIAL
|
|
52
|
+
- A quién notificar dentro de la empresa (escalación interna)
|
|
53
|
+
- Si se debe notificar proactivamente a clientes ahora o esperar diagnóstico
|
|
54
|
+
|
|
55
|
+
- id: s2-diagnostico
|
|
56
|
+
agent: technical-agent
|
|
57
|
+
depends_on: [s1-confirmacion]
|
|
58
|
+
task: |
|
|
59
|
+
Realizar el diagnóstico técnico profundo del incidente.
|
|
60
|
+
|
|
61
|
+
DOCUMENTO DE APERTURA DEL INCIDENTE:
|
|
62
|
+
{{steps.s1-confirmacion.output}}
|
|
63
|
+
|
|
64
|
+
INFORMACIÓN TÉCNICA DISPONIBLE:
|
|
65
|
+
- Sistemas afectados: {{payload.sistemas_afectados}}
|
|
66
|
+
- Síntomas: {{payload.sintomas}}
|
|
67
|
+
- Logs o errores disponibles: {{payload.logs}}
|
|
68
|
+
- Cambios recientes en producción: {{payload.cambios_recientes}}
|
|
69
|
+
|
|
70
|
+
Producir el diagnóstico técnico:
|
|
71
|
+
|
|
72
|
+
1. ANÁLISIS DE CAUSA RAÍZ
|
|
73
|
+
Evaluación de cada hipótesis con la evidencia disponible.
|
|
74
|
+
Conclusión: causa raíz confirmada o hipótesis más probable con nivel de confianza.
|
|
75
|
+
|
|
76
|
+
2. ÁRBOL DE IMPACTO
|
|
77
|
+
Qué sistemas dependen del sistema afectado y cómo se propaga el fallo.
|
|
78
|
+
|
|
79
|
+
3. OPCIONES DE RESOLUCIÓN
|
|
80
|
+
Para cada opción: descripción, tiempo estimado, riesgo, impacto secundario.
|
|
81
|
+
- Opción A (más rápida): workaround o rollback
|
|
82
|
+
- Opción B (más definitiva): fix en producción
|
|
83
|
+
- Opción C (si aplica): fallback o degraded mode
|
|
84
|
+
|
|
85
|
+
4. RECOMENDACIÓN
|
|
86
|
+
Qué opción ejecutar primero y por qué, con los pasos concretos.
|
|
87
|
+
|
|
88
|
+
5. RIESGOS DE LA INTERVENCIÓN
|
|
89
|
+
Qué puede salir mal al aplicar la solución y cómo mitigarlo.
|
|
90
|
+
|
|
91
|
+
- id: s3-plan-resolucion
|
|
92
|
+
agent: escalation-agent
|
|
93
|
+
depends_on: [s2-diagnostico]
|
|
94
|
+
gate: true
|
|
95
|
+
gate_criteria:
|
|
96
|
+
- "La opción de resolución elegida está aprobada por el responsable técnico"
|
|
97
|
+
- "Hay un rollback plan definido si la solución empeora el incidente"
|
|
98
|
+
- "El tiempo estimado de resolución está actualizado y es realista"
|
|
99
|
+
- "Se definió quién ejecuta cada paso (no puede quedar sin responsable asignado)"
|
|
100
|
+
task: |
|
|
101
|
+
Diseñar y coordinar el plan de resolución del incidente.
|
|
102
|
+
|
|
103
|
+
DIAGNÓSTICO TÉCNICO:
|
|
104
|
+
{{steps.s2-diagnostico.output}}
|
|
105
|
+
|
|
106
|
+
CONTEXTO DEL INCIDENTE:
|
|
107
|
+
ID: {{payload.incidente_id}} | Sistemas: {{payload.sistemas_afectados}}
|
|
108
|
+
Clientes impactados: {{payload.clientes_impactados}}
|
|
109
|
+
|
|
110
|
+
Producir el plan de resolución:
|
|
111
|
+
|
|
112
|
+
1. DECISIÓN DE RESOLUCIÓN
|
|
113
|
+
Opción elegida con justificación y aprobación requerida.
|
|
114
|
+
|
|
115
|
+
2. RUNBOOK DE EJECUCIÓN
|
|
116
|
+
Pasos numerados con:
|
|
117
|
+
- Acción específica
|
|
118
|
+
- Responsable (rol)
|
|
119
|
+
- Tiempo estimado
|
|
120
|
+
- Criterio de verificación (cómo saber que el paso funcionó)
|
|
121
|
+
|
|
122
|
+
3. ROLLBACK PLAN
|
|
123
|
+
Si el fix empeora el incidente, qué hacer en los primeros 5 minutos.
|
|
124
|
+
|
|
125
|
+
4. CRITERIO DE RESOLUCIÓN
|
|
126
|
+
Cómo sabemos que el incidente está cerrado (métricas, checks, confirmación).
|
|
127
|
+
|
|
128
|
+
5. COMUNICACIÓN DURANTE LA RESOLUCIÓN
|
|
129
|
+
- Cada cuánto actualizar a clientes (ej: cada 30 minutos)
|
|
130
|
+
- Qué decirle al equipo interno
|
|
131
|
+
- Cuándo declarar "resuelto" públicamente
|
|
132
|
+
|
|
133
|
+
6. EQUIPO DE GUARDIA
|
|
134
|
+
Roles y responsabilidades durante la ejecución del plan.
|
|
135
|
+
|
|
136
|
+
- id: s4-comunicado-externo
|
|
137
|
+
agent: communication-agent
|
|
138
|
+
depends_on: [s1-confirmacion, s3-plan-resolucion]
|
|
139
|
+
task: |
|
|
140
|
+
Redactar las comunicaciones externas para el incidente {{payload.incidente_id}}.
|
|
141
|
+
|
|
142
|
+
CONTEXTO DEL INCIDENTE:
|
|
143
|
+
{{steps.s1-confirmacion.output}}
|
|
144
|
+
|
|
145
|
+
PLAN DE RESOLUCIÓN:
|
|
146
|
+
{{steps.s3-plan-resolucion.output}}
|
|
147
|
+
|
|
148
|
+
Redactar los 3 comunicados necesarios:
|
|
149
|
+
|
|
150
|
+
## 1. COMUNICADO DE APERTURA (enviar ahora)
|
|
151
|
+
- Qué está pasando (sin jerga técnica, en términos de impacto al cliente)
|
|
152
|
+
- Qué estamos haciendo para resolverlo
|
|
153
|
+
- Tiempo estimado de resolución (dar rango, no promesas exactas)
|
|
154
|
+
- Dónde ver actualizaciones (status page, canal de comunicación)
|
|
155
|
+
- Contacto para urgencias
|
|
156
|
+
|
|
157
|
+
## 2. ACTUALIZACIONES DE PROGRESO (template reutilizable)
|
|
158
|
+
Template con placeholders para actualizar cada 30 minutos durante el incidente:
|
|
159
|
+
- [HORA] Estado actual
|
|
160
|
+
- [AVANCE] Qué se hizo
|
|
161
|
+
- [PRÓXIMOS PASOS] Qué sigue
|
|
162
|
+
- [ETA] Estimación actualizada
|
|
163
|
+
|
|
164
|
+
## 3. COMUNICADO DE CIERRE
|
|
165
|
+
- Confirmación de que el incidente fue resuelto
|
|
166
|
+
- Descripción breve de qué pasó y cómo se resolvió (sin exponer vulnerabilidades)
|
|
167
|
+
- Medidas tomadas para que no vuelva a ocurrir
|
|
168
|
+
- Disculpas y reconocimiento del impacto
|
|
169
|
+
- Crédito/compensación si aplica según política
|
|
170
|
+
|
|
171
|
+
- id: s5-postmortem
|
|
172
|
+
agent: technical-agent
|
|
173
|
+
depends_on: [s2-diagnostico, s3-plan-resolucion, s4-comunicado-externo]
|
|
174
|
+
task: |
|
|
175
|
+
Redactar el documento de postmortem del incidente {{payload.incidente_id}}.
|
|
176
|
+
|
|
177
|
+
DIAGNÓSTICO TÉCNICO:
|
|
178
|
+
{{steps.s2-diagnostico.output}}
|
|
179
|
+
|
|
180
|
+
PLAN Y RESOLUCIÓN:
|
|
181
|
+
{{steps.s3-plan-resolucion.output}}
|
|
182
|
+
|
|
183
|
+
DATOS DEL INCIDENTE:
|
|
184
|
+
- Hora de detección: {{payload.hora_deteccion}}
|
|
185
|
+
- Sistemas afectados: {{payload.sistemas_afectados}}
|
|
186
|
+
- Clientes impactados: {{payload.clientes_impactados}}
|
|
187
|
+
|
|
188
|
+
Estructura del postmortem (blameless — sin culpables, solo sistemas y procesos):
|
|
189
|
+
|
|
190
|
+
## Resumen Ejecutivo
|
|
191
|
+
3-4 líneas: qué pasó, cuánto duró, impacto total.
|
|
192
|
+
|
|
193
|
+
## Timeline
|
|
194
|
+
Cronología minuto a minuto desde la detección hasta la resolución.
|
|
195
|
+
|
|
196
|
+
## Causa Raíz
|
|
197
|
+
Causa técnica confirmada. Usar "5 Whys" para llegar al root cause real.
|
|
198
|
+
|
|
199
|
+
## Factores Contribuyentes
|
|
200
|
+
Condiciones que hicieron posible o empeoraron el incidente.
|
|
201
|
+
|
|
202
|
+
## Qué Funcionó Bien
|
|
203
|
+
Partes del proceso de respuesta que fueron efectivas.
|
|
204
|
+
|
|
205
|
+
## Qué No Funcionó
|
|
206
|
+
Gaps en detección, respuesta, comunicación o herramientas.
|
|
207
|
+
|
|
208
|
+
## Acciones Correctivas
|
|
209
|
+
Lista priorizada de mejoras con responsable y fecha límite:
|
|
210
|
+
- Acciones de remediación inmediata (ya implementadas)
|
|
211
|
+
- Acciones de prevención a corto plazo (< 2 semanas)
|
|
212
|
+
- Acciones estructurales a mediano plazo (< 3 meses)
|
|
213
|
+
|
|
214
|
+
## Métricas del Incidente
|
|
215
|
+
- MTTD (Mean Time to Detect)
|
|
216
|
+
- MTTA (Mean Time to Acknowledge)
|
|
217
|
+
- MTTR (Mean Time to Resolve)
|
|
218
|
+
- Clientes impactados y duración del impacto
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
|
|
3
|
+
orchestrator:
|
|
4
|
+
name: "Orquestador de Soporte al Cliente"
|
|
5
|
+
provider: __PROVIDER_ID__
|
|
6
|
+
vault:
|
|
7
|
+
path: ./vault
|
|
8
|
+
embedder: simple # change to "ollama" in production for better semantic search
|
|
9
|
+
|
|
10
|
+
__PROVIDERS_BLOCK__
|
|
11
|
+
|
|
12
|
+
flows:
|
|
13
|
+
- id: atencion-ticket
|
|
14
|
+
file: ./flows/atencion-ticket.yaml
|
|
15
|
+
trigger: "ticket|soporte|consulta|problema|error|bug|incidencia|reclamo|ayuda|no funciona|falla"
|
|
16
|
+
|
|
17
|
+
- id: incidente-critico
|
|
18
|
+
file: ./flows/incidente-critico.yaml
|
|
19
|
+
trigger: "incidente|crítico|caído|urgente|p1|p2|emergencia|producción|caída del sistema|outage"
|
|
20
|
+
|
|
21
|
+
agents:
|
|
22
|
+
- id: triage-agent
|
|
23
|
+
name: "Agente de Triage"
|
|
24
|
+
description: >
|
|
25
|
+
Clasifica y prioriza tickets de soporte entrantes. Determina la urgencia (P1-P4),
|
|
26
|
+
el tipo de issue (bug, consulta, facturación, feature request), el área de producto
|
|
27
|
+
afectada y el nivel de soporte requerido (L1/L2/L3). Genera el contexto inicial
|
|
28
|
+
para el agente que tomará el ticket.
|
|
29
|
+
capabilities: [triage, clasificacion, prioridad, sla, routing, diagnostico-inicial]
|
|
30
|
+
provider: __PROVIDER_ID__
|
|
31
|
+
domain: soporte
|
|
32
|
+
|
|
33
|
+
- id: support-agent
|
|
34
|
+
name: "Agente de Soporte L1"
|
|
35
|
+
description: >
|
|
36
|
+
Maneja tickets de soporte de nivel 1: consultas frecuentes, configuraciones estándar,
|
|
37
|
+
procedimientos documentados y troubleshooting básico. Usa la base de conocimiento para
|
|
38
|
+
dar respuestas precisas y consistentes. Si no puede resolver, prepara el contexto
|
|
39
|
+
para escalación a L2 con toda la información necesaria.
|
|
40
|
+
capabilities: [l1, soporte, faq, troubleshooting, kb, resolucion, guia-paso-a-paso]
|
|
41
|
+
provider: __PROVIDER_ID__
|
|
42
|
+
domain: soporte
|
|
43
|
+
|
|
44
|
+
- id: technical-agent
|
|
45
|
+
name: "Agente Técnico L2"
|
|
46
|
+
description: >
|
|
47
|
+
Investigación técnica profunda de issues complejos. Diagnóstico de root cause,
|
|
48
|
+
análisis de logs, identificación de bugs, propuesta de workarounds y soluciones
|
|
49
|
+
definitivas. Documenta hallazgos técnicos para el equipo de ingeniería y para
|
|
50
|
+
enriquecer la base de conocimiento.
|
|
51
|
+
capabilities: [l2, tecnico, diagnostico, root-cause, logs, bugs, workaround, ingenieria]
|
|
52
|
+
provider: __PROVIDER_ID__
|
|
53
|
+
domain: soporte
|
|
54
|
+
gate: true
|
|
55
|
+
gate_criteria:
|
|
56
|
+
- "El diagnóstico incluye el root cause o una hipótesis sólida con evidencia"
|
|
57
|
+
- "Se propone al menos un workaround inmediato para desbloquear al cliente"
|
|
58
|
+
- "La solución propuesta no implica cambios de datos o configuración sin respaldo"
|
|
59
|
+
- "Se documentaron los pasos de reproducción del issue"
|
|
60
|
+
|
|
61
|
+
- id: escalation-agent
|
|
62
|
+
name: "Agente de Escalación L3"
|
|
63
|
+
description: >
|
|
64
|
+
Gestiona incidentes críticos y escalaciones a ingeniería. Coordina la respuesta
|
|
65
|
+
ante outages, define el plan de acción con responsables y tiempos, y asegura que
|
|
66
|
+
se mantenga informado al cliente durante todo el incidente. Lidera el proceso de
|
|
67
|
+
postmortem y seguimiento de acciones correctivas.
|
|
68
|
+
capabilities: [l3, escalacion, incidente, outage, coordinacion, postmortem, p1, p2]
|
|
69
|
+
provider: __PROVIDER_ID__
|
|
70
|
+
domain: soporte
|
|
71
|
+
gate: true
|
|
72
|
+
gate_criteria:
|
|
73
|
+
- "La escalación a ingeniería está justificada y el impacto está cuantificado"
|
|
74
|
+
- "Hay un responsable asignado (nombre o rol) para cada acción del plan"
|
|
75
|
+
- "El cliente fue notificado del incidente y del tiempo estimado de resolución"
|
|
76
|
+
- "Se definió el criterio de resolución: cómo sabemos que el incidente está cerrado"
|
|
77
|
+
|
|
78
|
+
- id: communication-agent
|
|
79
|
+
name: "Agente de Comunicación"
|
|
80
|
+
description: >
|
|
81
|
+
Redacta todas las comunicaciones hacia el cliente: respuestas a tickets, actualizaciones
|
|
82
|
+
de estado durante incidentes, emails de cierre, solicitudes de información adicional y
|
|
83
|
+
encuestas de satisfacción. Adapta el tono y nivel técnico al perfil del cliente.
|
|
84
|
+
Asegura que cada comunicación sea clara, empática y accionable.
|
|
85
|
+
capabilities: [comunicacion, redaccion, email, respuesta-cliente, estado, cierre, empatia]
|
|
86
|
+
provider: __PROVIDER_ID__
|
|
87
|
+
domain: soporte
|
|
88
|
+
|
|
89
|
+
- id: knowledge-agent
|
|
90
|
+
name: "Agente de Base de Conocimiento"
|
|
91
|
+
description: >
|
|
92
|
+
Mantiene y mejora la base de conocimiento de soporte. Identifica gaps de documentación
|
|
93
|
+
a partir de tickets resueltos, propone nuevos artículos o actualizaciones de los
|
|
94
|
+
existentes, y sugiere mejoras en los procedimientos de atención para reducir el tiempo
|
|
95
|
+
de resolución en futuros tickets similares.
|
|
96
|
+
capabilities: [knowledge-base, documentacion, kb, articulos, mejora-continua, procedimientos]
|
|
97
|
+
provider: __PROVIDER_ID__
|
|
98
|
+
domain: soporte
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Test runner for the soporte orchestrator
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* node test-flow.mjs atencion-ticket # standard ticket (triage → L1 → gate → KB)
|
|
7
|
+
* node test-flow.mjs incidente-critico # P1 incident (gate → diagnosis → gate → comms → postmortem)
|
|
8
|
+
* node test-flow.mjs dynamic # dynamic planning (no flow match)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { spawn } from 'node:child_process';
|
|
12
|
+
import { createInterface } from 'node:readline';
|
|
13
|
+
import * as path from 'node:path';
|
|
14
|
+
import * as fs from 'node:fs';
|
|
15
|
+
import * as url from 'node:url';
|
|
16
|
+
|
|
17
|
+
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
|
|
18
|
+
const CONFIG_PATH = path.resolve(__dirname, 'orchestrator.yaml');
|
|
19
|
+
const SERVER_PATH = path.resolve(
|
|
20
|
+
__dirname,
|
|
21
|
+
'node_modules/@backendkit-labs/orchestrator-agent/dist/server.js',
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
// ── Sample payloads ───────────────────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
const FLOWS = {
|
|
27
|
+
'atencion-ticket': {
|
|
28
|
+
flow_id: 'atencion-ticket',
|
|
29
|
+
task: 'Atender ticket de soporte: error al exportar reportes en formato Excel',
|
|
30
|
+
payload: {
|
|
31
|
+
ticket_id: 'TKT-2024-1547',
|
|
32
|
+
cliente: 'Acme Corp',
|
|
33
|
+
plan: 'Professional',
|
|
34
|
+
canal: 'Portal de soporte',
|
|
35
|
+
asunto: 'Error al exportar reportes en formato Excel — aparece "Download failed"',
|
|
36
|
+
descripcion: 'Desde ayer a la tarde, cuando intento descargar cualquier reporte en formato Excel (no en CSV), me aparece el mensaje "Download failed" y no se genera ningún archivo. El botón de descarga en PDF sí funciona bien. Lo probé en Chrome y Firefox con el mismo resultado. Necesito los reportes para una reunión de directorio mañana a las 10hs.',
|
|
37
|
+
entorno: 'Chrome 124, Windows 11, cuenta admin. La sesión expira correctamente y puedo hacer todo lo demás en la plataforma sin problemas.',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
'incidente-critico': {
|
|
41
|
+
flow_id: 'incidente-critico',
|
|
42
|
+
task: 'Gestionar incidente crítico: plataforma inaccesible para clientes Enterprise',
|
|
43
|
+
payload: {
|
|
44
|
+
incidente_id: 'INC-2024-003',
|
|
45
|
+
reportado_por: 'Sistema de monitoreo + 3 clientes Enterprise simultáneamente',
|
|
46
|
+
hora_deteccion: '2024-06-14 09:23 ART',
|
|
47
|
+
descripcion: 'La plataforma devuelve error 503 para todos los usuarios. El health check de la API principal está fallando. Múltiples clientes Enterprise están llamando al número de emergencias.',
|
|
48
|
+
sistemas_afectados: 'API principal (/api/v3/*), Dashboard web, Mobile app. La base de datos parece responder (status page de RDS en verde).',
|
|
49
|
+
clientes_impactados: 'Estimado 100% de usuarios activos en este momento (~340 sesiones activas según los últimos logs disponibles)',
|
|
50
|
+
sintomas: 'HTTP 503 en todas las rutas de la API. Los worker processes de Node.js no están respondiendo. Los logs muestran "FATAL: Cannot allocate memory" repetidamente desde las 09:18.',
|
|
51
|
+
logs: 'FATAL: Cannot allocate memory in static TLS block\nnode: Cannot allocate memory\nAborted (core dumped)\nRestarting worker... (intent 47 en los últimos 5 minutos)',
|
|
52
|
+
cambios_recientes: 'Deploy de v3.4.1 a las 08:45 (35 minutos antes del incidente). El deploy incluyó actualización de una dependencia de procesamiento de imágenes.',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
'dynamic': {
|
|
56
|
+
flow_id: undefined,
|
|
57
|
+
task: process.env.TASK ?? 'Analizar los tickets de la última semana e identificar los 3 problemas más frecuentes que deberían documentarse como artículos de KB',
|
|
58
|
+
payload: {},
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// ── MCP Client (stdio) ────────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
class McpClient {
|
|
65
|
+
constructor(serverPath) {
|
|
66
|
+
this._nextId = 1;
|
|
67
|
+
this._pending = new Map();
|
|
68
|
+
|
|
69
|
+
const env = { ...process.env };
|
|
70
|
+
const dotenv = path.join(__dirname, '.env');
|
|
71
|
+
if (fs.existsSync(dotenv)) {
|
|
72
|
+
for (const line of fs.readFileSync(dotenv, 'utf-8').split('\n')) {
|
|
73
|
+
const m = line.match(/^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*?)\s*$/);
|
|
74
|
+
if (m && m[2] && !(m[1] in env)) env[m[1]] = m[2].replace(/^["']|["']$/g, '');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this._proc = spawn('node', [serverPath], { stdio: ['pipe', 'pipe', 'inherit'], env });
|
|
79
|
+
|
|
80
|
+
const rl = createInterface({ input: this._proc.stdout });
|
|
81
|
+
rl.on('line', (line) => {
|
|
82
|
+
if (!line.trim()) return;
|
|
83
|
+
try {
|
|
84
|
+
const msg = JSON.parse(line);
|
|
85
|
+
if (msg.id !== undefined && this._pending.has(msg.id)) {
|
|
86
|
+
const { resolve, reject } = this._pending.get(msg.id);
|
|
87
|
+
this._pending.delete(msg.id);
|
|
88
|
+
if (msg.error) reject(new Error(msg.error.message ?? JSON.stringify(msg.error)));
|
|
89
|
+
else resolve(msg.result);
|
|
90
|
+
}
|
|
91
|
+
} catch {}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
this._proc.on('error', (err) => console.error('[MCP] error:', err.message));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_send(msg) { this._proc.stdin.write(JSON.stringify(msg) + '\n'); }
|
|
98
|
+
|
|
99
|
+
async initialize() {
|
|
100
|
+
const id = this._nextId++;
|
|
101
|
+
const p = new Promise((res, rej) => this._pending.set(id, { resolve: res, reject: rej }));
|
|
102
|
+
this._send({ jsonrpc: '2.0', id, method: 'initialize', params: {
|
|
103
|
+
protocolVersion: '2024-11-05', capabilities: {},
|
|
104
|
+
clientInfo: { name: 'test-flow', version: '0.1.0' },
|
|
105
|
+
}});
|
|
106
|
+
await p;
|
|
107
|
+
this._send({ jsonrpc: '2.0', method: 'notifications/initialized', params: {} });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async callTool(name, args) {
|
|
111
|
+
const id = this._nextId++;
|
|
112
|
+
const p = new Promise((res, rej) => {
|
|
113
|
+
this._pending.set(id, { resolve: res, reject: rej });
|
|
114
|
+
setTimeout(() => {
|
|
115
|
+
if (this._pending.has(id)) { this._pending.delete(id); rej(new Error(`Timeout: ${name}`)); }
|
|
116
|
+
}, 120_000);
|
|
117
|
+
});
|
|
118
|
+
this._send({ jsonrpc: '2.0', id, method: 'tools/call', params: { name, arguments: args } });
|
|
119
|
+
return p;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
close() { this._proc.stdin.end(); }
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
126
|
+
|
|
127
|
+
const extractText = (r) => r?.content?.filter(c => c.type === 'text').map(c => c.text).join('\n') ?? String(r);
|
|
128
|
+
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
|
|
129
|
+
|
|
130
|
+
function printSection(title, text) {
|
|
131
|
+
const line = '─'.repeat(60);
|
|
132
|
+
console.log(`\n${line}\n ${title}\n${line}`);
|
|
133
|
+
console.log(text);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ── Main ──────────────────────────────────────────────────────────────────────
|
|
137
|
+
|
|
138
|
+
async function main() {
|
|
139
|
+
const flowKey = process.argv[2] ?? 'atencion-ticket';
|
|
140
|
+
const flowDef = FLOWS[flowKey];
|
|
141
|
+
if (!flowDef) {
|
|
142
|
+
console.error(`Unknown flow: ${flowKey}\nOptions: ${Object.keys(FLOWS).join(', ')}`);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
if (!fs.existsSync(SERVER_PATH)) {
|
|
146
|
+
console.error(`Server not found:\n ${SERVER_PATH}\nRun: npm install`);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
console.log(`\nStarting orchestrator (soporte)...`);
|
|
151
|
+
console.log(` Flow: ${flowKey}`);
|
|
152
|
+
|
|
153
|
+
const client = new McpClient(SERVER_PATH);
|
|
154
|
+
try {
|
|
155
|
+
await client.initialize();
|
|
156
|
+
console.log(' MCP: connected ✓\n');
|
|
157
|
+
|
|
158
|
+
const runArgs = { config_path: CONFIG_PATH, task: flowDef.task };
|
|
159
|
+
if (flowDef.flow_id) runArgs.flow_id = flowDef.flow_id;
|
|
160
|
+
if (Object.keys(flowDef.payload).length > 0) runArgs.payload = flowDef.payload;
|
|
161
|
+
|
|
162
|
+
const startText = extractText(await client.callTool('orchestrator_run', runArgs));
|
|
163
|
+
printSection('RUN STARTED', startText);
|
|
164
|
+
|
|
165
|
+
const runIdMatch = startText.match(/runId:\s*`?([a-z0-9-]+)`?/i);
|
|
166
|
+
if (!runIdMatch) { console.error('\n[ERROR] Could not extract runId.'); process.exit(1); }
|
|
167
|
+
const runId = runIdMatch[1];
|
|
168
|
+
|
|
169
|
+
let attempts = 0, lastStatus = '';
|
|
170
|
+
console.log(`\nPolling (runId: ${runId})...\n`);
|
|
171
|
+
|
|
172
|
+
while (attempts < 80) {
|
|
173
|
+
await sleep(5000);
|
|
174
|
+
attempts++;
|
|
175
|
+
|
|
176
|
+
const statusText = extractText(await client.callTool('orchestrator_status', {
|
|
177
|
+
config_path: CONFIG_PATH, run_id: runId,
|
|
178
|
+
}));
|
|
179
|
+
const status = statusText.match(/status:\s*\*\*([^*]+)\*\*/)?.[1]
|
|
180
|
+
?? statusText.match(/^status:\s*(\S+)/m)?.[1]
|
|
181
|
+
?? 'unknown';
|
|
182
|
+
|
|
183
|
+
if (status !== lastStatus) {
|
|
184
|
+
process.stdout.write(` [${new Date().toLocaleTimeString()}] status: ${status}\n`);
|
|
185
|
+
lastStatus = status;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (status === 'complete') { printSection('RESULT', statusText); break; }
|
|
189
|
+
if (status === 'failed') { printSection('ERROR', statusText); break; }
|
|
190
|
+
|
|
191
|
+
if (status === 'waiting_gate') {
|
|
192
|
+
printSection('GATE — APPROVAL REQUIRED', statusText);
|
|
193
|
+
console.log('\nAuto-approving...\n');
|
|
194
|
+
await sleep(2000);
|
|
195
|
+
const approveText = extractText(await client.callTool('orchestrator_approve', {
|
|
196
|
+
config_path: CONFIG_PATH, run_id: runId,
|
|
197
|
+
approved: true, notes: 'Auto-approved by test-flow.mjs',
|
|
198
|
+
}));
|
|
199
|
+
printSection('GATE APPROVED', approveText);
|
|
200
|
+
lastStatus = '';
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (attempts >= 80) console.log('\n[TIMEOUT] Check orchestrator_status manually.');
|
|
205
|
+
} finally {
|
|
206
|
+
client.close();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
main().catch(err => { console.error('\n[FATAL]', err.message); process.exit(1); });
|