Telegram

Cria e gere bots do Telegram ligados a agentes do Pepe.

Telegram

O Telegram é o canal mais rápido de pôr de pé porque não precisa de qualquer URL público. Cria um bot com o @BotFather, copia o respetivo token e regista-o. É o próprio Pepe que vai ao Telegram buscar as mensagens novas, por isso nada na tua máquina precisa de ficar exposto à internet.

Configura o bot predefinido de forma interativa:

pepe gateway telegram setup

Isto pede o token (podes colar um token literal ou uma referência ${ENV_VAR}), um agente opcional para associar e uma lista opcional de ids de conversa autorizados a falar com ele.

Podes executar mais do que um bot, cada um associado a um agente diferente:

pepe gateway telegram add support --token "${SUPPORT_BOT_TOKEN}" --agent helpdesk --trainers none
pepe gateway telegram add ops --token "${OPS_BOT_TOKEN}" --agent operator --heartbeat-minutes 30 --heartbeat-hours 8-22

As opções do telegram add:

Listar e remover bots:

pepe gateway telegram list
pepe gateway telegram remove support

Executa o poller em primeiro plano (um poller por bot):

pepe gateway telegram

Cada bot tem o seu próprio poller, o seu token, o seu agente associado, as suas listas de autorizados e o seu espaço de nomes de sessão. Dois bots que resolvem para o mesmo token são desduplicados, porque dois pollers num só token entrariam em conflito um com o outro.

Normalmente não precisas de executar isto em separado. O pepe serve arranca com os bots do Telegram configurados a par da API HTTP, por isso um único servidor em execução cobre todos os canais de uma vez.

Dentro de um único bot podes na mesma mudar de agente por conversa com /agent <nome> (vê Encaminhamento). Um bot dedicado é para quando um canal inteiro deve ser um agente.

Painel. A secção Channels do painel lista os teus bots com um distintivo ao vivo de ativo/inativo, permite-te adicionar um bot, editar com que agente ele fala e removê-lo. Grava a mesma configuração que a linha de comandos, e os pollers em execução reconciliam-se sem reinício.

Onde vive a configuração

O bot predefinido vive sob "telegram" no ~/.pepe/config.json. Os bots com nome adicionais vivem sob "telegrams", um mapa de nome para configuração, e cada um deles aceita as mesmas chaves do bot predefinido:

O /whoami numa conversa é a forma fácil de descobrir os ids para essas listas. Imprime o teu id de utilizador e o id da conversa.

As sessões têm espaço de nomes por bot. O bot predefinido indexa as conversas como telegram:<chat_id>, enquanto um bot com nome usa telegram:<name>:<chat_id>. Dois bots nunca colidem, portanto, nem nas conversas nem na entrega de tarefas agendadas.

Comandos de barra

Cada conversa é uma sessão persistente, conduzida por comandos de barra. Também aparecem no menu “/” do Telegram, no idioma que configuraste.

Comando O que faz
/new Começa uma conversa nova
/undo Anula a tua última mensagem
/retry Refaz a última resposta
/compact Resume o histórico para libertar contexto
/stop Para a execução atual
/inline <texto> Injeta uma mensagem na execução já a decorrer
/btw <pergunta> Faz uma pergunta paralela que não fica guardada na conversa
/mention on|off Num grupo, exigir ou não uma @menção
/model [nome] [session|global] Mostra o modelo atual, ou define-o
/learn Guarda o que o agente aprendeu na memória e nas skills
/whoami Mostra os teus ids de utilizador e de conversa do Telegram
/help Lista os comandos que podes executar

E os comandos de operador, que só os formadores do bot podem executar:

Comando O que faz
/agent <nome> Muda o agente que responde nesta conversa
/status Mostra informação da sessão
/models Escolhe um modelo numa lista de botões
/tools Lista as ferramentas de runtime disponíveis
/skill [nome] Lista as skills, ou executa uma pelo nome
/approve Gere as permissões de ferramenta guardadas
/usage Mostra o gasto e a contagem de mensagens do mês

As skills instaladas tornam-se também comandos de barra próprios, por isso uma skill chamada weather responde a /weather além de /skill weather, e fica descoberta a partir do menu “/”. Um comando de skill conta como comando de operador, porque uma skill executa instruções arbitrárias através do agente.

Os comandos de operador são só para formadores

Os comandos da segunda tabela expõem a superfície de operador: a tua configuração, as tuas permissões, o teu gasto e o inventário interno de modelos, ferramentas e skills. Estão restritos à lista trainers do bot, e a barreira fica no ponto único onde todos os comandos são despachados, por isso um comando que pode ser alcançado por dois nomes não consegue contorná-la.

O /model é, de propósito, metade de cada. Lê-lo (/model sem argumentos) revela qual o modelo por trás do bot, o que é infraestrutura, por isso esse caminho é só para formadores. Mudá-lo não é: um cliente pode escolher um modelo para a sua própria conversa, a não ser que tranques isso. Vê “Muda de modelo a meio de uma conversa” abaixo.

Em grupos

Num chat 1:1 o bot responde sempre. Adicionado a um grupo, por padrão só responde quando é @mencionado ou recebe um /comando; caso contrário, responderia a todas as mensagens num grupo movimentado. Desliga essa exigência por completo para um bot (em todos os grupos em que está) com require_mention: false durante o pepe gateway telegram setup.

Para um único grupo, sem mexer na configuração do bot inteiro, corre:

/mention off   # só neste grupo, até ao /new - não precisa de @menção para responder
/mention on    # volta a exigir uma @menção
/mention       # mostra a configuração atual

A dispensa vive na conversa desse grupo, não no bot, por isso nunca se propaga para nenhum outro grupo em que o mesmo bot esteja, e uma conversa nova (/new) esquece-a.

Uma conversa de grupo é uma única sessão partilhada entre todos os que estão nela. Cada mensagem recebida vem identificada com o nome de quem a enviou (Alice: como está o estado?), por isso o modelo sabe a quem está a responder em cada turno, em vez de presumir que quem escreveu por último é a mesma pessoa de quem se falava antes; uma conversa privada nunca vem identificada assim, já que não há mais ninguém que pudesse ser. O bot também é cego ao que não lhe é dirigido: uma mensagem que não o @menciona (e não está dispensada com /mention off) nunca chega ao agente, nem como contexto silencioso, por isso não consegue “pôr-se a par” do que se falou antes de ele ser trazido para a conversa.

Tópicos de fórum

Num grupo com tópicos ativados, cada tópico é uma conversa própria, e a resposta volta ao tópico de onde veio. Podes dar a um tópico o seu próprio agente: corre /agent <nome> dentro do tópico (ou simplesmente pede ao agente para ligar este tópico a outro, que ele faz por ti) e ele fica vinculado a esse agente, mantido através do /new e de reinícios. Os nomes são correspondidos sem distinguir maiúsculas, por isso /agent engenheiro encontra um agente chamado Engenheiro. Assim um grupo pode ter um tópico de “suporte” respondido pelo agente de suporte e um de “engenharia” pelo engenheiro, lado a lado. O agente de uma mensagem é o agente vinculado ao tópico, se houver; senão o agent do bot; senão a predefinição global. Um tópico vinculado ainda segue a regra de menção do grupo: põe require_mention: false (ou /mention off nesse tópico) se quiseres que responda sem @menção.

Muda de modelo a meio de uma conversa

/model mostra o modelo ativo nesse chat, com um botão Browse models para escolher outro; /models vai direto a esse seletor. O seletor está limitado ao teu projeto e põe um visto no modelo em uso, por isso tocas num para mudar. Ambas estas leituras são só para formadores, já que revelam que modelos estão por trás do bot. Utilização escrita:

/model openrouter               # pergunta se muda só este chat ou todos
/model openrouter session       # muda só para esta conversa
/model openrouter global        # muda para todos com quem este bot fala

Qualquer pessoa numa conversa permitida pode mudar a sua própria sessão; mudá-lo globalmente (para todas as conversas que este bot atende) está reservado a formadores (a mesma lista que rege o /learn e a memória), por isso um membro qualquer do chat não consegue reapontar todo o bot para outro modelo em silêncio. É ao formador que é perguntado qual das duas opções quis dizer; qualquer outra pessoa muda apenas a sua própria conversa, sem nada a responder. Define model_switch_locked: true no bot para desativar por completo a mudança de modelo para quem não é formador. Uma alteração de sessão vive só em memória; repõe-se com /new ou com um reinício do servidor, voltando ao que a configuração própria do agente disser.

Mostrar que está a trabalhar

Enquanto uma execução decorre, o bot mostra que está ocupado. Isto é de propósito um sinal ambiente, e não um relatório de estado que devas ler. O indicador nativo de “a escrever…” do Telegram mantém-se vivo em todos os modos. Por cima dele, o tool_progress (a opção --progress) escolhe um de quatro:

Define-o de três formas: pela linha de comandos com --progress; de dentro de uma conversa com a ferramenta manage_channel (set_progress); ou no painel, em Canais → o seu bot → Editar → “Enquanto o agente trabalha”, onde cada modo é explicado.

Heartbeat: contactos proativos

Um bot pode periodicamente dar a palavra ao seu agente para dizer alguma coisa por iniciativa própria (“o deploy terminou”, “pediste-me para ficar atento a X”) e, igualmente importante, o direito de não dizer nada na maior parte do tempo. Vem desligado, e ativa-lo por bot:

pepe gateway telegram add ops --token "${OPS_BOT_TOKEN}" --agent operator --heartbeat-minutes 30 --heartbeat-hours 8-22

Um agente que tenha a ferramenta manage_channel também consegue configurar isto sozinho, de dentro de uma conversa:

manage_channel set_heartbeat name: "sales" heartbeat_minutes: 30 heartbeat_hours: "8-22"

Cada pulsação executa o agente sobre o contexto vivo da sua sessão, com um prompt que diz que esta é uma verificação automática e que deve responder exatamente HEARTBEAT_OK se não houver nada que valha a pena dizer. Esse é o caso comum, e só uma mensagem genuína chega a ser enviada para a conversa. Alimenta-lo com duas coisas:

Um ciclo proativo descontrolado é impossível por construção. Uma barreira de arrefecimento impõe um mínimo de 30 segundos entre pulsações, e um disjuntor de cheia dispara com 5 disparos em 60 segundos. O heartbeat_hours (uma janela local como 8-22) mantém o bot calado fora das horas em que estás acordado.

As conversas mortas curam-se sozinhas

Se um envio volta com falha permanente, porque o bot foi bloqueado ou porque a conversa ou o utilizador desapareceu, essa conversa passa a ser ignorada em todos os envios seguintes. Não há chamadas de API desperdiçadas nem ruído no registo. No momento em que um envio para ela volta a resultar, por exemplo porque a pessoa desbloqueou o bot, a marca é retirada automaticamente. Não há nada para repor à mão.

Uma resposta sobrevive a um reinício a meio do envio

Se o Pepe reiniciar (um deploy, uma falha) no momento exato em que estava a enviar a resposta de um turno, essa resposta não se perde: é reenviada assim que o bot volta a funcionar, antes de começar a tratar seja o que for de novo. Quando o reinício aconteceu com o envio genuinamente em curso (por isso não há certeza se a mensagem já chegou), a cópia reenviada leva o prefixo “♻️ Recovered reply”, para que um possível duplicado fique sempre sinalizado em vez de se repetir em silêncio. Uma resposta que nunca chegou a ser enviada sai limpa, sem prefixo. Isto não precisa de nenhuma configuração e não há nada para repor à mão.

Idioma e erros

As mensagens fixas do próprio Pepe (respostas de comando, botões, recusas) seguem o locale que configuraste. As respostas do agente seguem o idioma em que a pessoa escreve, seja ele qual for. Os erros internos em bruto nunca são derramados na conversa.

Fá-lo pela conversa

Um agente que tenha a ferramenta manage_channel consegue criar e reassociar bots do Telegram a partir de uma conversa. Como edita a configuração, cada chamada passa pela barreira de permissão: o agente propõe a alteração e tu confirmas antes de ela ser aplicada.

Dirias:

Adiciona um bot do Telegram chamado sales que fale com o agente de vendas. O token está na variável de ambiente SALES_BOT_TOKEN.

O agente invoca manage_channel com action: "add", name: "sales", token_env: "SALES_BOT_TOKEN" e agent: "sales". Aqui importam duas salvaguardas:

Outras ações do manage_channel são list, set_agent (reassociar um bot a outro agente), set_trainers, set_heartbeat, set_progress, enable, disable e remove. Após qualquer alteração, reconcilia os pollers em execução, por isso um bot arranca ou pára ao vivo, sem reinício.

Apenas Telegram. A ferramenta de conversa gere bots do Telegram. As ligações por webhook (WhatsApp, Slack e as restantes) são criadas pela linha de comandos, pelo painel ou pelo pepe setup, não pela conversa.