Communitygithub.com

CounterCall - LlamadaVerificada

📞 CALL-E llama a un mostrador gubernamental indonesio antes de que vayas y devuelve una lista de verificación validada de lo que debes llevar, dejando los campos vacíos cuando el funcionario no lo sabe.

¿Qué es CounterCall - LlamadaVerificada?

CounterCall es una habilidad para CALL-E que automatiza llamadas telefónicas a mostradores de servicios públicos gubernamentales en Indonesia. Su propósito es obtener una lista de requisitos verificada y estructurada que un usuario puede llevar como referencia, evitando viajes perdidos por información incompleta o desactualizada. La habilidad realiza una llamada real, se identifica como asistente automatizado, y solo recopila requisitos; no realiza trámites ni da asesoría legal. La respuesta se valida contra un esquema estricto que rechaza resultados parciales o ambiguos, y se limita a una llamada por oficina, procedimiento y día. Está diseñada para casos de bajo volumen pero alto impacto, donde confiar en páginas web no es suficiente y el costo de un viaje fallido es alto. Soporta plataforma CALL-E, con scripts en Node.js y validación E.164 para números telefónicos.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add edycutjong/countercall

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace CounterCall - LlamadaVerificada?

Pak Yanto se tomó la mañana libre, viajó cuarenta minutos al mostrador de Samsat y fue rechazado porque su fotocopia era tamaño folio en lugar de A4. Perdió un día de ingresos, y todavía no sabía qué más le faltaba para mañana.

Los mostradores de servicios públicos publican listas de requisitos que son incompletas, desactualizadas o contradichas silenciosamente en la ventanilla. La única fuente confiable es la línea telefónica de la oficina, y esa línea está ocupada, protegida por IVR, y se responde al cuarto intento. Así que la gente no llama. Viajan, hacen fila, y son rechazados por un solo documento.

Esta habilidad hace la llamada en su lugar, y devuelve una lista de verificación que la persona puede capturar y llevar consigo.

Es una buena opción para el diseño de CALL-E: trabajo telefónico de baja frecuencia, personal y de alto riesgo contra un número que un humano de otro modo tendría que marcar toda la mañana.

Antes de empezar

Esta habilidad realiza una llamada telefónica real a una oficina pública real. Confirma con el usuario:

  • qué procedimiento está consultando, en las propias palabras de la oficina
  • qué oficina, y el número de teléfono en formato E.164, desde la página publicada de la oficina
  • que desea que se realice una llamada ahora

Nunca infieras un número de teléfono. Ni de un directorio, ni de una oficina similar, ni adivinando un código de país. Un número ingresa en el flujo solo cuando un humano lo ha leído directamente de la página publicada de la oficina. Llamar al número equivocado significa que un llamante automatizado contacta a un extraño, que es lo peor que esta habilidad puede hacer.

Límites de seguridad

Esta habilidad recopila únicamente requisitos de mostrador.

  • No presenta una solicitud, reserva una cita, paga una tarifa ni compromete al usuario a nada. Pregunta e informa.
  • No brinda asesoría legal ni de inmigración. Si un funcionario sugiere una alternativa, repórtalo textualmente como algo que dijo el funcionario, nunca como una recomendación.
  • La respuesta oral de un funcionario es informativa, no vinculante legalmente, y cada resultado generado lo dice. Los requisitos cambian y los mostradores individuales aplican discreción.
  • Al inicio de la llamada declara claramente que es un asistente automatizado, y por qué está llamando. Si la persona se niega a responder, le agradece y finaliza la llamada. No insiste, vuelve a preguntar ni llama de nuevo el mismo día.
  • Una llamada por oficina por procedimiento por día. Estas son líneas de servicio público atendidas por personas que tienen una cola frente a ellas. La clave de idempotencia lo garantiza; no la elimines.
  • Cuando el funcionario no está seguro, el resultado dice "no está seguro". Nunca llena un vacío con lo típico, y nunca presenta una ambigüedad como un hecho. Una persona puede viajar al otro lado de una ciudad basándose en esta respuesta.
  • Llama a las oficinas solo durante su horario de atención publicado. Una línea pública que suena a las 22:00 no es un dato, es una molestia.

Lee references/safety.md antes de adaptar esta habilidad a una nueva institución. Algunos destinatarios no son objetivos apropiados para un llamante automatizado.

Qué lo hace diferente de una transcripción

La mayoría de las habilidades de llamada devuelven prosa y dejan que el lector interprete. Esta devuelve un objeto validado y fijo, y se niega a devolver cualquier otra cosa.

El result_schema del Goal establece additionalProperties: false y restringe cuatro campos a enumeraciones — payment_method, appointment_required, originals_or_copies y clerk_certainty, cada una de las cuales incluye un valor para "el funcionario no lo sabía". Si la llamada regresa con una forma diferente, el resultado se pone en cuarentena en lugar de mostrarse. Una lista de verificación mal parseada es peor que ninguna lista, porque el usuario actúa en base a ella.

El contrato completo está en references/result-contract.md.

Flujo de trabajo

1. Recopilar la solicitud

Requerido: el nombre del procedimiento, el nombre de la oficina, el número de teléfono de la oficina en formato E.164, y la URL de la fuente publicada de donde se obtuvo el número.

Valida el número antes de que ocurra cualquier otra cosa. E.164 es un signo más, un dígito de código de país distinto de cero, luego de 7 a 14 dígitos más: ^\+[1-9]\d{7,14}$. Rechaza cualquier otra cosa y pídele al usuario. Nunca adivines un código de país. Un número en formato local que llega al marcador es cómo se llama a la persona equivocada.

Ejecuta scripts/preflight.mjs para verificar el número y el contrato sin marcar.

2. Verificar que el contrato publicado no haya cambiado

Antes de cada ejecución, lee la interfaz Goal en vivo y compárala con el contrato para el que se escribió esta habilidad.

import { diffContract, publishedRunSpec } from './scripts/_lib.mjs';

const goal = await client.goals.get(GOAL_ID);
const drift = diffContract(PINNED_CONTRACT, publishedRunSpec(goal));
if (drift.length) throw new ContractDrift(drift);   // negarse a marcar

Usa el helper publishedRunSpec(goal), no goal.published_run_spec directamente. El formato de cable y la documentación lo escriben published_run_spec.result_schema; el SDK de TypeScript lo convierte a camelCase como publishedRunSpec.resultSchema. Leer solo el nombre documentado contra el cliente TS devuelve undefined en lugar de lanzar una excepción — entonces la protección concluye "sin especificación publicada" y se niega a marcar cada vez mientras parece que funciona. El helper lee ambas ortografías. Esto nos costó un día; está documentado en FEEDBACK.md en la raíz del repositorio.

La documentación de CALL-E recomienda esta comparación antes de implementar un cambio de variable. Hacerlo en cada ejecución cuesta una llamada API y convierte un fallo silencioso en un rechazo evidente. Marcar a una persona real con un esquema obsoleto produce un resultado que parece correcto y está silenciosamente equivocado.

3. Realizar una llamada

goals.run con una Idempotency-Key limitada a oficina, procedimiento y fecha, para que un reintento nunca marque doble a una línea pública:

countercall:{office}:{procedure}:{yyyy-mm-dd}:v1

4. Consultar hasta obtener un resultado o un error

goals.waitForResult tiene una regla de finalización: detenerse cuando result o error sea distinto de nulo. Una llamada completada puede devolver brevemente ambos nulos mientras CALL-E analiza el resultado estructurado, así que no trates esa ventana como un fallo.

5. Mostrar, o fallar honestamente

Los ocho códigos publicados de GoalRunError se dirigen a un resultado distinto. El conjunto a continuación es el que implementa scripts/render.mjs — mantenlos sincronizados si CALL-E agrega un código.

ResultadoLo que ve el usuario
resultado válidola lista de verificación, con la línea textual del funcionario y la URL de la fuente
no_answer"la línea no respondió". Sin lista de verificación
declined"la oficina se negó a responder a un llamante automatizado". Sin lista de verificación
result_invalidla llamada se completó pero la respuesta no coincidió con el contrato. En cuarentena
result_unavailablela llamada se completó pero no produjo una respuesta estructurada. Sin lista de verificación
result_failedla respuesta no pudo procesarse en una lista de verificación. Sin lista de verificación
timed_out"sin respuesta utilizable" antes de la fecha límite. Sin lista de verificación
call_failedla llamada no pudo completarse. Sin lista de verificación
canceledcancelada antes de producir una respuesta. Sin lista de verificación

Ninguna rama muestra una lista de verificación parcial. Ejemplos prácticos de cada uno están en references/examples.md.

Ejecutarlo

scripts/call.mjs está en modo simulado de forma predeterminada. Imprime la solicitud exacta que enviaría y no realiza ninguna llamada. Marcar requiere un --live explícito:

# simulación — imprime la solicitud que enviaría, no marca nada, no necesita credenciales
node scripts/call.mjs --office <id> --procedure "<procedimiento>"

# realmente suena un teléfono
node scripts/call.mjs --office <id> --procedure "<procedimiento>" --live

Una habilidad que marca por defecto es una habilidad que marca por accidente.

data/offices.json se envía con su número de teléfono enmascarado (+62XXXXXXXXXX), por lo que la entrada inicial no puede marcar y cada comando contra ella sale con código 3 y REFUSING TO DIAL. Esto es deliberado: un número ingresa en el archivo solo cuando un humano lo ha leído directamente de la página publicada de la oficina y ha registrado source_url y source_checked. Agrega una entrada propia antes de ejecutar nada.

Para ver la salida de la simulación inmediatamente, el fixture de prueba incluye un número ficticio válido:

node scripts/call.mjs --offices ../../test/fixtures/offices.test.json \
  --office fixture-sourced --procedure "perpanjangan paspor"

Cuándo no usar esto

  • Emergencias. Esto es una consulta de requisitos con una latencia de varios minutos. No es una forma de contactar a alguien urgentemente.
  • Oficinas con una página publicada de requisitos confiable, actual y precisa. Si el sitio web es correcto, lee el sitio web. La llamada está justificada solo donde se sabe que la respuesta publicada está incompleta.
  • Cualquier institución que haya solicitado no ser contactada por sistemas automatizados, o donde la ley local restrinja las llamadas automatizadas. Verifica antes de agregar una oficina.
  • Consultas de alto volumen. Una oficina por procedimiento por día es el límite por diseño. Si necesitas volumen, necesitas un acuerdo de intercambio de datos, no un teléfono.
  • Cualquier cosa donde equivocarse sea barato. El valor aquí proviene del costo de un viaje perdido. Si el usuario simplemente puede ir y averiguar, déjalo.

Limitaciones honestas

  • La cobertura se limita a las oficinas en el archivo inicial, cada una con una URL de fuente publicada.
  • Las tasas de respuesta en líneas de servicio público varían según la oficina y la hora del día, y una gran parte de las llamadas no serán respondidas. Esa falta de fiabilidad es la razón por la que existe esta habilidad, y se informa en lugar de ocultarse.
  • El resultado es la respuesta de un funcionario en un día. Es evidencia, no una garantía.

Skills relacionados