npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

bacp-protocol

v0.5.0

Published

BACP (Brazilian Agent Communication Protocol) — mini framework para comunicação entre agentes.

Readme

BACP

Brazilian Agent Communication Protocol — um mini framework em TypeScript (publicado como JS + tipos .d.ts) para padronizar como agentes conversam entre si, pensado com a comunidade brasileira em mente.

npm version license node

Menos gambiarra, mais contrato claro entre orquestrador e agentes.


Por que existe?

Quando você começa a encaixar vários “agentes” (analisador, coletor, notificador…) no mesmo fluxo, aparecem perguntas repetidas: qual o formato da mensagem? quem fala com quem? como correlacionar uma resposta ao pedido original?

O BACP reúne um protocolo de mensagem, um barramento simples e uma classe base de agente, para você focar na lógica de negócio e não reinventar o encaixe toda vez.

É propositalmente pequeno: dá para ler o código em uma tarde e adaptar ao seu projeto.


Instalação

Requer Node.js 18+ (ES modules).

npm install bacp-protocol

O nome bacp sozinho costuma ser recusado no npm (similaridade com outros pacotes). Este projeto publica-se como bacp-protocol, neutro e alinhado ao propósito (protocolo BACP).

TypeScript

O pacote inclui definições de tipos (dist/*.d.ts). Em projetos TS:

npm install bacp-protocol
import {
  createBus,
  registerAgent,
  type AgentMessage,
  type BacpMiddleware,
} from "bacp-protocol";

const { ask } = createBus({
  middleware: [
    {
      beforeHandle(msg: AgentMessage) {
        console.log(msg.action);
      },
    },
  ],
});

O código-fonte TypeScript está em src/; o artefato publicado no npm é a pasta dist/ (.js + .d.ts), gerada com npm run build antes do npm publish (ou ao desenvolver no pacote: cd bacp && npm install && npm run build). Quem instala o pacote pelo npm já recebe o dist pronto.


Modo simples (poucos comandos, estilo Node comum)

Ideias centrais: createBus() monta tudo; registerAgent(bus, id, ações) registra um agente com funções; ask manda tarefa (um agente responde); on / emit / once tratam eventos (vários ouvintes, sem destinatário único).

Tarefas (ask)

import { createBus, registerAgent } from "bacp-protocol";

const { bus, ask } = createBus();

registerAgent(bus, "meu-agente", {
  saudar: (dados) => ({ texto: `Olá, ${dados.nome}!` }),
  somar: (dados) => ({ total: dados.a + dados.b }),
});

const r1 = await ask("meu-agente", "saudar", { nome: "Maria" });
const r2 = await ask("meu-agente", "somar", { a: 2, b: 3 });

Cada função em ações recebe (dados, mensagemCompleta) — na prática quase sempre só o primeiro argumento.

Eventos (on, emit, once)

Um evento usa type: "event" e destino reservado to: "*" (constante BROADCAST_TO). Vários handlers podem escutar o mesmo nome.

const { ask, on, once, emit } = createBus();

on("pedido.criado", (dados) => {
  console.log("listener A", dados);
});

on("pedido.criado", (dados) => {
  console.log("listener B", dados);
});

once("app.init", () => console.log("só uma vez"));

await emit("app.init", {});
await emit("pedido.criado", { id: 42 });

Dentro de um agente, use agent.emit("nome", { ... }) para publicar com from correto. O emit do createBus usa o id do orquestrador como remetente.

Se já tiver um Orchestrator, pode usar orchestrator.ask(...) em vez de montar o objeto do dispatch.

Produção leve (sem infra extra)

  • meta enriquecido por createMessage: protocolVersion (constante exportada PROTOCOL_VERSION, hoje "1") e traceId (por omissão igual a requestId, se você não passar outro).
  • Timeout ou cancelamento: quarto argumento de ask / opções em dispatch / bus.send:
    • await ask("agente", "acao", {}, { timeoutMs: 5000 })
    • await ask("agente", "acao", {}, { signal: controller.signal })
      Em falha por tempo, o erro é BacpTimeoutError (também em cancelamento via AbortSignal).
  • Middleware no barramento: bus.use({ async beforeHandle(msg) { ... }, async afterHandle(msg, result) { ... } }) ou passe createBus({ middleware: [ ... ] }). Erros em afterHandle só geram console.warn, para não mascarar o resultado principal.
  • Utilitário withTimeout(promise, { timeoutMs, signal }) para qualquer Promise.

Fora do escopo deste pacote (roadmap / integrações à parte): filas distribuídas (Redis, SQS), métricas Prometheus, OpenTelemetry completo, auditoria persistente, autenticação por token entre processos.


Modo completo (classes e agentes prontos)

import BACP from "bacp-protocol";

const bus = new BACP.MessageBus();
const orchestrator = new BACP.Orchestrator({ bus });

new BACP.AnalyzerAgent({ bus });
new BACP.CollectorAgent({ bus });

const resultado = await orchestrator.dispatch({
  to: "analyzer",
  action: "analyze_products",
  payload: { products: ["A", "B", "C"] },
});

console.log(resultado);

Imports nomeados também funcionam:

import { MessageBus, Orchestrator, createMessage } from "bacp-protocol";

Formato da mensagem

Toda troca segue um objeto com campos fixos — assim dá para logar, validar e evoluir sem quebrar o que já existe:

{
  "type": "task",
  "from": "orchestrator",
  "to": "analyzer",
  "action": "analyze_products",
  "payload": {
    "products": ["A", "B"]
  },
  "meta": {
    "requestId": "123",
    "timestamp": 1710000000,
    "protocolVersion": "1",
    "traceId": "123"
  }
}
  • type: task | response | event
  • from / to: ids dos agentes (o barramento usa to para rotear). Para eventos em broadcast, use to: "*" (BROADCAST_TO) — não use "*" como id de agente
  • action: nome da operação que o destinatário implementa
  • payload: dados da operação (objeto)
  • meta: obrigatórios na validação: requestId e timestamp. Em mensagens criadas com createMessage, também entram por defeito protocolVersion e traceId (pode sobrescrever em meta)

O que vem no pacote

| Peça | Papel | |------|--------| | createBus / registerAgent | API mínima: ask, on, once, emit + registro por funções; createBus({ middleware }) | | BROADCAST_TO / PROTOCOL_VERSION | Constantes do protocolo | | BacpTimeoutError / withTimeout | Timeout e cancelamento | | MessageBus | use(), agentes por id, send(msg, { timeoutMs, signal }) | | Agent | handle, task(), respond(), emit() e mapa de ações | | Orchestrator | dispatch(), ask() com timeout opcional; id padrão orchestrator | | validateMessage / assertValidMessage / createMessage | Contrato e fábrica de mensagens | | AnalyzerAgent / CollectorAgent | Exemplos prontos para copiar ou trocar |


Criar seu próprio agente

Sem classe — só funções:

import { createBus, registerAgent } from "bacp-protocol";

const { bus, ask } = createBus();

registerAgent(bus, "meu-agente", {
  minha_acao: (dados) => ({ resultado: dados.valor * 2 }),
});

Com classe (quando quiser herança ou organização maior):

import { Agent } from "bacp-protocol";

class MeuAgente extends Agent {
  constructor(bus) {
    super({
      id: "meu-agente",
      bus,
      actions: {
        minha_acao: (payload, message) => {
          return { ok: true, recebido: payload };
        },
      },
    });
  }
}

Estrutura do repositório (referência)

agent-framework/
├── core/
│   ├── Agent.js
│   ├── MessageBus.js
│   └── Orchestrator.js
├── protocol/
│   └── message.schema.js
├── agents/
│   ├── AnalyzerAgent.js
│   └── CollectorAgent.js
└── index.js

Contribuindo

Ideias, issues e PRs são bem-vindos. Se algo não ficou claro na API, abre uma issue — melhor documentação também é contribuição.


Licença

MIT — use à vontade nos seus projetos.


Feito com cuidado para quem curte código legível e protocolos explícitos.

Se o BACP te ajudou, uma estrela no repositório já anima demais.