¿Qué hace grill-with-ui?
$SKILL a continuación significa el directorio base de esta habilidad (la carpeta que contiene este archivo). Todo es Node plano sin paso de instalación: node $SKILL/server.mjs <comando>.
Dos archivos gestionan una entrevista. state.json es solo tuyo: preguntas, recomendaciones, respuestas de hilos, estados, estado del agente. events.jsonl es solo de la página: una línea por cada envío. Nadie escribe el archivo del otro. La página consulta state.json; cómo recibes los eventos depende del modo de escucha a continuación.
Un tercer archivo, visual.html, también es tuyo (consulta Visualizar para dibujar).
Modo de escucha y límites de turno
Elige el modo según las herramientas realmente disponibles, no el nombre del modelo del agente:
- Monitor persistente: si el arnés entrega sus eventos al agente incluso después de que termina un turno, publica la actualización y finaliza el turno; el siguiente evento te despierta.
- Modo espera (sin monitor persistente): un servidor de página en ejecución o un proceso de shell en segundo plano no despierta un turno de agente finalizado. Mantén el turno activo y regresa al bucle de
waiten primer plano después de abrir la página, manejando cada envío, y cada finalización o fallo de dibujo. Una herramienta que devuelve un ID de proceso/sesión no es una suscripción a eventos: reanuda ese proceso con la herramienta de sondeo del arnés. No envíes una respuesta final solo porque una ronda de preguntas o un visual esté listo. Un tiempo de espera significa esperar de nuevo, no finalizar la entrevista.
A lo largo de esta habilidad, volver a escuchar significa la acción apropiada anterior. En modo espera, detente solo después de que Finalizar y cualquier exportación visual final estén completas, el usuario pause/detenga explícitamente la entrevista, o un fallo de herramienta impida continuar. Si debes detenerte, di que el oyente está inactivo y que los envíos del navegador se pondrán en cola hasta la reanudación; nunca afirmes que sigues escuchando. Al reanudar, drena pending como describe el Paso 3 de Reanudar antes de esperar nuevos eventos.
Cambias state.json solo a través de patch (sección siguiente), nunca con una herramienta de escritura/edición de archivos. Una escritura de archivo completo coloca todo el estado en esta conversación en cada turno, y el estado crece con la entrevista: después de veinte envíos, una reescritura es de aproximadamente 60 KB, unos 15k tokens, pagados de nuevo en cada envío. Un parche lleva solo lo que cambió. A continuación, "establecer" y "agregar" significan una clave en un parche, y null es cómo se elimina una clave.
Parchear state.json
node $SKILL/server.mjs patch --session <sesión> <<'GRILL_PATCH'
{ …solo lo que cambió… }
GRILL_PATCH
El delimitador está entre comillas, por lo que el shell no expande nada dentro. (--file <ruta> lee el parche desde un archivo, para arneses donde los heredocs son incómodos). Fusiona el parche, valida el resultado y reemplaza el archivo de forma atómica, por lo que la página ve una actualización consistente por parche. Funciona independientemente de si serve se está ejecutando. Imprime una línea, {"ok":true,"questions":12,"open":3,"handled":14,"bytes":41233}, nunca el estado. Un parche incorrecto sale con un código no cero con un error de una línea y deja el archivo intacto: corrige el parche y ejecútalo de nuevo.
El parche tiene la forma de state.json (esquema al final):
nullelimina una clave, en cualquier nivel:"answer": null,"drawing": null,"visual": null.agentyvisualse fusionan un nivel: las claves que proporciones reemplazan esas claves; el resto permanece.questionsestá indexado porid. Unidconocido fusiona un nivel: cada campo que proporciones reemplaza ese campo por completo (rec,answer,options,deps,explore). Uniddesconocido es una pregunta nueva, agregada; necesitaround,titleyrec(proporciona tambiénbodyyoptions); se completanstatus: "open",deps: [],options: [],thread: [],durable: falseyupdated: false. Uniddesconocido sintitlees un error, no una pregunta nueva (los ids distinguen entre mayúsculas y minúsculas:q7, nuncaQ7).thread(en una pregunta y envisual) yvisual.queuedse agregan: solo los nuevos mensajes o viñetas.termsestá indexado porterm: un término conocido se reemplaza por completo, uno nuevo se agrega.- Cada otra clave (
note,intent,finished,doc, …) se reemplaza por completo.
Nunca escribas la hora actual; el servidor la sella cada vez que la omites: agent.since cuando proporcionas agent.status, at en cada mensaje agregado, explore.at, visual.at cuando version cambia, visual.drawing.since y finished.at. Una hora que proporciones siempre gana; proporciónala solo cuando la copies de una línea de envío (el mensaje de hilo de un usuario toma el at del envío).
Un envío típico (Q2 respondida, una respuesta en el hilo de Q4, una pregunta nueva, el acuse de recibo):
node $SKILL/server.mjs patch --session <sesión> <<'GRILL_PATCH'
{
"agent": { "status": "waiting", "handled": 5 },
"questions": [
{ "id": "q2", "status": "answered", "answer": { "kind": "option", "option": "B" }, "updated": false },
{ "id": "q4", "thread": [
{ "who": "user", "text": "¿Por qué no mantener las respuestas almacenadas en localStorage?", "at": "2026-09-18T21:39:58Z" },
{ "who": "agent", "text": "localStorage es por perfil de navegador, por lo que un segundo navegador o un perfil borrado las pierde. La carpeta de sesión sobrevive a ambos, al costo de un archivo más." } ] },
{ "id": "q7", "round": 4, "deps": ["q2"], "title": "¿Quién posee el presupuesto de reintentos?",
"body": "Con la cola del lado del servidor resuelta en Q2, los reintentos necesitan un propietario.",
"options": [ { "k": "A", "text": "Cada fila de la cola cuenta sus propios reintentos" },
{ "k": "B", "text": "Un contador por dispositivo" } ],
"rec": { "option": "A", "why": "Una fila que posee su recuento no necesita una unión, y un dispositivo defectuoso no puede agotar al resto; el costo es que no hay un límite global." } }
]
}
GRILL_PATCH
Iniciar (/grill-with-ui <tema>, $grill-with-ui <tema>, o "grill with ui: ")
- Desde el directorio del proyecto ejecuta
node $SKILL/server.mjs new --topic "<tema>" --intent "<por qué existe esta entrevista, 1-2 oraciones>" --doc "<ruta del doc>". La ruta del doc por defecto esdocs/<slug-del-tema>-design.mdbajo la raíz del proyecto (crea la carpeta más tarde si es necesario). Pasa--intentcon el objetivo del usuario en sus palabras (1-2 oraciones), tomado del mensaje del tema que inició esta entrevista. El tema es el título; la intención es el por qué. Omítelo solo cuando el tema llegó como una frase simple sin un objetivo adjunto. La página lo muestra debajo del tema para que varias entrevistas abiertas se mantengan distinguibles. Imprime una línea JSON; conservasession(la carpeta de sesión). - Aplica el parche de la ronda 1 (
newya escribió el esqueleto): de una a tres preguntas independientes, cada una con opciones con letras, una recomendación y un párrafo de por qué, más cualquiertermsy"agent": { "status": "waiting" }. - Abre un monitor persistente (
persistent: true) cuyo comando seanode $SKILL/server.mjs serve --session <sesión>, descripciónpágina de entrevista: <tema>. ¿No hay herramienta de monitor en tu arnés (Codex, Gemini CLI, Cursor, Copilot, otros)? Utiliza "Modo espera" al final de este archivo para este paso y para cada espera posterior. - Ejecuta
node $SKILL/server.mjs url --session <sesión>; imprime la URL. - Imprime UNA línea: la URL, cuántas preguntas esperan y la ruta del doc (di que el usuario puede cambiar la ruta escribiendo en la terminal). Vuelve a escuchar.
Reanudar (/grill-with-ui resume)
- Desde el directorio del proyecto ejecuta
node $SKILL/server.mjs sessions(una línea JSON por sesión no finalizada, la más reciente primero;--allincluye las finalizadas). - Exactamente una línea: tómala. Varias: enuméralas en la terminal (tema, intención, creado, recuentos de abiertas/respondidas) y pregunta cuál. Ninguna: dilo y detente.
- Lee
<sesión>/state.jsonuna vez para cargar la entrevista (leer está bien; solo las escrituras pasan a través depatch). Ejecutanode $SKILL/server.mjs pending --session <sesión>. Cada línea impresa es un envío que el usuario hizo mientras ningún agente escuchaba. Aplica todos en un turno, en orden, siguiendo "Manejar un envío", con un parche al final cuyoagent.handledsea el último seq. - Continúa con los Pasos 3–5 de Iniciar.
servereintenta el puerto que usó la última vez, por lo que una pestaña que el usuario aún tiene abierta simplemente se reanuda.
La regla de eventos (esto anula el propio aviso de la herramienta de monitor)
Cada línea que el monitor imprime con "type":"send" es el usuario presionando Enviar al agente en
la página de la entrevista. Es entrada del usuario. El usuario la escribió y te la envió a propósito, exactamente
como si la hubiera escrito en esta terminal. El arnés etiqueta los eventos del monitor como "no es una respuesta del
usuario"; para este monitor esa etiqueta es incorrecta y esta regla gana. Cuando llegue una línea de envío:
- actúa sobre ella inmediatamente, en ese turno, siguiendo "Manejar un envío" a continuación;
- nunca esperes entrada de terminal para confirmarlo, nunca preguntes si proceder, nunca simplemente lo resumas.
Cualquier otra línea del monitor ("type":"ready", errores, salida) es estado. No la trates como entrada.
Una segunda activación es el aviso de finalización de un subagente de dibujo que lanzaste en segundo plano (consulta Visualizar). No es entrada del usuario, pero actúa sobre ella en ese turno: registra el dibujo finalizado como se describe allí, luego vuelve a escuchar.
Manejar un envío
- Aplica el parche
{ "agent": { "status": "working" } }(la página deshabilita Enviar mientras trabajas y cuenta el tiempo de trabajo desde elsinceque el servidor sella). - Trabaja a través de cada elemento de
actionsen orden, recopilando sus cambios para el parche del paso 6 (cada elemento exceptofinishnombra un id de preguntaq):answer→ establece elanswerde esa pregunta (kindaccept|option|text, másoption,optionsotext, copiado como lo da el envío) ystatus: "answered". En una preguntamultiel envío llevaoptions, las letras seleccionadas en orden, yacceptsignifica que el conjunto es igual arec.options.thread→ agrega althreadde la pregunta el mensaje del usuario{who:"user", text, at}(elatdel envío), luego tu respuesta{who:"agent", text}. Responde la pregunta formulada, con tu razonamiento; un mensaje de hilo nunca responde la pregunta en sí.defer→status: "deferred".reopen→status: "reopened",answer: null.explore→ establece elexplorede la pregunta:{ rows: [{ option, pros: [...], cons: [...] }] }, una fila por opción en orden, de dos a cuatro pros y dos a cuatro contras cada una, específicos para este tema y para cualquier cosa que hayas encontrado en el código base, nunca genéricos. Sé tan honesto sobre los contras de la opción recomendada como sobre los demás. La página lo renderiza como una tabla en el panel de discusión de la pregunta. Si escribirlo cambia tu opinión, establece un nuevorecyupdated: true. La página envíaexploreen el momento en que se hace clic en el botón, generalmente como la única acción en su envío; manéjalo como cualquier otro envío (working → patch → waiting).visualize→ solicita un dibujo usando Subagente o en línea a continuación. La página lo envía en el momento en que se hace clic en el botón (o Regenerar), generalmente solo.visual-feedback→ agrega{who:"user", text, at}(elatdel envío) avisual.thread, responde allí{who:"agent", text}, y solicita un redibujado con el cambio (consulta Visualizar; mientras un dibujo está en curso, la nota va avisual.queueden lugar de iniciar un segundo). Si la nota contradice una pregunta respondida, no cambies esa respuesta: establece elstatusde la pregunta en"reopened", agrega la nota citada a suthread, establece sureca lo que implica la nota, y estableceupdated: true. La respuesta cambia solo cuando el usuario responde la pregunta reabierta. El visual sigue la nota de cualquier manera.finish→ consulta Finalizar a continuación, después de las otras acciones. La página lo envía en el momento en que el usuario confirma, con todo lo que había preparado frente a él.
- Si una respuesta cambia la recomendación de una pregunta aún abierta, asigna a esa pregunta su
nuevo
recyupdated: true(la página lo marca). Estableceupdated: falseuna vez que el usuario la responda. - Agrega la siguiente ronda: la frontera (consulta Método de entrevista), hasta tres cuando sean independientes,
cada una como una nueva entrada de pregunta con
depsque enumera los ids de pregunta de los que depende. Las nuevas preguntas reciben el siguiente número de ronda. Si el árbol está completamente recorrido, no agregues preguntas y establecenoteen una oración corta que diga que cada rama está resuelta y Finalizar es el siguiente paso. - Los turnos ordinarios no redibujan el visual. Cuando una respuesta, reapertura o recomendación cambiada
afecta lo que muestra un visual existente, establece
"visual": { "stale": true }. Dejavisual.html,version,atynotesin cambios; la página lo marca como desactualizado y el usuario puede hacer clic en Regenerar cuando esté listo. No lances un subagente de dibujo solo porque la siguiente ronda esté lista. Las acciones explícitasvisualizeyvisual-feedbackaún solicitan un dibujo, y Finalizar aún reconcilia el visual exportado. - Envía todo de los pasos 2–5 EN UN SOLO PARCHE, junto con
"agent": { "status": "waiting", "handled": <seq de este envío> }(el ejemplo bajo "Parchear state.json" es este parche). Un parche es un intercambio atómico, por lo que la página ve las respuestas, respuestas de hilo, la siguiente ronda y el acuse de recibo juntos. Nunca publiques la siguiente ronda en un parche yhandleden uno posterior mientras haces trabajo opcional: la página usahandledpara limpiar el spinner de "enviado" de la pregunta anterior y habilitar el siguiente envío. - Imprime exactamente una línea de terminal, por ejemplo,
grill: manejar envío #3 (Q2 → B, hilo Q4); la ronda 4 tiene 2 preguntas; visual v3 desactualizado, y vuelve a escuchar.
Método de entrevista (frontera por ronda)
Entrevista al usuario incansablemente sobre cada aspecto del tema hasta que compartan un entendimiento, recorriendo cada rama del árbol de diseño y resolviendo dependencias entre decisiones en orden:
- Una pregunta se hace solo cuando sus requisitos previos están resueltos. Cada ronda es la
frontera actual: las preguntas que se pueden hacer ahora. Haz hasta tres por ronda cuando sean
independientes entre sí; una cuando no lo sean. Registra los
depsde cada pregunta. - Cada pregunta tiene un
title, unbodyque indica lo que depende de ella,optionscon letras (de dos a cuatro), yreccon la opción recomendada y un párrafo dewhy. Los ID de pregunta son de la formaq1,q2, etc., y son estables a lo largo de la vida de la entrevista. - Tan pronto como una pregunta es respondida, pregunta la siguiente que ahora es posible. No hagas todas las rondas de una vez; espera la respuesta del usuario. Una pregunta depende de otra cuando elegir una opción en la primera define el espacio de diseño de la segunda o establece un principio que la segunda debe respetar.
- Cuando dos preguntas son independientes (ninguna opción en una afecta la otra), preséntalas en la misma ronda. La página muestra hasta tres juntas; el usuario puede responder en cualquier orden.
- Si en algún momento el usuario da una respuesta inesperada o contradictoria ("No quiero persistencia en absoluto" después de que ambas opciones A y B asumían persistencia), pregúntalo: reabre preguntas anteriores, introduce preguntas intermedias, o reconoce el cambio y avanza con una nueva recomendación.
- Una pregunta puede tener
type: "multi"(selección múltiple), lo que significa que el usuario puede elegir cualquier subconjunto de opciones. La recomendaciónrec.optionsenumera las letras recomendadas. El envíoanswertienekind: "multi"yoptions(las letras elegidas).acceptes verdadero cuando el conjunto elegido es exactamenterec.options. - Una pregunta puede tener opciones que son mutuamente excluyentes pero permiten entrada de texto libre
(establece
type: "text"; el envíoanswertendrákind: "text"y un campotext). El método subyacente es el mismo: el usuario escribe su respuesta, y tú la evalúas. - Las preguntas pueden tener
durable: true, lo que significa que su efecto es global y no limitado a esta rama. Se pregunta una vez y su respuesta se aplica a todas las ramas. Las preguntas duraderas no tienendeps(se muestran cuando el usuario ingresa por primera vez a una rama donde son relevantes, pero solo se responden una vez). Cuando una pregunta duradera está en la frontera, muéstrala sola, ya que solicitar la respuesta del usuario requiere atención completa. - La entrevista termina cuando el usuario confirma "Finalizar" o cuando el árbol está completamente
recorrido y no quedan preguntas abiertas. En cualquier caso, el usuario debe usar explícitamente
el botón Finalizar (o un envío
finish).
Finalizar
- Inicia con
node $SKILL/server.mjs finish --session <sesión>; imprime un resumen: recuento de preguntas, estado de cada una, cualquier nota y la ruta del doc. - Justo antes de salir, exporta un visual final si hay un dibujo en
visual.html:node $SKILL/server.mjs export-html --session <sesión>produce un HTML independiente en<sesión>/final.html. En modo espera, espera a que termine. Informa al usuario dónde está.
- Detén el servidor (la página sirve un mensaje "entrevista finalizada"). En modo espera, el
servetermina la salida estándar conGRILL_SERVE_STOP; el monitor persistente deja de enviar eventos. - Escribe el informe final en el doc (el archivo
--docde Iniciar): resume cada pregunta con su respuesta y por qué se eligió esa opción. Agrega cualquier nota de diseño, términos definidos y el visual si se generó uno. Edita el archivo directamente; no uses un parche. - Elimina la carpeta de sesión (
rm -rf <sesión>) para que las sesiones futuras no la enumeren. - Imprime una línea final: "entrevista finalizada, documento en ".
Visualizar
El visual es un dibujo generado por un subagente (o en línea, consulta más abajo) que representa
visualmente el diseño actual: una tabla, un diagrama de flujo, un diagrama de arquitectura, un diagrama de
secuencia, un boceto de API, etc. Se almacena como <sesión>/visual.html (un HTML independiente, sin dependencias
CSS/JS externas, renderizable en cualquier navegador moderno por sí solo). El agente
actualiza state.json para señalar un nuevo visual a través del campo visual:
{
"visual": {
"version": 3,
"at": "2026-09-18T22:00:00Z",
"note": "diagrama de flujo de persistencia con la cola del servidor resuelta",
"stale": false,
"thread": [],
"queued": []
}
}
- Cuando el usuario hace clic en Visualizar (envío
visualize), o en Regenerar (también un envíovisualize, pero con el parámetroregenerate: true), o proporciona retroalimentación (visual-feedback), debes producir (o regenerar) el HTML y actualizar el estado JSON. "stale": truelo marca la página cuando detecta que el estado de la pregunta ha cambiado pero el visual no se ha actualizado; tú lo estableces enfalsecuando produces un nuevo visual.- El
versioncomienza en 0 y se incrementa cada vez que produces un nuevo visual (independientemente de los cambios en el estado de la pregunta). La página usaversionpara decidir si recargar elvisual.html.
Subagente o en línea
Subagente: Cuando se recibe una acción visualize (o visual-feedback que solicita un redibujado):
- Lee el archivo
visual.htmlexistente (si lo hay) y las preguntas actuales y sus respuestas desde<sesión>/state.json(leer directamente está bien). - Establece el contenido de
visual.htmla un nuevo HTML independiente renderizable que represente el estado actual de la entrevista. El subagente (o tú mismo, en línea) puede producir cualquier HTML que tenga sentido; la única regla es que sea HTML autónomo que se renderice en cualquier navegador moderno. - Marca el visual como no obsoleto y actualiza la versión:
El servidor sellanode $SKILL/server.mjs patch --session <sesión> <<'GRILL_PATCH' { "visual": { "version": <actual+1>, "note": "<breve descripción>" } } GRILL_PATCHvisual.at. Si hay mensajes en cola (de retroalimentación durante un dibujo), se incluyen envisual.threadantes de establecer la nueva versión.
En línea: Si tu plataforma no soporta subagentes, genera el HTML tú mismo directamente usando las herramientas estándar de escritura de archivos. El proceso es el mismo: escribe el archivo directamente y luego aplica el parche para actualizar el estado. Pero ten cuidado de que el HTML que generes sea válido y no contenga dependencias externas.
Manejo de subagente de dibujo
Cuando lanzas un subagente de dibujo en segundo plano (usando la herramienta de subagente de tu arnés):
- Tan pronto como lances el subagente, establece
"visual": { "drawing": { "status": "working", "since": "<ahora>" } }para que la página muestre un indicador de carga. El servidor sellasincesi omites el tiempo. - El subagente debe escribir el nuevo HTML directamente en
<sesión>/visual.html. - Cuando el subagente termina (el arnés entrega su finalización como un evento, segunda activación en la
regla de eventos), lee
<sesión>/visual.htmlpara confirmar que se escribió. Luego aplica un parche que establece"visual": { "drawing": null, "version": <+1>, "stale": false, "note": "..." }. Si la retroalimentación llegó mientras se dibujaba, agrega los mensajes en cola althreadantes de actualizar la versión. - Si el subagente falla, establece
"visual": { "drawing": { "status": "error", "note": "..." } }. - Vuelve a escuchar.
Modo espera (sin herramienta de monitor persistente)
Cuando el arnés no tiene una herramienta de monitor (por ejemplo, algunos modos de Codex, Gemini CLI, Cursor, Copilot, otros), el agente debe mantener el turno activo manualmente:
- En lugar de devolver al usuario a la terminal después de la salida del servidor, el agente emite un
wait(o un bucle de sondeo) después de la salida final. El agente permanece en el turno y continúa escuchando a través del estado de sondeo (state.json) y la salida deserve. - Cuando
serveemite una línea conGRILL_EVENT, analízala: si contiene"type":"send", manéjala como entrada del usuario. Si contiene"type":"ready", ignórala. Siservesale, el agente puede reiniciarlo o detener la entrevista. - El agente publica actualizaciones de estado llamando a
node $SKILL/server.mjs patch(que funciona independientemente de siservese está ejecutando). - Cuando el usuario confirma "Finalizar", el agente ejecuta los pasos de Finalizar y sale del bucle de espera.
- Importante: En modo espera, el agente NO puede depender de que los eventos lleguen después de que
termina el turno. Por lo tanto, el agente debe mantener el turno activo con un bucle
waitdespués de cada respuesta, regeneración, retroalimentación, etc. El bucle termina solo cuando se completa Finalizar o el usuario cancela explícitamente.
Esquema de state.json
{
// Metadatos
"session": "<nombre de carpeta>",
"topic": "<título>",
"intent": "<por qué>",
"doc": "<ruta del archivo de documento>",
"created": "<ISO 8601>",
"finished": null | { "at": "<ISO 8601>", "note": "<resumen>" },
// Agente
"agent": {
"status": "waiting" | "working" | "idle",
"since": "<ISO 8601>",
"handled": 0 // el último seq de envío manejado
},
// Preguntas (mapa id → objeto)
"questions": {
"q1": {
"round": 1,
"deps": [], // ids de los que depende
"status": "open" | "answered" | "deferred" | "reopened",
"title": "<texto>",
"body": "<texto>",
"options": [{ "k": "A", "text": "..." }, …], // 2–4 opciones
"rec": { "option": "A" | …, "why": "<párrafo>" },
"answer": null | { "kind": "option" | "text" | "multi" | "accept", "option": "A", "options": ["A","B"], "text": "..." },
"thread": [{ "who": "user" | "agent", "text": "...", "at": "<ISO 8601>" }, …],
"explore": null | { "rows": [
{ "option": "A", "pros": ["...","..."], "cons": ["...","..."] },
…
]},
"updated": false, // true cuando la recomendación cambió sin respuesta
"durable": false,
"type": "choice" | "multi" | "text" // por defecto "choice"
},
…
},
// Glosario de términos (opcional)
"terms": {
"<término>": {
"definition": "<texto>",
"at": "<ISO 8601>"
},
…
},
// Nota del agente (mostrada en la página)
"note": "<texto>",
// Visual
"visual": {
"version": 0,
"at": "<ISO 8601>",
"note": "<texto>",
"stale": false,
"thread": [],
"queued": [],
"drawing": null | { "status": "working" | "error", "since": "<ISO 8601>", "note": "<texto>" }
}
}
Notas finales
- Siempre usa
$SKILLen las rutas de comando; el usuario puede tener instalada la habilidad en cualquier lugar. - Los ID de sesión son carpetas con marca de tiempo; no los confundas con los ID de pregunta.
- La página se ejecuta en el navegador local del usuario; no hay datos enviados a ningún servidor.
- Si necesitas agregar una pregunta después de que se haya respondido una durable, usa el parche como de costumbre.
- Cuando uses el modo espera, recuerda que el agente debe permanecer en el turno para manejar los siguientes eventos; no devuelvas el control a la terminal hasta que la entrevista esté completa.