Por que ela existia
- Limite de segurança: expunha uma pequena lista de permissões em vez de toda a superfície da API do Gateway.
- Emparelhamento + identidade do nó: a admissão do nó era controlada pelo Gateway e vinculada a um token específico por nó.
- Experiência de descoberta: os nós podiam descobrir Gateways via Bonjour na LAN ou se conectar diretamente por uma tailnet.
- WS em local loopback: todo o plano de controle por WS permanecia local, a menos que fosse encapsulado via SSH.
Transporte
- TCP, um objeto JSON por linha (JSONL).
- TLS opcional (
bridge.tls.enabled: true). - A porta padrão do listener era
18790.
bridgeTls=1 e bridgeTlsSha256 como uma indicação não secreta. Os registros TXT do Bonjour/mDNS não são autenticados; os clientes não podiam tratar a impressão digital anunciada como uma fixação autoritativa sem outra verificação fora de banda.
Handshake e emparelhamento
- O cliente envia
hellocom os metadados do nó e o token (se já estiver emparelhado). - Se não estiver emparelhado, o Gateway responde com
error(NOT_PAIRED/UNAUTHORIZED). - O cliente envia
pair-request. - O Gateway aguarda aprovação e então envia
pair-okehello-ok.
hello-ok retornava serverName; as superfícies de Plugin hospedadas agora são anunciadas por meio de pluginSurfaceUrls no protocolo atual do Gateway (Canvas/A2UI usa pluginSurfaceUrls.canvas).
Quadros
Do cliente para o Gateway:req/res: RPC do Gateway com escopo limitado (chat, sessões, configuração, integridade, voicewake, skills.bins).event: sinais do nó (transcrição de voz, solicitação do agente, inscrição no chat, ciclo de vida da execução).
invoke/invoke-res: comandos do nó (canvas.*,camera.*,screen.record,location.get,sms.send).event: atualizações do chat para sessões inscritas.ping/pong: manutenção da conexão.
src/gateway/server-bridge.ts (removido).
Eventos do ciclo de vida da execução
Os nós emitiamexec.finished para expor atividades concluídas de system.run, mapeadas para eventos do sistema pelo Gateway (nós legados também podiam emitir exec.started). exec.denied marcava uma tentativa negada de system.run como uma negação terminal, sem enfileirar um evento do sistema nem despertar o trabalho do agente.
Campos da carga útil (todos opcionais, salvo indicação em contrário):
Uso histórico da tailnet
- Vinculava a ponte a um IP da tailnet:
bridge.bind: "tailnet"em~/.openclaw/openclaw.json(apenas histórico;bridge.*não é mais uma configuração válida). - Os clientes se conectavam pelo nome MagicDNS ou pelo IP da tailnet.
- O Bonjour não atravessa redes; caso contrário, era necessário usar DNS-SD de longa distância ou um host/porta manual.