Communitygithub.com

CounterCall

📞 O CALL-E liga para um balcão de serviços públicos indonésio antes de você ir e retorna uma lista de verificação validada do que levar — e deixa o campo vazio quando o atendente não soube responder.

O que é CounterCall?

O CounterCall é uma skill projetada para o assistente de chamadas CALL-E que telefona automaticamente para balcões de serviços públicos na Indonésia para obter informações precisas sobre requisitos documentais. Em vez de depender de listas desatualizadas ou incompletas publicadas online, esta skill faz uma chamada telefônica real para o escritório e retorna uma lista de verificação estruturada e validada que o usuário pode usar para preparar sua visita. A skill garante segurança através de múltiplas salvaguardas: verifica rigorosamente os números de telefone contra fontes oficiais, usa chaves de idempotência para evitar múltiplas chamadas para o mesmo escritório no mesmo dia, e valida o resultado contra um esquema estrito antes de apresentá-lo ao usuário. A saída é um objeto JSON com campos enumerados para método de pagamento, necessidade de agendamento, originais versus cópias e certeza do atendente — incluindo valores explícitos para quando o atendente não soube responder. A skill é ideal para consultas de baixo volume, de alto risco pessoal, onde uma viagem desperdiçada tem um custo real, e explicitamente não deve ser usada para emergências, consultas em massa, ou para escritórios que publicam informações confiáveis online ou que solicitaram não ser contatados por sistemas automatizados.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add edycutjong/countercall

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que CounterCall faz?

Pak Yanto tirou a manhã de folga do trabalho, pedalou quarenta minutos até o balcão do Samsat e foi dispensado porque sua fotocópia era folha tamanho ofício em vez de A4. Ele perdeu um dia de salário, e ainda não sabia o que mais estava faltando para amanhã.

Os balcões de serviços públicos publicam listas de requisitos que são incompletas, desatualizadas ou silenciosamente contraditadas no guichê. A fonte confiável é a linha telefônica do escritório, e essa linha está ocupada, protegida por URA, e atendida na quarta tentativa. Então as pessoas não ligam. Elas viajam, enfrentam filas, e são dispensadas por um único documento.

Esta skill faz a ligação no lugar delas e retorna uma lista de verificação que a pessoa pode capturar de tela e levar consigo.

Ela se encaixa bem no design do CALL-E: trabalho telefônico de baixa frequência, pessoal, de alto risco, contra um número que um humano teria que rediscar a manhã toda.

Antes de começar

Esta skill faz uma chamada telefônica real para um escritório público real. Confirme com o usuário:

  • qual procedimento ele está consultando, nas próprias palavras do escritório
  • qual escritório, e o número de telefone no formato E.164, a partir da página publicada do escritório
  • que ele deseja que uma chamada seja feita agora

Nunca inferir um número de telefone. Nem de um diretório, nem de um escritório similar, nem adivinhando um código de país. Um número entra no fluxo apenas quando um humano o leu da página publicada do próprio escritório. Ligar para o número errado significa que um chamador automatizado alcança um desconhecido, que é a pior coisa que esta skill pode fazer.

Limites de segurança

Esta skill coleta apenas requisitos de balcão.

  • Ela não submete uma solicitação, agenda uma consulta, paga uma taxa ou compromete o usuário a nada. Ela pergunta e relata.
  • Ela não fornece aconselhamento jurídico ou de imigração. Se um atendente sugerir uma rota alternativa, reporte-a textualmente como algo que o atendente disse, nunca como uma recomendação.
  • A resposta verbal de um atendente é informativa, não juridicamente vinculante, e todo resultado renderizado diz isso. Requisitos mudam e balcões individuais aplicam discricionariedade.
  • Ela declara claramente no início da chamada que é um assistente automatizado e por que está ligando. Se a pessoa se recusar a responder, agradece e encerra a chamada. Ela não insiste, pergunta novamente ou retorna a ligação no mesmo dia.
  • Uma chamada por escritório por procedimento por dia. Essas são linhas de serviço público atendidas por pessoas com uma fila na frente delas. A chave de idempotência impõe isso; não a remova.
  • Quando o atendente não tem certeza, o resultado diz incerto. Nunca preenche uma lacuna com o que é típico e nunca apresenta uma hesitação como fato. Uma pessoa pode viajar por uma cidade com base nesta resposta.
  • Liga para escritórios apenas durante seu horário de funcionamento publicado. Uma linha pública tocando às 22:00 não é um dado, é um incômodo.

Leia references/safety.md antes de adaptar esta skill para uma nova instituição. Alguns destinatários não são alvos apropriados para um chamador automatizado.

O que torna isso diferente de uma transcrição

A maioria das skills de chamada retorna prosa e deixa o leitor interpretá-la. Esta retorna um objeto fixo, validado e se recusa a retornar qualquer outra coisa.

O result_schema do Goal define additionalProperties: false e restringe quatro campos a enumerações — payment_method, appointment_required, originals_or_copies e clerk_certainty, cada um incluindo um valor para "o atendente não sabia". Se a chamada retornar com formato diferente, o resultado é colocado em quarentena em vez de renderizado. Uma lista de verificação meio interpretada é pior do que nenhuma lista, porque o usuário age com base nela.

O contrato completo está em references/result-contract.md.

Fluxo de trabalho

1. Coletar a solicitação

Obrigatório: o nome do procedimento, o nome do escritório, o número de telefone do escritório em E.164 e a URL da fonte publicada de onde o número veio.

Validar o número antes de qualquer outra coisa acontecer. E.164 é um sinal de mais, um dígito de código de país não zero, depois 7 a 14 dígitos adicionais: ^\+[1-9]\d{7,14}$. Rejeitar qualquer outra coisa e pedir ao usuário. Nunca adivinhar um código de país. Um número em formato local chegando ao discador é como a pessoa errada é chamada.

Execute scripts/preflight.mjs para verificar o número e o contrato sem discar.

2. Verificar se o contrato publicado não mudou

Antes de cada execução, leia a interface do Goal ao vivo e compare-a com o contrato para o qual esta skill foi escrita.

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);   // recusar discar

Use o helper publishedRunSpec(goal), não goal.published_run_spec diretamente. O formato do fio e a documentação escrevem published_run_spec.result_schema; o SDK TypeScript converte para camelCase como publishedRunSpec.resultSchema. Ler apenas o nome documentado contra o cliente TS retorna undefined em vez de lançar um erro — o guarda então conclui "nenhuma especificação publicada" e recusa cada discagem enquanto parece estar funcionando. O helper lê ambas as grafias. Isso nos custou um dia; está documentado em FEEDBACK.md na raiz do repositório.

A documentação do CALL-E recomenda essa comparação antes de implantar uma alteração de variável. Fazer isso em toda execução custa uma chamada de API e converte uma falha silenciosa em uma recusa sonora. Discar para uma pessoa real com um esquema desatualizado produz um resultado que parece bom e está silenciosamente errado.

3. Fazer uma chamada

goals.run com uma Idempotency-Key com escopo para escritório, procedimento e data, para que uma repetição nunca disque duas vezes uma linha pública:

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

4. Aguardar até obter um resultado ou um erro

goals.waitForResult tem uma regra de conclusão: parar quando result ou error for não nulo. Uma chamada concluída pode brevemente retornar ambos nulos enquanto o CALL-E analisa o resultado estruturado, portanto não trate essa janela como uma falha.

5. Renderizar, ou falhar honestamente

Todos os oito códigos publicados de GoalRunError direcionam para um resultado distinto. O conjunto abaixo é aquele que scripts/render.mjs implementa — mantenha-os sincronizados se o CALL-E adicionar um código.

ResultadoO que o usuário vê
resultado válidoa lista de verificação, com a linha textual do atendente e a URL da fonte
no_answer"a linha não atendeu". Sem lista de verificação
declined"o escritório recusou-se a atender um chamador automatizado". Sem lista de verificação
result_invalida chamada foi concluída mas a resposta não correspondeu ao contrato. Colocado em quarentena
result_unavailablea chamada foi concluída mas não produziu resposta estruturada. Sem lista de verificação
result_faileda resposta não pôde ser processada em uma lista de verificação. Sem lista de verificação
timed_out"nenhuma resposta utilizável" antes do prazo. Sem lista de verificação
call_faileda chamada não pôde ser concluída. Sem lista de verificação
canceledcancelada antes de produzir uma resposta. Sem lista de verificação

Nenhum ramo renderiza uma lista de verificação parcial. Exemplos trabalhados de cada um estão em references/examples.md.

Executando

scripts/call.mjs é dry-run por padrão. Ele imprime a solicitação exata que enviaria e não faz nenhuma chamada. Discar requer um --live explícito:

# dry run — imprime a solicitação que enviaria, não disca nada, não precisa de credenciais
node scripts/call.mjs --office <id> --procedure "<procedure>"

# realmente toca um telefone
node scripts/call.mjs --office <id> --procedure "<procedure>" --live

Uma skill que disca por padrão é uma skill que disca por acidente.

data/offices.json vem com seu número de telefone mascarado (+62XXXXXXXXXX), então a entrada seminal não pode discar e todo comando contra ela sai com 3 e REFUSING TO DIAL. Isso é intencional: um número entra no arquivo apenas quando um humano o leu da página publicada do próprio escritório e registrou source_url e source_checked. Adicione sua própria entrada antes de executar qualquer coisa.

Para ver a saída do dry-run imediatamente, o fixture de teste carrega um número fictício válido:

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

Quando não usar isso

  • Emergências. Esta é uma consulta de requisitos com latência de vários minutos. Não é um meio de contatar alguém urgentemente.
  • Escritórios com uma página de requisitos publicada, confiável e atualizada. Se o site estiver correto, leia o site. A chamada só se justifica onde a resposta publicada é conhecida por ser incompleta.
  • Qualquer instituição que tenha solicitado não ser contatada por sistemas automatizados, ou onde a lei local restrinja chamadas automatizadas. Verifique antes de adicionar um escritório.
  • Consultas de alto volume. Um escritório por procedimento por dia é o teto por design. Se você precisa de volume, você precisa de um acordo de compartilhamento de dados, não de um telefone.
  • Qualquer coisa onde estar errado é barato. O valor aqui vem do custo de uma viagem desperdiçada. Se o usuário pode simplesmente ir e descobrir, deixe-o fazer isso.

Limitações honestas

  • A cobertura é limitada a escritórios no arquivo seminal, cada um com uma URL de fonte publicada.
  • As taxas de resposta em linhas de serviço público variam por escritório e horário do dia, e uma grande parte das chamadas não será atendida. Essa falta de confiabilidade é a razão pela qual esta skill existe, e é relatada em vez de oculta.
  • O resultado é a resposta de um único atendente em um único dia. É evidência, não uma garantia.

Habilidades Relacionadas