diff --git a/docs/pt-BR/channels/matrix.md b/docs/pt-BR/channels/matrix.md index 35fa6ff61..35ed9e3d6 100644 --- a/docs/pt-BR/channels/matrix.md +++ b/docs/pt-BR/channels/matrix.md @@ -5,26 +5,24 @@ read_when: summary: Status do suporte ao Matrix, configuração inicial e exemplos de configuração title: Matrix x-i18n: - generated_at: "2026-04-09T01:29:34Z" + generated_at: "2026-04-15T05:33:50Z" model: gpt-5.4 provider: openai - source_hash: 28fc13c7620c1152200315ae69c94205da6de3180c53c814dd8ce03b5cb1758f + source_hash: 631f6fdcfebc23136c1a66b04851a25c047535d13cceba5650b8b421bc3afcf8 source_path: channels/matrix.md workflow: 15 --- # Matrix -O Matrix é um plugin de canal incluído no OpenClaw. +Matrix é um Plugin de canal incluído no OpenClaw. Ele usa o `matrix-js-sdk` oficial e oferece suporte a DMs, salas, threads, mídia, reações, enquetes, localização e E2EE. ## Plugin incluído -O Matrix vem como um plugin incluído nas versões atuais do OpenClaw, então builds -empacotadas normais não precisam de uma instalação separada. +O Matrix é distribuído como um Plugin incluído nas versões atuais do OpenClaw, então compilações empacotadas normais não precisam de uma instalação separada. -Se você estiver em uma build mais antiga ou em uma instalação personalizada que exclui o Matrix, instale-o -manualmente: +Se você estiver em uma compilação mais antiga ou em uma instalação personalizada que exclua o Matrix, instale-o manualmente: Instale pelo npm: @@ -38,18 +36,18 @@ Instale a partir de um checkout local: openclaw plugins install ./path/to/local/matrix-plugin ``` -Veja [Plugins](/pt-BR/tools/plugin) para comportamento de plugins e regras de instalação. +Consulte [Plugins](/pt-BR/tools/plugin) para ver o comportamento dos plugins e as regras de instalação. ## Configuração inicial -1. Verifique se o plugin Matrix está disponível. +1. Verifique se o Plugin Matrix está disponível. - As versões empacotadas atuais do OpenClaw já o incluem. - Instalações antigas/personalizadas podem adicioná-lo manualmente com os comandos acima. 2. Crie uma conta Matrix no seu homeserver. -3. Configure `channels.matrix` com um destes formatos: +3. Configure `channels.matrix` com um destes conjuntos: - `homeserver` + `accessToken`, ou - `homeserver` + `userId` + `password`. -4. Reinicie o gateway. +4. Reinicie o Gateway. 5. Inicie uma DM com o bot ou convide-o para uma sala. - Convites novos do Matrix só funcionam quando `channels.matrix.autoJoin` os permite. @@ -60,35 +58,35 @@ openclaw channels add openclaw configure --section channels ``` -O assistente do Matrix pergunta por: +O assistente do Matrix solicita: - URL do homeserver - método de autenticação: token de acesso ou senha -- ID do usuário (apenas autenticação por senha) +- ID do usuário (somente autenticação por senha) - nome do dispositivo opcional - se deve ativar E2EE -- se deve configurar acesso à sala e entrada automática por convite +- se deve configurar acesso a salas e entrada automática por convite Comportamentos principais do assistente: -- Se as variáveis de ambiente de autenticação do Matrix já existirem e essa conta ainda não tiver autenticação salva na configuração, o assistente oferece um atalho de env para manter a autenticação nas variáveis de ambiente. -- Os nomes das contas são normalizados para o ID da conta. Por exemplo, `Ops Bot` vira `ops-bot`. -- Entradas de allowlist de DM aceitam `@user:server` diretamente; nomes de exibição só funcionam quando a busca ativa no diretório encontra uma correspondência exata. -- Entradas de allowlist de sala aceitam IDs e aliases de sala diretamente. Prefira `!room:server` ou `#alias:server`; nomes não resolvidos são ignorados em tempo de execução pela resolução da allowlist. -- No modo de allowlist de entrada automática por convite, use apenas destinos de convite estáveis: `!roomId:server`, `#alias:server` ou `*`. Nomes simples de salas são rejeitados. +- Se as variáveis de ambiente de autenticação do Matrix já existirem e essa conta ainda não tiver autenticação salva na configuração, o assistente oferece um atalho de ambiente para manter a autenticação em variáveis de ambiente. +- Os nomes das contas são normalizados para o ID da conta. Por exemplo, `Ops Bot` se torna `ops-bot`. +- Entradas de lista de permissões de DM aceitam `@user:server` diretamente; nomes de exibição só funcionam quando a busca em diretório ao vivo encontra uma correspondência exata. +- Entradas de lista de permissões de sala aceitam IDs de sala e aliases diretamente. Prefira `!room:server` ou `#alias:server`; nomes não resolvidos são ignorados em tempo de execução pela resolução da lista de permissões. +- No modo de lista de permissões para entrada automática por convite, use apenas destinos de convite estáveis: `!roomId:server`, `#alias:server` ou `*`. Nomes simples de salas são rejeitados. - Para resolver nomes de salas antes de salvar, use `openclaw channels resolve --channel matrix "Project Room"`. -`channels.matrix.autoJoin` tem como padrão `off`. +`channels.matrix.autoJoin` tem o padrão `off`. -Se você deixá-lo sem definir, o bot não entrará em salas convidadas nem em convites novos no estilo DM, então ele não aparecerá em novos grupos ou DMs por convite, a menos que você entre manualmente primeiro. +Se você deixá-lo sem definir, o bot não entrará em salas convidadas nem em convites novos no estilo DM, então ele não aparecerá em novos grupos nem em DMs por convite, a menos que você entre manualmente primeiro. -Defina `autoJoin: "allowlist"` junto com `autoJoinAllowlist` para restringir quais convites ele aceita, ou defina `autoJoin: "always"` se quiser que ele entre em todo convite. +Defina `autoJoin: "allowlist"` junto com `autoJoinAllowlist` para restringir quais convites ele aceita, ou defina `autoJoin: "always"` se quiser que ele entre em todos os convites. No modo `allowlist`, `autoJoinAllowlist` aceita apenas `!roomId:server`, `#alias:server` ou `*`. -Exemplo de allowlist: +Exemplo de lista de permissões: ```json5 { @@ -106,7 +104,7 @@ Exemplo de allowlist: } ``` -Entrar em todo convite: +Entrar em todos os convites: ```json5 { @@ -151,7 +149,7 @@ Configuração baseada em senha (o token é armazenado em cache após o login): O Matrix armazena credenciais em cache em `~/.openclaw/credentials/matrix/`. A conta padrão usa `credentials.json`; contas nomeadas usam `credentials-.json`. -Quando existem credenciais em cache nesse local, o OpenClaw trata o Matrix como configurado para configuração inicial, doctor e descoberta de status do canal, mesmo que a autenticação atual não esteja definida diretamente na configuração. +Quando existem credenciais em cache nesse local, o OpenClaw trata o Matrix como configurado para configuração inicial, doctor e detecção de status do canal, mesmo que a autenticação atual não esteja definida diretamente na configuração. Equivalentes em variáveis de ambiente (usados quando a chave de configuração não está definida): @@ -181,14 +179,14 @@ Para o ID de conta normalizado `ops-bot`, use: - `MATRIX_OPS_X2D_BOT_HOMESERVER` - `MATRIX_OPS_X2D_BOT_ACCESS_TOKEN` -O Matrix escapa pontuação nos IDs de conta para manter variáveis de ambiente com escopo sem colisões. -Por exemplo, `-` vira `_X2D_`, então `ops-prod` mapeia para `MATRIX_OPS_X2D_PROD_*`. +O Matrix escapa a pontuação nos IDs de conta para manter as variáveis de ambiente com escopo livres de colisão. +Por exemplo, `-` se torna `_X2D_`, então `ops-prod` é mapeado para `MATRIX_OPS_X2D_PROD_*`. O assistente interativo só oferece o atalho de variável de ambiente quando essas variáveis de autenticação já estão presentes e a conta selecionada ainda não tem autenticação do Matrix salva na configuração. ## Exemplo de configuração -Esta é uma configuração base prática com pareamento por DM, allowlist de sala e E2EE ativado: +Esta é uma configuração base prática com pareamento de DM, lista de permissões de sala e E2EE ativado: ```json5 { @@ -223,17 +221,13 @@ Esta é uma configuração base prática com pareamento por DM, allowlist de sal } ``` -`autoJoin` se aplica a todos os convites do Matrix, incluindo convites no estilo DM. O OpenClaw não consegue -classificar com confiabilidade uma sala convidada como DM ou grupo no momento do convite, então todos os convites passam por `autoJoin` -primeiro. `dm.policy` se aplica depois que o bot entra e a sala é classificada como DM. +`autoJoin` se aplica a todos os convites do Matrix, incluindo convites no estilo DM. O OpenClaw não consegue classificar com confiabilidade uma sala convidada como DM ou grupo no momento do convite, então todos os convites passam primeiro por `autoJoin`. `dm.policy` se aplica depois que o bot entra e a sala é classificada como DM. -## Prévias por streaming +## Prévias de streaming -O streaming de respostas no Matrix é opt-in. +O streaming de respostas do Matrix é opcional. -Defina `channels.matrix.streaming` como `"partial"` quando quiser que o OpenClaw envie uma única prévia ao vivo -da resposta, edite essa prévia no lugar enquanto o modelo gera texto e depois a -finalize quando a resposta terminar: +Defina `channels.matrix.streaming` como `"partial"` quando quiser que o OpenClaw envie uma única resposta de prévia ao vivo, edite essa prévia no mesmo lugar enquanto o modelo gera texto e depois a finalize quando a resposta terminar: ```json5 { @@ -245,29 +239,28 @@ finalize quando a resposta terminar: } ``` -- `streaming: "off"` é o padrão. O OpenClaw espera a resposta final e a envia uma vez. -- `streaming: "partial"` cria uma mensagem de prévia editável para o bloco atual do assistente usando mensagens de texto normais do Matrix. Isso preserva o comportamento legado do Matrix de notificar primeiro a prévia, então clientes padrão podem notificar com base no primeiro texto da prévia transmitida em vez do bloco finalizado. -- `streaming: "quiet"` cria uma prévia silenciosa e editável para o bloco atual do assistente. Use isso apenas quando também configurar regras de push do destinatário para edições finalizadas da prévia. -- `blockStreaming: true` ativa mensagens separadas de progresso no Matrix. Com streaming de prévia ativado, o Matrix mantém o rascunho ao vivo do bloco atual e preserva os blocos concluídos como mensagens separadas. -- Quando a prévia por streaming está ativada e `blockStreaming` está desativado, o Matrix edita o rascunho ao vivo no lugar e finaliza esse mesmo evento quando o bloco ou turno termina. -- Se a prévia não couber mais em um único evento do Matrix, o OpenClaw interrompe a prévia por streaming e volta para a entrega final normal. -- Respostas com mídia continuam enviando anexos normalmente. Se uma prévia antiga não puder mais ser reutilizada com segurança, o OpenClaw a remove antes de enviar a resposta final com mídia. +- `streaming: "off"` é o padrão. O OpenClaw espera a resposta final e a envia uma única vez. +- `streaming: "partial"` cria uma mensagem de prévia editável para o bloco atual do assistente usando mensagens de texto normais do Matrix. Isso preserva o comportamento legado de notificação baseado na primeira prévia do Matrix, então clientes padrão podem notificar com o primeiro texto transmitido em streaming em vez do bloco concluído. +- `streaming: "quiet"` cria uma prévia silenciosa editável para o bloco atual do assistente. Use isso apenas quando você também configurar regras de push do destinatário para edições de prévia finalizadas. +- `blockStreaming: true` ativa mensagens de progresso separadas do Matrix. Com o streaming de prévia ativado, o Matrix mantém o rascunho ao vivo do bloco atual e preserva os blocos concluídos como mensagens separadas. +- Quando o streaming de prévia está ativado e `blockStreaming` está desativado, o Matrix edita o rascunho ao vivo no mesmo lugar e finaliza esse mesmo evento quando o bloco ou o turno termina. +- Se a prévia não couber mais em um único evento do Matrix, o OpenClaw interrompe o streaming de prévia e volta à entrega final normal. +- Respostas com mídia ainda enviam anexos normalmente. Se uma prévia antiga não puder mais ser reutilizada com segurança, o OpenClaw a remove antes de enviar a resposta final com mídia. - Edições de prévia geram chamadas extras à API do Matrix. Deixe o streaming desativado se quiser o comportamento mais conservador em relação a limite de taxa. `blockStreaming` não ativa prévias em rascunho por si só. -Use `streaming: "partial"` ou `streaming: "quiet"` para edições de prévia; depois adicione `blockStreaming: true` apenas se também quiser que blocos concluídos do assistente continuem visíveis como mensagens separadas de progresso. +Use `streaming: "partial"` ou `streaming: "quiet"` para edições de prévia; depois adicione `blockStreaming: true` somente se você também quiser que os blocos concluídos do assistente permaneçam visíveis como mensagens de progresso separadas. -Se você precisa de notificações padrão do Matrix sem regras de push personalizadas, use `streaming: "partial"` para o comportamento de prévia primeiro ou deixe `streaming` desativado para entrega apenas final. Com `streaming: "off"`: +Se você precisar de notificações padrão do Matrix sem regras de push personalizadas, use `streaming: "partial"` para o comportamento baseado na primeira prévia ou deixe `streaming` desativado para entrega somente final. Com `streaming: "off"`: - `blockStreaming: true` envia cada bloco concluído como uma mensagem normal notificável do Matrix. - `blockStreaming: false` envia apenas a resposta final concluída como uma mensagem normal notificável do Matrix. ### Regras de push auto-hospedadas para prévias silenciosas finalizadas -Se você executa sua própria infraestrutura Matrix e quer que prévias silenciosas notifiquem apenas quando um bloco ou -a resposta final terminarem, defina `streaming: "quiet"` e adicione uma regra de push por usuário para edições finalizadas da prévia. +Se você executa sua própria infraestrutura Matrix e quer que prévias silenciosas notifiquem apenas quando um bloco ou resposta final for concluído, defina `streaming: "quiet"` e adicione uma regra de push por usuário para edições de prévia finalizadas. -Normalmente isso é uma configuração do usuário destinatário, não uma alteração global de configuração do homeserver: +Normalmente isso é uma configuração do usuário destinatário, não uma alteração de configuração global do homeserver: Mapa rápido antes de começar: @@ -288,13 +281,12 @@ Mapa rápido antes de começar: } ``` -2. Certifique-se de que a conta destinatária já receba notificações push normais do Matrix. Regras para prévias silenciosas - só funcionam se esse usuário já tiver pushers/dispositivos funcionando. +2. Certifique-se de que a conta destinatária já recebe notificações push normais do Matrix. As regras de prévia silenciosa só funcionam se esse usuário já tiver pushers/dispositivos funcionando. 3. Obtenha o token de acesso do usuário destinatário. - Use o token do usuário que recebe, não o token do bot. - - Reaproveitar o token de uma sessão existente do cliente normalmente é o mais fácil. - - Se precisar gerar um token novo, você pode fazer login pela API Client-Server padrão do Matrix: + - Reutilizar um token de sessão de cliente existente geralmente é a opção mais fácil. + - Se você precisar gerar um token novo, pode fazer login pela API Client-Server padrão do Matrix: ```bash curl -sS -X POST \ @@ -318,8 +310,7 @@ curl -sS \ "https://matrix.example.org/_matrix/client/v3/pushers" ``` -Se isso retornar sem pushers/dispositivos ativos, corrija primeiro as notificações normais do Matrix antes de adicionar a -regra do OpenClaw abaixo. +Se isso retornar zero pushers/dispositivos ativos, corrija primeiro as notificações normais do Matrix antes de adicionar a regra do OpenClaw abaixo. O OpenClaw marca edições finalizadas de prévia somente de texto com: @@ -329,7 +320,7 @@ O OpenClaw marca edições finalizadas de prévia somente de texto com: } ``` -5. Crie uma regra de push de override para cada conta destinatária que deve receber essas notificações: +5. Crie uma regra de push de substituição para cada conta destinatária que deve receber essas notificações: ```bash curl -sS -X PUT \ @@ -361,21 +352,21 @@ curl -sS -X PUT \ Substitua estes valores antes de executar o comando: -- `https://matrix.example.org`: URL base do seu homeserver -- `$USER_ACCESS_TOKEN`: token de acesso do usuário que recebe -- `openclaw-finalized-preview-botname`: um ID de regra único para este bot para este usuário destinatário -- `@bot:example.org`: o MXID do seu bot Matrix do OpenClaw, não o MXID do usuário destinatário +- `https://matrix.example.org`: a URL base do seu homeserver +- `$USER_ACCESS_TOKEN`: o token de acesso do usuário que recebe +- `openclaw-finalized-preview-botname`: um ID de regra único para este bot para este usuário que recebe +- `@bot:example.org`: o MXID do seu bot Matrix do OpenClaw, não o MXID do usuário que recebe Importante para configurações com vários bots: -- Regras de push são indexadas por `ruleId`. Executar `PUT` novamente contra o mesmo ID de regra atualiza essa regra. -- Se um usuário destinatário deve receber notificações de várias contas Matrix bot do OpenClaw, crie uma regra por bot com um ID de regra único para cada correspondência de remetente. +- As regras de push são indexadas por `ruleId`. Executar `PUT` novamente no mesmo ID de regra atualiza essa única regra. +- Se um mesmo usuário destinatário deve receber notificações de várias contas de bot Matrix do OpenClaw, crie uma regra por bot com um ID de regra único para cada correspondência de remetente. - Um padrão simples é `openclaw-finalized-preview-`, como `openclaw-finalized-preview-ops` ou `openclaw-finalized-preview-support`. -A regra é avaliada em relação ao remetente do evento: +A regra é avaliada com base no remetente do evento: - autentique com o token do usuário destinatário -- faça a correspondência de `sender` com o MXID do bot do OpenClaw +- faça a correspondência de `sender` com o MXID do bot OpenClaw 6. Verifique se a regra existe: @@ -385,10 +376,9 @@ curl -sS \ "https://matrix.example.org/_matrix/client/v3/pushrules/global/override/openclaw-finalized-preview-botname" ``` -7. Teste uma resposta por streaming. No modo silencioso, a sala deve mostrar uma prévia silenciosa em rascunho e a - edição final no lugar deve notificar quando o bloco ou o turno terminar. +7. Teste uma resposta em streaming. No modo silencioso, a sala deve mostrar uma prévia de rascunho silenciosa, e a edição final no mesmo lugar deve enviar uma notificação quando o bloco ou turno terminar. -Se precisar remover a regra depois, exclua esse mesmo ID de regra com o token do usuário destinatário: +Se você precisar remover a regra depois, exclua esse mesmo ID de regra com o token do usuário destinatário: ```bash curl -sS -X DELETE \ @@ -400,29 +390,29 @@ Observações: - Crie a regra com o token de acesso do usuário destinatário, não com o token do bot. - Novas regras `override` definidas pelo usuário são inseridas antes das regras padrão de supressão, então nenhum parâmetro extra de ordenação é necessário. -- Isso afeta apenas edições de prévia somente de texto que o OpenClaw consegue finalizar com segurança no lugar. Fallbacks de mídia e fallbacks de prévia antiga continuam usando a entrega normal do Matrix. -- Se `GET /_matrix/client/v3/pushers` não mostrar pushers, o usuário ainda não tem entrega push do Matrix funcionando para essa conta/dispositivo. +- Isso afeta apenas edições de prévia somente de texto que o OpenClaw pode finalizar com segurança no mesmo lugar. Fallbacks de mídia e fallbacks de prévia obsoleta ainda usam a entrega normal do Matrix. +- Se `GET /_matrix/client/v3/pushers` não mostrar pushers, o usuário ainda não tem entrega de push do Matrix funcionando para essa conta/dispositivo. #### Synapse -No Synapse, a configuração acima normalmente já é suficiente por si só: +Para o Synapse, a configuração acima normalmente já é suficiente por si só: - Nenhuma alteração especial em `homeserver.yaml` é necessária para notificações de prévia finalizada do OpenClaw. - Se sua implantação do Synapse já envia notificações push normais do Matrix, o token do usuário + a chamada `pushrules` acima são a principal etapa de configuração. -- Se você executa o Synapse atrás de um proxy reverso ou workers, certifique-se de que `/_matrix/client/.../pushrules/` chegue corretamente ao Synapse. -- Se você executa workers do Synapse, certifique-se de que os pushers estejam saudáveis. A entrega de push é tratada pelo processo principal ou por `synapse.app.pusher` / workers de pusher configurados. +- Se você executa o Synapse atrás de um proxy reverso ou workers, verifique se `/_matrix/client/.../pushrules/` chega corretamente ao Synapse. +- Se você executa workers do Synapse, verifique se os pushers estão saudáveis. A entrega de push é tratada pelo processo principal ou por `synapse.app.pusher` / workers de pusher configurados. #### Tuwunel -Para Tuwunel, use o mesmo fluxo de configuração e a mesma chamada de API `pushrules` mostrada acima: +Para o Tuwunel, use o mesmo fluxo de configuração e a chamada de API `pushrules` mostrados acima: -- Nenhuma configuração específica do Tuwunel é necessária para o marcador de prévia finalizada em si. +- Nenhuma configuração específica do Tuwunel é necessária para o próprio marcador de prévia finalizada. - Se as notificações normais do Matrix já funcionam para esse usuário, o token do usuário + a chamada `pushrules` acima são a principal etapa de configuração. -- Se as notificações parecerem desaparecer enquanto o usuário está ativo em outro dispositivo, verifique se `suppress_push_when_active` está ativado. O Tuwunel adicionou essa opção no Tuwunel 1.4.2 em 12 de setembro de 2025, e ela pode suprimir intencionalmente envios push para outros dispositivos enquanto um dispositivo está ativo. +- Se as notificações parecerem desaparecer enquanto o usuário está ativo em outro dispositivo, verifique se `suppress_push_when_active` está ativado. O Tuwunel adicionou essa opção no Tuwunel 1.4.2 em 12 de setembro de 2025, e ela pode suprimir intencionalmente pushes para outros dispositivos enquanto um dispositivo está ativo. ## Salas bot para bot -Por padrão, mensagens Matrix de outras contas Matrix do OpenClaw configuradas são ignoradas. +Por padrão, mensagens do Matrix vindas de outras contas Matrix do OpenClaw configuradas são ignoradas. Use `allowBots` quando você quiser intencionalmente tráfego Matrix entre agentes: @@ -441,19 +431,19 @@ Use `allowBots` quando você quiser intencionalmente tráfego Matrix entre agent } ``` -- `allowBots: true` aceita mensagens de outras contas Matrix bot configuradas em salas e DMs permitidas. -- `allowBots: "mentions"` aceita essas mensagens apenas quando mencionam visivelmente este bot em salas. DMs continuam permitidas. -- `groups..allowBots` substitui a configuração em nível de conta para uma sala. +- `allowBots: true` aceita mensagens de outras contas de bot Matrix configuradas em salas e DMs permitidas. +- `allowBots: "mentions"` aceita essas mensagens apenas quando elas mencionam visivelmente este bot nas salas. DMs continuam permitidas. +- `groups..allowBots` substitui a configuração no nível da conta para uma sala. - O OpenClaw ainda ignora mensagens do mesmo ID de usuário Matrix para evitar loops de autorresposta. -- O Matrix não expõe aqui uma sinalização nativa de bot; o OpenClaw trata "de autoria de bot" como "enviado por outra conta Matrix configurada neste gateway OpenClaw". +- O Matrix não expõe aqui um sinalizador nativo de bot; o OpenClaw trata "de autoria de bot" como "enviado por outra conta Matrix configurada neste Gateway OpenClaw". -Use allowlists estritas de sala e exigências de menção ao ativar tráfego bot para bot em salas compartilhadas. +Use listas de permissões de sala estritas e exigências de menção ao ativar tráfego bot para bot em salas compartilhadas. ## Criptografia e verificação -Em salas criptografadas (E2EE), eventos de imagem de saída usam `thumbnail_file` para que prévias de imagem sejam criptografadas junto com o anexo completo. Salas não criptografadas continuam usando `thumbnail_url` simples. Nenhuma configuração é necessária — o plugin detecta o estado de E2EE automaticamente. +Em salas criptografadas (E2EE), eventos de imagem de saída usam `thumbnail_file` para que as prévias de imagem sejam criptografadas junto com o anexo completo. Salas não criptografadas continuam usando `thumbnail_url` simples. Nenhuma configuração é necessária — o Plugin detecta automaticamente o estado de E2EE. -Ative a criptografia: +Ativar criptografia: ```json5 { @@ -469,91 +459,89 @@ Ative a criptografia: } ``` -Verifique o status de verificação: +Verificar o status da verificação: ```bash openclaw matrix verify status ``` -Status detalhado (diagnóstico completo): +Status detalhado (diagnósticos completos): ```bash openclaw matrix verify status --verbose ``` -Inclua a chave de recuperação armazenada na saída legível por máquina: +Incluir a chave de recuperação armazenada na saída legível por máquina: ```bash openclaw matrix verify status --include-recovery-key --json ``` -Inicialize o estado de cross-signing e verificação: +Inicializar o estado de cross-signing e verificação: ```bash openclaw matrix verify bootstrap ``` -Diagnóstico detalhado de bootstrap: +Diagnósticos detalhados de bootstrap: ```bash openclaw matrix verify bootstrap --verbose ``` -Force uma redefinição nova da identidade de cross-signing antes do bootstrap: +Forçar uma redefinição nova da identidade de cross-signing antes do bootstrap: ```bash openclaw matrix verify bootstrap --force-reset-cross-signing ``` -Verifique este dispositivo com uma chave de recuperação: +Verificar este dispositivo com uma chave de recuperação: ```bash openclaw matrix verify device "" ``` -Detalhes de verificação do dispositivo em modo detalhado: +Detalhes detalhados da verificação do dispositivo: ```bash openclaw matrix verify device "" --verbose ``` -Verifique a integridade do backup de chaves de sala: +Verificar a integridade do backup de chaves de sala: ```bash openclaw matrix verify backup status ``` -Diagnóstico detalhado da integridade do backup: +Diagnósticos detalhados da integridade do backup: ```bash openclaw matrix verify backup status --verbose ``` -Restaure chaves de sala a partir do backup do servidor: +Restaurar chaves de sala do backup no servidor: ```bash openclaw matrix verify backup restore ``` -Diagnóstico detalhado da restauração: +Diagnósticos detalhados da restauração: ```bash openclaw matrix verify backup restore --verbose ``` -Exclua o backup atual no servidor e crie uma nova base de backup. Se a chave de -backup armazenada não puder ser carregada corretamente, essa redefinição também pode recriar o armazenamento secreto para que -inicializações frias futuras consigam carregar a nova chave de backup: +Excluir o backup atual do servidor e criar uma nova base de backup. Se a chave de backup armazenada não puder ser carregada corretamente, essa redefinição também poderá recriar o armazenamento de segredos para que futuras inicializações a frio consigam carregar a nova chave de backup: ```bash openclaw matrix verify backup reset --yes ``` -Todos os comandos `verify` são concisos por padrão (incluindo logs internos silenciosos do SDK) e mostram diagnósticos detalhados apenas com `--verbose`. -Use `--json` para saída completa legível por máquina ao automatizar. +Todos os comandos `verify` são concisos por padrão (incluindo logs internos silenciosos do SDK) e só mostram diagnósticos detalhados com `--verbose`. +Use `--json` para saída completa legível por máquina ao criar scripts. -Em configurações com múltiplas contas, comandos de CLI do Matrix usam a conta padrão implícita do Matrix, a menos que você passe `--account `. -Se você configurar várias contas nomeadas, defina `channels.matrix.defaultAccount` primeiro ou essas operações implícitas de CLI vão parar e pedir que você escolha uma conta explicitamente. +Em configurações com várias contas, os comandos CLI do Matrix usam a conta padrão implícita do Matrix, a menos que você passe `--account `. +Se você configurar várias contas nomeadas, defina primeiro `channels.matrix.defaultAccount`, ou essas operações implícitas da CLI vão parar e pedir que você escolha uma conta explicitamente. Use `--account` sempre que quiser que operações de verificação ou de dispositivo tenham como alvo explicitamente uma conta nomeada: ```bash @@ -564,41 +552,38 @@ openclaw matrix devices list --account assistant Quando a criptografia está desativada ou indisponível para uma conta nomeada, avisos do Matrix e erros de verificação apontam para a chave de configuração dessa conta, por exemplo `channels.matrix.accounts.assistant.encryption`. -### O que "verified" significa +### O que "verificado" significa O OpenClaw trata este dispositivo Matrix como verificado apenas quando ele é verificado pela sua própria identidade de cross-signing. Na prática, `openclaw matrix verify status --verbose` expõe três sinais de confiança: - `Locally trusted`: este dispositivo é confiável apenas pelo cliente atual -- `Cross-signing verified`: o SDK relata o dispositivo como verificado via cross-signing -- `Signed by owner`: o dispositivo é assinado pela sua própria chave self-signing +- `Cross-signing verified`: o SDK informa que o dispositivo está verificado por cross-signing +- `Signed by owner`: o dispositivo é assinado pela sua própria chave de self-signing -`Verified by owner` só passa a ser `yes` quando há verificação por cross-signing ou assinatura do proprietário. -Confiabilidade local sozinha não é suficiente para que o OpenClaw trate o dispositivo como totalmente verificado. +`Verified by owner` só se torna `yes` quando há verificação por cross-signing ou assinatura pelo proprietário. +A confiança local, por si só, não é suficiente para o OpenClaw tratar o dispositivo como totalmente verificado. ### O que o bootstrap faz `openclaw matrix verify bootstrap` é o comando de reparo e configuração para contas Matrix criptografadas. -Ele faz tudo o que segue nesta ordem: +Ele faz tudo o seguinte, nesta ordem: -- inicializa o armazenamento secreto, reaproveitando uma chave de recuperação existente quando possível -- inicializa o cross-signing e faz upload das chaves públicas de cross-signing ausentes -- tenta marcar e assinar via cross-signing o dispositivo atual -- cria um novo backup de chaves de sala no servidor se ainda não existir +- inicializa o armazenamento de segredos, reutilizando uma chave de recuperação existente quando possível +- inicializa o cross-signing e envia as chaves públicas de cross-signing ausentes +- tenta marcar e assinar por cross-signing o dispositivo atual +- cria um novo backup de chaves de sala no lado do servidor, se ainda não existir um -Se o homeserver exigir autenticação interativa para fazer upload das chaves de cross-signing, o OpenClaw tenta o upload primeiro sem autenticação, depois com `m.login.dummy` e depois com `m.login.password` quando `channels.matrix.password` está configurado. +Se o homeserver exigir autenticação interativa para enviar chaves de cross-signing, o OpenClaw tenta o envio primeiro sem autenticação, depois com `m.login.dummy`, e depois com `m.login.password` quando `channels.matrix.password` está configurado. -Use `--force-reset-cross-signing` apenas quando quiser intencionalmente descartar a identidade de cross-signing atual e criar uma nova. +Use `--force-reset-cross-signing` apenas quando você quiser intencionalmente descartar a identidade atual de cross-signing e criar uma nova. -Se você quiser intencionalmente descartar o backup atual de chaves de sala e iniciar uma nova -base de backup para mensagens futuras, use `openclaw matrix verify backup reset --yes`. -Faça isso apenas quando aceitar que o histórico criptografado antigo irrecuperável continuará -indisponível e que o OpenClaw pode recriar o armazenamento secreto se o segredo atual do backup -não puder ser carregado com segurança. +Se você quiser intencionalmente descartar o backup atual de chaves de sala e iniciar uma nova base de backup para mensagens futuras, use `openclaw matrix verify backup reset --yes`. +Faça isso apenas se aceitar que o histórico criptografado antigo irrecuperável continuará indisponível e que o OpenClaw pode recriar o armazenamento de segredos se o segredo atual de backup não puder ser carregado com segurança. ### Nova base de backup -Se você quiser manter mensagens criptografadas futuras funcionando e aceitar perder histórico antigo irrecuperável, execute estes comandos nesta ordem: +Se você quiser manter o funcionamento das futuras mensagens criptografadas e aceitar perder o histórico antigo irrecuperável, execute estes comandos em ordem: ```bash openclaw matrix verify backup reset --yes @@ -611,42 +596,40 @@ Adicione `--account ` a cada comando quando quiser direcionar explicitamente ### Comportamento na inicialização Quando `encryption: true`, o Matrix define `startupVerification` como `"if-unverified"` por padrão. -Na inicialização, se este dispositivo ainda não estiver verificado, o Matrix solicitará autoverificação em outro cliente Matrix, -ignorará solicitações duplicadas enquanto já houver uma pendente e aplicará um cooldown local antes de tentar novamente após reinicializações. -Tentativas de solicitação com falha são repetidas antes do que a criação bem-sucedida de solicitações, por padrão. -Defina `startupVerification: "off"` para desativar solicitações automáticas na inicialização, ou ajuste `startupVerificationCooldownHours` -se quiser uma janela de repetição mais curta ou mais longa. +Na inicialização, se este dispositivo ainda não estiver verificado, o Matrix solicitará autoverificação em outro cliente Matrix, ignorará solicitações duplicadas enquanto uma já estiver pendente e aplicará um cooldown local antes de tentar novamente após reinicializações. +Tentativas de solicitação com falha tentam novamente mais cedo do que a criação bem-sucedida da solicitação por padrão. +Defina `startupVerification: "off"` para desativar solicitações automáticas na inicialização, ou ajuste `startupVerificationCooldownHours` se quiser uma janela de nova tentativa mais curta ou mais longa. -A inicialização também executa automaticamente uma etapa conservadora de bootstrap de criptografia. -Essa etapa tenta primeiro reutilizar o armazenamento secreto e a identidade de cross-signing atuais e evita redefinir o cross-signing, a menos que você execute um fluxo explícito de reparo de bootstrap. +A inicialização também executa automaticamente uma passagem conservadora de bootstrap de criptografia. +Essa passagem tenta reutilizar primeiro o armazenamento de segredos e a identidade de cross-signing atuais, e evita redefinir o cross-signing, a menos que você execute um fluxo explícito de reparo de bootstrap. Se a inicialização encontrar um estado de bootstrap quebrado e `channels.matrix.password` estiver configurado, o OpenClaw poderá tentar um caminho de reparo mais rigoroso. -Se o dispositivo atual já estiver assinado pelo proprietário, o OpenClaw preserva essa identidade em vez de redefini-la automaticamente. +Se o dispositivo atual já estiver assinado pelo proprietário, o OpenClaw preservará essa identidade em vez de redefini-la automaticamente. -Veja [Migração do Matrix](/pt-BR/install/migrating-matrix) para o fluxo completo de atualização, limites, comandos de recuperação e mensagens comuns de migração. +Consulte [migração do Matrix](/pt-BR/install/migrating-matrix) para ver o fluxo completo de upgrade, limites, comandos de recuperação e mensagens comuns de migração. ### Avisos de verificação -O Matrix publica avisos do ciclo de vida de verificação diretamente na DM estrita de verificação como mensagens `m.notice`. +O Matrix publica avisos do ciclo de vida da verificação diretamente na DM estrita de verificação como mensagens `m.notice`. Isso inclui: - avisos de solicitação de verificação - avisos de verificação pronta (com orientação explícita "Verifique por emoji") - avisos de início e conclusão da verificação -- detalhes de SAS (emoji e decimal) quando disponíveis +- detalhes SAS (emoji e decimal), quando disponíveis Solicitações de verificação recebidas de outro cliente Matrix são rastreadas e aceitas automaticamente pelo OpenClaw. -Para fluxos de autoverificação, o OpenClaw também inicia automaticamente o fluxo SAS quando a verificação por emoji fica disponível e confirma seu próprio lado. -Para solicitações de verificação de outro usuário/dispositivo Matrix, o OpenClaw aceita automaticamente a solicitação e depois espera que o fluxo SAS prossiga normalmente. -Você ainda precisa comparar o SAS em emoji ou decimal no seu cliente Matrix e confirmar "They match" lá para concluir a verificação. +Para fluxos de autoverificação, o OpenClaw também inicia automaticamente o fluxo SAS quando a verificação por emoji fica disponível e confirma o próprio lado. +Para solicitações de verificação de outro usuário/dispositivo Matrix, o OpenClaw aceita automaticamente a solicitação e então espera que o fluxo SAS prossiga normalmente. +Ainda assim, você precisa comparar o SAS em emoji ou decimal no seu cliente Matrix e confirmar "They match" lá para concluir a verificação. -O OpenClaw não aceita automaticamente fluxos duplicados iniciados por ele mesmo sem critério. Na inicialização, ele evita criar uma nova solicitação quando já existe uma solicitação pendente de autoverificação. +O OpenClaw não aceita automaticamente de forma cega fluxos duplicados iniciados por ele mesmo. Na inicialização, ele não cria uma nova solicitação quando uma solicitação de autoverificação já está pendente. Avisos de protocolo/sistema de verificação não são encaminhados para o pipeline de chat do agente, então eles não produzem `NO_REPLY`. ### Higiene de dispositivos -Dispositivos Matrix antigos gerenciados pelo OpenClaw podem se acumular na conta e tornar mais difícil entender a confiança em salas criptografadas. +Dispositivos Matrix antigos gerenciados pelo OpenClaw podem se acumular na conta e tornar a confiança em salas criptografadas mais difícil de entender. Liste-os com: ```bash @@ -659,22 +642,22 @@ Remova dispositivos antigos gerenciados pelo OpenClaw com: openclaw matrix devices prune-stale ``` -### Armazenamento de criptografia +### Armazenamento criptográfico -O E2EE do Matrix usa o caminho oficial de criptografia Rust do `matrix-js-sdk` em Node, com `fake-indexeddb` como shim de IndexedDB. O estado de criptografia é persistido em um arquivo de snapshot (`crypto-idb-snapshot.json`) e restaurado na inicialização. O arquivo de snapshot é um estado de execução sensível armazenado com permissões restritivas. +O E2EE do Matrix usa o caminho de criptografia Rust oficial do `matrix-js-sdk` no Node, com `fake-indexeddb` como shim do IndexedDB. O estado criptográfico é persistido em um arquivo de snapshot (`crypto-idb-snapshot.json`) e restaurado na inicialização. O arquivo de snapshot é um estado de execução sensível armazenado com permissões restritivas de arquivo. -O estado de execução criptografado fica em raízes por conta, por usuário e por hash de token em +O estado criptografado em execução fica em raízes por conta, por usuário e por hash de token em `~/.openclaw/matrix/accounts//__//`. -Esse diretório contém o armazenamento de sync (`bot-storage.json`), armazenamento de criptografia (`crypto/`), +Esse diretório contém o armazenamento de sincronização (`bot-storage.json`), armazenamento criptográfico (`crypto/`), arquivo de chave de recuperação (`recovery-key.json`), snapshot do IndexedDB (`crypto-idb-snapshot.json`), -bindings de thread (`thread-bindings.json`) e estado de verificação na inicialização (`startup-verification.json`). -Quando o token muda, mas a identidade da conta permanece a mesma, o OpenClaw reutiliza a melhor -raiz existente para essa tupla de conta/homeserver/usuário para que o estado anterior de sync, estado de criptografia, bindings de thread +vínculos de thread (`thread-bindings.json`) e estado de verificação na inicialização (`startup-verification.json`). +Quando o token muda, mas a identidade da conta permanece a mesma, o OpenClaw reutiliza a melhor raiz existente +para essa tupla conta/homeserver/usuário para que o estado anterior de sincronização, estado criptográfico, vínculos de thread e estado de verificação na inicialização continuem visíveis. ## Gerenciamento de perfil -Atualize o perfil próprio do Matrix para a conta selecionada com: +Atualize o próprio perfil Matrix da conta selecionada com: ```bash openclaw matrix profile set --name "OpenClaw Assistant" @@ -687,41 +670,41 @@ O Matrix aceita URLs de avatar `mxc://` diretamente. Quando você passa uma URL ## Threads -O Matrix oferece suporte a threads nativas do Matrix tanto para respostas automáticas quanto para envios com ferramentas de mensagem. +O Matrix oferece suporte a threads nativas do Matrix tanto para respostas automáticas quanto para envios da ferramenta de mensagem. - `dm.sessionScope: "per-user"` (padrão) mantém o roteamento de DM do Matrix com escopo por remetente, para que várias salas de DM possam compartilhar uma sessão quando forem resolvidas para o mesmo par. -- `dm.sessionScope: "per-room"` isola cada sala de DM do Matrix em sua própria chave de sessão, ainda usando autenticação normal de DM e verificações de allowlist. -- Bindings explícitos de conversa Matrix ainda têm precedência sobre `dm.sessionScope`, então salas e threads vinculadas mantêm a sessão de destino escolhida. -- `threadReplies: "off"` mantém respostas no nível superior e mantém mensagens recebidas em thread na sessão pai. +- `dm.sessionScope: "per-room"` isola cada sala de DM do Matrix em sua própria chave de sessão, ainda usando autenticação e verificações de lista de permissões normais de DM. +- Vínculos explícitos de conversa do Matrix ainda têm precedência sobre `dm.sessionScope`, então salas e threads vinculadas mantêm a sessão de destino escolhida. +- `threadReplies: "off"` mantém as respostas no nível superior e mantém as mensagens encadeadas de entrada na sessão pai. - `threadReplies: "inbound"` responde dentro de uma thread apenas quando a mensagem recebida já estava nessa thread. -- `threadReplies: "always"` mantém respostas de sala em uma thread enraizada na mensagem que acionou a resposta e encaminha essa conversa pela sessão com escopo de thread correspondente a partir da primeira mensagem acionadora. -- `dm.threadReplies` substitui a configuração de nível superior apenas para DMs. Por exemplo, você pode manter threads de sala isoladas enquanto mantém DMs planas. -- Mensagens recebidas em thread incluem a mensagem raiz da thread como contexto extra para o agente. -- Envios com ferramentas de mensagem herdam automaticamente a thread atual do Matrix quando o destino é a mesma sala, ou o mesmo alvo de usuário em DM, a menos que um `threadId` explícito seja fornecido. -- O reaproveitamento do mesmo alvo de usuário de DM na mesma sessão só entra em ação quando os metadados da sessão atual comprovam o mesmo par de DM na mesma conta Matrix; caso contrário, o OpenClaw volta para o roteamento normal com escopo por usuário. -- Quando o OpenClaw detecta que uma sala de DM do Matrix colide com outra sala de DM na mesma sessão de DM compartilhada do Matrix, ele publica um `m.notice` único nessa sala com a rota de escape `/focus` quando bindings de thread estão ativados e a dica `dm.sessionScope`. -- Bindings de thread em tempo de execução são suportados para Matrix. `/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age` e `/acp spawn` vinculado a thread funcionam em salas e DMs do Matrix. -- `/focus` de sala/DM Matrix no nível superior cria uma nova thread Matrix e a vincula à sessão de destino quando `threadBindings.spawnSubagentSessions=true`. -- Executar `/focus` ou `/acp spawn --thread here` dentro de uma thread Matrix existente vincula essa thread atual. +- `threadReplies: "always"` mantém respostas de sala em uma thread enraizada na mensagem que acionou a resposta e roteia essa conversa pela sessão com escopo de thread correspondente a partir da primeira mensagem acionadora. +- `dm.threadReplies` substitui a configuração de nível superior apenas para DMs. Por exemplo, você pode manter threads de sala isoladas enquanto mantém DMs sem threads. +- Mensagens encadeadas recebidas incluem a mensagem raiz da thread como contexto extra do agente. +- Envios da ferramenta de mensagem herdam automaticamente a thread atual do Matrix quando o destino é a mesma sala, ou o mesmo destino de usuário em DM, a menos que um `threadId` explícito seja fornecido. +- A reutilização do mesmo destino de usuário em DM na mesma sessão só entra em ação quando os metadados da sessão atual comprovam o mesmo par de DM na mesma conta Matrix; caso contrário, o OpenClaw recorre ao roteamento normal com escopo por usuário. +- Quando o OpenClaw detecta que uma sala de DM do Matrix colide com outra sala de DM na mesma sessão compartilhada de DM do Matrix, ele publica um único `m.notice` nessa sala com a rota de escape `/focus` quando os vínculos de thread estão ativados e a dica `dm.sessionScope`. +- Vínculos de thread em execução são suportados para o Matrix. `/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age` e `/acp spawn` vinculado a thread funcionam em salas e DMs do Matrix. +- `/focus` no nível superior de sala/DM do Matrix cria uma nova thread do Matrix e a vincula à sessão de destino quando `threadBindings.spawnSubagentSessions=true`. +- Executar `/focus` ou `/acp spawn --thread here` dentro de uma thread existente do Matrix vincula essa thread atual no lugar. -## Bindings de conversa ACP +## Vínculos de conversa ACP -Salas, DMs e threads Matrix existentes podem ser transformadas em workspaces ACP duráveis sem mudar a superfície de chat. +Salas, DMs e threads existentes do Matrix podem ser transformadas em espaços de trabalho ACP duráveis sem mudar a superfície do chat. -Fluxo rápido do operador: +Fluxo rápido para operador: - Execute `/acp spawn codex --bind here` dentro da DM, sala ou thread existente do Matrix que você quer continuar usando. -- Em uma DM ou sala Matrix no nível superior, a DM/sala atual permanece como superfície de chat e mensagens futuras são roteadas para a sessão ACP criada. -- Dentro de uma thread Matrix existente, `--bind here` vincula essa thread atual no lugar. +- Em uma DM ou sala Matrix de nível superior, a DM/sala atual continua sendo a superfície do chat e as mensagens futuras são roteadas para a sessão ACP criada. +- Dentro de uma thread existente do Matrix, `--bind here` vincula essa thread atual no lugar. - `/new` e `/reset` redefinem a mesma sessão ACP vinculada no lugar. -- `/acp close` fecha a sessão ACP e remove o binding. +- `/acp close` fecha a sessão ACP e remove o vínculo. Observações: -- `--bind here` não cria uma thread Matrix filha. -- `threadBindings.spawnAcpSessions` só é necessário para `/acp spawn --thread auto|here`, quando o OpenClaw precisa criar ou vincular uma thread Matrix filha. +- `--bind here` não cria uma thread filha do Matrix. +- `threadBindings.spawnAcpSessions` só é necessário para `/acp spawn --thread auto|here`, quando o OpenClaw precisa criar ou vincular uma thread filha do Matrix. -### Configuração de binding de thread +### Configuração de vínculo de thread O Matrix herda padrões globais de `session.threadBindings` e também oferece suporte a substituições por canal: @@ -731,22 +714,22 @@ O Matrix herda padrões globais de `session.threadBindings` e também oferece su - `threadBindings.spawnSubagentSessions` - `threadBindings.spawnAcpSessions` -As flags de criação vinculada a thread no Matrix são opt-in: +Os sinalizadores de criação vinculada a thread do Matrix são opt-in: -- Defina `threadBindings.spawnSubagentSessions: true` para permitir que `/focus` no nível superior crie e vincule novas threads Matrix. -- Defina `threadBindings.spawnAcpSessions: true` para permitir que `/acp spawn --thread auto|here` vincule sessões ACP a threads Matrix. +- Defina `threadBindings.spawnSubagentSessions: true` para permitir que `/focus` no nível superior crie e vincule novas threads do Matrix. +- Defina `threadBindings.spawnAcpSessions: true` para permitir que `/acp spawn --thread auto|here` vincule sessões ACP a threads do Matrix. ## Reações -O Matrix oferece suporte a ações de reação de saída, notificações de reação de entrada e reações de confirmação recebidas. +O Matrix oferece suporte a ações de reação de saída, notificações de reação de entrada e reações de confirmação de entrada. -- O uso de reações de saída é controlado por `channels["matrix"].actions.reactions`. -- `react` adiciona uma reação a um evento Matrix específico. -- `reactions` lista o resumo atual de reações para um evento Matrix específico. -- `emoji=""` remove as reações da própria conta do bot nesse evento. -- `remove: true` remove apenas a reação do emoji especificado da conta do bot. +- A ferramenta de reação de saída é controlada por `channels["matrix"].actions.reactions`. +- `react` adiciona uma reação a um evento específico do Matrix. +- `reactions` lista o resumo atual de reações de um evento específico do Matrix. +- `emoji=""` remove as próprias reações da conta do bot nesse evento. +- `remove: true` remove apenas a reação de emoji especificada da conta do bot. -O escopo de resolução das reações de confirmação segue a ordem padrão do OpenClaw: +O escopo das reações de confirmação é resolvido nesta ordem: - `channels["matrix"].accounts..ackReaction` - `channels["matrix"].ackReaction` @@ -769,26 +752,26 @@ Comportamento: - `reactionNotifications: "own"` encaminha eventos `m.reaction` adicionados quando eles têm como alvo mensagens Matrix de autoria do bot. - `reactionNotifications: "off"` desativa eventos de sistema de reação. -- Remoções de reação não são sintetizadas em eventos de sistema porque o Matrix as expõe como redações, não como remoções independentes de `m.reaction`. +- Remoções de reação não são sintetizadas em eventos de sistema porque o Matrix as expõe como redações, não como remoções autônomas de `m.reaction`. ## Contexto de histórico -- `channels.matrix.historyLimit` controla quantas mensagens recentes da sala são incluídas como `InboundHistory` quando uma mensagem de sala no Matrix aciona o agente. Usa `messages.groupChat.historyLimit` como fallback; se ambos não estiverem definidos, o padrão efetivo é `0`. Defina `0` para desativar. -- O histórico de sala do Matrix é apenas da sala. DMs continuam usando o histórico normal da sessão. -- O histórico de sala do Matrix é apenas pendente: o OpenClaw armazena em buffer mensagens da sala que ainda não acionaram resposta, depois tira um snapshot dessa janela quando chega uma menção ou outro gatilho. -- A mensagem atual que acionou a resposta não é incluída em `InboundHistory`; ela permanece no corpo principal de entrada para esse turno. -- Novas tentativas do mesmo evento Matrix reutilizam o snapshot de histórico original em vez de avançar para mensagens mais novas da sala. +- `channels.matrix.historyLimit` controla quantas mensagens recentes da sala são incluídas como `InboundHistory` quando uma mensagem de sala do Matrix aciona o agente. Usa como fallback `messages.groupChat.historyLimit`; se ambos não estiverem definidos, o padrão efetivo é `0`. Defina `0` para desativar. +- O histórico de sala do Matrix é somente da sala. DMs continuam usando o histórico normal da sessão. +- O histórico de sala do Matrix é apenas pendente: o OpenClaw armazena em buffer mensagens da sala que ainda não acionaram uma resposta e então captura esse intervalo quando uma menção ou outro gatilho chega. +- A mensagem gatilho atual não é incluída em `InboundHistory`; ela permanece no corpo principal de entrada daquele turno. +- Novas tentativas do mesmo evento do Matrix reutilizam o snapshot original do histórico em vez de avançar para mensagens mais recentes da sala. ## Visibilidade de contexto -O Matrix oferece suporte ao controle compartilhado `contextVisibility` para contexto suplementar da sala, como texto de resposta buscado, raízes de thread e histórico pendente. +O Matrix oferece suporte ao controle compartilhado `contextVisibility` para contexto suplementar de sala, como texto de resposta buscado, raízes de thread e histórico pendente. - `contextVisibility: "all"` é o padrão. O contexto suplementar é mantido como recebido. -- `contextVisibility: "allowlist"` filtra o contexto suplementar para remetentes permitidos pelas verificações ativas de allowlist de sala/usuário. +- `contextVisibility: "allowlist"` filtra o contexto suplementar para remetentes permitidos pelas verificações ativas de lista de permissões de sala/usuário. - `contextVisibility: "allowlist_quote"` se comporta como `allowlist`, mas ainda mantém uma resposta citada explícita. -Essa configuração afeta a visibilidade do contexto suplementar, não se a própria mensagem recebida pode acionar uma resposta. -A autorização do gatilho continua vindo de `groupPolicy`, `groups`, `groupAllowFrom` e das configurações de política de DM. +Essa configuração afeta a visibilidade do contexto suplementar, não se a própria mensagem de entrada pode acionar uma resposta. +A autorização do gatilho ainda vem de `groupPolicy`, `groups`, `groupAllowFrom` e das configurações de política de DM. ## Política de DM e sala @@ -813,7 +796,7 @@ A autorização do gatilho continua vindo de `groupPolicy`, `groups`, `groupAllo } ``` -Veja [Grupos](/pt-BR/channels/groups) para comportamento de exigência de menção e allowlist. +Consulte [Groups](/pt-BR/channels/groups) para ver o comportamento de exigência de menção e lista de permissões. Exemplo de pareamento para DMs do Matrix: @@ -824,17 +807,17 @@ openclaw pairing approve matrix Se um usuário Matrix não aprovado continuar enviando mensagens antes da aprovação, o OpenClaw reutiliza o mesmo código de pareamento pendente e pode enviar uma resposta de lembrete novamente após um curto cooldown em vez de gerar um novo código. -Veja [Pareamento](/pt-BR/channels/pairing) para o fluxo compartilhado de pareamento por DM e layout de armazenamento. +Consulte [Pairing](/pt-BR/channels/pairing) para ver o fluxo compartilhado de pareamento de DM e o layout de armazenamento. -## Reparo de sala direta +## Reparo direto de sala -Se o estado de mensagem direta ficar fora de sincronia, o OpenClaw pode acabar com mapeamentos `m.direct` obsoletos que apontam para salas individuais antigas em vez da DM ativa. Inspecione o mapeamento atual de um par com: +Se o estado de mensagem direta sair de sincronia, o OpenClaw pode acabar com mapeamentos `m.direct` obsoletos que apontam para salas individuais antigas em vez da DM ativa. Inspecione o mapeamento atual de um par com: ```bash openclaw matrix direct inspect --user-id @alice:example.org ``` -Repare com: +Repare-o com: ```bash openclaw matrix direct repair --user-id @alice:example.org @@ -843,30 +826,30 @@ openclaw matrix direct repair --user-id @alice:example.org O fluxo de reparo: - prefere uma DM estrita 1:1 que já esteja mapeada em `m.direct` -- recorre a qualquer DM estrita 1:1 atualmente conectada com esse usuário +- recorre a qualquer DM estrita 1:1 atualmente ingressada com esse usuário - cria uma nova sala direta e reescreve `m.direct` se não existir uma DM saudável -O fluxo de reparo não exclui salas antigas automaticamente. Ele apenas escolhe a DM saudável e atualiza o mapeamento para que novos envios do Matrix, avisos de verificação e outros fluxos de mensagem direta voltem a apontar para a sala correta. +O fluxo de reparo não exclui automaticamente salas antigas. Ele apenas escolhe a DM saudável e atualiza o mapeamento para que novos envios do Matrix, avisos de verificação e outros fluxos de mensagem direta voltem a apontar para a sala correta. -## Aprovações de exec +## Aprovações de execução O Matrix pode atuar como um cliente nativo de aprovação para uma conta Matrix. Os controles nativos -de roteamento de DM/canal continuam ficando na configuração de aprovação de exec: +de roteamento de DM/canal ainda ficam sob a configuração de aprovação de execução: - `channels.matrix.execApprovals.enabled` -- `channels.matrix.execApprovals.approvers` (opcional; usa `channels.matrix.dm.allowFrom` como fallback) +- `channels.matrix.execApprovals.approvers` (opcional; usa como fallback `channels.matrix.dm.allowFrom`) - `channels.matrix.execApprovals.target` (`dm` | `channel` | `both`, padrão: `dm`) - `channels.matrix.execApprovals.agentFilter` - `channels.matrix.execApprovals.sessionFilter` -Os aprovadores devem ser IDs de usuário Matrix como `@owner:example.org`. O Matrix ativa aprovações nativas automaticamente quando `enabled` está sem definir ou `"auto"` e pelo menos um aprovador pode ser resolvido. Aprovações de exec usam primeiro o conjunto de aprovadores de `execApprovals.approvers` e podem usar `channels.matrix.dm.allowFrom` como fallback. Aprovações de plugin autorizam por meio de `channels.matrix.dm.allowFrom`. Defina `enabled: false` para desativar explicitamente o Matrix como cliente nativo de aprovação. Caso contrário, solicitações de aprovação recorrem a outras rotas de aprovação configuradas ou à política de fallback de aprovação. +Os aprovadores devem ser IDs de usuário Matrix, como `@owner:example.org`. O Matrix ativa automaticamente aprovações nativas quando `enabled` não está definido ou é `"auto"` e pelo menos um aprovador pode ser resolvido. Aprovações de execução usam primeiro `execApprovals.approvers` e podem usar como fallback `channels.matrix.dm.allowFrom`. Aprovações de Plugin autorizam por meio de `channels.matrix.dm.allowFrom`. Defina `enabled: false` para desativar explicitamente o Matrix como cliente nativo de aprovação. Caso contrário, solicitações de aprovação recorrem a outras rotas de aprovação configuradas ou à política de fallback de aprovação. O roteamento nativo do Matrix oferece suporte a ambos os tipos de aprovação: -- `channels.matrix.execApprovals.*` controla o modo nativo de distribuição em DM/canal para prompts de aprovação do Matrix. -- Aprovações de exec usam o conjunto de aprovadores de exec de `execApprovals.approvers` ou `channels.matrix.dm.allowFrom`. -- Aprovações de plugin usam a allowlist de DM do Matrix em `channels.matrix.dm.allowFrom`. -- Atalhos por reação e atualizações de mensagem do Matrix se aplicam tanto a aprovações de exec quanto a aprovações de plugin. +- `channels.matrix.execApprovals.*` controla o modo nativo de fanout por DM/canal para prompts de aprovação do Matrix. +- Aprovações de execução usam o conjunto de aprovadores de execução de `execApprovals.approvers` ou `channels.matrix.dm.allowFrom`. +- Aprovações de Plugin usam a lista de permissões de DM do Matrix em `channels.matrix.dm.allowFrom`. +- Atalhos de reação e atualizações de mensagem do Matrix se aplicam tanto a aprovações de execução quanto a aprovações de Plugin. Regras de entrega: @@ -874,23 +857,23 @@ Regras de entrega: - `target: "channel"` envia o prompt de volta para a sala ou DM Matrix de origem - `target: "both"` envia para as DMs dos aprovadores e para a sala ou DM Matrix de origem -Prompts de aprovação do Matrix adicionam atalhos por reação na mensagem principal de aprovação: +Os prompts de aprovação do Matrix semeiam atalhos de reação na mensagem principal de aprovação: - `✅` = permitir uma vez - `❌` = negar -- `♾️` = permitir sempre quando essa decisão for permitida pela política efetiva de exec +- `♾️` = permitir sempre quando essa decisão for permitida pela política efetiva de execução -Aprovadores podem reagir nessa mensagem ou usar os comandos slash alternativos: `/approve allow-once`, `/approve allow-always` ou `/approve deny`. +Os aprovadores podem reagir nessa mensagem ou usar os comandos slash de fallback: `/approve allow-once`, `/approve allow-always` ou `/approve deny`. -Apenas aprovadores resolvidos podem aprovar ou negar. Para aprovações de exec, a entrega em canal inclui o texto do comando, então só ative `channel` ou `both` em salas confiáveis. +Somente aprovadores resolvidos podem aprovar ou negar. Para aprovações de execução, a entrega por canal inclui o texto do comando, então só ative `channel` ou `both` em salas confiáveis. Substituição por conta: - `channels.matrix.accounts..execApprovals` -Documentação relacionada: [Aprovações de exec](/pt-BR/tools/exec-approvals) +Documentação relacionada: [Aprovações de execução](/pt-BR/tools/exec-approvals) -## Múltiplas contas +## Várias contas ```json5 { @@ -920,23 +903,24 @@ Documentação relacionada: [Aprovações de exec](/pt-BR/tools/exec-approvals) } ``` -Valores de nível superior em `channels.matrix` atuam como padrões para contas nomeadas, a menos que uma conta os substitua. -Você pode aplicar entradas de sala herdadas a uma conta Matrix com `groups..account`. -Entradas sem `account` continuam compartilhadas entre todas as contas Matrix, e entradas com `account: "default"` continuam funcionando quando a conta padrão está configurada diretamente no nível superior em `channels.matrix.*`. -Padrões compartilhados parciais de autenticação não criam sozinhos uma conta padrão implícita separada. O OpenClaw só sintetiza a conta `default` de nível superior quando essa conta padrão tem autenticação válida (`homeserver` mais `accessToken`, ou `homeserver` mais `userId` e `password`); contas nomeadas ainda podem continuar detectáveis com `homeserver` mais `userId` quando credenciais em cache satisfazem a autenticação mais tarde. -Se o Matrix já tiver exatamente uma conta nomeada, ou se `defaultAccount` apontar para uma chave existente de conta nomeada, a promoção de reparo/configuração inicial de conta única para múltiplas contas preserva essa conta em vez de criar uma nova entrada `accounts.default`. Apenas chaves de autenticação/bootstrap do Matrix são movidas para essa conta promovida; chaves compartilhadas de política de entrega permanecem no nível superior. -Defina `defaultAccount` quando quiser que o OpenClaw prefira uma conta Matrix nomeada para roteamento implícito, probing e operações de CLI. -Se você configurar várias contas nomeadas, defina `defaultAccount` ou passe `--account ` para comandos de CLI que dependem de seleção implícita de conta. +Os valores de nível superior em `channels.matrix` atuam como padrões para contas nomeadas, a menos que uma conta os substitua. +Você pode restringir entradas de sala herdadas a uma conta Matrix com `groups..account`. +Entradas sem `account` permanecem compartilhadas entre todas as contas Matrix, e entradas com `account: "default"` continuam funcionando quando a conta padrão é configurada diretamente no nível superior em `channels.matrix.*`. +Padrões parciais compartilhados de autenticação não criam, por si só, uma conta padrão implícita separada. O OpenClaw só sintetiza a conta `default` de nível superior quando esse padrão tem autenticação nova (`homeserver` mais `accessToken`, ou `homeserver` mais `userId` e `password`); contas nomeadas ainda podem continuar detectáveis a partir de `homeserver` mais `userId` quando credenciais em cache satisfazem a autenticação mais tarde. +Se o Matrix já tiver exatamente uma conta nomeada, ou `defaultAccount` apontar para uma chave existente de conta nomeada, a promoção de reparo/configuração de conta única para várias contas preserva essa conta em vez de criar uma nova entrada `accounts.default`. Somente chaves de autenticação/bootstrap do Matrix são movidas para essa conta promovida; chaves compartilhadas de política de entrega permanecem no nível superior. +Defina `defaultAccount` quando quiser que o OpenClaw prefira uma conta Matrix nomeada para roteamento implícito, sondagem e operações da CLI. +Se várias contas Matrix estiverem configuradas e um ID de conta for `default`, o OpenClaw usa essa conta implicitamente mesmo quando `defaultAccount` não está definido. +Se você configurar várias contas nomeadas, defina `defaultAccount` ou passe `--account ` para comandos da CLI que dependem de seleção implícita de conta. Passe `--account ` para `openclaw matrix verify ...` e `openclaw matrix devices ...` quando quiser substituir essa seleção implícita para um comando. -Veja [Referência de configuração](/pt-BR/gateway/configuration-reference#multi-account-all-channels) para o padrão compartilhado de múltiplas contas. +Consulte [Referência de configuração](/pt-BR/gateway/configuration-reference#multi-account-all-channels) para ver o padrão compartilhado de várias contas. ## Homeservers privados/LAN Por padrão, o OpenClaw bloqueia homeservers Matrix privados/internos para proteção contra SSRF, a menos que você -faça opt-in explicitamente por conta. +ative explicitamente essa permissão por conta. -Se seu homeserver roda em localhost, um IP de LAN/Tailscale ou um hostname interno, ative +Se seu homeserver estiver em localhost, em um IP de LAN/Tailscale ou em um nome de host interno, ative `network.dangerouslyAllowPrivateNetwork` para essa conta Matrix: ```json5 @@ -953,7 +937,7 @@ Se seu homeserver roda em localhost, um IP de LAN/Tailscale ou um hostname inter } ``` -Exemplo de configuração por CLI: +Exemplo de configuração pela CLI: ```bash openclaw matrix account add \ @@ -963,8 +947,8 @@ openclaw matrix account add \ --access-token syt_ops_xxx ``` -Esse opt-in permite apenas destinos privados/internos confiáveis. Homeservers públicos em texto claro como -`http://matrix.example.org:8008` continuam bloqueados. Prefira `https://` sempre que possível. +Essa permissão explícita permite apenas destinos privados/internos confiáveis. Homeservers públicos em texto simples, como +`http://matrix.example.org:8008`, continuam bloqueados. Prefira `https://` sempre que possível. ## Uso de proxy para tráfego Matrix @@ -983,85 +967,85 @@ Se sua implantação Matrix precisar de um proxy HTTP(S) de saída explícito, d ``` Contas nomeadas podem substituir o padrão de nível superior com `channels.matrix.accounts..proxy`. -O OpenClaw usa a mesma configuração de proxy para tráfego Matrix em tempo de execução e para sondas de status da conta. +O OpenClaw usa a mesma configuração de proxy para tráfego Matrix em execução e para sondas de status da conta. ## Resolução de destino -O Matrix aceita estas formas de destino em qualquer lugar onde o OpenClaw peça um destino de sala ou usuário: +O Matrix aceita estes formatos de destino em qualquer lugar onde o OpenClaw pedir um destino de sala ou usuário: - Usuários: `@user:server`, `user:@user:server` ou `matrix:user:@user:server` - Salas: `!room:server`, `room:!room:server` ou `matrix:room:!room:server` - Aliases: `#alias:server`, `channel:#alias:server` ou `matrix:channel:#alias:server` -A busca ativa em diretório usa a conta Matrix autenticada: +A busca ao vivo em diretório usa a conta Matrix autenticada: -- Buscas de usuário consultam o diretório de usuários do Matrix nesse homeserver. -- Buscas de sala aceitam diretamente IDs e aliases explícitos de sala, depois recorrem à busca por nomes de salas já conectadas para essa conta. -- A busca por nome de sala conectada é best-effort. Se o nome de uma sala não puder ser resolvido para um ID ou alias, ele será ignorado pela resolução de allowlist em tempo de execução. +- Buscas de usuário consultam o diretório de usuários Matrix nesse homeserver. +- Buscas de sala aceitam diretamente IDs e aliases explícitos de sala e depois recorrem à busca por nomes de salas ingressadas para essa conta. +- A busca por nome de sala ingressada é feita em regime de melhor esforço. Se o nome de uma sala não puder ser resolvido para um ID ou alias, ele será ignorado pela resolução da lista de permissões em tempo de execução. ## Referência de configuração - `enabled`: ativa ou desativa o canal. -- `name`: rótulo opcional da conta. -- `defaultAccount`: ID de conta preferido quando várias contas Matrix estão configuradas. +- `name`: rótulo opcional para a conta. +- `defaultAccount`: ID de conta preferido quando várias contas Matrix estiverem configuradas. - `homeserver`: URL do homeserver, por exemplo `https://matrix.example.org`. -- `network.dangerouslyAllowPrivateNetwork`: permite que esta conta Matrix se conecte a homeservers privados/internos. Ative isso quando o homeserver resolver para `localhost`, um IP de LAN/Tailscale ou um host interno como `matrix-synapse`. +- `network.dangerouslyAllowPrivateNetwork`: permite que esta conta Matrix se conecte a homeservers privados/internos. Ative isso quando o homeserver for resolvido para `localhost`, um IP de LAN/Tailscale ou um host interno como `matrix-synapse`. - `proxy`: URL opcional de proxy HTTP(S) para tráfego Matrix. Contas nomeadas podem substituir o padrão de nível superior com seu próprio `proxy`. -- `userId`: ID completo de usuário Matrix, por exemplo `@bot:example.org`. -- `accessToken`: token de acesso para autenticação baseada em token. Valores em texto simples e valores SecretRef são compatíveis com `channels.matrix.accessToken` e `channels.matrix.accounts..accessToken` em provedores env/file/exec. Veja [Gerenciamento de segredos](/pt-BR/gateway/secrets). +- `userId`: ID completo do usuário Matrix, por exemplo `@bot:example.org`. +- `accessToken`: token de acesso para autenticação baseada em token. Valores em texto simples e valores SecretRef são compatíveis com `channels.matrix.accessToken` e `channels.matrix.accounts..accessToken` nos provedores env/file/exec. Consulte [Gerenciamento de segredos](/pt-BR/gateway/secrets). - `password`: senha para login baseado em senha. Valores em texto simples e valores SecretRef são compatíveis. - `deviceId`: ID explícito do dispositivo Matrix. - `deviceName`: nome de exibição do dispositivo para login por senha. - `avatarUrl`: URL armazenada do próprio avatar para sincronização de perfil e atualizações de `profile set`. -- `initialSyncLimit`: número máximo de eventos buscados durante a sincronização na inicialização. +- `initialSyncLimit`: número máximo de eventos buscados durante a sincronização de inicialização. - `encryption`: ativa E2EE. -- `allowlistOnly`: quando `true`, promove a política de sala `open` para `allowlist` e força todas as políticas ativas de DM, exceto `disabled` (incluindo `pairing` e `open`), para `allowlist`. Não afeta políticas `disabled`. +- `allowlistOnly`: quando `true`, atualiza a política de sala `open` para `allowlist` e força todas as políticas ativas de DM, exceto `disabled` (incluindo `pairing` e `open`), para `allowlist`. Não afeta políticas `disabled`. - `allowBots`: permite mensagens de outras contas Matrix do OpenClaw configuradas (`true` ou `"mentions"`). - `groupPolicy`: `open`, `allowlist` ou `disabled`. -- `contextVisibility`: modo de visibilidade do contexto suplementar da sala (`all`, `allowlist`, `allowlist_quote`). -- `groupAllowFrom`: allowlist de IDs de usuário para tráfego de sala. As entradas devem ser IDs completos de usuário Matrix; nomes não resolvidos são ignorados em tempo de execução. -- `historyLimit`: máximo de mensagens da sala a incluir como contexto de histórico de grupo. Usa `messages.groupChat.historyLimit` como fallback; se ambos não estiverem definidos, o padrão efetivo é `0`. Defina `0` para desativar. +- `contextVisibility`: modo de visibilidade de contexto suplementar de sala (`all`, `allowlist`, `allowlist_quote`). +- `groupAllowFrom`: lista de permissões de IDs de usuário para tráfego de sala. As entradas devem ser IDs completos de usuário Matrix; nomes não resolvidos são ignorados em tempo de execução. +- `historyLimit`: número máximo de mensagens da sala a incluir como contexto de histórico de grupo. Usa como fallback `messages.groupChat.historyLimit`; se ambos não estiverem definidos, o padrão efetivo é `0`. Defina `0` para desativar. - `replyToMode`: `off`, `first`, `all` ou `batched`. -- `markdown`: configuração opcional de renderização Markdown para texto Matrix de saída. -- `streaming`: `off` (padrão), `"partial"`, `"quiet"`, `true` ou `false`. `"partial"` e `true` ativam atualizações de rascunho com prévia primeiro usando mensagens de texto normais do Matrix. `"quiet"` usa avisos de prévia sem notificação para configurações auto-hospedadas com regras de push. `false` equivale a `"off"`. -- `blockStreaming`: `true` ativa mensagens separadas de progresso para blocos concluídos do assistente enquanto o streaming de prévia em rascunho estiver ativo. +- `markdown`: configuração opcional de renderização de Markdown para texto Matrix de saída. +- `streaming`: `off` (padrão), `"partial"`, `"quiet"`, `true` ou `false`. `"partial"` e `true` ativam atualizações de rascunho com prévia primeiro usando mensagens de texto normais do Matrix. `"quiet"` usa avisos de prévia sem notificação para configurações auto-hospedadas com regras de push. `false` é equivalente a `"off"`. +- `blockStreaming`: `true` ativa mensagens de progresso separadas para blocos concluídos do assistente enquanto o streaming de prévia em rascunho está ativo. - `threadReplies`: `off`, `inbound` ou `always`. -- `threadBindings`: substituições por canal para roteamento e ciclo de vida de sessão vinculada a thread. +- `threadBindings`: substituições por canal para roteamento e ciclo de vida de sessão vinculados a thread. - `startupVerification`: modo automático de solicitação de autoverificação na inicialização (`if-unverified`, `off`). -- `startupVerificationCooldownHours`: cooldown antes de repetir solicitações automáticas de verificação na inicialização. -- `textChunkLimit`: tamanho do bloco de mensagem de saída em caracteres (aplica-se quando `chunkMode` é `length`). +- `startupVerificationCooldownHours`: cooldown antes de tentar novamente solicitações automáticas de verificação na inicialização. +- `textChunkLimit`: tamanho de fragmento da mensagem de saída em caracteres (aplica-se quando `chunkMode` é `length`). - `chunkMode`: `length` divide mensagens por contagem de caracteres; `newline` divide em limites de linha. -- `responsePrefix`: string opcional prefixada a todas as respostas de saída deste canal. +- `responsePrefix`: string opcional adicionada ao início de todas as respostas de saída deste canal. - `ackReaction`: substituição opcional da reação de confirmação para este canal/conta. - `ackReactionScope`: substituição opcional do escopo da reação de confirmação (`group-mentions`, `group-all`, `direct`, `all`, `none`, `off`). -- `reactionNotifications`: modo de notificação de reação recebida (`own`, `off`). -- `mediaMaxMb`: limite de tamanho de mídia em MB para envios de saída e processamento de mídia recebida. +- `reactionNotifications`: modo de notificação de reação de entrada (`own`, `off`). +- `mediaMaxMb`: limite de tamanho de mídia em MB para envios de saída e processamento de mídia de entrada. - `autoJoin`: política de entrada automática por convite (`always`, `allowlist`, `off`). Padrão: `off`. Aplica-se a todos os convites do Matrix, incluindo convites no estilo DM. - `autoJoinAllowlist`: salas/aliases permitidos quando `autoJoin` é `allowlist`. Entradas de alias são resolvidas para IDs de sala durante o tratamento do convite; o OpenClaw não confia no estado de alias declarado pela sala convidada. - `dm`: bloco de política de DM (`enabled`, `policy`, `allowFrom`, `sessionScope`, `threadReplies`). -- `dm.policy`: controla o acesso à DM depois que o OpenClaw entrou na sala e a classificou como DM. Não altera se um convite é aceito automaticamente. -- `dm.allowFrom`: as entradas devem ser IDs completos de usuário Matrix, a menos que você já as tenha resolvido via busca ativa no diretório. -- `dm.sessionScope`: `per-user` (padrão) ou `per-room`. Use `per-room` quando quiser que cada sala de DM do Matrix mantenha contexto separado mesmo se o par for o mesmo. -- `dm.threadReplies`: substituição da política de thread apenas para DMs (`off`, `inbound`, `always`). Ela substitui a configuração de nível superior `threadReplies` tanto para posicionamento da resposta quanto para isolamento de sessão em DMs. -- `execApprovals`: entrega nativa de aprovação de exec no Matrix (`enabled`, `approvers`, `target`, `agentFilter`, `sessionFilter`). -- `execApprovals.approvers`: IDs de usuário Matrix autorizados a aprovar solicitações de exec. Opcional quando `dm.allowFrom` já identifica os aprovadores. +- `dm.policy`: controla o acesso à DM depois que o OpenClaw entra na sala e a classifica como DM. Isso não altera se um convite é aceito automaticamente. +- `dm.allowFrom`: as entradas devem ser IDs completos de usuário Matrix, a menos que você já as tenha resolvido por meio de busca ao vivo em diretório. +- `dm.sessionScope`: `per-user` (padrão) ou `per-room`. Use `per-room` quando quiser que cada sala de DM do Matrix mantenha contexto separado mesmo que o par seja o mesmo. +- `dm.threadReplies`: substituição da política de thread apenas para DM (`off`, `inbound`, `always`). Ela substitui a configuração de nível superior `threadReplies` tanto para o posicionamento da resposta quanto para o isolamento de sessão em DMs. +- `execApprovals`: entrega nativa de aprovações de execução do Matrix (`enabled`, `approvers`, `target`, `agentFilter`, `sessionFilter`). +- `execApprovals.approvers`: IDs de usuário Matrix autorizados a aprovar solicitações de execução. Opcional quando `dm.allowFrom` já identifica os aprovadores. - `execApprovals.target`: `dm | channel | both` (padrão: `dm`). -- `accounts`: substituições nomeadas por conta. Valores de nível superior em `channels.matrix` atuam como padrões para essas entradas. -- `groups`: mapa de políticas por sala. Prefira IDs ou aliases de sala; nomes de salas não resolvidos são ignorados em tempo de execução. A identidade de sessão/grupo usa o ID estável da sala após a resolução. -- `groups..account`: restringe uma entrada de sala herdada a uma conta Matrix específica em configurações com múltiplas contas. -- `groups..allowBots`: substituição em nível de sala para remetentes bot configurados (`true` ou `"mentions"`). -- `groups..users`: allowlist de remetentes por sala. -- `groups..tools`: substituições por sala de permitir/negar ferramentas. -- `groups..autoReply`: substituição em nível de sala para exigência de menção. `true` desativa exigências de menção para essa sala; `false` volta a forçá-las. +- `accounts`: substituições nomeadas por conta. Os valores de nível superior de `channels.matrix` atuam como padrões para essas entradas. +- `groups`: mapa de políticas por sala. Prefira IDs ou aliases de sala; nomes de sala não resolvidos são ignorados em tempo de execução. A identidade da sessão/do grupo usa o ID estável da sala após a resolução. +- `groups..account`: restringe uma entrada de sala herdada a uma conta Matrix específica em configurações com várias contas. +- `groups..allowBots`: substituição no nível da sala para remetentes de bots configurados (`true` ou `"mentions"`). +- `groups..users`: lista de permissões de remetentes por sala. +- `groups..tools`: substituições por sala para permitir/negar ferramentas. +- `groups..autoReply`: substituição no nível da sala para exigência de menção. `true` desativa a exigência de menção para essa sala; `false` a força de volta. - `groups..skills`: filtro opcional de Skills por sala. - `groups..systemPrompt`: trecho opcional de prompt de sistema por sala. - `rooms`: alias legado para `groups`. -- `actions`: controle por ação do uso de ferramentas (`messages`, `reactions`, `pins`, `profile`, `memberInfo`, `channelInfo`, `verification`). +- `actions`: controle por ação de ferramentas (`messages`, `reactions`, `pins`, `profile`, `memberInfo`, `channelInfo`, `verification`). ## Relacionado - [Visão geral dos canais](/pt-BR/channels) — todos os canais compatíveis -- [Pareamento](/pt-BR/channels/pairing) — autenticação por DM e fluxo de pareamento -- [Grupos](/pt-BR/channels/groups) — comportamento de chat em grupo e exigência de menção -- [Roteamento de canal](/pt-BR/channels/channel-routing) — roteamento de sessão para mensagens -- [Segurança](/pt-BR/gateway/security) — modelo de acesso e endurecimento +- [Pairing](/pt-BR/channels/pairing) — autenticação de DM e fluxo de pareamento +- [Groups](/pt-BR/channels/groups) — comportamento de chat em grupo e exigência de menção +- [Roteamento de canais](/pt-BR/channels/channel-routing) — roteamento de sessão para mensagens +- [Segurança](/pt-BR/gateway/security) — modelo de acesso e reforço de segurança diff --git a/docs/pt-BR/concepts/dreaming.md b/docs/pt-BR/concepts/dreaming.md index 15e96823b..72f008e4a 100644 --- a/docs/pt-BR/concepts/dreaming.md +++ b/docs/pt-BR/concepts/dreaming.md @@ -1,15 +1,15 @@ --- read_when: - Você quer que a promoção de memória seja executada automaticamente - - Você quer entender o que cada fase do dreaming faz - - Você quer ajustar a consolidação sem poluir o `MEMORY.md` -summary: Consolidação de memória em segundo plano com fases leve, profunda e REM, além de um Diário de Sonhos + - Você quer entender o que cada fase de Dreaming faz + - Você quer ajustar a consolidação sem poluir `MEMORY.md` +summary: Consolidação da memória em segundo plano com fases leve, profunda e REM, além de um Diário de Sonhos title: Dreaming (experimental) x-i18n: - generated_at: "2026-04-09T01:27:43Z" + generated_at: "2026-04-15T05:33:47Z" model: gpt-5.4 provider: openai - source_hash: 26476eddb8260e1554098a6adbb069cf7f5e284cf2e09479c6d9d8f8b93280ef + source_hash: 5882a5068f2eabe54ca9893184e5385330a432b921870c38626399ce11c31e25 source_path: concepts/dreaming.md workflow: 15 --- @@ -17,27 +17,27 @@ x-i18n: # Dreaming (experimental) Dreaming é o sistema de consolidação de memória em segundo plano no `memory-core`. -Ele ajuda o OpenClaw a mover sinais fortes de curto prazo para memória durável, enquanto +Ele ajuda o OpenClaw a mover sinais fortes de curto prazo para memória durável, ao mesmo tempo em que mantém o processo explicável e revisável. -Dreaming é **opt-in** e fica desativado por padrão. +Dreaming é **opt-in** e vem desabilitado por padrão. -## O que o dreaming grava +## O que o Dreaming grava O Dreaming mantém dois tipos de saída: - **Estado da máquina** em `memory/.dreams/` (armazenamento de recall, sinais de fase, checkpoints de ingestão, locks). -- **Saída legível por humanos** em `DREAMS.md` (ou `dreams.md`, se já existir) e arquivos opcionais de relatório de fase em `memory/dreaming//YYYY-MM-DD.md`. +- **Saída legível por humanos** em `DREAMS.md` (ou `dreams.md`, se já existir) e arquivos opcionais de relatório por fase em `memory/dreaming//YYYY-MM-DD.md`. -A promoção para longo prazo ainda grava somente em `MEMORY.md`. +A promoção de longo prazo ainda grava apenas em `MEMORY.md`. ## Modelo de fases -Dreaming usa três fases cooperativas: +O Dreaming usa três fases cooperativas: | Fase | Finalidade | Gravação durável | | ----- | ---------- | ---------------- | -| Leve | Classificar e preparar material recente de curto prazo | Não | +| Leve | Organizar e preparar material recente de curto prazo | Não | | Profunda | Pontuar e promover candidatos duráveis | Sim (`MEMORY.md`) | | REM | Refletir sobre temas e ideias recorrentes | Não | @@ -46,7 +46,7 @@ separados configurados pelo usuário. ### Fase leve -A fase leve ingere sinais recentes de memória diária e rastros de recall, remove duplicatas +A fase leve ingere sinais recentes de memória diária e rastros de recall, remove duplicações e prepara linhas candidatas. - Lê do estado de recall de curto prazo, de arquivos recentes de memória diária e de transcrições de sessão redigidas, quando disponíveis. @@ -59,10 +59,10 @@ e prepara linhas candidatas. A fase profunda decide o que se torna memória de longo prazo. - Classifica candidatos usando pontuação ponderada e limites mínimos. -- Exige que `minScore`, `minRecallCount` e `minUniqueQueries` sejam atingidos. -- Reidrata trechos a partir de arquivos diários ativos antes de gravar, para que trechos obsoletos ou excluídos sejam ignorados. +- Exige que `minScore`, `minRecallCount` e `minUniqueQueries` sejam atendidos. +- Reidrata trechos a partir de arquivos diários ativos antes de gravar, portanto trechos desatualizados/excluídos são ignorados. - Acrescenta entradas promovidas a `MEMORY.md`. -- Grava um resumo `## Deep Sleep` em `DREAMS.md` e, opcionalmente, grava em `memory/dreaming/deep/YYYY-MM-DD.md`. +- Grava um resumo `## Deep Sleep` em `DREAMS.md` e, opcionalmente, grava `memory/dreaming/deep/YYYY-MM-DD.md`. ### Fase REM @@ -75,63 +75,65 @@ A fase REM extrai padrões e sinais reflexivos. ## Ingestão de transcrições de sessão -Dreaming pode ingerir transcrições de sessão redigidas no corpus do dreaming. Quando -as transcrições estão disponíveis, elas são alimentadas na fase leve junto com sinais -de memória diária e rastros de recall. Conteúdo pessoal e sensível é redigido +O Dreaming pode ingerir transcrições de sessão redigidas no corpus de Dreaming. Quando +as transcrições estão disponíveis, elas são alimentadas na fase leve junto com sinais de +memória diária e rastros de recall. Conteúdo pessoal e sensível é redigido antes da ingestão. ## Diário de Sonhos -Dreaming também mantém um **Diário de Sonhos** narrativo em `DREAMS.md`. -Depois que cada fase tem material suficiente, o `memory-core` executa uma rodada em segundo plano -de subagente em modo best-effort (usando o modelo de runtime padrão) e acrescenta uma entrada curta ao diário. +O Dreaming também mantém um **Diário de Sonhos** narrativo em `DREAMS.md`. +Depois que cada fase tem material suficiente, o `memory-core` executa uma rodada em segundo plano de subagente em modo best-effort +(usando o modelo padrão de runtime) e acrescenta uma entrada curta ao diário. -Este diário é para leitura humana na interface Dreams, não uma fonte de promoção. +Esse diário é para leitura humana na UI de Sonhos, não é uma fonte de promoção. +Artefatos de diário/relatório gerados pelo Dreaming são excluídos da +promoção de curto prazo. Apenas trechos de memória fundamentados são elegíveis para promoção para +`MEMORY.md`. -Também existe um fluxo fundamentado de preenchimento histórico para trabalho de revisão e recuperação: +Também existe uma trilha fundamentada de preenchimento retroativo histórico para trabalho de revisão e recuperação: -- `memory rem-harness --path ... --grounded` mostra uma prévia da saída fundamentada do diário a partir de notas históricas `YYYY-MM-DD.md`. -- `memory rem-backfill --path ...` grava entradas fundamentadas e reversíveis no diário em `DREAMS.md`. +- `memory rem-harness --path ... --grounded` pré-visualiza a saída fundamentada do diário a partir de notas históricas `YYYY-MM-DD.md`. +- `memory rem-backfill --path ...` grava entradas reversíveis fundamentadas do diário em `DREAMS.md`. - `memory rem-backfill --path ... --stage-short-term` prepara candidatos duráveis fundamentados no mesmo armazenamento de evidências de curto prazo que a fase profunda normal já usa. -- `memory rem-backfill --rollback` e `--rollback-short-term` removem esses artefatos preparados de backfill sem tocar nas entradas normais do diário nem no recall ativo de curto prazo. +- `memory rem-backfill --rollback` e `--rollback-short-term` removem esses artefatos preparados de preenchimento retroativo sem tocar em entradas comuns do diário nem no recall ativo normal de curto prazo. -A Control UI expõe o mesmo fluxo de backfill/redefinição do diário para que você possa inspecionar -os resultados na cena Dreams antes de decidir se os candidatos fundamentados -merecem promoção. A cena também mostra uma faixa fundamentada distinta para que você veja +A UI de Controle expõe o mesmo fluxo de preenchimento retroativo/redefinição do diário para que você possa inspecionar +os resultados na cena de Sonhos antes de decidir se os candidatos fundamentados +merecem promoção. A cena também mostra uma trilha fundamentada distinta para que você possa ver quais entradas preparadas de curto prazo vieram de replay histórico, quais itens promovidos -foram guiados por conteúdo fundamentado e limpe apenas as entradas preparadas exclusivamente fundamentadas sem -tocar no estado normal ativo de curto prazo. +foram conduzidos por conteúdo fundamentado e limpar apenas entradas preparadas exclusivamente fundamentadas sem +tocar no estado comum ativo de curto prazo. ## Sinais de classificação profunda A classificação profunda usa seis sinais-base ponderados mais reforço de fase: | Sinal | Peso | Descrição | -| ------ | ---- | --------- | +| ------------------- | ------ | ------------------------------------------------- | | Frequência | 0.24 | Quantos sinais de curto prazo a entrada acumulou | | Relevância | 0.30 | Qualidade média de recuperação da entrada | -| Diversidade de consultas | 0.15 | Contextos distintos de consulta/dia que a revelaram | +| Diversidade de consulta | 0.15 | Contextos distintos de consulta/dia que a trouxeram à tona | | Recência | 0.15 | Pontuação de atualização com decaimento temporal | -| Consolidação | 0.10 | Força de recorrência em múltiplos dias | -| Riqueza conceitual | 0.06 | Densidade de tags conceituais do trecho/caminho | +| Consolidação | 0.10 | Força de recorrência em vários dias | +| Riqueza conceitual | 0.06 | Densidade de tags de conceito a partir do trecho/caminho | -Acertos das fases leve e REM adicionam um pequeno reforço com decaimento temporal a partir de +Acertos das fases leve e REM adicionam um pequeno impulso com decaimento de recência a partir de `memory/.dreams/phase-signals.json`. ## Agendamento -Quando ativado, o `memory-core` gerencia automaticamente um job cron para uma varredura completa -de dreaming. Cada varredura executa as fases em ordem: leve -> REM -> profunda. +Quando habilitado, o `memory-core` gerencia automaticamente um trabalho de Cron para uma varredura completa de Dreaming. Cada varredura executa as fases em ordem: leve -> REM -> profunda. -Comportamento de cadência padrão: +Comportamento padrão de cadência: | Configuração | Padrão | -| ------------ | ------ | +| -------------------- | ----------- | | `dreaming.frequency` | `0 3 * * *` | ## Início rápido -Ative o dreaming: +Habilite o Dreaming: ```json { @@ -149,7 +151,7 @@ Ative o dreaming: } ``` -Ative o dreaming com uma cadência personalizada de varredura: +Habilite o Dreaming com uma cadência de varredura personalizada: ```json { @@ -180,7 +182,7 @@ Ative o dreaming com uma cadência personalizada de varredura: ## Fluxo de trabalho da CLI -Use a promoção pela CLI para prévia ou aplicação manual: +Use a promoção via CLI para pré-visualização ou aplicação manual: ```bash openclaw memory promote @@ -190,7 +192,7 @@ openclaw memory status --deep ``` O `memory promote` manual usa os limites da fase profunda por padrão, a menos que sejam substituídos -com flags da CLI. +por flags da CLI. Explique por que um candidato específico seria ou não promovido: @@ -199,7 +201,7 @@ openclaw memory promote-explain "router vlan" openclaw memory promote-explain "router vlan" --json ``` -Visualize reflexões REM, verdades candidatas e a saída de promoção profunda sem +Pré-visualize reflexões REM, verdades candidatas e a saída de promoção profunda sem gravar nada: ```bash @@ -212,30 +214,30 @@ openclaw memory rem-harness --json Todas as configurações ficam em `plugins.entries.memory-core.config.dreaming`. | Chave | Padrão | -| ----- | ------ | +| ----------- | ----------- | | `enabled` | `false` | | `frequency` | `0 3 * * *` | -Política de fases, limites e comportamento de armazenamento são detalhes internos de implementação -(não configuração voltada ao usuário). +Política de fase, limites e comportamento de armazenamento são detalhes internos de implementação +(não são configurações voltadas ao usuário). Consulte a [referência de configuração de memória](/pt-BR/reference/memory-config#dreaming-experimental) para ver a lista completa de chaves. -## Interface Dreams +## UI de Sonhos -Quando ativada, a aba **Dreams** do Gateway mostra: +Quando habilitada, a aba **Dreams** do Gateway mostra: -- estado atual de ativação do dreaming -- status em nível de fase e presença de varredura gerenciada +- estado atual de habilitação do Dreaming +- status por fase e presença de varredura gerenciada - contagens de curto prazo, fundamentadas, de sinais e promovidas hoje - horário da próxima execução agendada -- uma faixa Scene fundamentada distinta para entradas preparadas de replay histórico -- um leitor expansível do Diário de Sonhos com base em `doctor.memory.dreamDiary` +- uma trilha distinta fundamentada na cena para entradas preparadas de replay histórico +- um leitor expansível do Diário de Sonhos baseado em `doctor.memory.dreamDiary` ## Relacionado -- [Memory](/pt-BR/concepts/memory) -- [Memory Search](/pt-BR/concepts/memory-search) +- [Memória](/pt-BR/concepts/memory) +- [Busca de memória](/pt-BR/concepts/memory-search) - [CLI de memory](/cli/memory) -- [referência de configuração de memória](/pt-BR/reference/memory-config) +- [Referência de configuração de memória](/pt-BR/reference/memory-config) diff --git a/docs/pt-BR/gateway/local-models.md b/docs/pt-BR/gateway/local-models.md index 643cc448d..5dee434ca 100644 --- a/docs/pt-BR/gateway/local-models.md +++ b/docs/pt-BR/gateway/local-models.md @@ -6,23 +6,23 @@ read_when: summary: Execute o OpenClaw em LLMs locais (LM Studio, vLLM, LiteLLM, endpoints OpenAI personalizados) title: Modelos locais x-i18n: - generated_at: "2026-04-14T13:04:28Z" + generated_at: "2026-04-15T05:33:49Z" model: gpt-5.4 provider: openai - source_hash: 1544c522357ba4b18dfa6d05ea8d60c7c6262281b53863d9aee7002464703ca7 + source_hash: 8778cc1c623a356ff3cf306c494c046887f9417a70ec71e659e4a8aae912a780 source_path: gateway/local-models.md workflow: 15 --- # Modelos locais -Localmente é viável, mas o OpenClaw espera contexto grande + defesas fortes contra injeção de prompt. Placas pequenas truncam o contexto e enfraquecem a segurança. Mire alto: **≥2 Mac Studios no máximo ou uma máquina com GPU equivalente (~US$ 30 mil+)**. Uma única GPU de **24 GB** funciona apenas para prompts mais leves, com latência maior. Use a **maior variante / variante de tamanho completo do modelo que você conseguir executar**; checkpoints agressivamente quantizados ou “small” aumentam o risco de injeção de prompt (veja [Segurança](/pt-BR/gateway/security)). +Localmente é viável, mas o OpenClaw espera um contexto grande + defesas fortes contra injeção de prompt. Placas pequenas truncam o contexto e comprometem a segurança. Mire alto: **≥2 Mac Studios no máximo ou equipamento GPU equivalente (~US$ 30 mil+)**. Uma única GPU de **24 GB** funciona apenas para prompts mais leves, com latência maior. Use a **maior variante / variante de tamanho completo do modelo que você conseguir executar**; checkpoints agressivamente quantizados ou “small” aumentam o risco de injeção de prompt (veja [Segurança](/pt-BR/gateway/security)). -Se você quer a configuração local com menos atrito, comece com [LM Studio](/pt-BR/providers/lmstudio) ou [Ollama](/pt-BR/providers/ollama) e `openclaw onboard`. Esta página é o guia opinativo para stacks locais de nível mais alto e servidores locais personalizados compatíveis com OpenAI. +Se você quiser a configuração local com menos atrito, comece com [LM Studio](/pt-BR/providers/lmstudio) ou [Ollama](/pt-BR/providers/ollama) e `openclaw onboard`. Esta página é o guia opinativo para stacks locais mais robustas e servidores locais personalizados compatíveis com OpenAI. -## Recomendado: LM Studio + modelo local grande (Responses API) +## Recomendado: LM Studio + modelo local grande (API Responses) -Melhor stack local atual. Carregue um modelo grande no LM Studio (por exemplo, uma versão completa do Qwen, DeepSeek ou Llama), habilite o servidor local (padrão `http://127.0.0.1:1234`), e use a Responses API para manter o raciocínio separado do texto final. +Melhor stack local atual. Carregue um modelo grande no LM Studio (por exemplo, uma build completa de Qwen, DeepSeek ou Llama), ative o servidor local (padrão `http://127.0.0.1:1234`) e use a API Responses para manter o raciocínio separado do texto final. ```json5 { @@ -62,15 +62,15 @@ Melhor stack local atual. Carregue um modelo grande no LM Studio (por exemplo, u **Checklist de configuração** - Instale o LM Studio: [https://lmstudio.ai](https://lmstudio.ai) -- No LM Studio, baixe a **maior versão de modelo disponível** (evite variantes “small”/fortemente quantizadas), inicie o servidor e confirme que `http://127.0.0.1:1234/v1/models` o lista. -- Substitua `my-local-model` pelo ID real do modelo mostrado no LM Studio. -- Mantenha o modelo carregado; carregamento a frio adiciona latência de inicialização. -- Ajuste `contextWindow`/`maxTokens` se a sua versão do LM Studio for diferente. -- Para WhatsApp, mantenha a Responses API para que apenas o texto final seja enviado. +- No LM Studio, baixe a **maior build de modelo disponível** (evite variantes “small”/muito quantizadas), inicie o servidor e confirme que `http://127.0.0.1:1234/v1/models` o lista. +- Substitua `my-local-model` pelo ID real do modelo exibido no LM Studio. +- Mantenha o modelo carregado; o carregamento a frio adiciona latência na inicialização. +- Ajuste `contextWindow`/`maxTokens` se a sua build do LM Studio for diferente. +- Para WhatsApp, use a API Responses para que apenas o texto final seja enviado. -Mantenha modelos hospedados configurados mesmo ao executar localmente; use `models.mode: "merge"` para que os fallbacks continuem disponíveis. +Mantenha também os modelos hospedados configurados mesmo ao executar localmente; use `models.mode: "merge"` para que fallbacks continuem disponíveis. -### Configuração híbrida: principal hospedado, fallback local +### Configuração híbrida: primário hospedado, fallback local ```json5 { @@ -111,18 +111,18 @@ Mantenha modelos hospedados configurados mesmo ao executar localmente; use `mode } ``` -### Prioridade local com rede de segurança hospedada +### Local primeiro com rede de segurança hospedada -Troque a ordem do principal e do fallback; mantenha o mesmo bloco de providers e `models.mode: "merge"` para poder recorrer a Sonnet ou Opus quando a máquina local estiver fora do ar. +Troque a ordem de primário e fallback; mantenha o mesmo bloco `providers` e `models.mode: "merge"` para poder recorrer a Sonnet ou Opus quando a máquina local estiver indisponível. ### Hospedagem regional / roteamento de dados -- Variantes hospedadas de MiniMax/Kimi/GLM também existem no OpenRouter com endpoints fixados por região (por exemplo, hospedados nos EUA). Escolha ali a variante regional para manter o tráfego na jurisdição desejada, enquanto continua usando `models.mode: "merge"` para fallbacks de Anthropic/OpenAI. -- Somente local continua sendo o caminho mais forte em privacidade; o roteamento regional hospedado é o meio-termo quando você precisa de recursos do provedor, mas quer controle sobre o fluxo de dados. +- Variantes hospedadas de MiniMax/Kimi/GLM também existem no OpenRouter com endpoints fixados por região (por exemplo, hospedados nos EUA). Escolha ali a variante regional para manter o tráfego dentro da jurisdição desejada, enquanto ainda usa `models.mode: "merge"` para fallbacks de Anthropic/OpenAI. +- Somente local continua sendo o caminho mais forte para privacidade; o roteamento regional hospedado é o meio-termo quando você precisa de recursos do provedor, mas quer controle sobre o fluxo de dados. ## Outros proxies locais compatíveis com OpenAI -vLLM, LiteLLM, OAI-proxy ou gateways personalizados funcionam se expuserem um endpoint `/v1` no estilo OpenAI. Substitua o bloco do provider acima pelo seu endpoint e ID de modelo: +vLLM, LiteLLM, OAI-proxy ou gateways personalizados funcionam se expuserem um endpoint `/v1` no estilo OpenAI. Substitua o bloco do provedor acima pelo seu endpoint e ID de modelo: ```json5 { @@ -150,40 +150,30 @@ vLLM, LiteLLM, OAI-proxy ou gateways personalizados funcionam se expuserem um en } ``` -Mantenha `models.mode: "merge"` para que modelos hospedados continuem disponíveis como fallbacks. +Mantenha `models.mode: "merge"` para que os modelos hospedados continuem disponíveis como fallbacks. -Observação de comportamento para backends `/v1` locais/com proxy: +Observação de comportamento para backends locais/proxy com `/v1`: -- O OpenClaw trata isso como rotas compatíveis com OpenAI no estilo proxy, não como endpoints OpenAI nativos -- a modelagem de requisição específica do OpenAI nativo não se aplica aqui: sem - `service_tier`, sem `store` da Responses, sem modelagem de payload de compatibilidade de raciocínio do OpenAI, e sem dicas de cache de prompt -- cabeçalhos ocultos de atribuição do OpenClaw (`originator`, `version`, `User-Agent`) - não são injetados nesses URLs de proxy personalizados +- O OpenClaw trata esses backends como rotas no estilo proxy compatíveis com OpenAI, não como endpoints OpenAI nativos +- a formatação de requisição exclusiva do OpenAI nativo não se aplica aqui: sem `service_tier`, sem `store` de Responses, sem formatação de payload de compatibilidade de raciocínio do OpenAI e sem dicas de cache de prompt +- cabeçalhos ocultos de atribuição do OpenClaw (`originator`, `version`, `User-Agent`) não são injetados nessas URLs de proxy personalizadas -Observações de compatibilidade para backends compatíveis com OpenAI mais rígidos: +Observações de compatibilidade para backends compatíveis com OpenAI mais restritivos: -- Alguns servidores aceitam apenas `messages[].content` como string em Chat Completions, não - arrays estruturados de partes de conteúdo. Defina - `models.providers..models[].compat.requiresStringContent: true` para - esses endpoints. -- Alguns backends locais menores ou mais rígidos ficam instáveis com o formato completo de prompt do runtime do agente do OpenClaw, - especialmente quando esquemas de ferramentas estão incluídos. Se o - backend funciona para chamadas diretas pequenas de `/v1/chat/completions`, mas falha em turnos normais de agente do - OpenClaw, tente primeiro - `models.providers..models[].compat.supportsTools: false`. -- Se o backend ainda falhar apenas em execuções maiores do OpenClaw, o problema restante - geralmente está na capacidade do modelo/servidor upstream ou em um bug do backend, não na camada de transporte do OpenClaw. +- Alguns servidores aceitam apenas `messages[].content` como string em Chat Completions, e não arrays estruturados de partes de conteúdo. Defina `models.providers..models[].compat.requiresStringContent: true` para esses endpoints. +- Alguns backends locais menores ou mais restritivos são instáveis com o formato completo de prompt do runtime do agente do OpenClaw, especialmente quando esquemas de ferramentas são incluídos. Se o backend funciona para chamadas diretas pequenas a `/v1/chat/completions`, mas falha em turnos normais do agente do OpenClaw, primeiro tente `agents.defaults.localModelMode: "lean"` para remover ferramentas padrão pesadas como `browser`, `cron` e `message`; se isso ainda falhar, tente `models.providers..models[].compat.supportsTools: false`. +- Se o backend ainda falhar apenas em execuções maiores do OpenClaw, o problema restante normalmente é capacidade do modelo/servidor upstream ou um bug do backend, não da camada de transporte do OpenClaw. ## Solução de problemas - O Gateway consegue alcançar o proxy? `curl http://127.0.0.1:1234/v1/models`. -- O modelo do LM Studio foi descarregado? Recarregue; inicialização a frio é uma causa comum de “travamento”. -- O OpenClaw avisa quando a janela de contexto detectada está abaixo de **32k** e bloqueia abaixo de **16k**. Se você atingir essa verificação prévia, aumente o limite de contexto do servidor/modelo ou escolha um modelo maior. +- Modelo do LM Studio descarregado? Carregue novamente; inicialização a frio é uma causa comum de “travamento”. +- O OpenClaw avisa quando a janela de contexto detectada fica abaixo de **32k** e bloqueia abaixo de **16k**. Se você encontrar essa verificação prévia, aumente o limite de contexto do servidor/modelo ou escolha um modelo maior. - Erros de contexto? Reduza `contextWindow` ou aumente o limite do seu servidor. - O servidor compatível com OpenAI retorna `messages[].content ... expected a string`? Adicione `compat.requiresStringContent: true` nessa entrada de modelo. - Chamadas diretas pequenas para `/v1/chat/completions` funcionam, mas `openclaw infer model run` - falha com Gemma ou outro modelo local? Primeiro desative os esquemas de ferramentas com + falha com Gemma ou outro modelo local? Desative primeiro os esquemas de ferramentas com `compat.supportsTools: false`, depois teste novamente. Se o servidor ainda travar apenas - com prompts maiores do OpenClaw, trate isso como uma limitação do modelo/servidor upstream. -- Segurança: modelos locais ignoram filtros do lado do provedor; mantenha os agentes restritos e a Compaction ativada para limitar o raio de impacto de injeção de prompt. + com prompts maiores do OpenClaw, trate isso como uma limitação do servidor/modelo upstream. +- Segurança: modelos locais ignoram filtros do lado do provedor; mantenha os agentes limitados e a Compaction ativada para limitar o raio de impacto da injeção de prompt. diff --git a/docs/pt-BR/help/testing.md b/docs/pt-BR/help/testing.md index c6ccb7347..97b891d36 100644 --- a/docs/pt-BR/help/testing.md +++ b/docs/pt-BR/help/testing.md @@ -3,26 +3,26 @@ read_when: - Executando testes localmente ou na CI - Adicionando regressões para bugs de modelo/provedor - Depurando o comportamento do Gateway + agente -summary: 'Kit de testes: suítes unit/e2e/live, executores Docker e o que cada teste cobre' +summary: 'Kit de testes: suítes unitárias/e2e/ao vivo, executores Docker e o que cada teste cobre' title: Testes x-i18n: - generated_at: "2026-04-13T05:41:51Z" + generated_at: "2026-04-15T05:33:50Z" model: gpt-5.4 provider: openai - source_hash: 3db91b4bc36f626cd014958ec66b08b9cecd9faaa20a5746cd3a49ad4b0b1c38 + source_hash: fbf647a5cf13b5861a3ba0cb367dc816c57f0e9c60d3cd6320da193bfadf5609 source_path: help/testing.md workflow: 15 --- # Testes -O OpenClaw tem três suítes Vitest (unit/integration, e2e, live) e um pequeno conjunto de executores Docker. +O OpenClaw tem três suítes Vitest (unitária/integração, e2e, ao vivo) e um pequeno conjunto de executores Docker. Este documento é um guia de “como testamos”: - O que cada suíte cobre (e o que ela deliberadamente _não_ cobre) -- Quais comandos executar para fluxos de trabalho comuns (local, pré-push, depuração) -- Como os testes live descobrem credenciais e selecionam modelos/provedores +- Quais comandos executar para fluxos comuns (local, antes do push, depuração) +- Como os testes ao vivo descobrem credenciais e selecionam modelos/provedores - Como adicionar regressões para problemas reais de modelo/provedor ## Início rápido @@ -30,70 +30,73 @@ Este documento é um guia de “como testamos”: Na maioria dos dias: - Gate completo (esperado antes do push): `pnpm build && pnpm check && pnpm test` -- Execução local mais rápida da suíte completa em uma máquina folgada: `pnpm test:max` -- Loop direto de watch do Vitest: `pnpm test:watch` -- O direcionamento direto por arquivo agora também encaminha caminhos de extensão/canal: `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` -- Prefira execuções direcionadas primeiro quando estiver iterando sobre uma única falha. -- Site de QA com suporte de Docker: `pnpm qa:lab:up` -- Faixa de QA com suporte de VM Linux: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` +- Execução mais rápida da suíte completa localmente em uma máquina robusta: `pnpm test:max` +- Loop direto do Vitest em watch: `pnpm test:watch` +- O direcionamento direto para arquivo agora também encaminha caminhos de extensões/canais: `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` +- Prefira primeiro execuções direcionadas quando estiver iterando sobre uma única falha. +- Site de QA com Docker: `pnpm qa:lab:up` +- Faixa de QA com VM Linux: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` Quando você altera testes ou quer confiança extra: - Gate de cobertura: `pnpm test:coverage` -- Suíte E2E: `pnpm test:e2e` +- Suíte e2e: `pnpm test:e2e` Ao depurar provedores/modelos reais (requer credenciais reais): -- Suíte live (probes de modelos + ferramentas/imagens do Gateway): `pnpm test:live` -- Direcionar um arquivo live em modo silencioso: `pnpm test:live -- src/agents/models.profiles.live.test.ts` +- Suíte ao vivo (modelos + sondas de ferramenta/imagem do Gateway): `pnpm test:live` +- Direcionar um único arquivo ao vivo silenciosamente: `pnpm test:live -- src/agents/models.profiles.live.test.ts` -Dica: quando você precisa apenas de um caso com falha, prefira restringir os testes live usando as variáveis de ambiente de allowlist descritas abaixo. +Dica: quando você só precisa de um caso com falha, prefira restringir os testes ao vivo por meio das variáveis de ambiente de allowlist descritas abaixo. ## Executores específicos de QA Esses comandos ficam ao lado das suítes principais de teste quando você precisa do realismo do QA-lab: - `pnpm openclaw qa suite` - - Executa cenários de QA baseados no repositório diretamente no host. - - Executa vários cenários selecionados em paralelo por padrão com workers isolados do gateway, até 64 workers ou a contagem de cenários selecionados. Use `--concurrency ` para ajustar a quantidade de workers, ou `--concurrency 1` para a antiga faixa serial. + - Executa cenários de QA do repositório diretamente no host. + - Executa vários cenários selecionados em paralelo por padrão com workers isolados do gateway, até 64 workers ou a quantidade de cenários selecionados. Use `--concurrency ` para ajustar a quantidade de workers, ou `--concurrency 1` para a antiga faixa serial. - `pnpm openclaw qa suite --runner multipass` - - Executa a mesma suíte de QA dentro de uma VM Linux Multipass descartável. + - Executa a mesma suíte de QA dentro de uma VM Linux descartável do Multipass. - Mantém o mesmo comportamento de seleção de cenários que `qa suite` no host. - Reutiliza as mesmas flags de seleção de provedor/modelo que `qa suite`. - - Execuções live encaminham as entradas de autenticação de QA compatíveis que são práticas para a VM convidada: - chaves de provedor baseadas em env, o caminho de configuração do provedor live de QA e `CODEX_HOME` quando presente. + - Execuções ao vivo encaminham as entradas de autenticação de QA compatíveis que são práticas para a VM convidada: + chaves de provedor baseadas em env, o caminho da configuração do provedor ao vivo de QA e `CODEX_HOME` quando presente. - Os diretórios de saída devem permanecer sob a raiz do repositório para que a VM convidada possa gravar de volta por meio do workspace montado. - - Grava o relatório + resumo normal de QA, além dos logs do Multipass, em + - Grava o relatório + resumo normais de QA, além dos logs do Multipass em `.artifacts/qa-e2e/...`. - `pnpm qa:lab:up` - - Inicia o site de QA com suporte de Docker para trabalho de QA no estilo operador. + - Inicia o site de QA com Docker para trabalho de QA no estilo operador. - `pnpm openclaw qa matrix` - - Executa a faixa de QA live do Matrix contra um homeserver Tuwunel descartável com suporte de Docker. - - Provisiona três usuários temporários do Matrix (`driver`, `sut`, `observer`) mais uma sala privada, depois inicia um processo filho do gateway de QA com o Plugin real do Matrix como transporte SUT. - - Usa a imagem estável fixada do Tuwunel `ghcr.io/matrix-construct/tuwunel:v1.5.1` por padrão. Substitua com `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE` quando precisar testar outra imagem. - - Atualmente o Matrix oferece suporte apenas a `--credential-source env` porque a faixa provisiona usuários descartáveis localmente. - - Grava um relatório de QA do Matrix, um resumo e um artefato de eventos observados em `.artifacts/qa-e2e/...`. + - Executa a faixa de QA ao vivo do Matrix contra um homeserver Tuwunel descartável com Docker. + - Esse host de QA hoje é apenas para repositório/desenvolvimento. Instalações empacotadas do OpenClaw não incluem `qa-lab`, portanto não expõem `openclaw qa`. + - Checkouts do repositório carregam o executor empacotado diretamente; não é necessária uma etapa separada de instalação de Plugin. + - Provisiona três usuários temporários do Matrix (`driver`, `sut`, `observer`) mais uma sala privada, e então inicia um processo filho do gateway de QA com o Plugin real do Matrix como transporte do SUT. + - Usa por padrão a imagem estável fixada do Tuwunel `ghcr.io/matrix-construct/tuwunel:v1.5.1`. Substitua com `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE` quando precisar testar uma imagem diferente. + - O Matrix não expõe flags compartilhadas de fonte de credenciais porque a faixa provisiona usuários descartáveis localmente. + - Grava um relatório de QA do Matrix, resumo e artefato de eventos observados em `.artifacts/qa-e2e/...`. - `pnpm openclaw qa telegram` - - Executa a faixa de QA live do Telegram contra um grupo privado real usando os tokens do bot driver e do bot SUT vindos de env. + - Executa a faixa de QA ao vivo do Telegram contra um grupo privado real usando os tokens de bot do driver e do SUT vindos do ambiente. - Requer `OPENCLAW_QA_TELEGRAM_GROUP_ID`, `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` e `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`. O id do grupo deve ser o id numérico do chat do Telegram. - - Oferece suporte a `--credential-source convex` para credenciais compartilhadas em pool. Use o modo env por padrão, ou defina `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` para optar por leases em pool. + - Suporta `--credential-source convex` para credenciais compartilhadas em pool. Use o modo env por padrão, ou defina `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` para optar por leases compartilhados. - Requer dois bots distintos no mesmo grupo privado, com o bot SUT expondo um nome de usuário do Telegram. - - Para observação estável entre bots, habilite o Modo de Comunicação Bot-to-Bot em `@BotFather` para ambos os bots e garanta que o bot driver possa observar o tráfego de bots no grupo. - - Grava um relatório de QA do Telegram, um resumo e um artefato de mensagens observadas em `.artifacts/qa-e2e/...`. + - Para observação estável entre bots, habilite o Modo de Comunicação Bot-to-Bot no `@BotFather` para ambos os bots e garanta que o bot driver possa observar o tráfego de bots no grupo. + - Grava um relatório de QA do Telegram, resumo e artefato de mensagens observadas em `.artifacts/qa-e2e/...`. -As faixas de transporte live compartilham um contrato padrão para que novos transportes não sofram desvio: +As faixas de transporte ao vivo compartilham um contrato padrão para que novos transportes não sofram deriva: -`qa-channel` continua sendo a suíte ampla de QA sintética e não faz parte da matriz de cobertura de transporte live. +`qa-channel` continua sendo a suíte ampla de QA sintético e não faz parte da matriz de cobertura de transporte ao vivo. -| Faixa | Canary | Bloqueio por menção | Bloco de allowlist | Resposta de nível superior | Retomada após reinício | Acompanhamento em thread | Isolamento de thread | Observação de reação | Comando de ajuda | -| -------- | ------ | ------------------- | ------------------ | -------------------------- | ---------------------- | ------------------------ | -------------------- | -------------------- | ---------------- | -| Matrix | x | x | x | x | x | x | x | x | | -| Telegram | x | | | | | | | | x | +| Faixa | Canary | Gating de menção | Bloco de allowlist | Resposta de nível superior | Retomada após reinício | Acompanhamento de thread | Isolamento de thread | Observação de reação | Comando de ajuda | +| -------- | ------ | ---------------- | ------------------ | -------------------------- | ---------------------- | ------------------------ | -------------------- | ------------------- | ---------------- | +| Matrix | x | x | x | x | x | x | x | x | | +| Telegram | x | | | | | | | | x | ### Credenciais compartilhadas do Telegram via Convex (v1) Quando `--credential-source convex` (ou `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`) está habilitado para -`openclaw qa telegram`, o laboratório de QA adquire um lease exclusivo de um pool com suporte de Convex, envia Heartbeat desse lease enquanto a faixa está em execução e libera o lease ao encerrar. +`openclaw qa telegram`, o QA lab adquire um lease exclusivo de um pool com backend em Convex, envia heartbeats +desse lease enquanto a faixa está em execução e libera o lease no desligamento. Estrutura de referência do projeto Convex: @@ -107,7 +110,7 @@ Variáveis de ambiente obrigatórias: - `OPENCLAW_QA_CONVEX_SECRET_CI` para `ci` - Seleção do papel da credencial: - CLI: `--credential-role maintainer|ci` - - Padrão por env: `OPENCLAW_QA_CREDENTIAL_ROLE` (o padrão é `maintainer`) + - Padrão do env: `OPENCLAW_QA_CREDENTIAL_ROLE` (o padrão é `maintainer`) Variáveis de ambiente opcionais: @@ -117,11 +120,11 @@ Variáveis de ambiente opcionais: - `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS` (padrão `15000`) - `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX` (padrão `/qa-credentials/v1`) - `OPENCLAW_QA_CREDENTIAL_OWNER_ID` (id de rastreamento opcional) -- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` permite URLs Convex `http://` em loopback para desenvolvimento somente local. +- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` permite URLs Convex `http://` em loopback apenas para desenvolvimento local. `OPENCLAW_QA_CONVEX_SITE_URL` deve usar `https://` em operação normal. -Comandos administrativos de mantenedor (adicionar/remover/listar pool) exigem +Comandos administrativos de mantenedor (adicionar/remover/listar do pool) exigem `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` especificamente. Helpers de CLI para mantenedores: @@ -134,7 +137,7 @@ pnpm openclaw qa credentials remove --credential-id Use `--json` para saída legível por máquina em scripts e utilitários de CI. -Contrato de endpoint padrão (`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`): +Contrato padrão do endpoint (`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`): - `POST /acquire` - Requisição: `{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }` @@ -146,18 +149,18 @@ Contrato de endpoint padrão (`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v - `POST /release` - Requisição: `{ kind, ownerId, actorRole, credentialId, leaseToken }` - Sucesso: `{ status: "ok" }` (ou `2xx` vazio) -- `POST /admin/add` (somente segredo de mantenedor) +- `POST /admin/add` (apenas com segredo de mantenedor) - Requisição: `{ kind, actorId, payload, note?, status? }` - Sucesso: `{ status: "ok", credential }` -- `POST /admin/remove` (somente segredo de mantenedor) +- `POST /admin/remove` (apenas com segredo de mantenedor) - Requisição: `{ credentialId, actorId }` - Sucesso: `{ status: "ok", changed, credential }` - - Proteção contra lease ativo: `{ status: "error", code: "LEASE_ACTIVE", ... }` -- `POST /admin/list` (somente segredo de mantenedor) + - Proteção de lease ativo: `{ status: "error", code: "LEASE_ACTIVE", ... }` +- `POST /admin/list` (apenas com segredo de mantenedor) - Requisição: `{ kind?, status?, includePayload?, limit? }` - Sucesso: `{ status: "ok", credentials, count }` -Formato de payload para o tipo Telegram: +Formato do payload para o tipo Telegram: - `{ groupId: string, driverToken: string, sutToken: string }` - `groupId` deve ser uma string com o id numérico do chat do Telegram. @@ -165,49 +168,55 @@ Formato de payload para o tipo Telegram: ### Adicionando um canal ao QA -Adicionar um canal ao sistema de QA em Markdown exige exatamente duas coisas: +Adicionar um canal ao sistema de QA em markdown exige exatamente duas coisas: 1. Um adaptador de transporte para o canal. 2. Um pacote de cenários que exercite o contrato do canal. -Não adicione um executor de QA específico do canal quando o executor compartilhado `qa-lab` puder assumir o fluxo. +Não adicione uma nova raiz de comando de QA de nível superior quando o host compartilhado `qa-lab` puder +ser o dono do fluxo. -`qa-lab` é responsável pela mecânica compartilhada: +`qa-lab` é o dono dos mecanismos compartilhados do host: -- inicialização e encerramento da suíte +- a raiz de comando `openclaw qa` +- inicialização e desligamento da suíte - concorrência de workers - gravação de artefatos - geração de relatórios - execução de cenários -- aliases de compatibilidade para cenários antigos de `qa-channel` +- aliases de compatibilidade para cenários `qa-channel` mais antigos -O adaptador de canal é responsável pelo contrato de transporte: +Plugins de executor são os donos do contrato de transporte: +- como `openclaw qa ` é montado sob a raiz compartilhada `qa` - como o gateway é configurado para esse transporte - como a prontidão é verificada - como eventos de entrada são injetados - como mensagens de saída são observadas - como transcrições e estado de transporte normalizado são expostos - como ações com suporte de transporte são executadas -- como o reset ou a limpeza específicos do transporte são tratados +- como redefinição ou limpeza específica do transporte é tratada A barra mínima de adoção para um novo canal é: -1. Implementar o adaptador de transporte na interface compartilhada do `qa-lab`. -2. Registrar o adaptador no registro de transportes. -3. Manter a mecânica específica do transporte dentro do adaptador ou do harness do canal. -4. Criar ou adaptar cenários Markdown em `qa/scenarios/`. -5. Usar os helpers genéricos de cenário para novos cenários. -6. Manter os aliases de compatibilidade existentes funcionando, a menos que o repositório esteja fazendo uma migração intencional. +1. Manter `qa-lab` como dono da raiz compartilhada `qa`. +2. Implementar o executor de transporte na costura compartilhada do host `qa-lab`. +3. Manter mecanismos específicos do transporte dentro do Plugin do executor ou do harness do Plugin. +4. Montar o executor como `openclaw qa ` em vez de registrar um comando raiz concorrente. + Plugins de executor devem declarar `qaRunners` em `openclaw.plugin.json` e exportar um array `qaRunnerCliRegistrations` correspondente em `runtime-api.ts`. + Mantenha `runtime-api.ts` leve; a CLI lazy e a execução do executor devem permanecer atrás de entrypoints separados. +5. Criar ou adaptar cenários em markdown em `qa/scenarios/`. +6. Usar os helpers genéricos de cenários para novos cenários. +7. Manter funcionando os aliases de compatibilidade existentes, a menos que o repositório esteja fazendo uma migração intencional. A regra de decisão é estrita: -- Se um comportamento puder ser expresso uma única vez em `qa-lab`, coloque-o em `qa-lab`. -- Se um comportamento depender de um transporte de canal, mantenha-o nesse adaptador ou harness de Plugin. -- Se um cenário precisar de uma nova capacidade que mais de um canal possa usar, adicione um helper genérico em vez de um branch específico de canal em `suite.ts`. -- Se um comportamento só fizer sentido para um transporte, mantenha o cenário específico desse transporte e deixe isso explícito no contrato do cenário. +- Se o comportamento puder ser expresso uma única vez em `qa-lab`, coloque-o em `qa-lab`. +- Se o comportamento depender de um transporte de canal, mantenha-o nesse Plugin de executor ou harness de Plugin. +- Se um cenário precisar de uma nova capacidade que mais de um canal possa usar, adicione um helper genérico em vez de uma ramificação específica de canal em `suite.ts`. +- Se um comportamento só fizer sentido para um transporte, mantenha o cenário específico do transporte e deixe isso explícito no contrato do cenário. -Os nomes preferidos para novos helpers genéricos de cenário são: +Os nomes preferidos de helpers genéricos para novos cenários são: - `waitForTransportReady` - `waitForChannelReady` @@ -230,37 +239,38 @@ Aliases de compatibilidade continuam disponíveis para cenários existentes, inc - `formatConversationTranscript` - `resetBus` -Novos trabalhos de canal devem usar os nomes genéricos de helper. -Os aliases de compatibilidade existem para evitar uma migração de uma só vez, não como modelo para a criação de novos cenários. +Novo trabalho de canal deve usar os nomes genéricos de helpers. +Os aliases de compatibilidade existem para evitar uma migração abrupta, não como modelo para +a directing de novos cenários. ## Suítes de teste (o que roda onde) -Pense nas suítes como “realismo crescente” (e também instabilidade/custo crescentes): +Pense nas suítes como “realismo crescente” (e custo/instabilidade crescentes): -### Unit / integration (padrão) +### Unitária / integração (padrão) - Comando: `pnpm test` -- Configuração: dez execuções sequenciais de shard (`vitest.full-*.config.ts`) sobre os projetos Vitest com escopo já existentes -- Arquivos: inventários core/unit em `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts` e os testes Node de `ui` incluídos na allowlist coberta por `vitest.unit.config.ts` +- Configuração: dez execuções sequenciais de shards (`vitest.full-*.config.ts`) sobre os projetos Vitest com escopo já existentes +- Arquivos: inventários core/unit em `src/**/*.test.ts`, `packages/**/*.test.ts`, `test/**/*.test.ts` e os testes Node com allowlist de `ui` cobertos por `vitest.unit.config.ts` - Escopo: - - Testes unitários puros - - Testes de integração in-process (autenticação do gateway, roteamento, ferramentas, parsing, configuração) + - Testes puramente unitários + - Testes de integração em processo (autenticação do gateway, roteamento, ferramentas, parsing, configuração) - Regressões determinísticas para bugs conhecidos - Expectativas: - - Executa na CI + - Roda na CI - Não requer chaves reais - Deve ser rápido e estável - Observação sobre projetos: - - `pnpm test` sem alvo agora executa onze configurações de shard menores (`core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) em vez de um único processo gigante do projeto raiz nativo. Isso reduz o pico de RSS em máquinas carregadas e evita que o trabalho de auto-reply/extensões afete suítes não relacionadas. + - `pnpm test` sem alvo agora executa onze configurações menores de shard (`core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) em vez de um único processo gigante do projeto raiz nativo. Isso reduz o pico de RSS em máquinas carregadas e evita que o trabalho de auto-reply/extensões sufoque suítes não relacionadas. - `pnpm test --watch` ainda usa o grafo de projetos nativo da raiz em `vitest.config.ts`, porque um loop de watch com múltiplos shards não é prático. - - `pnpm test`, `pnpm test:watch` e `pnpm test:perf:imports` encaminham alvos explícitos de arquivo/diretório primeiro por faixas com escopo, então `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` evita pagar o custo de inicialização completo do projeto raiz. - - `pnpm test:changed` expande caminhos git alterados nas mesmas faixas com escopo quando o diff toca apenas arquivos de origem/teste roteáveis; edições de config/setup ainda recorrem à reexecução ampla do projeto raiz. - - Testes unitários leves de importação de agents, commands, plugins, helpers de auto-reply, `plugin-sdk` e áreas utilitárias puras semelhantes passam pela faixa `unit-fast`, que ignora `test/setup-openclaw-runtime.ts`; arquivos stateful/pesados em runtime permanecem nas faixas existentes. - - Alguns arquivos de origem auxiliares de `plugin-sdk` e `commands` também mapeiam execuções em modo changed para testes irmãos explícitos nessas faixas leves, para que edições em helpers evitem reexecutar a suíte pesada completa desse diretório. - - `auto-reply` agora tem três buckets dedicados: helpers principais de nível superior do core, testes de integração `reply.*` de nível superior e a subárvore `src/auto-reply/reply/**`. Isso mantém o trabalho mais pesado do harness de reply longe dos testes baratos de status/chunk/token. + - `pnpm test`, `pnpm test:watch` e `pnpm test:perf:imports` encaminham primeiro alvos explícitos de arquivo/diretório por faixas com escopo, então `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` evita pagar o custo de inicialização do projeto raiz completo. + - `pnpm test:changed` expande caminhos Git alterados nas mesmas faixas com escopo quando o diff toca apenas arquivos de código-fonte/teste roteáveis; edições de config/setup ainda recaem na reexecução ampla do projeto raiz. + - Testes unitários leves de importação de agents, commands, plugins, helpers de auto-reply, `plugin-sdk` e áreas utilitárias puras semelhantes passam pela faixa `unit-fast`, que ignora `test/setup-openclaw-runtime.ts`; arquivos stateful/pesados de runtime permanecem nas faixas existentes. + - Alguns arquivos-fonte auxiliares selecionados de `plugin-sdk` e `commands` também mapeiam execuções no modo changed para testes irmãos explícitos nessas faixas leves, para que alterações em helpers evitem rerodar a suíte pesada completa desse diretório. + - `auto-reply` agora tem três buckets dedicados: helpers core de nível superior, testes de integração `reply.*` de nível superior e a subárvore `src/auto-reply/reply/**`. Isso mantém o trabalho mais pesado do harness de reply fora dos testes baratos de status/chunk/token. - Observação sobre o executor embutido: - - Ao alterar entradas de descoberta de ferramentas de mensagem ou o contexto de runtime de Compaction, - mantenha ambos os níveis de cobertura. + - Quando você alterar entradas de descoberta de message-tool ou o contexto de runtime de Compaction, + mantenha os dois níveis de cobertura. - Adicione regressões focadas em helpers para limites puros de roteamento/normalização. - Também mantenha saudáveis as suítes de integração do executor embutido: `src/agents/pi-embedded-runner/compact.hooks.test.ts`, @@ -271,23 +281,23 @@ Pense nas suítes como “realismo crescente” (e também instabilidade/custo c substituto suficiente para esses caminhos de integração. - Observação sobre pool: - A configuração base do Vitest agora usa `threads` por padrão. - - A configuração compartilhada do Vitest também fixa `isolate: false` e usa o executor não isolado em todos os projetos da raiz, configs e2e e live. - - A faixa UI da raiz mantém sua configuração e otimizador de `jsdom`, mas agora também roda no executor compartilhado não isolado. + - A configuração compartilhada do Vitest também fixa `isolate: false` e usa o executor não isolado nos projetos da raiz, e2e e ao vivo. + - A faixa de UI da raiz mantém seu setup `jsdom` e otimizador, mas agora também roda no executor compartilhado não isolado. - Cada shard de `pnpm test` herda os mesmos padrões `threads` + `isolate: false` da configuração compartilhada do Vitest. - - O iniciador compartilhado `scripts/run-vitest.mjs` agora também adiciona `--no-maglev` por padrão aos processos Node filhos do Vitest para reduzir a rotatividade de compilação do V8 durante grandes execuções locais. Defina `OPENCLAW_VITEST_ENABLE_MAGLEV=1` se precisar comparar com o comportamento padrão do V8. + - O launcher compartilhado `scripts/run-vitest.mjs` agora também adiciona `--no-maglev` por padrão para processos Node filhos do Vitest para reduzir churn de compilação do V8 durante grandes execuções locais. Defina `OPENCLAW_VITEST_ENABLE_MAGLEV=1` se precisar comparar com o comportamento padrão do V8. - Observação sobre iteração local rápida: - - `pnpm test:changed` encaminha por faixas com escopo quando os caminhos alterados mapeiam claramente para uma suíte menor. + - `pnpm test:changed` encaminha por faixas com escopo quando os caminhos alterados mapeiam de forma limpa para uma suíte menor. - `pnpm test:max` e `pnpm test:changed:max` mantêm o mesmo comportamento de roteamento, apenas com um limite maior de workers. - - O autoescalonamento local de workers agora é intencionalmente conservador e também recua quando a média de carga do host já está alta, então múltiplas execuções simultâneas do Vitest causam menos impacto por padrão. - - A configuração base do Vitest marca os arquivos de projetos/config como `forceRerunTriggers` para que as reexecuções em modo changed continuem corretas quando a fiação dos testes muda. + - O autoescalonamento local de workers agora é intencionalmente conservador e também reduz quando a média de carga do host já está alta, para que várias execuções simultâneas do Vitest causem menos dano por padrão. + - A configuração base do Vitest marca os projetos/arquivos de configuração como `forceRerunTriggers` para que reexecuções no modo changed permaneçam corretas quando o wiring de testes mudar. - A configuração mantém `OPENCLAW_VITEST_FS_MODULE_CACHE` habilitado em hosts compatíveis; defina `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path` se quiser um local de cache explícito para profiling direto. - Observação sobre depuração de performance: - - `pnpm test:perf:imports` habilita o relatório de duração de importação do Vitest e também a saída do detalhamento de importações. - - `pnpm test:perf:imports:changed` limita a mesma visualização de profiling aos arquivos alterados desde `origin/main`. + - `pnpm test:perf:imports` habilita relatórios de duração de importação do Vitest mais a saída de detalhamento de importações. + - `pnpm test:perf:imports:changed` aplica a mesma visão de profiling aos arquivos alterados desde `origin/main`. - `pnpm test:perf:changed:bench -- --ref ` compara `test:changed` roteado com o caminho nativo do projeto raiz para esse diff commitado e imprime tempo total mais RSS máximo no macOS. -- `pnpm test:perf:changed:bench -- --worktree` faz benchmark da árvore atual com alterações roteando a lista de arquivos alterados por `scripts/test-projects.mjs` e pela configuração raiz do Vitest. +- `pnpm test:perf:changed:bench -- --worktree` faz benchmark da árvore atual com alterações locais roteando a lista de arquivos alterados por `scripts/test-projects.mjs` e pela configuração raiz do Vitest. - `pnpm test:perf:profile:main` grava um perfil de CPU da thread principal para a sobrecarga de inicialização e transformação do Vitest/Vite. - - `pnpm test:perf:profile:runner` grava perfis de CPU+heap do executor para a suíte unitária com o paralelismo de arquivos desabilitado. + - `pnpm test:perf:profile:runner` grava perfis de CPU+heap do executor para a suíte unitária com paralelismo de arquivos desabilitado. ### E2E (smoke do gateway) @@ -295,17 +305,17 @@ Pense nas suítes como “realismo crescente” (e também instabilidade/custo c - Configuração: `vitest.e2e.config.ts` - Arquivos: `src/**/*.e2e.test.ts`, `test/**/*.e2e.test.ts` - Padrões de runtime: - - Usa `threads` do Vitest com `isolate: false`, em linha com o restante do repositório. + - Usa `threads` do Vitest com `isolate: false`, alinhado com o restante do repositório. - Usa workers adaptativos (CI: até 2, local: 1 por padrão). - - Executa em modo silencioso por padrão para reduzir a sobrecarga de E/S no console. + - Roda em modo silencioso por padrão para reduzir a sobrecarga de E/S de console. - Substituições úteis: - - `OPENCLAW_E2E_WORKERS=` para forçar a contagem de workers (limitada a 16). - - `OPENCLAW_E2E_VERBOSE=1` para reativar a saída detalhada no console. + - `OPENCLAW_E2E_WORKERS=` para forçar a quantidade de workers (limitada a 16). + - `OPENCLAW_E2E_VERBOSE=1` para reabilitar a saída detalhada no console. - Escopo: - Comportamento end-to-end do gateway com múltiplas instâncias - - Superfícies WebSocket/HTTP, pareamento de Node e rede mais pesada + - Superfícies WebSocket/HTTP, pareamento de nodes e rede mais pesada - Expectativas: - - Executa na CI (quando habilitado no pipeline) + - Roda na CI (quando habilitado no pipeline) - Não requer chaves reais - Tem mais partes móveis do que testes unitários (pode ser mais lento) @@ -316,58 +326,58 @@ Pense nas suítes como “realismo crescente” (e também instabilidade/custo c - Escopo: - Inicia um gateway OpenShell isolado no host via Docker - Cria um sandbox a partir de um Dockerfile local temporário - - Exercita o backend OpenShell do OpenClaw sobre `sandbox ssh-config` + execução SSH reais - - Verifica o comportamento canônico remoto do sistema de arquivos por meio da bridge fs do sandbox + - Exercita o backend OpenShell do OpenClaw por meio de `sandbox ssh-config` real + execução SSH + - Verifica o comportamento canônico remoto do sistema de arquivos por meio da ponte fs do sandbox - Expectativas: - Apenas opt-in; não faz parte da execução padrão de `pnpm test:e2e` - - Requer uma CLI local `openshell` e um daemon Docker funcional - - Usa `HOME` / `XDG_CONFIG_HOME` isolados e então destrói o gateway e sandbox de teste + - Requer uma CLI `openshell` local mais um daemon Docker funcional + - Usa `HOME` / `XDG_CONFIG_HOME` isolados e então destrói o gateway de teste e o sandbox - Substituições úteis: - `OPENCLAW_E2E_OPENSHELL=1` para habilitar o teste ao executar manualmente a suíte e2e mais ampla - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` para apontar para um binário CLI não padrão ou script wrapper -### Live (provedores reais + modelos reais) +### Ao vivo (provedores reais + modelos reais) - Comando: `pnpm test:live` - Configuração: `vitest.live.config.ts` - Arquivos: `src/**/*.live.test.ts` - Padrão: **habilitado** por `pnpm test:live` (define `OPENCLAW_LIVE_TEST=1`) - Escopo: - - “Este provedor/modelo realmente funciona _hoje_ com credenciais reais?” - - Detectar mudanças de formato do provedor, peculiaridades de chamada de ferramenta, problemas de autenticação e comportamento de rate limit + - “Esse provedor/modelo realmente funciona _hoje_ com credenciais reais?” + - Detectar mudanças de formato de provedor, peculiaridades de tool calling, problemas de autenticação e comportamento de limite de taxa - Expectativas: - Não é estável em CI por definição (redes reais, políticas reais de provedores, cotas, indisponibilidades) - - Custa dinheiro / usa rate limits + - Custa dinheiro / consome limites de taxa - Prefira executar subconjuntos restritos em vez de “tudo” -- As execuções live carregam `~/.profile` para obter chaves de API ausentes. -- Por padrão, execuções live ainda isolam `HOME` e copiam material de config/autenticação para um diretório temporário de home de teste para que fixtures unitários não possam alterar seu `~/.openclaw` real. -- Defina `OPENCLAW_LIVE_USE_REAL_HOME=1` somente quando quiser intencionalmente que os testes live usem seu diretório home real. -- `pnpm test:live` agora usa por padrão um modo mais silencioso: mantém a saída de progresso `[live] ...`, mas suprime o aviso extra de `~/.profile` e silencia logs de bootstrap do gateway/ruído do Bonjour. Defina `OPENCLAW_LIVE_TEST_QUIET=0` se quiser restaurar os logs completos de inicialização. -- Rotação de chaves de API (específica por provedor): defina `*_API_KEYS` com formato separado por vírgula/ponto e vírgula ou `*_API_KEY_1`, `*_API_KEY_2` (por exemplo `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GEMINI_API_KEYS`) ou substituição por live via `OPENCLAW_LIVE_*_KEY`; os testes tentam novamente em respostas de rate limit. +- Execuções ao vivo carregam `~/.profile` para obter chaves de API ausentes. +- Por padrão, execuções ao vivo ainda isolam `HOME` e copiam material de config/auth para um diretório home temporário de teste para que fixtures unitárias não possam alterar seu `~/.openclaw` real. +- Defina `OPENCLAW_LIVE_USE_REAL_HOME=1` apenas quando você intencionalmente precisar que os testes ao vivo usem seu diretório home real. +- `pnpm test:live` agora usa por padrão um modo mais silencioso: ele mantém a saída de progresso `[live] ...`, mas suprime o aviso extra de `~/.profile` e silencia logs de bootstrap do gateway/conversa do Bonjour. Defina `OPENCLAW_LIVE_TEST_QUIET=0` se quiser de volta os logs completos de inicialização. +- Rotação de chaves de API (específica do provedor): defina `*_API_KEYS` com formato separado por vírgula/ponto e vírgula ou `*_API_KEY_1`, `*_API_KEY_2` (por exemplo `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GEMINI_API_KEYS`) ou use a substituição por execução ao vivo `OPENCLAW_LIVE_*_KEY`; os testes repetem em respostas de limite de taxa. - Saída de progresso/Heartbeat: - - As suítes live agora emitem linhas de progresso para stderr para que chamadas longas de provedores apareçam como ativas mesmo quando a captura de console do Vitest está silenciosa. - - `vitest.live.config.ts` desabilita a interceptação de console do Vitest para que linhas de progresso de provedor/gateway sejam transmitidas imediatamente durante execuções live. + - As suítes ao vivo agora emitem linhas de progresso para stderr para que chamadas longas ao provedor mostrem atividade visível mesmo quando a captura de console do Vitest está silenciosa. + - `vitest.live.config.ts` desabilita a interceptação de console do Vitest para que linhas de progresso do provedor/gateway sejam transmitidas imediatamente durante execuções ao vivo. - Ajuste Heartbeats de modelo direto com `OPENCLAW_LIVE_HEARTBEAT_MS`. - - Ajuste Heartbeats de gateway/probe com `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS`. + - Ajuste Heartbeats de gateway/sonda com `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS`. ## Qual suíte devo executar? Use esta tabela de decisão: -- Editando lógica/testes: execute `pnpm test` (e `pnpm test:coverage` se você alterou muita coisa) -- Alterando rede do gateway / protocolo WS / pareamento: adicione `pnpm test:e2e` -- Depurando “meu bot está fora do ar” / falhas específicas de provedor / chamada de ferramenta: execute um `pnpm test:live` restrito +- Editando lógica/testes: execute `pnpm test` (e `pnpm test:coverage` se você alterou bastante) +- Tocando em rede do gateway / protocolo WS / pareamento: adicione `pnpm test:e2e` +- Depurando “meu bot caiu” / falhas específicas de provedor / tool calling: execute um `pnpm test:live` restrito -## Live: varredura de capacidade do Node Android +## Ao vivo: varredura de capacidades do node Android - Teste: `src/gateway/android-node.capabilities.live.test.ts` - Script: `pnpm android:test:integration` -- Objetivo: invocar **todo comando atualmente anunciado** por um Node Android conectado e validar o comportamento do contrato de comando. +- Objetivo: invocar **todo comando atualmente anunciado** por um node Android conectado e validar o comportamento do contrato do comando. - Escopo: - - Configuração prévia/manual (a suíte não instala/executa/faz pareamento do app). - - Validação `node.invoke` do gateway comando por comando para o Node Android selecionado. -- Pré-configuração obrigatória: - - App Android já conectado + pareado ao gateway. + - Setup manual/com pré-condições (a suíte não instala/executa/faz pareamento do app). + - Validação `node.invoke` do gateway comando a comando para o node Android selecionado. +- Pré-setup obrigatório: + - App Android já conectado e pareado com o gateway. - App mantido em primeiro plano. - Permissões/consentimento de captura concedidos para as capacidades que você espera que passem. - Substituições opcionais de alvo: @@ -375,71 +385,71 @@ Use esta tabela de decisão: - `OPENCLAW_ANDROID_GATEWAY_URL` / `OPENCLAW_ANDROID_GATEWAY_TOKEN` / `OPENCLAW_ANDROID_GATEWAY_PASSWORD`. - Detalhes completos de configuração do Android: [Android App](/pt-BR/platforms/android) -## Live: smoke de modelo (chaves de perfil) +## Ao vivo: smoke de modelo (chaves de perfil) -Os testes live são divididos em duas camadas para que possamos isolar falhas: +Os testes ao vivo são divididos em duas camadas para que possamos isolar falhas: -- “Modelo direto” nos informa se o provedor/modelo consegue responder com a chave fornecida. -- “Smoke do gateway” nos informa se o pipeline completo gateway+agente funciona para esse modelo (sessões, histórico, ferramentas, política de sandbox etc.). +- “Modelo direto” nos diz se o provedor/modelo consegue responder de fato com a chave fornecida. +- “Smoke do gateway” nos diz se o pipeline completo gateway+agent funciona para esse modelo (sessões, histórico, ferramentas, política de sandbox etc.). -### Camada 1: conclusão direta de modelo (sem gateway) +### Camada 1: conclusão direta do modelo (sem gateway) - Teste: `src/agents/models.profiles.live.test.ts` - Objetivo: - - Enumerar modelos descobertos - - Usar `getApiKeyForModel` para selecionar modelos para os quais você tem credenciais + - Enumerar os modelos descobertos + - Usar `getApiKeyForModel` para selecionar os modelos para os quais você tem credenciais - Executar uma pequena conclusão por modelo (e regressões direcionadas quando necessário) - Como habilitar: - `pnpm test:live` (ou `OPENCLAW_LIVE_TEST=1` se estiver invocando o Vitest diretamente) -- Defina `OPENCLAW_LIVE_MODELS=modern` (ou `all`, alias para modern) para realmente executar esta suíte; caso contrário, ela é ignorada para manter `pnpm test:live` focado no smoke do gateway +- Defina `OPENCLAW_LIVE_MODELS=modern` (ou `all`, alias para modern) para realmente executar esta suíte; caso contrário ela é ignorada para manter `pnpm test:live` focado no smoke do gateway - Como selecionar modelos: - `OPENCLAW_LIVE_MODELS=modern` para executar a allowlist moderna (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4) - `OPENCLAW_LIVE_MODELS=all` é um alias para a allowlist moderna - ou `OPENCLAW_LIVE_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,..."` (allowlist separada por vírgulas) - - As varreduras modern/all usam por padrão um limite curado de alto sinal; defina `OPENCLAW_LIVE_MAX_MODELS=0` para uma varredura moderna exaustiva ou um número positivo para um limite menor. + - Varreduras modern/all usam por padrão um limite curado de alto sinal; defina `OPENCLAW_LIVE_MAX_MODELS=0` para uma varredura moderna exaustiva ou um número positivo para um limite menor. - Como selecionar provedores: - `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"` (allowlist separada por vírgulas) - De onde vêm as chaves: - Por padrão: armazenamento de perfis e fallbacks de env - - Defina `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para impor **somente armazenamento de perfis** + - Defina `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para exigir **apenas armazenamento de perfis** - Por que isso existe: - - Separa “a API do provedor está quebrada / a chave é inválida” de “o pipeline do agente do gateway está quebrado” - - Contém regressões pequenas e isoladas (exemplo: fluxos de replay de raciocínio do OpenAI Responses/Codex Responses + chamada de ferramenta) + - Separa “a API do provedor está quebrada / a chave é inválida” de “o pipeline do agent do gateway está quebrado” + - Contém regressões pequenas e isoladas (exemplo: replay de reasoning do OpenAI Responses/Codex Responses + fluxos de tool-call) -### Camada 2: smoke do Gateway + agente dev (o que `@openclaw` realmente faz) +### Camada 2: smoke do Gateway + agent de desenvolvimento (o que `@openclaw` realmente faz) - Teste: `src/gateway/gateway-models.profiles.live.test.ts` - Objetivo: - - Iniciar um gateway in-process - - Criar/atualizar uma sessão `agent:dev:*` (substituição de modelo por execução) - - Iterar por modelos-com-chaves e validar: + - Iniciar um gateway em processo + - Criar/aplicar patch em uma sessão `agent:dev:*` (substituição de modelo por execução) + - Iterar por modelos-com-chaves e verificar: - resposta “significativa” (sem ferramentas) - - uma invocação real de ferramenta funciona (probe de `read`) - - probes opcionais extras de ferramenta (probe de `exec+read`) - - caminhos de regressão do OpenAI (somente chamada de ferramenta → acompanhamento) continuam funcionando -- Detalhes dos probes (para que você possa explicar falhas rapidamente): - - probe de `read`: o teste grava um arquivo nonce no workspace e pede ao agente para fazer `read` dele e ecoar o nonce de volta. - - probe de `exec+read`: o teste pede ao agente para gravar um nonce em um arquivo temporário com `exec` e depois lê-lo de volta com `read`. - - probe de imagem: o teste anexa um PNG gerado (gato + código aleatório) e espera que o modelo retorne `cat `. + - uma invocação real de ferramenta funciona (sonda de `read`) + - sondas extras opcionais de ferramenta (sonda de `exec+read`) + - caminhos de regressão do OpenAI (somente tool-call → acompanhamento) continuam funcionando +- Detalhes das sondas (para que você possa explicar falhas rapidamente): + - sonda de `read`: o teste grava um arquivo nonce no workspace e pede ao agent para fazer `read` dele e devolver o nonce. + - sonda de `exec+read`: o teste pede ao agent para gravar um nonce em um arquivo temporário via `exec` e depois fazer `read` dele. + - sonda de imagem: o teste anexa um PNG gerado (gato + código aleatório) e espera que o modelo retorne `cat `. - Referência de implementação: `src/gateway/gateway-models.profiles.live.test.ts` e `src/gateway/live-image-probe.ts`. - Como habilitar: - `pnpm test:live` (ou `OPENCLAW_LIVE_TEST=1` se estiver invocando o Vitest diretamente) - Como selecionar modelos: - Padrão: allowlist moderna (Opus/Sonnet 4.6+, GPT-5.x + Codex, Gemini 3, GLM 4.7, MiniMax M2.7, Grok 4) - `OPENCLAW_LIVE_GATEWAY_MODELS=all` é um alias para a allowlist moderna - - Ou defina `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"` (ou lista separada por vírgulas) para restringir - - As varreduras modern/all do gateway usam por padrão um limite curado de alto sinal; defina `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` para uma varredura moderna exaustiva ou um número positivo para um limite menor. -- Como selecionar provedores (evite “OpenRouter everything”): + - Ou defina `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"` (ou uma lista separada por vírgulas) para restringir + - Varreduras modernas/all do gateway usam por padrão um limite curado de alto sinal; defina `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` para uma varredura moderna exaustiva ou um número positivo para um limite menor. +- Como selecionar provedores (evite “OpenRouter inteiro”): - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"` (allowlist separada por vírgulas) -- Probes de ferramenta + imagem estão sempre ativos neste teste live: - - probe de `read` + probe de `exec+read` (estresse de ferramenta) - - o probe de imagem é executado quando o modelo anuncia suporte a entrada de imagem +- As sondas de ferramenta + imagem estão sempre ativas neste teste ao vivo: + - sonda de `read` + sonda de `exec+read` (estresse de ferramenta) + - a sonda de imagem roda quando o modelo anuncia suporte a entrada de imagem - Fluxo (alto nível): - - O teste gera um PNG pequeno com “CAT” + código aleatório (`src/gateway/live-image-probe.ts`) + - O teste gera um PNG minúsculo com “CAT” + código aleatório (`src/gateway/live-image-probe.ts`) - Envia via `agent` `attachments: [{ mimeType: "image/png", content: "" }]` - - O gateway faz o parse dos anexos em `images[]` (`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`) - - O agente embutido encaminha uma mensagem multimodal do usuário para o modelo - - Validação: a resposta contém `cat` + o código (tolerância de OCR: pequenos erros são permitidos) + - O Gateway faz o parsing dos anexos em `images[]` (`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`) + - O agent embutido encaminha uma mensagem de usuário multimodal para o modelo + - Verificação: a resposta contém `cat` + o código (tolerância de OCR: pequenos erros são permitidos) Dica: para ver o que você pode testar na sua máquina (e os ids exatos `provider/model`), execute: @@ -448,26 +458,26 @@ openclaw models list openclaw models list --json ``` -## Live: smoke do backend de CLI (Claude, Codex, Gemini ou outras CLIs locais) +## Ao vivo: smoke do backend de CLI (Claude, Codex, Gemini ou outras CLIs locais) - Teste: `src/gateway/gateway-cli-backend.live.test.ts` -- Objetivo: validar o pipeline Gateway + agente usando um backend de CLI local, sem tocar na sua configuração padrão. -- Os padrões de smoke específicos de backend vivem na definição `cli-backend.ts` da extensão proprietária. +- Objetivo: validar o pipeline Gateway + agent usando um backend de CLI local, sem tocar na sua configuração padrão. +- Os padrões de smoke específicos do backend ficam com a definição `cli-backend.ts` da extensão proprietária. - Habilitar: - `pnpm test:live` (ou `OPENCLAW_LIVE_TEST=1` se estiver invocando o Vitest diretamente) - `OPENCLAW_LIVE_CLI_BACKEND=1` - Padrões: - Provedor/modelo padrão: `claude-cli/claude-sonnet-4-6` - O comportamento de comando/args/imagem vem dos metadados do Plugin proprietário do backend de CLI. -- Substituições opcionais: +- Substituições (opcionais): - `OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.4"` - `OPENCLAW_LIVE_CLI_BACKEND_COMMAND="/full/path/to/codex"` - `OPENCLAW_LIVE_CLI_BACKEND_ARGS='["exec","--json","--color","never","--sandbox","read-only","--skip-git-repo-check"]'` - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` para enviar um anexo de imagem real (os caminhos são injetados no prompt). - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` para passar caminhos de arquivos de imagem como argumentos da CLI em vez de injeção no prompt. + - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` para passar caminhos de arquivos de imagem como argumentos de CLI em vez de injeção no prompt. - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"` (ou `"list"`) para controlar como os argumentos de imagem são passados quando `IMAGE_ARG` está definido. - `OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1` para enviar um segundo turno e validar o fluxo de retomada. - - `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0` para desabilitar o probe padrão de continuidade na mesma sessão Claude Sonnet -> Opus (defina como `1` para forçar a ativação quando o modelo selecionado oferecer suporte a um alvo de troca). + - `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0` para desabilitar a sonda padrão de continuidade na mesma sessão de Claude Sonnet -> Opus (defina como `1` para forçá-la quando o modelo selecionado suportar um alvo de troca). Exemplo: @@ -483,7 +493,7 @@ Receita Docker: pnpm test:docker:live-cli-backend ``` -Receitas Docker para um único provedor: +Receitas Docker de provedor único: ```bash pnpm test:docker:live-cli-backend:claude @@ -492,30 +502,30 @@ pnpm test:docker:live-cli-backend:codex pnpm test:docker:live-cli-backend:gemini ``` -Notas: +Observações: - O executor Docker fica em `scripts/test-live-cli-backend-docker.sh`. -- Ele executa o smoke live do backend de CLI dentro da imagem Docker do repositório como o usuário não root `node`. -- Ele resolve os metadados do smoke de CLI a partir da extensão proprietária e então instala o pacote Linux correspondente da CLI (`@anthropic-ai/claude-code`, `@openai/codex` ou `@google/gemini-cli`) em um prefixo gravável com cache em `OPENCLAW_DOCKER_CLI_TOOLS_DIR` (padrão: `~/.cache/openclaw/docker-cli-tools`). -- `pnpm test:docker:live-cli-backend:claude-subscription` requer OAuth portátil de assinatura do Claude Code por meio de `~/.claude/.credentials.json` com `claudeAiOauth.subscriptionType` ou `CLAUDE_CODE_OAUTH_TOKEN` de `claude setup-token`. Primeiro ele comprova `claude -p` direto no Docker, depois executa dois turnos do backend de CLI do Gateway sem preservar variáveis de ambiente de chave de API da Anthropic. Essa faixa de assinatura desabilita por padrão os probes Claude de MCP/ferramenta e imagem porque o Claude atualmente roteia o uso de apps de terceiros por faturamento de uso extra em vez dos limites normais do plano de assinatura. -- O smoke live do backend de CLI agora exercita o mesmo fluxo end-to-end para Claude, Codex e Gemini: turno de texto, turno de classificação de imagem e depois chamada da ferramenta MCP `cron` validada por meio da CLI do gateway. -- O smoke padrão do Claude também atualiza a sessão de Sonnet para Opus e valida que a sessão retomada ainda se lembra de uma anotação anterior. +- Ele executa o smoke ao vivo do backend de CLI dentro da imagem Docker do repositório como o usuário não root `node`. +- Ele resolve metadados de smoke da CLI a partir da extensão proprietária e depois instala o pacote Linux de CLI correspondente (`@anthropic-ai/claude-code`, `@openai/codex` ou `@google/gemini-cli`) em um prefixo gravável em cache em `OPENCLAW_DOCKER_CLI_TOOLS_DIR` (padrão: `~/.cache/openclaw/docker-cli-tools`). +- `pnpm test:docker:live-cli-backend:claude-subscription` requer OAuth portátil de assinatura do Claude Code via `~/.claude/.credentials.json` com `claudeAiOauth.subscriptionType` ou `CLAUDE_CODE_OAUTH_TOKEN` de `claude setup-token`. Primeiro ele comprova `claude -p` direto no Docker, depois executa dois turnos do backend de CLI do Gateway sem preservar variáveis de ambiente de chave de API da Anthropic. Essa faixa de assinatura desabilita por padrão as sondas de MCP/ferramenta e imagem do Claude porque o Claude atualmente roteia o uso de apps de terceiros por cobrança de uso extra em vez dos limites normais do plano de assinatura. +- O smoke ao vivo do backend de CLI agora exercita o mesmo fluxo end-to-end para Claude, Codex e Gemini: turno de texto, turno de classificação de imagem e então chamada da ferramenta MCP `cron` verificada pela CLI do gateway. +- O smoke padrão do Claude também aplica patch na sessão de Sonnet para Opus e verifica que a sessão retomada ainda se lembra de uma anotação anterior. -## Live: smoke de bind ACP (`/acp spawn ... --bind here`) +## Ao vivo: smoke de bind do ACP (`/acp spawn ... --bind here`) - Teste: `src/gateway/gateway-acp-bind.live.test.ts` -- Objetivo: validar o fluxo real de conversation-bind do ACP com um agente ACP live: +- Objetivo: validar o fluxo real de conversation-bind do ACP com um agent ACP ao vivo: - enviar `/acp spawn --bind here` - - vincular no local uma conversa sintética de canal de mensagens + - vincular uma conversa sintética de canal de mensagem no local - enviar um acompanhamento normal nessa mesma conversa - - validar que o acompanhamento chega à transcrição da sessão ACP vinculada + - verificar que o acompanhamento chega à transcrição da sessão ACP vinculada - Habilitar: - `pnpm test:live src/gateway/gateway-acp-bind.live.test.ts` - `OPENCLAW_LIVE_ACP_BIND=1` - Padrões: - - Agentes ACP no Docker: `claude,codex,gemini` - - Agente ACP para `pnpm test:live ...` direto: `claude` - - Canal sintético: contexto de conversa estilo DM do Slack + - Agents ACP no Docker: `claude,codex,gemini` + - Agent ACP para `pnpm test:live ...` direto: `claude` + - Canal sintético: contexto de conversa no estilo DM do Slack - Backend ACP: `acpx` - Substituições: - `OPENCLAW_LIVE_ACP_BIND_AGENT=claude` @@ -523,9 +533,9 @@ Notas: - `OPENCLAW_LIVE_ACP_BIND_AGENT=gemini` - `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini` - `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND='npx -y @agentclientprotocol/claude-agent-acp@'` -- Notas: - - Essa faixa usa a superfície `chat.send` do gateway com campos sintéticos de origem-da-rota apenas para admin, para que os testes possam anexar contexto de canal de mensagens sem fingir entrega externa. - - Quando `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` não está definido, o teste usa o registro interno de agentes do Plugin embutido `acpx` para o agente de harness ACP selecionado. +- Observações: + - Essa faixa usa a superfície `chat.send` do gateway com campos sintéticos de originating-route apenas para admin para que os testes possam anexar contexto de canal de mensagem sem fingir entrega externa. + - Quando `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` não está definido, o teste usa o registro embutido de agents do Plugin `acpx` para o agent de harness ACP selecionado. Exemplo: @@ -541,7 +551,7 @@ Receita Docker: pnpm test:docker:live-acp-bind ``` -Receitas Docker para um único agente: +Receitas Docker de agent único: ```bash pnpm test:docker:live-acp-bind:claude @@ -549,34 +559,34 @@ pnpm test:docker:live-acp-bind:codex pnpm test:docker:live-acp-bind:gemini ``` -Notas sobre Docker: +Observações sobre Docker: - O executor Docker fica em `scripts/test-live-acp-bind-docker.sh`. -- Por padrão, ele executa o smoke de bind ACP contra todos os agentes de CLI live compatíveis em sequência: `claude`, `codex` e `gemini`. +- Por padrão, ele executa o smoke de bind do ACP contra todos os agents de CLI ao vivo compatíveis em sequência: `claude`, `codex` e depois `gemini`. - Use `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`, `OPENCLAW_LIVE_ACP_BIND_AGENTS=codex` ou `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini` para restringir a matriz. -- Ele carrega `~/.profile`, prepara o material de autenticação da CLI correspondente no contêiner, instala `acpx` em um prefixo npm gravável e então instala a CLI live solicitada (`@anthropic-ai/claude-code`, `@openai/codex` ou `@google/gemini-cli`) se estiver ausente. -- Dentro do Docker, o executor define `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx` para que o acpx mantenha as variáveis de ambiente do provedor vindas do profile carregado disponíveis para a CLI filha do harness. +- Ele carrega `~/.profile`, prepara o material de autenticação da CLI correspondente no contêiner, instala `acpx` em um prefixo npm gravável e então instala a CLI ao vivo solicitada (`@anthropic-ai/claude-code`, `@openai/codex` ou `@google/gemini-cli`) se ela estiver ausente. +- Dentro do Docker, o executor define `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx` para que o acpx mantenha as variáveis de ambiente do provedor do profile carregado disponíveis para a CLI filha do harness. -## Live: smoke do harness app-server do Codex +## Ao vivo: smoke do harness app-server do Codex -- Objetivo: validar o harness Codex de propriedade do Plugin por meio do método - `agent` normal do gateway: - - carregar o Plugin agrupado `codex` +- Objetivo: validar o harness do Codex pertencente ao Plugin pelo método normal + `agent` do gateway: + - carregar o Plugin empacotado `codex` - selecionar `OPENCLAW_AGENT_RUNTIME=codex` - - enviar um primeiro turno do agente do gateway para `codex/gpt-5.4` - - enviar um segundo turno para a mesma sessão do OpenClaw e validar que a thread do app-server + - enviar um primeiro turno do agent do gateway para `codex/gpt-5.4` + - enviar um segundo turno para a mesma sessão OpenClaw e verificar se a thread do app-server consegue retomar - executar `/codex status` e `/codex models` pelo mesmo caminho de comando do gateway - Teste: `src/gateway/gateway-codex-harness.live.test.ts` - Habilitar: `OPENCLAW_LIVE_CODEX_HARNESS=1` - Modelo padrão: `codex/gpt-5.4` -- Probe de imagem opcional: `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1` -- Probe opcional de MCP/ferramenta: `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1` -- O smoke define `OPENCLAW_AGENT_HARNESS_FALLBACK=none` para que um harness Codex - quebrado não passe ao recorrer silenciosamente ao fallback para PI. -- Autenticação: `OPENAI_API_KEY` do shell/profile, mais opcionais - `~/.codex/auth.json` e `~/.codex/config.toml` copiados +- Sonda opcional de imagem: `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1` +- Sonda opcional de MCP/ferramenta: `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1` +- O smoke define `OPENCLAW_AGENT_HARNESS_FALLBACK=none` para que um harness do Codex + quebrado não passe caindo silenciosamente para o PI. +- Autenticação: `OPENAI_API_KEY` do shell/profile, mais os opcionais copiados + `~/.codex/auth.json` e `~/.codex/config.toml` Receita local: @@ -596,22 +606,22 @@ source ~/.profile pnpm test:docker:live-codex-harness ``` -Notas sobre Docker: +Observações sobre Docker: - O executor Docker fica em `scripts/test-live-codex-harness-docker.sh`. - Ele carrega o `~/.profile` montado, passa `OPENAI_API_KEY`, copia arquivos de autenticação da CLI do Codex quando presentes, instala `@openai/codex` em um prefixo npm - gravável montado, prepara a árvore de origem e então executa apenas o teste live do harness Codex. -- O Docker habilita por padrão os probes de imagem e MCP/ferramenta. Defina + gravável montado, prepara a árvore de código-fonte e então executa apenas o teste ao vivo do harness do Codex. +- O Docker habilita por padrão as sondas de imagem e MCP/ferramenta. Defina `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0` ou `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0` quando precisar de uma execução de depuração mais restrita. -- O Docker também exporta `OPENCLAW_AGENT_HARNESS_FALLBACK=none`, em linha com a configuração - do teste live, para que o fallback para `openai-codex/*` ou PI não possa esconder uma regressão - do harness Codex. +- O Docker também exporta `OPENCLAW_AGENT_HARNESS_FALLBACK=none`, alinhado com a configuração do teste ao vivo + para que fallback de `openai-codex/*` ou PI não esconda uma + regressão do harness do Codex. -### Receitas live recomendadas +### Receitas ao vivo recomendadas -Allowlists restritas e explícitas são mais rápidas e menos instáveis: +Allowlists estreitas e explícitas são mais rápidas e menos instáveis: - Modelo único, direto (sem gateway): - `OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts` @@ -619,34 +629,34 @@ Allowlists restritas e explícitas são mais rápidas e menos instáveis: - Modelo único, smoke do gateway: - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -- Chamada de ferramenta em vários provedores: +- Tool calling em vários provedores: - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -- Foco em Google (chave de API Gemini + Antigravity): +- Foco em Google (chave da API Gemini + Antigravity): - Gemini (chave de API): `OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` - Antigravity (OAuth): `OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -Notas: +Observações: - `google/...` usa a API Gemini (chave de API). -- `google-antigravity/...` usa a bridge OAuth do Antigravity (endpoint de agente no estilo Cloud Code Assist). -- `google-gemini-cli/...` usa a CLI Gemini local na sua máquina (autenticação separada + peculiaridades de ferramentas). +- `google-antigravity/...` usa a ponte OAuth do Antigravity (endpoint de agent no estilo Cloud Code Assist). +- `google-gemini-cli/...` usa a CLI local do Gemini na sua máquina (autenticação separada + peculiaridades de tooling). - API Gemini vs CLI Gemini: - - API: o OpenClaw chama a API Gemini hospedada pelo Google via HTTP (chave de API / autenticação por perfil); é isso que a maioria dos usuários quer dizer com “Gemini”. - - CLI: o OpenClaw executa um binário local `gemini`; ele tem sua própria autenticação e pode se comportar de forma diferente (streaming/suporte a ferramentas/desalinhamento de versão). + - API: OpenClaw chama a API Gemini hospedada do Google por HTTP (autenticação por chave de API / perfil); é isso que a maioria dos usuários quer dizer com “Gemini”. + - CLI: OpenClaw executa um binário local `gemini`; ele tem sua própria autenticação e pode se comportar de forma diferente (streaming/suporte a ferramentas/descompasso de versão). -## Live: matriz de modelos (o que cobrimos) +## Ao vivo: matriz de modelos (o que cobrimos) -Não há uma “lista fixa de modelos da CI” (live é opt-in), mas estes são os modelos **recomendados** para cobrir regularmente em uma máquina de desenvolvimento com chaves. +Não há uma “lista fixa de modelos na CI” (ao vivo é opt-in), mas estes são os modelos **recomendados** para cobrir regularmente em uma máquina de desenvolvimento com chaves. -### Conjunto de smoke moderno (chamada de ferramenta + imagem) +### Conjunto smoke moderno (tool calling + imagem) Esta é a execução de “modelos comuns” que esperamos manter funcionando: - OpenAI (não-Codex): `openai/gpt-5.4` (opcional: `openai/gpt-5.4-mini`) - OpenAI Codex: `openai-codex/gpt-5.4` - Anthropic: `anthropic/claude-opus-4-6` (ou `anthropic/claude-sonnet-4-6`) -- Google (API Gemini): `google/gemini-3.1-pro-preview` e `google/gemini-3-flash-preview` (evite modelos Gemini 2.x mais antigos) +- Google (API Gemini): `google/gemini-3.1-pro-preview` e `google/gemini-3-flash-preview` (evite modelos antigos Gemini 2.x) - Google (Antigravity): `google-antigravity/claude-opus-4-6-thinking` e `google-antigravity/gemini-3-flash` - Z.AI (GLM): `zai/glm-4.7` - MiniMax: `minimax/MiniMax-M2.7` @@ -654,9 +664,9 @@ Esta é a execução de “modelos comuns” que esperamos manter funcionando: Execute o smoke do gateway com ferramentas + imagem: `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.4,openai-codex/gpt-5.4,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-flash,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -### Linha de base: chamada de ferramenta (Read + Exec opcional) +### Linha de base: tool calling (Read + Exec opcional) -Escolha pelo menos um por família de provedor: +Escolha pelo menos um por família de provedores: - OpenAI: `openai/gpt-5.4` (ou `openai/gpt-5.4-mini`) - Anthropic: `anthropic/claude-opus-4-6` (ou `anthropic/claude-sonnet-4-6`) @@ -666,14 +676,14 @@ Escolha pelo menos um por família de provedor: Cobertura adicional opcional (bom ter): -- xAI: `xai/grok-4` (ou a versão mais recente disponível) +- xAI: `xai/grok-4` (ou o mais recente disponível) - Mistral: `mistral/`… (escolha um modelo com capacidade de ferramentas que você tenha habilitado) - Cerebras: `cerebras/`… (se você tiver acesso) -- LM Studio: `lmstudio/`… (local; a chamada de ferramenta depende do modo da API) +- LM Studio: `lmstudio/`… (local; o tool calling depende do modo da API) ### Visão: envio de imagem (anexo → mensagem multimodal) -Inclua pelo menos um modelo com suporte a imagem em `OPENCLAW_LIVE_GATEWAY_MODELS` (variantes com suporte a visão do Claude/Gemini/OpenAI etc.) para exercitar o probe de imagem. +Inclua pelo menos um modelo com capacidade de imagem em `OPENCLAW_LIVE_GATEWAY_MODELS` (variantes com suporte a visão do Claude/Gemini/OpenAI etc.) para exercitar a sonda de imagem. ### Agregadores / gateways alternativos @@ -682,63 +692,63 @@ Se você tiver chaves habilitadas, também oferecemos suporte a testes via: - OpenRouter: `openrouter/...` (centenas de modelos; use `openclaw models scan` para encontrar candidatos com capacidade de ferramenta+imagem) - OpenCode: `opencode/...` para Zen e `opencode-go/...` para Go (autenticação via `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY`) -Mais provedores que você pode incluir na matriz live (se tiver credenciais/configuração): +Mais provedores que você pode incluir na matriz ao vivo (se tiver credenciais/configuração): - Embutidos: `openai`, `openai-codex`, `anthropic`, `google`, `google-vertex`, `google-antigravity`, `google-gemini-cli`, `zai`, `openrouter`, `opencode`, `opencode-go`, `xai`, `groq`, `cerebras`, `mistral`, `github-copilot` - Via `models.providers` (endpoints personalizados): `minimax` (nuvem/API), além de qualquer proxy compatível com OpenAI/Anthropic (LM Studio, vLLM, LiteLLM etc.) -Dica: não tente codificar “todos os modelos” nos docs. A lista autoritativa é tudo o que `discoverModels(...)` retorna na sua máquina + quaisquer chaves disponíveis. +Dica: não tente fixar “todos os modelos” na documentação. A lista autoritativa é o que `discoverModels(...)` retorna na sua máquina + quaisquer chaves disponíveis. ## Credenciais (nunca faça commit) -Os testes live descobrem credenciais da mesma forma que a CLI. Implicações práticas: +Os testes ao vivo descobrem credenciais da mesma forma que a CLI. Implicações práticas: -- Se a CLI funciona, os testes live devem encontrar as mesmas chaves. -- Se um teste live disser “sem credenciais”, depure da mesma forma que você depuraria `openclaw models list` / seleção de modelo. +- Se a CLI funciona, os testes ao vivo devem encontrar as mesmas chaves. +- Se um teste ao vivo disser “sem credenciais”, faça a depuração da mesma forma que faria em `openclaw models list` / seleção de modelo. -- Perfis de autenticação por agente: `~/.openclaw/agents//agent/auth-profiles.json` (é isso que “profile keys” significa nos testes live) +- Perfis de autenticação por agent: `~/.openclaw/agents//agent/auth-profiles.json` (é isso que “profile keys” significa nos testes ao vivo) - Configuração: `~/.openclaw/openclaw.json` (ou `OPENCLAW_CONFIG_PATH`) -- Diretório de estado legado: `~/.openclaw/credentials/` (copiado para o home live preparado quando presente, mas não é o armazenamento principal de chaves de perfil) -- As execuções live locais copiam por padrão a configuração ativa, arquivos `auth-profiles.json` por agente, `credentials/` legados e diretórios de autenticação de CLI externos compatíveis para um home temporário de teste; os homes live preparados ignoram `workspace/` e `sandboxes/`, e as substituições de caminho `agents.*.workspace` / `agentDir` são removidas para que os probes fiquem fora do seu workspace real do host. +- Diretório de estado legado: `~/.openclaw/credentials/` (copiado para o home ao vivo preparado quando presente, mas não é o armazenamento principal de chaves de perfil) +- Execuções locais ao vivo copiam por padrão a configuração ativa, arquivos `auth-profiles.json` por agent, `credentials/` legado e diretórios compatíveis de autenticação de CLI externa para um diretório home temporário de teste; homes ao vivo preparados ignoram `workspace/` e `sandboxes/`, e substituições de caminho `agents.*.workspace` / `agentDir` são removidas para que as sondas não toquem seu workspace real do host. -Se quiser depender de chaves de env (por exemplo, exportadas no seu `~/.profile`), execute testes locais após `source ~/.profile`, ou use os executores Docker abaixo (eles podem montar `~/.profile` no contêiner). +Se quiser depender de chaves de env (por exemplo, exportadas no seu `~/.profile`), execute os testes locais após `source ~/.profile`, ou use os executores Docker abaixo (eles podem montar `~/.profile` no contêiner). -## Live do Deepgram (transcrição de áudio) +## Ao vivo do Deepgram (transcrição de áudio) - Teste: `src/media-understanding/providers/deepgram/audio.live.test.ts` - Habilitar: `DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live src/media-understanding/providers/deepgram/audio.live.test.ts` -## Live do plano de codificação BytePlus +## Ao vivo do plano de codificação BytePlus - Teste: `src/agents/byteplus.live.test.ts` - Habilitar: `BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live src/agents/byteplus.live.test.ts` - Substituição opcional de modelo: `BYTEPLUS_CODING_MODEL=ark-code-latest` -## Live de mídia do fluxo de trabalho do ComfyUI +## Ao vivo de mídia de fluxo de trabalho ComfyUI - Teste: `extensions/comfy/comfy.live.test.ts` - Habilitar: `OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts` - Escopo: - - Exercita os caminhos agrupados do comfy para imagem, vídeo e `music_generate` - - Ignora cada capacidade a menos que `models.providers.comfy.` esteja configurado - - Útil após alterar envio de fluxo de trabalho do comfy, polling, downloads ou registro de Plugin + - Exercita os caminhos empacotados de imagem, vídeo e `music_generate` do comfy + - Ignora cada capacidade, a menos que `models.providers.comfy.` esteja configurado + - Útil após mudar envio de fluxo de trabalho do comfy, polling, downloads ou registro do Plugin -## Live de geração de imagem +## Geração de imagem ao vivo - Teste: `src/image-generation/runtime.live.test.ts` - Comando: `pnpm test:live src/image-generation/runtime.live.test.ts` - Harness: `pnpm test:live:media image` - Escopo: - - Enumera cada Plugin de provedor de geração de imagem registrado - - Carrega variáveis de ambiente ausentes do provedor a partir do seu shell de login (`~/.profile`) antes dos probes - - Usa por padrão chaves de API live/env antes dos perfis de autenticação armazenados, para que chaves de teste obsoletas em `auth-profiles.json` não ocultem credenciais reais do shell + - Enumera todos os Plugins de provedor de geração de imagem registrados + - Carrega variáveis de ambiente ausentes do provedor a partir do seu shell de login (`~/.profile`) antes da sonda + - Usa por padrão chaves de API ao vivo/env antes dos perfis de autenticação armazenados, para que chaves de teste desatualizadas em `auth-profiles.json` não escondam credenciais reais do shell - Ignora provedores sem autenticação/perfil/modelo utilizável - - Executa as variantes padrão de geração de imagem pela capacidade compartilhada de runtime: + - Executa as variantes padrão de geração de imagem por meio da capacidade compartilhada de runtime: - `google:flash-generate` - `google:pro-generate` - `google:pro-edit` - `openai:default-generate` -- Provedores agrupados atualmente cobertos: +- Provedores empacotados cobertos atualmente: - `openai` - `google` - Restrição opcional: @@ -746,70 +756,74 @@ Se quiser depender de chaves de env (por exemplo, exportadas no seu `~/.profile` - `OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-1,google/gemini-3.1-flash-image-preview"` - `OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit"` - Comportamento opcional de autenticação: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para forçar autenticação via armazenamento de perfis e ignorar substituições somente de env + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para forçar autenticação pelo armazenamento de perfis e ignorar substituições apenas de env -## Live de geração de música +## Geração de música ao vivo - Teste: `extensions/music-generation-providers.live.test.ts` - Habilitar: `OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/music-generation-providers.live.test.ts` - Harness: `pnpm test:live:media music` - Escopo: - - Exercita o caminho compartilhado agrupado de provedor de geração de música + - Exercita o caminho compartilhado empacotado de provedor de geração de música - Atualmente cobre Google e MiniMax - - Carrega variáveis de ambiente do provedor a partir do seu shell de login (`~/.profile`) antes dos probes - - Usa por padrão chaves de API live/env antes dos perfis de autenticação armazenados, para que chaves de teste obsoletas em `auth-profiles.json` não ocultem credenciais reais do shell + - Carrega variáveis de ambiente do provedor a partir do seu shell de login (`~/.profile`) antes da sonda + - Usa por padrão chaves de API ao vivo/env antes dos perfis de autenticação armazenados, para que chaves de teste desatualizadas em `auth-profiles.json` não escondam credenciais reais do shell - Ignora provedores sem autenticação/perfil/modelo utilizável - Executa ambos os modos de runtime declarados quando disponíveis: - - `generate` com entrada somente de prompt + - `generate` com entrada apenas de prompt - `edit` quando o provedor declara `capabilities.edit.enabled` - Cobertura atual da faixa compartilhada: - `google`: `generate`, `edit` - `minimax`: `generate` - - `comfy`: arquivo live separado do Comfy, não esta varredura compartilhada + - `comfy`: arquivo ao vivo separado do Comfy, não esta varredura compartilhada - Restrição opcional: - `OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"` - `OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"` - Comportamento opcional de autenticação: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para forçar autenticação via armazenamento de perfis e ignorar substituições somente de env + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para forçar autenticação pelo armazenamento de perfis e ignorar substituições apenas de env -## Live de geração de vídeo +## Geração de vídeo ao vivo - Teste: `extensions/video-generation-providers.live.test.ts` - Habilitar: `OPENCLAW_LIVE_TEST=1 pnpm test:live -- extensions/video-generation-providers.live.test.ts` - Harness: `pnpm test:live:media video` - Escopo: - - Exercita o caminho compartilhado agrupado de provedor de geração de vídeo - - Carrega variáveis de ambiente do provedor a partir do seu shell de login (`~/.profile`) antes dos probes - - Usa por padrão chaves de API live/env antes dos perfis de autenticação armazenados, para que chaves de teste obsoletas em `auth-profiles.json` não ocultem credenciais reais do shell + - Exercita o caminho compartilhado empacotado de provedor de geração de vídeo + - Usa por padrão o caminho smoke seguro para release: provedores não FAL, uma requisição text-to-video por provedor, prompt de lagosta de um segundo e um limite de operação por provedor vindo de `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` (`180000` por padrão) + - Ignora FAL por padrão porque a latência de fila do lado do provedor pode dominar o tempo de release; passe `--video-providers fal` ou `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"` para executá-lo explicitamente + - Carrega variáveis de ambiente do provedor a partir do seu shell de login (`~/.profile`) antes da sonda + - Usa por padrão chaves de API ao vivo/env antes dos perfis de autenticação armazenados, para que chaves de teste desatualizadas em `auth-profiles.json` não escondam credenciais reais do shell - Ignora provedores sem autenticação/perfil/modelo utilizável - - Executa ambos os modos de runtime declarados quando disponíveis: - - `generate` com entrada somente de prompt - - `imageToVideo` quando o provedor declara `capabilities.imageToVideo.enabled` e o provedor/modelo selecionado aceita entrada de imagem local com suporte de buffer na varredura compartilhada - - `videoToVideo` quando o provedor declara `capabilities.videoToVideo.enabled` e o provedor/modelo selecionado aceita entrada de vídeo local com suporte de buffer na varredura compartilhada - - Provedores `imageToVideo` atualmente declarados, mas ignorados, na varredura compartilhada: - - `vydra` porque o `veo3` agrupado é somente texto e o `kling` agrupado requer uma URL remota de imagem - - Cobertura específica de provedor para Vydra: + - Executa apenas `generate` por padrão + - Defina `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1` para também executar modos de transformação declarados quando disponíveis: + - `imageToVideo` quando o provedor declara `capabilities.imageToVideo.enabled` e o provedor/modelo selecionado aceita entrada de imagem local baseada em buffer na varredura compartilhada + - `videoToVideo` quando o provedor declara `capabilities.videoToVideo.enabled` e o provedor/modelo selecionado aceita entrada de vídeo local baseada em buffer na varredura compartilhada + - Provedores `imageToVideo` atualmente declarados, mas ignorados na varredura compartilhada: + - `vydra` porque o `veo3` empacotado é apenas texto e o `kling` empacotado exige uma URL remota de imagem + - Cobertura específica de provedor Vydra: - `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_VYDRA_VIDEO=1 pnpm test:live -- extensions/vydra/vydra.live.test.ts` - - esse arquivo executa `veo3` text-to-video mais uma faixa `kling` que usa por padrão uma fixture de URL remota de imagem - - Cobertura live atual de `videoToVideo`: - - `runway` apenas quando o modelo selecionado é `runway/gen4_aleph` - - Provedores `videoToVideo` atualmente declarados, mas ignorados, na varredura compartilhada: + - esse arquivo executa `veo3` text-to-video mais uma faixa `kling` que usa por padrão um fixture de URL remota de imagem + - Cobertura atual ao vivo de `videoToVideo`: + - apenas `runway` quando o modelo selecionado é `runway/gen4_aleph` + - Provedores `videoToVideo` atualmente declarados, mas ignorados na varredura compartilhada: - `alibaba`, `qwen`, `xai` porque esses caminhos atualmente exigem URLs de referência remotas `http(s)` / MP4 - - `google` porque a faixa compartilhada atual Gemini/Veo usa entrada local com suporte de buffer e esse caminho não é aceito na varredura compartilhada - - `openai` porque a faixa compartilhada atual não garante acesso específico da organização a inpaint/remix de vídeo + - `google` porque a faixa compartilhada atual Gemini/Veo usa entrada local baseada em buffer e esse caminho não é aceito na varredura compartilhada + - `openai` porque a faixa compartilhada atual não garante acesso específico da organização a vídeo inpaint/remix - Restrição opcional: - `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="google,openai,runway"` - `OPENCLAW_LIVE_VIDEO_GENERATION_MODELS="google/veo-3.1-fast-generate-preview,openai/sora-2,runway/gen4_aleph"` + - `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""` para incluir todos os provedores na varredura padrão, incluindo FAL + - `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000` para reduzir o limite de operação de cada provedor em uma execução smoke agressiva - Comportamento opcional de autenticação: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para forçar autenticação via armazenamento de perfis e ignorar substituições somente de env + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para forçar autenticação pelo armazenamento de perfis e ignorar substituições apenas de env -## Harness live de mídia +## Harness de mídia ao vivo - Comando: `pnpm test:live:media` -- Objetivo: - - Executa as suítes live compartilhadas de imagem, música e vídeo por um único ponto de entrada nativo do repositório +- Finalidade: + - Executa as suítes compartilhadas ao vivo de imagem, música e vídeo por um único entrypoint nativo do repositório - Carrega automaticamente variáveis de ambiente ausentes do provedor a partir de `~/.profile` - - Restringe automaticamente cada suíte aos provedores que atualmente têm autenticação utilizável por padrão + - Restringe automaticamente por padrão cada suíte aos provedores que atualmente têm autenticação utilizável - Reutiliza `scripts/test-live.mjs`, para que o comportamento de Heartbeat e modo silencioso permaneça consistente - Exemplos: - `pnpm test:live:media` @@ -817,78 +831,78 @@ Se quiser depender de chaves de env (por exemplo, exportadas no seu `~/.profile` - `pnpm test:live:media video --video-providers openai,runway --all-providers` - `pnpm test:live:media music --quiet` -## Executores Docker (verificações opcionais de “funciona em Linux”) +## Executores Docker (verificações opcionais de "funciona no Linux") Esses executores Docker se dividem em dois grupos: -- Executores live-model: `test:docker:live-models` e `test:docker:live-gateway` executam apenas seu arquivo live de chaves de perfil correspondente dentro da imagem Docker do repositório (`src/agents/models.profiles.live.test.ts` e `src/gateway/gateway-models.profiles.live.test.ts`), montando seu diretório local de config e workspace (e carregando `~/.profile` se estiver montado). Os pontos de entrada locais correspondentes são `test:live:models-profiles` e `test:live:gateway-profiles`. -- Os executores live em Docker usam por padrão um limite menor de smoke para que uma varredura completa em Docker continue prática: +- Executores de modelo ao vivo: `test:docker:live-models` e `test:docker:live-gateway` executam apenas seu arquivo ao vivo correspondente de chaves de perfil dentro da imagem Docker do repositório (`src/agents/models.profiles.live.test.ts` e `src/gateway/gateway-models.profiles.live.test.ts`), montando seu diretório de configuração local e workspace (e carregando `~/.profile` se estiver montado). Os entrypoints locais correspondentes são `test:live:models-profiles` e `test:live:gateway-profiles`. +- Os executores Docker ao vivo usam por padrão um limite smoke menor para que uma varredura Docker completa continue prática: `test:docker:live-models` usa por padrão `OPENCLAW_LIVE_MAX_MODELS=12`, e `test:docker:live-gateway` usa por padrão `OPENCLAW_LIVE_GATEWAY_SMOKE=1`, `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`, `OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000` e `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`. Substitua essas variáveis de ambiente quando quiser explicitamente a varredura exaustiva maior. -- `test:docker:all` constrói a imagem Docker live uma vez via `test:docker:live-build` e depois a reutiliza para as duas faixas Docker live. -- Executores de smoke em contêiner: `test:docker:openwebui`, `test:docker:onboard`, `test:docker:gateway-network`, `test:docker:mcp-channels` e `test:docker:plugins` inicializam um ou mais contêineres reais e verificam caminhos de integração de nível mais alto. +- `test:docker:all` constrói a imagem Docker ao vivo uma vez por meio de `test:docker:live-build` e depois a reutiliza para as duas faixas Docker ao vivo. +- Executores smoke de contêiner: `test:docker:openwebui`, `test:docker:onboard`, `test:docker:gateway-network`, `test:docker:mcp-channels` e `test:docker:plugins` iniciam um ou mais contêineres reais e verificam caminhos de integração de nível mais alto. -Os executores Docker live-model também fazem bind-mount apenas dos homes de autenticação de CLI necessários (ou de todos os compatíveis quando a execução não está restrita), depois os copiam para o home do contêiner antes da execução para que o OAuth de CLI externa possa atualizar tokens sem alterar o armazenamento de autenticação do host: +Os executores Docker de modelo ao vivo também fazem bind-mount apenas dos homes de autenticação de CLI necessários (ou de todos os compatíveis quando a execução não está restrita), depois os copiam para o home do contêiner antes da execução para que o OAuth de CLI externa possa atualizar tokens sem modificar o armazenamento de autenticação do host: - Modelos diretos: `pnpm test:docker:live-models` (script: `scripts/test-live-models-docker.sh`) -- Smoke de bind ACP: `pnpm test:docker:live-acp-bind` (script: `scripts/test-live-acp-bind-docker.sh`) +- Smoke de bind do ACP: `pnpm test:docker:live-acp-bind` (script: `scripts/test-live-acp-bind-docker.sh`) - Smoke do backend de CLI: `pnpm test:docker:live-cli-backend` (script: `scripts/test-live-cli-backend-docker.sh`) - Smoke do harness app-server do Codex: `pnpm test:docker:live-codex-harness` (script: `scripts/test-live-codex-harness-docker.sh`) -- Gateway + agente dev: `pnpm test:docker:live-gateway` (script: `scripts/test-live-gateway-models-docker.sh`) -- Smoke live do Open WebUI: `pnpm test:docker:openwebui` (script: `scripts/e2e/openwebui-docker.sh`) +- Gateway + agent de desenvolvimento: `pnpm test:docker:live-gateway` (script: `scripts/test-live-gateway-models-docker.sh`) +- Smoke ao vivo do Open WebUI: `pnpm test:docker:openwebui` (script: `scripts/e2e/openwebui-docker.sh`) - Assistente de onboarding (TTY, scaffolding completo): `pnpm test:docker:onboard` (script: `scripts/e2e/onboard-docker.sh`) -- Rede do gateway (dois contêineres, autenticação WS + health): `pnpm test:docker:gateway-network` (script: `scripts/e2e/gateway-network-docker.sh`) -- Bridge de canal MCP (Gateway preparado + bridge stdio + smoke bruto de frame de notificação do Claude): `pnpm test:docker:mcp-channels` (script: `scripts/e2e/mcp-channels-docker.sh`) -- Plugins (smoke de instalação + alias `/plugin` + semântica de reinício do bundle Claude): `pnpm test:docker:plugins` (script: `scripts/e2e/plugins-docker.sh`) +- Rede do Gateway (dois contêineres, autenticação WS + health): `pnpm test:docker:gateway-network` (script: `scripts/e2e/gateway-network-docker.sh`) +- Ponte de canal MCP (Gateway semeado + ponte stdio + smoke bruto de frame de notificação do Claude): `pnpm test:docker:mcp-channels` (script: `scripts/e2e/mcp-channels-docker.sh`) +- Plugins (smoke de instalação + alias `/plugin` + semântica de reinício do pacote Claude): `pnpm test:docker:plugins` (script: `scripts/e2e/plugins-docker.sh`) -Os executores Docker live-model também montam via bind a checkout atual como somente leitura e -a preparam em um workdir temporário dentro do contêiner. Isso mantém a imagem de runtime -enxuta e ainda assim executa o Vitest contra sua origem/configuração local exata. -A etapa de preparação ignora caches grandes somente locais e saídas de build de apps, como -`.pnpm-store`, `.worktrees`, `__openclaw_vitest__` e diretórios locais de saída de `.build` ou -Gradle, para que execuções live em Docker não passem minutos copiando +Os executores Docker de modelo ao vivo também fazem bind-mount do checkout atual como somente leitura e +o preparam em um workdir temporário dentro do contêiner. Isso mantém a imagem de runtime +enxuta, ao mesmo tempo em que ainda executa o Vitest contra seu código-fonte/configuração local exatos. +A etapa de preparação ignora caches grandes apenas locais e saídas de build do app, como +`.pnpm-store`, `.worktrees`, `__openclaw_vitest__` e diretórios `.build` locais do app ou +diretórios de saída do Gradle, para que execuções Docker ao vivo não gastem minutos copiando artefatos específicos da máquina. -Eles também definem `OPENCLAW_SKIP_CHANNELS=1` para que probes live do gateway não iniciem -workers reais de canal do Telegram/Discord/etc. dentro do contêiner. -`test:docker:live-models` ainda executa `pnpm test:live`, então também passe -`OPENCLAW_LIVE_GATEWAY_*` quando precisar restringir ou excluir a cobertura live -do gateway dessa faixa Docker. +Eles também definem `OPENCLAW_SKIP_CHANNELS=1` para que sondas ao vivo do gateway não iniciem +workers reais de canais Telegram/Discord/etc. dentro do contêiner. +`test:docker:live-models` ainda executa `pnpm test:live`, então repasse também +`OPENCLAW_LIVE_GATEWAY_*` quando precisar restringir ou excluir cobertura ao vivo do gateway +dessa faixa Docker. `test:docker:openwebui` é um smoke de compatibilidade de nível mais alto: ele inicia um -contêiner de gateway do OpenClaw com endpoints HTTP compatíveis com OpenAI habilitados, -inicia um contêiner fixado do Open WebUI contra esse gateway, faz login pelo -Open WebUI, valida que `/api/models` expõe `openclaw/default` e então envia uma +contêiner de gateway do OpenClaw com os endpoints HTTP compatíveis com OpenAI habilitados, +inicia um contêiner fixado do Open WebUI contra esse gateway, faz login por +meio do Open WebUI, verifica se `/api/models` expõe `openclaw/default` e depois envia uma requisição real de chat pelo proxy `/api/chat/completions` do Open WebUI. A primeira execução pode ser visivelmente mais lenta porque o Docker pode precisar baixar a -imagem do Open WebUI e o Open WebUI pode precisar concluir sua própria configuração de cold start. -Essa faixa espera uma chave live de modelo utilizável, e `OPENCLAW_PROFILE_FILE` +imagem do Open WebUI e o Open WebUI pode precisar concluir seu próprio setup de cold start. +Essa faixa espera uma chave de modelo ao vivo utilizável, e `OPENCLAW_PROFILE_FILE` (`~/.profile` por padrão) é a forma principal de fornecê-la em execuções em Docker. Execuções bem-sucedidas imprimem uma pequena carga JSON como `{ "ok": true, "model": "openclaw/default", ... }`. `test:docker:mcp-channels` é intencionalmente determinístico e não precisa de uma -conta real de Telegram, Discord ou iMessage. Ele inicializa um contêiner de Gateway -preparado, inicia um segundo contêiner que executa `openclaw mcp serve` e então -valida descoberta de conversa roteada, leituras de transcrição, metadados de anexo, -comportamento da fila de eventos live, roteamento de envio de saída e notificações -de canal + permissão no estilo Claude pela bridge MCP stdio real. A verificação de notificação -inspeciona diretamente os frames MCP stdio brutos, para que o smoke valide o que a -bridge realmente emite, não apenas o que um SDK cliente específico por acaso expõe. +conta real de Telegram, Discord ou iMessage. Ele inicia um contêiner de Gateway +semeado, inicia um segundo contêiner que executa `openclaw mcp serve` e então +verifica descoberta de conversa roteada, leituras de transcrição, metadados de anexo, +comportamento de fila de eventos ao vivo, roteamento de envio de saída e notificações +de canal + permissão no estilo Claude pela ponte stdio MCP real. A verificação de notificação +inspeciona diretamente os frames MCP brutos de stdio para que o smoke valide o que a +ponte realmente emite, não apenas o que um SDK cliente específico venha a expor. Smoke manual de thread ACP em linguagem natural (não CI): - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` -- Mantenha este script para fluxos de trabalho de regressão/depuração. Ele pode ser necessário novamente para validação de roteamento de thread ACP, então não o exclua. +- Mantenha este script para fluxos de regressão/depuração. Ele pode voltar a ser necessário para validação de roteamento de thread ACP, portanto não o exclua. Variáveis de ambiente úteis: - `OPENCLAW_CONFIG_DIR=...` (padrão: `~/.openclaw`) montado em `/home/node/.openclaw` - `OPENCLAW_WORKSPACE_DIR=...` (padrão: `~/.openclaw/workspace`) montado em `/home/node/.openclaw/workspace` - `OPENCLAW_PROFILE_FILE=...` (padrão: `~/.profile`) montado em `/home/node/.profile` e carregado antes de executar os testes -- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...` (padrão: `~/.cache/openclaw/docker-cli-tools`) montado em `/home/node/.npm-global` para instalações de CLI com cache dentro do Docker -- Diretórios/arquivos de autenticação de CLI externa em `$HOME` são montados como somente leitura em `/host-auth...` e depois copiados para `/home/node/...` antes do início dos testes +- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...` (padrão: `~/.cache/openclaw/docker-cli-tools`) montado em `/home/node/.npm-global` para instalações de CLI em cache dentro do Docker +- Diretórios/arquivos de autenticação de CLI externa sob `$HOME` são montados como somente leitura sob `/host-auth...` e depois copiados para `/home/node/...` antes de os testes começarem - Diretórios padrão: `.minimax` - Arquivos padrão: `~/.codex/auth.json`, `~/.codex/config.toml`, `.claude.json`, `~/.claude/.credentials.json`, `~/.claude/settings.json`, `~/.claude/settings.local.json` - Execuções restritas por provedor montam apenas os diretórios/arquivos necessários inferidos de `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` @@ -896,49 +910,49 @@ Variáveis de ambiente úteis: - `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` para restringir a execução - `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` para filtrar provedores dentro do contêiner - `OPENCLAW_SKIP_DOCKER_BUILD=1` para reutilizar uma imagem `openclaw:local-live` existente em reexecuções que não precisem de rebuild -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para garantir que as credenciais venham do armazenamento de perfis (não de env) +- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para garantir que as credenciais venham do armazenamento de perfis (não do env) - `OPENCLAW_OPENWEBUI_MODEL=...` para escolher o modelo exposto pelo gateway para o smoke do Open WebUI - `OPENCLAW_OPENWEBUI_PROMPT=...` para substituir o prompt de verificação de nonce usado pelo smoke do Open WebUI -- `OPENWEBUI_IMAGE=...` para substituir a tag de imagem fixada do Open WebUI +- `OPENWEBUI_IMAGE=...` para substituir a tag da imagem fixada do Open WebUI ## Sanidade da documentação -Execute verificações de docs após edições na documentação: `pnpm check:docs`. -Execute a validação completa de âncoras do Mintlify quando também precisar de verificações de headings na página: `pnpm docs:check-links:anchors`. +Execute verificações da documentação após edições de docs: `pnpm check:docs`. +Execute a validação completa de âncoras do Mintlify quando também precisar de verificações de cabeçalhos na página: `pnpm docs:check-links:anchors`. ## Regressão offline (segura para CI) Estas são regressões de “pipeline real” sem provedores reais: -- Chamada de ferramenta do gateway (OpenAI simulado, gateway real + loop de agente): `src/gateway/gateway.test.ts` (caso: "runs a mock OpenAI tool call end-to-end via gateway agent loop") -- Assistente do gateway (WS `wizard.start`/`wizard.next`, gravação obrigatória de config + autenticação): `src/gateway/gateway.test.ts` (caso: "runs wizard over ws and writes auth token config") +- Tool calling do Gateway (OpenAI simulado, gateway real + loop de agent): `src/gateway/gateway.test.ts` (caso: "runs a mock OpenAI tool call end-to-end via gateway agent loop") +- Assistente do Gateway (WS `wizard.start`/`wizard.next`, grava config + autenticação obrigatória): `src/gateway/gateway.test.ts` (caso: "runs wizard over ws and writes auth token config") -## Evals de confiabilidade do agente (Skills) +## Avaliações de confiabilidade do agent (Skills) -Já temos alguns testes seguros para CI que se comportam como “evals de confiabilidade do agente”: +Já temos alguns testes seguros para CI que se comportam como “avaliações de confiabilidade do agent”: -- Chamada de ferramenta simulada pelo gateway real + loop de agente (`src/gateway/gateway.test.ts`). -- Fluxos end-to-end do assistente que validam a fiação da sessão e efeitos de configuração (`src/gateway/gateway.test.ts`). +- Tool-calling simulado pelo loop real do Gateway + agent (`src/gateway/gateway.test.ts`). +- Fluxos end-to-end do assistente que validam wiring de sessão e efeitos na configuração (`src/gateway/gateway.test.ts`). O que ainda falta para Skills (veja [Skills](/pt-BR/tools/skills)): -- **Tomada de decisão:** quando Skills são listadas no prompt, o agente escolhe a Skill correta (ou evita as irrelevantes)? -- **Conformidade:** o agente lê `SKILL.md` antes do uso e segue etapas/args obrigatórios? -- **Contratos de fluxo de trabalho:** cenários multi-turn que validam ordem de ferramentas, persistência do histórico da sessão e limites de sandbox. +- **Tomada de decisão:** quando Skills são listadas no prompt, o agent escolhe a Skill certa (ou evita as irrelevantes)? +- **Conformidade:** o agent lê `SKILL.md` antes de usar e segue as etapas/args exigidos? +- **Contratos de fluxo de trabalho:** cenários de múltiplos turnos que verificam ordem de ferramentas, continuidade do histórico da sessão e limites de sandbox. -Evals futuros devem continuar determinísticos primeiro: +Avaliações futuras devem permanecer determinísticas primeiro: -- Um executor de cenários usando provedores simulados para validar chamadas de ferramenta + ordem, leituras de arquivo de Skill e fiação de sessão. -- Um pequeno conjunto de cenários focados em Skill (usar vs evitar, gating, injeção de prompt). -- Evals live opcionais (opt-in, controlados por env) somente depois que a suíte segura para CI estiver pronta. +- Um executor de cenários usando provedores simulados para verificar chamadas de ferramenta + ordem, leituras de arquivo de Skill e wiring de sessão. +- Uma pequena suíte de cenários focados em Skill (usar vs evitar, gating, injeção de prompt). +- Avaliações ao vivo opcionais (opt-in, protegidas por env) só depois que a suíte segura para CI estiver implementada. ## Testes de contrato (formato de Plugin e canal) -Os testes de contrato verificam que cada Plugin e canal registrado está em conformidade com seu -contrato de interface. Eles iteram por todos os Plugins descobertos e executam um conjunto de -validações de formato e comportamento. A faixa unitária padrão de `pnpm test` -intencionalmente ignora esses arquivos compartilhados de seam e smoke; execute os comandos de contrato explicitamente -quando tocar em superfícies compartilhadas de canal ou provedor. +Testes de contrato verificam se todo Plugin e canal registrados estão em conformidade com seu +contrato de interface. Eles iteram sobre todos os Plugins descobertos e executam uma suíte de +verificações de formato e comportamento. A faixa unitária padrão de `pnpm test` +intencionalmente ignora esses arquivos compartilhados de seam e smoke; execute explicitamente +os comandos de contrato quando tocar em superfícies compartilhadas de canal ou provedor. ### Comandos @@ -952,11 +966,11 @@ Localizados em `src/channels/plugins/contracts/*.contract.test.ts`: - **plugin** - Formato básico do Plugin (id, nome, capacidades) - **setup** - Contrato do assistente de configuração -- **session-binding** - Comportamento de vinculação de sessão -- **outbound-payload** - Estrutura de payload de mensagem -- **inbound** - Manipulação de mensagens de entrada +- **session-binding** - Comportamento de vínculo de sessão +- **outbound-payload** - Estrutura da carga de mensagem +- **inbound** - Manipulação de mensagem de entrada - **actions** - Handlers de ação de canal -- **threading** - Manipulação de id de thread +- **threading** - Manipulação de ID de thread - **directory** - API de diretório/lista - **group-policy** - Aplicação de política de grupo @@ -964,8 +978,8 @@ Localizados em `src/channels/plugins/contracts/*.contract.test.ts`: Localizados em `src/plugins/contracts/*.contract.test.ts`. -- **status** - Probes de status de canal -- **registry** - Formato do registro de Plugins +- **status** - Sondas de status do canal +- **registry** - Formato do registro de Plugin ### Contratos de provedor @@ -982,21 +996,21 @@ Localizados em `src/plugins/contracts/*.contract.test.ts`: ### Quando executar -- Após alterar exports ou subpaths do plugin-sdk -- Após adicionar ou modificar um Plugin de canal ou provedor +- Após alterar exports ou subpaths de plugin-sdk +- Após adicionar ou modificar um canal ou Plugin de provedor - Após refatorar registro ou descoberta de Plugin -Os testes de contrato executam na CI e não exigem chaves reais de API. +Os testes de contrato rodam na CI e não exigem chaves reais de API. ## Adicionando regressões (orientação) -Ao corrigir um problema de provedor/modelo descoberto em live: +Quando você corrigir um problema de provedor/modelo descoberto ao vivo: -- Adicione uma regressão segura para CI, se possível (provedor simulado/stub, ou capture a transformação exata do formato da requisição) -- Se for inerentemente apenas live (rate limits, políticas de autenticação), mantenha o teste live restrito e opt-in via variáveis de ambiente -- Prefira direcionar a menor camada que capture o bug: - - bug de conversão/replay de requisição do provedor → teste direto de modelos - - bug de pipeline de sessão/histórico/ferramenta do gateway → smoke live do gateway ou teste simulado do gateway seguro para CI -- Proteção de travessia SecretRef: - - `src/secrets/exec-secret-ref-id-parity.test.ts` deriva um alvo amostrado por classe SecretRef a partir dos metadados do registro (`listSecretTargetRegistryEntries()`), depois valida que ids de exec de segmento de travessia são rejeitados. - - Se você adicionar uma nova família de alvos SecretRef `includeInPlan` em `src/secrets/target-registry-data.ts`, atualize `classifyTargetClass` nesse teste. O teste falha intencionalmente em ids de alvo não classificados, para que novas classes não possam ser ignoradas silenciosamente. +- Adicione uma regressão segura para CI, se possível (provedor mock/stub ou capture a transformação exata do formato da requisição) +- Se for inerentemente apenas ao vivo (limites de taxa, políticas de autenticação), mantenha o teste ao vivo restrito e opt-in por meio de variáveis de ambiente +- Prefira mirar na menor camada que detecta o bug: + - bug de conversão/replay de requisição do provedor → teste de modelos diretos + - bug no pipeline de sessão/histórico/ferramenta do gateway → smoke ao vivo do gateway ou teste mock seguro para CI do gateway +- Guardrail de travessia SecretRef: + - `src/secrets/exec-secret-ref-id-parity.test.ts` deriva um alvo amostrado por classe de SecretRef a partir dos metadados do registro (`listSecretTargetRegistryEntries()`), depois verifica que ids de exec de segmento de travessia são rejeitados. + - Se você adicionar uma nova família de alvos SecretRef `includeInPlan` em `src/secrets/target-registry-data.ts`, atualize `classifyTargetClass` nesse teste. O teste falha intencionalmente em ids de alvo não classificados para que novas classes não possam ser ignoradas silenciosamente. diff --git a/docs/pt-BR/plugins/architecture.md b/docs/pt-BR/plugins/architecture.md index 9a93b45f0..435d68745 100644 --- a/docs/pt-BR/plugins/architecture.md +++ b/docs/pt-BR/plugins/architecture.md @@ -1,181 +1,194 @@ --- read_when: - - Criando ou depurando Plugins nativos do OpenClaw - - Entender o modelo de capacidades de Plugin ou os limites de propriedade - - Trabalhar no pipeline de carregamento ou no registro de Plugin - - Implementar hooks de runtime de provider ou plugins de canal + - Criando ou depurando plugins nativos do OpenClaw + - Entendendo o modelo de capacidades do plugin ou os limites de propriedade + - Trabalhando no pipeline de carregamento do plugin ou no registro + - Implementando hooks de runtime do provedor ou plugins de canal sidebarTitle: Internals -summary: 'Internos de Plugin: modelo de capacidades, propriedade, contratos, pipeline de carregamento e helpers de runtime' -title: Internos de Plugin +summary: 'Internos do Plugin: modelo de capacidades, propriedade, contratos, pipeline de carregamento e auxiliares de runtime' +title: Internos do Plugin x-i18n: - generated_at: "2026-04-12T23:28:29Z" + generated_at: "2026-04-15T05:33:50Z" model: gpt-5.4 provider: openai - source_hash: 37361c1e9d2da57c77358396f19dfc7f749708b66ff68f1bf737d051b5d7675d + source_hash: f86798b5d2b0ad82d2397a52a6c21ed37fe6eee1dd3d124a9e4150c4f630b841 source_path: plugins/architecture.md workflow: 15 --- -# Internos de Plugin +# Internos do Plugin - Esta é a **referência aprofundada de arquitetura**. Para guias práticos, consulte: + Esta é a **referência de arquitetura aprofundada**. Para guias práticos, veja: - [Instalar e usar plugins](/pt-BR/tools/plugin) — guia do usuário - - [Primeiros passos](/pt-BR/plugins/building-plugins) — primeiro tutorial de Plugin + - [Primeiros passos](/pt-BR/plugins/building-plugins) — primeiro tutorial de plugin - [Plugins de canal](/pt-BR/plugins/sdk-channel-plugins) — crie um canal de mensagens - - [Plugins de provider](/pt-BR/plugins/sdk-provider-plugins) — crie um provider de modelo + - [Plugins de provedor](/pt-BR/plugins/sdk-provider-plugins) — crie um provedor de modelos - [Visão geral do SDK](/pt-BR/plugins/sdk-overview) — mapa de importação e API de registro -Esta página cobre a arquitetura interna do sistema de Plugin do OpenClaw. +Esta página cobre a arquitetura interna do sistema de plugins do OpenClaw. ## Modelo público de capacidades -Capacidades são o modelo público de **Plugin nativo** dentro do OpenClaw. Todo -Plugin nativo do OpenClaw se registra em um ou mais tipos de capacidade: +As capacidades são o modelo público de **plugin nativo** dentro do OpenClaw. Todo +plugin nativo do OpenClaw é registrado em um ou mais tipos de capacidade: -| Capacidade | Método de registro | Plugins de exemplo | -| --------------------- | ----------------------------------------------- | ------------------------------------ | -| Inferência de texto | `api.registerProvider(...)` | `openai`, `anthropic` | -| Backend de inferência da CLI | `api.registerCliBackend(...)` | `openai`, `anthropic` | -| Fala | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` | -| Transcrição em tempo real | `api.registerRealtimeTranscriptionProvider(...)` | `openai` | -| Voz em tempo real | `api.registerRealtimeVoiceProvider(...)` | `openai` | -| Entendimento de mídia | `api.registerMediaUnderstandingProvider(...)` | `openai`, `google` | -| Geração de imagem | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` | -| Geração de música | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` | -| Geração de vídeo | `api.registerVideoGenerationProvider(...)` | `qwen` | -| Busca na web | `api.registerWebFetchProvider(...)` | `firecrawl` | -| Pesquisa na web | `api.registerWebSearchProvider(...)` | `google` | -| Canal / mensagens | `api.registerChannel(...)` | `msteams`, `matrix` | +| Capacidade | Método de registro | Plugins de exemplo | +| ---------------------- | ------------------------------------------------ | ------------------------------------- | +| Inferência de texto | `api.registerProvider(...)` | `openai`, `anthropic` | +| Backend de inferência da CLI | `api.registerCliBackend(...)` | `openai`, `anthropic` | +| Fala | `api.registerSpeechProvider(...)` | `elevenlabs`, `microsoft` | +| Transcrição em tempo real | `api.registerRealtimeTranscriptionProvider(...)` | `openai` | +| Voz em tempo real | `api.registerRealtimeVoiceProvider(...)` | `openai` | +| Compreensão de mídia | `api.registerMediaUnderstandingProvider(...)` | `openai`, `google` | +| Geração de imagens | `api.registerImageGenerationProvider(...)` | `openai`, `google`, `fal`, `minimax` | +| Geração de música | `api.registerMusicGenerationProvider(...)` | `google`, `minimax` | +| Geração de vídeo | `api.registerVideoGenerationProvider(...)` | `qwen` | +| Busca na web | `api.registerWebFetchProvider(...)` | `firecrawl` | +| Pesquisa na web | `api.registerWebSearchProvider(...)` | `google` | +| Canal / mensagens | `api.registerChannel(...)` | `msteams`, `matrix` | -Um Plugin que registra zero capacidades, mas fornece hooks, ferramentas ou -serviços, é um Plugin **legado somente com hooks**. Esse padrão continua sendo totalmente compatível. +Um plugin que registra zero capacidades, mas fornece hooks, ferramentas ou +serviços, é um plugin **legado somente com hooks**. Esse padrão ainda é totalmente compatível. -### Posição de compatibilidade externa +### Postura de compatibilidade externa -O modelo de capacidades já está implementado no core e é usado hoje por -plugins nativos/embutidos, mas a compatibilidade de plugins externos ainda -precisa de uma barra mais rígida do que “está exportado, portanto está congelado”. +O modelo de capacidades já foi incorporado ao core e é usado por plugins +nativos/empacotados hoje, mas a compatibilidade com plugins externos ainda +precisa de um critério mais rígido do que “está exportado, portanto está +congelado”. Orientação atual: -- **plugins externos existentes:** mantenha integrações baseadas em hooks funcionando; trate +- **plugins externos existentes:** mantenha funcionando as integrações baseadas em hooks; trate isso como a linha de base de compatibilidade -- **novos plugins nativos/embutidos:** prefira registro explícito de capacidades em vez de - acessos específicos de fornecedor ou novos designs somente com hooks -- **plugins externos adotando registro de capacidades:** permitido, mas trate as superfícies de helper - específicas de capacidade como em evolução, a menos que a documentação marque explicitamente um contrato como estável +- **novos plugins nativos/empacotados:** prefira registro explícito de capacidades em vez de + acessos específicos de fornecedor a partes internas ou novos designs somente com hooks +- **plugins externos adotando registro de capacidades:** permitido, mas trate as + superfícies auxiliares específicas de capacidades como algo em evolução, a menos que a documentação + marque explicitamente um contrato como estável Regra prática: - as APIs de registro de capacidades são a direção pretendida -- hooks legados continuam sendo o caminho mais seguro, sem quebra, para plugins externos durante +- hooks legados continuam sendo o caminho mais seguro, sem quebras, para plugins externos durante a transição -- nem todos os subcaminhos de helper exportados são equivalentes; prefira o contrato estreito e documentado, não exports incidentais +- nem todos os subcaminhos auxiliares exportados são equivalentes; prefira o contrato + estreito e documentado, não exportações auxiliares incidentais -### Formatos de Plugin +### Formas de plugin -O OpenClaw classifica cada Plugin carregado em um formato com base em seu comportamento real -de registro (não apenas em metadados estáticos): +O OpenClaw classifica todo plugin carregado em uma forma com base em seu +comportamento real de registro (não apenas em metadados estáticos): - **plain-capability** -- registra exatamente um tipo de capacidade (por exemplo, um - Plugin somente de provider como `mistral`) -- **hybrid-capability** -- registra múltiplos tipos de capacidade (por exemplo, - `openai` é proprietário de inferência de texto, fala, entendimento de mídia e - geração de imagem) + plugin somente de provedor, como `mistral`) +- **hybrid-capability** -- registra vários tipos de capacidade (por exemplo, + `openai` é responsável por inferência de texto, fala, compreensão de mídia e geração + de imagens) - **hook-only** -- registra apenas hooks (tipados ou personalizados), sem capacidades, ferramentas, comandos ou serviços - **non-capability** -- registra ferramentas, comandos, serviços ou rotas, mas nenhuma capacidade -Use `openclaw plugins inspect ` para ver o formato de um Plugin e o detalhamento -de capacidades. Consulte [Referência da CLI](/cli/plugins#inspect) para detalhes. +Use `openclaw plugins inspect ` para ver a forma e o detalhamento de +capacidades de um plugin. Consulte [Referência da CLI](/cli/plugins#inspect) para detalhes. ### Hooks legados -O hook `before_agent_start` continua compatível como um caminho de compatibilidade para +O hook `before_agent_start` continua compatível como caminho de compatibilidade para plugins somente com hooks. Plugins legados do mundo real ainda dependem dele. Direção: -- mantenha-o funcionando -- documente-o como legado -- prefira `before_model_resolve` para trabalho de substituição de modelo/provider +- mantenha funcionando +- documente como legado +- prefira `before_model_resolve` para trabalho de substituição de modelo/provedor - prefira `before_prompt_build` para trabalho de mutação de prompt -- remova-o somente depois que o uso real cair e a cobertura de fixtures comprovar a segurança da migração +- remova apenas depois que o uso real cair e a cobertura de fixtures comprovar a segurança da migração ### Sinais de compatibilidade Quando você executa `openclaw doctor` ou `openclaw plugins inspect `, pode ver um destes rótulos: -| Sinal | Significado | -| ------------------------- | ------------------------------------------------------------ | +| Sinal | Significado | +| ------------------------- | ------------------------------------------------------------- | | **config valid** | A configuração é analisada corretamente e os plugins são resolvidos | -| **compatibility advisory** | O Plugin usa um padrão compatível, mas mais antigo (por exemplo, `hook-only`) | -| **legacy warning** | O Plugin usa `before_agent_start`, que está obsoleto | -| **hard error** | A configuração é inválida ou o Plugin não conseguiu carregar | +| **compatibility advisory** | O plugin usa um padrão compatível, mas mais antigo (por exemplo, `hook-only`) | +| **legacy warning** | O plugin usa `before_agent_start`, que está obsoleto | +| **hard error** | A configuração é inválida ou o plugin falhou ao carregar | -Nem `hook-only` nem `before_agent_start` vão quebrar seu Plugin hoje -- -`hook-only` é apenas informativo, e `before_agent_start` dispara somente um aviso. Esses +Nem `hook-only` nem `before_agent_start` vão quebrar seu plugin hoje -- +`hook-only` é apenas informativo, e `before_agent_start` apenas gera um aviso. Esses sinais também aparecem em `openclaw status --all` e `openclaw plugins doctor`. ## Visão geral da arquitetura -O sistema de Plugin do OpenClaw tem quatro camadas: +O sistema de plugins do OpenClaw tem quatro camadas: 1. **Manifesto + descoberta** - O OpenClaw encontra Plugins candidatos em caminhos configurados, raízes de workspace, - raízes globais de extensões e extensões embutidas. A descoberta lê primeiro - manifestos nativos `openclaw.plugin.json` e manifestos de bundle compatíveis. + O OpenClaw encontra plugins candidatos a partir de caminhos configurados, raízes de workspace, + raízes globais de extensões e extensões empacotadas. A descoberta lê primeiro + manifestos nativos `openclaw.plugin.json` junto com manifestos de bundle compatíveis. 2. **Habilitação + validação** - O core decide se um Plugin descoberto está habilitado, desabilitado, bloqueado ou + O core decide se um plugin descoberto está habilitado, desabilitado, bloqueado ou selecionado para um slot exclusivo, como memória. 3. **Carregamento em runtime** - Plugins nativos do OpenClaw são carregados em processo via jiti e registram + Os plugins nativos do OpenClaw são carregados no processo via jiti e registram capacidades em um registro central. Bundles compatíveis são normalizados em registros do registro sem importar código de runtime. 4. **Consumo de superfícies** - O restante do OpenClaw lê o registro para expor ferramentas, canais, configuração - de provider, hooks, rotas HTTP, comandos de CLI e serviços. + O restante do OpenClaw lê o registro para expor ferramentas, canais, configuração de provedor, hooks, + rotas HTTP, comandos da CLI e serviços. -Especificamente para a CLI de Plugin, a descoberta do comando raiz é dividida em duas fases: +Especificamente para a CLI de plugin, a descoberta do comando raiz é dividida em duas fases: -- os metadados em tempo de parsing vêm de `registerCli(..., { descriptors: [...] })` -- o módulo real de CLI do Plugin pode continuar lazy e se registrar na primeira invocação +- os metadados em tempo de análise vêm de `registerCli(..., { descriptors: [...] })` +- o módulo real da CLI do plugin pode permanecer lazy e registrar na primeira invocação -Isso mantém o código de CLI pertencente ao Plugin dentro do próprio Plugin, enquanto ainda permite que o OpenClaw -reserve nomes de comando raiz antes do parsing. +Isso mantém o código da CLI pertencente ao plugin dentro do próprio plugin, ao mesmo tempo que permite ao OpenClaw +reservar nomes de comandos raiz antes da análise. O limite de design importante: -- descoberta + validação de configuração devem funcionar a partir de **metadados de manifesto/schema** - sem executar código do Plugin -- o comportamento nativo em runtime vem do caminho `register(api)` do módulo do Plugin +- a descoberta + validação de configuração devem funcionar a partir de **metadados de manifesto/schema** + sem executar código do plugin +- o comportamento nativo em runtime vem do caminho `register(api)` do módulo do plugin -Essa divisão permite ao OpenClaw validar configuração, explicar plugins ausentes/desabilitados e -construir dicas de UI/schema antes que o runtime completo esteja ativo. +Essa separação permite ao OpenClaw validar configuração, explicar plugins ausentes/desabilitados e +montar dicas de UI/schema antes que o runtime completo esteja ativo. ### Plugins de canal e a ferramenta compartilhada de mensagem Plugins de canal não precisam registrar uma ferramenta separada de enviar/editar/reagir para -ações normais de chat. O OpenClaw mantém uma única ferramenta compartilhada `message` no core, e -plugins de canal são proprietários da descoberta e execução específicas do canal por trás dela. +ações normais de chat. O OpenClaw mantém uma ferramenta `message` compartilhada no core, e +plugins de canal são responsáveis pela descoberta e execução específicas do canal por trás dela. O limite atual é: -- o core é proprietário do host da ferramenta compartilhada `message`, da integração com prompt, do - controle de sessão/thread e do despacho de execução -- plugins de canal são proprietários da descoberta de ações com escopo, da descoberta de capacidades e de quaisquer fragmentos de schema específicos do canal -- plugins de canal são proprietários da gramática de conversa de sessão específica do provider, como - ids de conversa codificando ids de thread ou herdando de conversas pai +- o core é responsável pelo host da ferramenta `message` compartilhada, integração com prompt, controle de sessão/thread + e despacho de execução +- plugins de canal são responsáveis pela descoberta de ações com escopo, descoberta de capacidades e + quaisquer fragmentos de schema específicos do canal +- plugins de canal são responsáveis pela gramática de conversa de sessão específica do provedor, como + a forma como ids de conversa codificam ids de thread ou herdam de conversas pai - plugins de canal executam a ação final por meio de seu adaptador de ação Para plugins de canal, a superfície do SDK é `ChannelMessageActionAdapter.describeMessageTool(...)`. Essa chamada unificada de descoberta -permite que um Plugin retorne, em conjunto, suas ações visíveis, capacidades e contribuições para schema -para que essas partes não se desencontrem. +permite que um plugin retorne suas ações visíveis, capacidades e contribuições de schema +juntas, para que essas partes não se desencontrem. + +Quando um parâmetro da ferramenta de mensagem específico de canal contém uma fonte de mídia, como um +caminho local ou URL de mídia remota, o plugin também deve retornar +`mediaSourceParams` de `describeMessageTool(...)`. O core usa essa lista explícita +para aplicar normalização de caminho em sandbox e dicas de acesso a mídia de saída +sem codificar nomes de parâmetros pertencentes ao plugin. +Prefira mapas com escopo por ação, não uma lista plana para todo o canal, para que um +parâmetro de mídia apenas de perfil não seja normalizado em ações não relacionadas como +`send`. O core passa o escopo de runtime para essa etapa de descoberta. Campos importantes incluem: @@ -186,126 +199,121 @@ O core passa o escopo de runtime para essa etapa de descoberta. Campos important - `sessionKey` - `sessionId` - `agentId` -- `requesterSenderId` confiável de entrada +- `requesterSenderId` de entrada confiável -Isso importa para plugins sensíveis a contexto. Um canal pode ocultar ou expor -ações de mensagem com base na conta ativa, sala/thread/mensagem atuais ou -identidade confiável do solicitante sem codificar branches específicos do canal na -ferramenta `message` do core. +Isso importa para plugins sensíveis ao contexto. Um canal pode ocultar ou expor +ações de mensagem com base na conta ativa, sala/thread/mensagem atual ou +identidade confiável do solicitante, sem codificar ramificações específicas do canal na ferramenta +`message` do core. -É por isso que mudanças de roteamento do runner embutido ainda são trabalho de Plugin: o runner é -responsável por encaminhar a identidade atual de chat/sessão para o limite de descoberta do Plugin, para que a -ferramenta compartilhada `message` exponha a superfície correta, pertencente ao canal, para o turno atual. +É por isso que alterações de roteamento do executor embutido ainda são trabalho do plugin: o executor é +responsável por encaminhar a identidade atual de chat/sessão para o limite de descoberta do plugin +para que a ferramenta `message` compartilhada exponha a superfície pertencente ao canal correta +para o turno atual. -Para helpers de execução pertencentes ao canal, plugins embutidos devem manter o runtime de execução -dentro de seus próprios módulos de extensão. O core não é mais proprietário dos runtimes de ação de mensagem de -Discord, Slack, Telegram ou WhatsApp em `src/agents/tools`. -Não publicamos subcaminhos separados `plugin-sdk/*-action-runtime`, e plugins embutidos -devem importar seu próprio código local de runtime diretamente de seus +Para auxiliares de execução pertencentes ao canal, plugins empacotados devem manter o runtime de execução +dentro de seus próprios módulos de extensão. O core não é mais responsável pelos runtimes de ação de mensagem +de Discord, Slack, Telegram ou WhatsApp em `src/agents/tools`. +Não publicamos subcaminhos `plugin-sdk/*-action-runtime` separados, e plugins empacotados +devem importar seu próprio código de runtime local diretamente de seus módulos pertencentes à extensão. -O mesmo limite se aplica, em geral, a seams do SDK nomeadas por provider: o core não -deve importar barrels de conveniência específicos de canal para Slack, Discord, Signal, -WhatsApp ou extensões similares. Se o core precisa de um comportamento, ou deve consumir o -próprio barrel `api.ts` / `runtime-api.ts` do Plugin embutido, ou promover a necessidade -para uma capacidade genérica e estreita no SDK compartilhado. +O mesmo limite se aplica a interfaces do SDK nomeadas por provedor em geral: o core não +deve importar barrels de conveniência específicos de canal para extensões como Slack, Discord, Signal, +WhatsApp ou semelhantes. Se o core precisar de um comportamento, deve consumir o próprio barrel +`api.ts` / `runtime-api.ts` do plugin empacotado ou promover a necessidade para uma capacidade +genérica e estreita no SDK compartilhado. Especificamente para enquetes, há dois caminhos de execução: - `outbound.sendPoll` é a linha de base compartilhada para canais que se encaixam no modelo comum de enquete -- `actions.handleAction("poll")` é o caminho preferido para semântica de enquete específica do canal +- `actions.handleAction("poll")` é o caminho preferido para semânticas de enquete específicas do canal ou parâmetros extras de enquete -Agora o core adia o parsing compartilhado de enquete até depois que o despacho de enquete do Plugin recusa -a ação, para que handlers de enquete pertencentes ao Plugin possam aceitar campos de enquete -específicos do canal sem serem bloqueados antes pelo parser genérico de enquete. +O core agora adia a análise compartilhada de enquete até depois que o despacho de enquete do plugin +recusa a ação, para que manipuladores de enquete pertencentes ao plugin possam aceitar campos +de enquete específicos do canal sem serem bloqueados antes pelo analisador genérico de enquete. Consulte [Pipeline de carregamento](#load-pipeline) para a sequência completa de inicialização. -## Modelo de propriedade de capacidade +## Modelo de propriedade de capacidades -O OpenClaw trata um Plugin nativo como o limite de propriedade para uma **empresa** ou um -**recurso**, não como uma coleção desorganizada de integrações sem relação. +O OpenClaw trata um plugin nativo como o limite de propriedade de uma **empresa** ou de um +**recurso**, não como uma coleção de integrações sem relação. Isso significa: -- um Plugin de empresa normalmente deve ser proprietário de todas as superfícies voltadas ao OpenClaw - dessa empresa -- um Plugin de recurso normalmente deve ser proprietário da superfície completa do recurso que ele introduz +- um plugin de empresa normalmente deve ser responsável por todas as superfícies do OpenClaw + voltadas àquela empresa +- um plugin de recurso normalmente deve ser responsável por toda a superfície do recurso que ele introduz - canais devem consumir capacidades compartilhadas do core em vez de reimplementar - comportamento de provider de forma ad hoc + o comportamento do provedor de forma ad hoc Exemplos: -- o Plugin embutido `openai` é proprietário do comportamento de provider de modelos da OpenAI e do comportamento da OpenAI para - fala + voz em tempo real + entendimento de mídia + geração de imagem -- o Plugin embutido `elevenlabs` é proprietário do comportamento de fala da ElevenLabs -- o Plugin embutido `microsoft` é proprietário do comportamento de fala da Microsoft -- o Plugin embutido `google` é proprietário do comportamento de provider de modelos do Google, além do comportamento do Google para - entendimento de mídia + geração de imagem + pesquisa na web -- o Plugin embutido `firecrawl` é proprietário do comportamento de busca na web do Firecrawl -- os Plugins embutidos `minimax`, `mistral`, `moonshot` e `zai` são proprietários de seus - backends de entendimento de mídia -- o Plugin embutido `qwen` é proprietário do comportamento de provider de texto do Qwen, além do - comportamento de entendimento de mídia e geração de vídeo -- o Plugin `voice-call` é um Plugin de recurso: ele é proprietário de transporte de chamadas, ferramentas, - CLI, rotas e ponte de media-stream do Twilio, mas consome capacidades compartilhadas de fala, - transcrição em tempo real e voz em tempo real em vez de importar plugins de fornecedor diretamente +- o plugin empacotado `openai` é responsável pelo comportamento do provedor de modelos da OpenAI e pelo comportamento de fala + voz em tempo real + compreensão de mídia + geração de imagens da OpenAI +- o plugin empacotado `elevenlabs` é responsável pelo comportamento de fala do ElevenLabs +- o plugin empacotado `microsoft` é responsável pelo comportamento de fala da Microsoft +- o plugin empacotado `google` é responsável pelo comportamento do provedor de modelos do Google, além do comportamento de compreensão de mídia + geração de imagens + pesquisa na web do Google +- o plugin empacotado `firecrawl` é responsável pelo comportamento de busca na web do Firecrawl +- os plugins empacotados `minimax`, `mistral`, `moonshot` e `zai` são responsáveis por seus backends de compreensão de mídia +- o plugin empacotado `qwen` é responsável pelo comportamento do provedor de texto do Qwen, além do comportamento de compreensão de mídia e geração de vídeo +- o plugin `voice-call` é um plugin de recurso: ele é responsável pelo transporte de chamadas, ferramentas, CLI, rotas e pela ponte de fluxo de mídia do Twilio, mas consome capacidades compartilhadas de fala, transcrição em tempo real e voz em tempo real em vez de importar plugins de fornecedor diretamente O estado final pretendido é: -- A OpenAI fica em um único Plugin mesmo que abranja modelos de texto, fala, imagens e +- a OpenAI fica em um único plugin, mesmo que abranja modelos de texto, fala, imagens e vídeo no futuro -- outro fornecedor pode fazer o mesmo para sua própria área de superfície -- canais não se importam com qual Plugin de fornecedor é proprietário do provider; eles consomem o - contrato de capacidade compartilhada exposto pelo core +- outro fornecedor pode fazer o mesmo para sua própria área de atuação +- canais não se importam com qual plugin de fornecedor é responsável pelo provedor; eles consomem o + contrato de capacidade compartilhado exposto pelo core Esta é a distinção principal: - **plugin** = limite de propriedade -- **capability** = contrato do core que múltiplos plugins podem implementar ou consumir +- **capability** = contrato do core que vários plugins podem implementar ou consumir -Portanto, se o OpenClaw adicionar um novo domínio, como vídeo, a primeira pergunta não é -“qual provider deve codificar o tratamento de vídeo?” A primeira pergunta é “qual é -o contrato de capacidade de vídeo do core?” Assim que esse contrato existir, plugins de fornecedor -podem se registrar nele e plugins de canal/recurso podem consumi-lo. +Portanto, se o OpenClaw adicionar um novo domínio como vídeo, a primeira pergunta não é +“qual provedor deve codificar o tratamento de vídeo de forma fixa?” A primeira pergunta é “qual é +o contrato de capacidade de vídeo do core?” Quando esse contrato existir, plugins de fornecedor +podem se registrar nele, e plugins de canal/recurso podem consumi-lo. -Se a capacidade ainda não existir, a ação correta normalmente é: +Se a capacidade ainda não existir, o movimento correto geralmente é: 1. definir a capacidade ausente no core -2. expô-la por meio da API/runtime de Plugin de forma tipada +2. expô-la por meio da API/runtime de plugin de forma tipada 3. conectar canais/recursos a essa capacidade 4. permitir que plugins de fornecedor registrem implementações -Isso mantém a propriedade explícita, ao mesmo tempo que evita comportamento no core que dependa de um -único fornecedor ou de um caminho de código específico de Plugin. +Isso mantém a propriedade explícita e evita comportamento do core que dependa de um +único fornecedor ou de um caminho de código específico de plugin e isolado. ### Camadas de capacidade Use este modelo mental ao decidir onde o código deve ficar: -- **camada de capacidade do core**: orquestração compartilhada, política, fallback, regras - de merge de configuração, semântica de entrega e contratos tipados -- **camada de Plugin de fornecedor**: APIs específicas do fornecedor, autenticação, catálogos de modelos, síntese - de fala, geração de imagens, backends futuros de vídeo, endpoints de uso -- **camada de Plugin de canal/recurso**: integração com Slack/Discord/voice-call/etc. +- **camada de capacidade do core**: orquestração compartilhada, política, fallback, regras de + mesclagem de configuração, semântica de entrega e contratos tipados +- **camada de plugin de fornecedor**: APIs específicas do fornecedor, autenticação, catálogos de modelos, fala + sintética, geração de imagens, backends futuros de vídeo, endpoints de uso +- **camada de plugin de canal/recurso**: integração com Slack/Discord/voice-call/etc. que consome capacidades do core e as apresenta em uma superfície Por exemplo, TTS segue este formato: -- o core é proprietário da política de TTS em tempo de resposta, da ordem de fallback, das preferências e da entrega por canal -- `openai`, `elevenlabs` e `microsoft` são proprietários das implementações de síntese -- `voice-call` consome o helper de runtime de TTS para telefonia +- o core é responsável pela política de TTS em tempo de resposta, ordem de fallback, preferências e entrega por canal +- `openai`, `elevenlabs` e `microsoft` são responsáveis pelas implementações de síntese +- `voice-call` consome o auxiliar de runtime de TTS de telefonia Esse mesmo padrão deve ser preferido para capacidades futuras. -### Exemplo de Plugin de empresa com múltiplas capacidades +### Exemplo de plugin de empresa com múltiplas capacidades -Um Plugin de empresa deve parecer coeso visto de fora. Se o OpenClaw tiver contratos compartilhados -para modelos, fala, transcrição em tempo real, voz em tempo real, entendimento de mídia, -geração de imagem, geração de vídeo, busca na web e pesquisa na web, -um fornecedor pode ser proprietário de todas as suas superfícies em um só lugar: +Um plugin de empresa deve parecer coeso do lado de fora. Se o OpenClaw tiver +contratos compartilhados para modelos, fala, transcrição em tempo real, voz em tempo real, compreensão de mídia, +geração de imagens, geração de vídeo, busca na web e pesquisa na web, +um fornecedor pode ser responsável por todas as suas superfícies em um só lugar: ```ts import type { OpenClawPluginDefinition } from "openclaw/plugin-sdk/plugin-entry"; @@ -359,235 +367,233 @@ const plugin: OpenClawPluginDefinition = { export default plugin; ``` -O importante não é o nome exato dos helpers. O formato é o que importa: +O que importa não são os nomes exatos dos auxiliares. O formato importa: -- um Plugin é proprietário da superfície do fornecedor -- o core continua sendo proprietário dos contratos de capacidade -- canais e plugins de recurso consomem helpers `api.runtime.*`, não código do fornecedor -- testes de contrato podem verificar se o Plugin registrou as capacidades que +- um plugin é responsável pela superfície do fornecedor +- o core continua sendo responsável pelos contratos de capacidade +- plugins de canal e de recurso consomem auxiliares `api.runtime.*`, não código do fornecedor +- testes de contrato podem verificar que o plugin registrou as capacidades que afirma possuir -### Exemplo de capacidade: entendimento de vídeo +### Exemplo de capacidade: compreensão de vídeo -O OpenClaw já trata entendimento de imagem/áudio/vídeo como uma única +O OpenClaw já trata compreensão de imagem/áudio/vídeo como uma única capacidade compartilhada. O mesmo modelo de propriedade se aplica aqui: -1. o core define o contrato de entendimento de mídia +1. o core define o contrato de compreensão de mídia 2. plugins de fornecedor registram `describeImage`, `transcribeAudio` e `describeVideo`, conforme aplicável -3. canais e plugins de recurso consomem o comportamento compartilhado do core em vez de +3. plugins de canal e de recurso consomem o comportamento compartilhado do core em vez de se conectar diretamente ao código do fornecedor -Isso evita incorporar no core as suposições de vídeo de um provider. O Plugin é proprietário -da superfície do fornecedor; o core é proprietário do contrato de capacidade e do comportamento de fallback. +Isso evita incorporar ao core as suposições de vídeo de um único provedor. O plugin é responsável +pela superfície do fornecedor; o core é responsável pelo contrato de capacidade e pelo comportamento de fallback. -A geração de vídeo já usa essa mesma sequência: o core é proprietário do -contrato tipado de capacidade e do helper de runtime, e plugins de fornecedor registram +A geração de vídeo já usa essa mesma sequência: o core é responsável pelo contrato de +capacidade tipado e pelo auxiliar de runtime, e plugins de fornecedor registram implementações `api.registerVideoGenerationProvider(...)` nele. -Precisa de uma checklist concreta de rollout? Consulte -[Livro de receitas de capacidade](/pt-BR/plugins/architecture). +Precisa de um checklist concreto de implementação? Veja +[Capability Cookbook](/pt-BR/plugins/architecture). ## Contratos e aplicação -A superfície da API de Plugin é intencionalmente tipada e centralizada em +A superfície da API de plugins é intencionalmente tipada e centralizada em `OpenClawPluginApi`. Esse contrato define os pontos de registro compatíveis e -os helpers de runtime nos quais um Plugin pode confiar. +os auxiliares de runtime nos quais um plugin pode confiar. Por que isso importa: -- autores de plugins têm um padrão interno estável +- autores de plugins obtêm um padrão interno estável - o core pode rejeitar propriedade duplicada, como dois plugins registrando o mesmo - id de provider -- a inicialização pode expor diagnósticos acionáveis para registros malformados -- testes de contrato podem aplicar a propriedade de plugins embutidos e evitar desvios silenciosos + id de provedor +- a inicialização pode mostrar diagnósticos acionáveis para registros malformados +- testes de contrato podem aplicar a propriedade de plugins empacotados e evitar desvio silencioso Há duas camadas de aplicação: 1. **aplicação de registro em runtime** - O registro de plugins valida registros à medida que os plugins são carregados. Exemplos: - ids de provider duplicados, ids de provider de fala duplicados e registros - malformados produzem diagnósticos de Plugin em vez de comportamento indefinido. + O registro de plugins valida os registros à medida que os plugins são carregados. Exemplos: + ids de provedor duplicados, ids de provedor de fala duplicados e registros + malformados produzem diagnósticos de plugin em vez de comportamento indefinido. 2. **testes de contrato** - Plugins embutidos são capturados em registros de contrato durante execuções de teste para que o + Plugins empacotados são capturados em registros de contrato durante execuções de teste para que o OpenClaw possa verificar a propriedade explicitamente. Hoje isso é usado para - providers de modelo, providers de fala, providers de pesquisa na web e propriedade - de registro embutido. + provedores de modelos, provedores de fala, provedores de pesquisa na web e propriedade de registro empacotado. -O efeito prático é que o OpenClaw sabe, de antemão, qual Plugin é proprietário de qual -superfície. Isso permite que o core e os canais componham sem atrito, porque a propriedade é -declarada, tipada e testável, em vez de implícita. +O efeito prático é que o OpenClaw sabe, de antemão, qual plugin é responsável por qual +superfície. Isso permite que o core e os canais componham de forma integrada, porque a propriedade é +declarada, tipada e testável, e não implícita. ### O que pertence a um contrato -Bons contratos de Plugin são: +Bons contratos de plugin são: - tipados - pequenos - específicos de capacidade - pertencentes ao core -- reutilizáveis por múltiplos plugins +- reutilizáveis por vários plugins - consumíveis por canais/recursos sem conhecimento do fornecedor -Contratos ruins de Plugin são: +Contratos ruins de plugin são: -- política específica de fornecedor escondida no core -- rotas de escape pontuais de Plugin que ignoram o registro +- política específica de fornecedor oculta no core +- rotas de escape pontuais de plugin que ignoram o registro - código de canal acessando diretamente uma implementação de fornecedor -- objetos de runtime ad hoc que não fazem parte de `OpenClawPluginApi` nem de +- objetos de runtime ad hoc que não fazem parte de `OpenClawPluginApi` ou `api.runtime` -Em caso de dúvida, eleve o nível de abstração: defina primeiro a capacidade, depois -permita que os plugins se conectem a ela. +Em caso de dúvida, eleve o nível de abstração: defina primeiro a capacidade e, depois, +deixe os plugins se conectarem a ela. ## Modelo de execução -Plugins nativos do OpenClaw executam **em processo** com o Gateway. Eles não -são isolados em sandbox. Um Plugin nativo carregado tem o mesmo limite de confiança em nível de processo que -o código do core. +Plugins nativos do OpenClaw são executados **no processo** com o Gateway. Eles não +são isolados em sandbox. Um plugin nativo carregado tem o mesmo limite de confiança em nível de processo que o +código do core. Implicações: -- um Plugin nativo pode registrar ferramentas, handlers de rede, hooks e serviços -- um bug em um Plugin nativo pode derrubar ou desestabilizar o gateway -- um Plugin nativo malicioso equivale a execução arbitrária de código dentro - do processo do OpenClaw +- um plugin nativo pode registrar ferramentas, manipuladores de rede, hooks e serviços +- um bug em um plugin nativo pode travar ou desestabilizar o gateway +- um plugin nativo malicioso equivale à execução arbitrária de código dentro do + processo do OpenClaw Bundles compatíveis são mais seguros por padrão porque o OpenClaw atualmente os trata como pacotes de metadados/conteúdo. Nas versões atuais, isso significa principalmente -Skills embutidas. +Skills empacotadas. -Use allowlists e caminhos explícitos de instalação/carregamento para plugins não embutidos. Trate -plugins de workspace como código de desenvolvimento, não como padrões de produção. +Use allowlists e caminhos explícitos de instalação/carregamento para plugins não empacotados. Trate +plugins de workspace como código de desenvolvimento, não como padrão de produção. -Para nomes de pacote de workspace embutido, mantenha o id do Plugin ancorado no -nome npm: `@openclaw/` por padrão, ou um sufixo tipado aprovado como -`-provider`, `-plugin`, `-speech`, `-sandbox` ou `-media-understanding` quando -o pacote expõe intencionalmente uma função de Plugin mais restrita. +Para nomes de pacotes de workspace empacotados, mantenha o id do plugin ancorado no nome +npm: `@openclaw/` por padrão, ou um sufixo tipado aprovado, como +`-provider`, `-plugin`, `-speech`, `-sandbox` ou `-media-understanding`, quando +o pacote intencionalmente expuser uma função de plugin mais restrita. -Observação importante de confiança: +Observação importante sobre confiança: -- `plugins.allow` confia em **ids de Plugin**, não na proveniência da origem. -- Um Plugin de workspace com o mesmo id de um Plugin embutido intencionalmente substitui - a cópia embutida quando esse Plugin de workspace está habilitado/em allowlist. +- `plugins.allow` confia em **ids de plugin**, não na procedência da origem. +- Um plugin de workspace com o mesmo id de um plugin empacotado intencionalmente sobrescreve + a cópia empacotada quando esse plugin de workspace está habilitado/na allowlist. - Isso é normal e útil para desenvolvimento local, testes de patch e hotfixes. ## Limite de exportação O OpenClaw exporta capacidades, não conveniências de implementação. -Mantenha o registro de capacidades público. Reduza exports de helpers fora de contrato: +Mantenha público o registro de capacidades. Reduza exportações auxiliares que não sejam contratos: -- subcaminhos de helper específicos de Plugin embutido -- subcaminhos de infraestrutura de runtime não destinados a API pública -- helpers de conveniência específicos de fornecedor -- helpers de configuração/onboarding que são detalhes de implementação +- subcaminhos auxiliares específicos de plugin empacotado +- subcaminhos de infraestrutura de runtime não destinados à API pública +- auxiliares de conveniência específicos de fornecedor +- auxiliares de configuração/onboarding que são detalhes de implementação -Alguns subcaminhos de helper de Plugin embutido ainda permanecem no mapa de exportação -gerado do SDK por compatibilidade e manutenção de plugins embutidos. Exemplos atuais incluem +Alguns subcaminhos auxiliares de plugins empacotados ainda permanecem no mapa de exportação +gerado do SDK por compatibilidade e manutenção de plugins empacotados. Exemplos atuais incluem `plugin-sdk/feishu`, `plugin-sdk/feishu-setup`, `plugin-sdk/zalo`, -`plugin-sdk/zalo-setup` e vários seams `plugin-sdk/matrix*`. Trate-os como -exports reservados de detalhe de implementação, não como o padrão de SDK recomendado para +`plugin-sdk/zalo-setup` e várias interfaces `plugin-sdk/matrix*`. Trate-os como +exportações reservadas de detalhe de implementação, não como o padrão de SDK recomendado para novos plugins de terceiros. ## Pipeline de carregamento Na inicialização, o OpenClaw faz aproximadamente isto: -1. descobre raízes de Plugins candidatas +1. descobre raízes candidatas de plugin 2. lê manifestos nativos ou de bundle compatível e metadados de pacote 3. rejeita candidatos inseguros -4. normaliza a configuração de Plugin (`plugins.enabled`, `allow`, `deny`, `entries`, +4. normaliza a configuração do plugin (`plugins.enabled`, `allow`, `deny`, `entries`, `slots`, `load.paths`) -5. decide a habilitação para cada candidato +5. decide a habilitação de cada candidato 6. carrega módulos nativos habilitados via jiti -7. chama hooks nativos `register(api)` (ou `activate(api)` — um alias legado) e coleta registros no registro de plugins +7. chama hooks nativos `register(api)` (ou `activate(api)` — um alias legado) e coleta os registros no registro de plugins 8. expõe o registro para comandos/superfícies de runtime -`activate` é um alias legado para `register` — o carregador resolve o que estiver presente (`def.register ?? def.activate`) e o chama no mesmo ponto. Todos os plugins embutidos usam `register`; prefira `register` para novos plugins. +`activate` é um alias legado de `register` — o carregador resolve o que estiver presente (`def.register ?? def.activate`) e o chama no mesmo ponto. Todos os plugins empacotados usam `register`; prefira `register` para novos plugins. -As portas de segurança ocorrem **antes** da execução em runtime. Candidatos são bloqueados -quando a entrada escapa da raiz do Plugin, o caminho tem permissão de escrita global ou a -propriedade do caminho parece suspeita para plugins não embutidos. +As barreiras de segurança acontecem **antes** da execução em runtime. Os candidatos são bloqueados +quando a entrada escapa da raiz do plugin, o caminho tem permissão de escrita global, ou a propriedade do caminho parece suspeita para plugins não empacotados. -### Comportamento orientado a manifesto +### Comportamento manifest-first O manifesto é a fonte de verdade do plano de controle. O OpenClaw o usa para: -- identificar o Plugin +- identificar o plugin - descobrir canais/Skills/schema de configuração declarados ou capacidades do bundle - validar `plugins.entries..config` - complementar rótulos/placeholders da Control UI - mostrar metadados de instalação/catálogo -- preservar descritores baratos de ativação e configuração sem carregar o runtime do Plugin +- preservar descritores baratos de ativação e configuração sem carregar o runtime do plugin -Para plugins nativos, o módulo de runtime é a parte do plano de dados. Ele registra -o comportamento real, como hooks, ferramentas, comandos ou fluxos de provider. +Para plugins nativos, o módulo de runtime é a parte do plano de dados. Ele registra o +comportamento real, como hooks, ferramentas, comandos ou fluxos de provedor. Blocos opcionais `activation` e `setup` do manifesto permanecem no plano de controle. -Eles são descritores somente de metadados para planejamento de ativação e descoberta de setup; -não substituem registro em runtime, `register(...)` ou `setupEntry`. -Os primeiros consumidores de ativação ao vivo agora usam dicas de comando, canal e provider do manifesto +Eles são descritores somente de metadados para planejamento de ativação e descoberta de configuração; +não substituem o registro em runtime, `register(...)` ou `setupEntry`. +Os primeiros consumidores reais de ativação agora usam dicas de comando, canal e provedor do manifesto para restringir o carregamento de plugins antes de uma materialização mais ampla do registro: -- o carregamento da CLI se restringe aos plugins que são proprietários do comando primário solicitado -- a resolução de setup/canal de Plugin se restringe aos plugins que são proprietários do +- o carregamento da CLI é restringido aos plugins que possuem o comando primário solicitado +- a resolução de configuração/canal do plugin é restringida aos plugins que possuem o id de canal solicitado -- a resolução explícita de setup/runtime de provider se restringe aos plugins que são proprietários do - id de provider solicitado +- a resolução explícita de configuração/runtime do provedor é restringida aos plugins que possuem o + id de provedor solicitado -A descoberta de setup agora prefere ids pertencentes ao descritor, como `setup.providers` e +A descoberta de configuração agora prefere ids pertencentes a descritores, como `setup.providers` e `setup.cliBackends`, para restringir plugins candidatos antes de recorrer a -`setup-api` para plugins que ainda precisam de hooks de runtime em tempo de setup. Se mais de -um Plugin descoberto reivindicar o mesmo id normalizado de provider de setup ou backend de CLI, -a busca de setup recusa o proprietário ambíguo em vez de depender da ordem de descoberta. +`setup-api` para plugins que ainda precisam de hooks de runtime no momento da configuração. Se mais de +um plugin descoberto declarar o mesmo id normalizado de provedor de configuração ou backend da CLI, +a busca de configuração recusa o proprietário ambíguo em vez de depender da ordem de descoberta. ### O que o carregador armazena em cache -O OpenClaw mantém caches curtos em processo para: +O OpenClaw mantém caches curtos no processo para: - resultados de descoberta -- dados do registro de manifesto +- dados do registro de manifestos - registros de plugins carregados -Esses caches reduzem sobrecarga de inicialização em rajadas e repetição de comandos. É seguro +Esses caches reduzem inicializações em rajada e a sobrecarga de comandos repetidos. É seguro pensar neles como caches de desempenho de curta duração, não como persistência. Observação de desempenho: - Defina `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` ou - `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` para desativar esses caches. + `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` para desabilitar esses caches. - Ajuste as janelas de cache com `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` e `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS`. ## Modelo de registro -Plugins carregados não alteram diretamente globais aleatórias do core. Eles se registram em um +Plugins carregados não alteram diretamente globais aleatórios do core. Eles se registram em um registro central de plugins. O registro rastreia: -- registros de Plugin (identidade, origem, procedência, status, diagnósticos) +- registros de plugin (identidade, origem, procedência, status, diagnósticos) - ferramentas - hooks legados e hooks tipados - canais -- providers -- handlers de RPC do Gateway +- provedores +- manipuladores RPC do Gateway - rotas HTTP -- registradores de CLI +- registradores da CLI - serviços em segundo plano -- comandos pertencentes ao Plugin +- comandos pertencentes ao plugin -Recursos do core então leem desse registro em vez de falar diretamente com módulos de Plugin. -Isso mantém o carregamento unidirecional: +Os recursos do core então leem desse registro em vez de falar diretamente com módulos de plugin. +Isso mantém o carregamento em um único sentido: -- módulo do Plugin -> registro no registro +- módulo do plugin -> registro no registro - runtime do core -> consumo do registro -Essa separação importa para a manutenção. Isso significa que a maioria das superfícies do core só -precisa de um ponto de integração: “ler o registro”, não “criar caso especial para cada módulo de Plugin”. +Essa separação é importante para a manutenção. Isso significa que a maioria das superfícies do core +precisa apenas de um ponto de integração: “ler o registro”, não “tratar cada módulo de plugin com um caso especial”. ## Callbacks de vinculação de conversa @@ -613,27 +619,27 @@ export default { }; ``` -Campos do payload do callback: +Campos da carga útil do callback: - `status`: `"approved"` ou `"denied"` - `decision`: `"allow-once"`, `"allow-always"` ou `"deny"` - `binding`: o vínculo resolvido para solicitações aprovadas -- `request`: o resumo da solicitação original, dica de desanexação, id do remetente e +- `request`: o resumo da solicitação original, dica de desvinculação, id do remetente e metadados da conversa Esse callback é apenas de notificação. Ele não altera quem tem permissão para vincular uma conversa, e é executado depois que o tratamento de aprovação do core termina. -## Hooks de runtime de provider +## Hooks de runtime do provedor -Plugins de provider agora têm duas camadas: +Plugins de provedor agora têm duas camadas: -- metadados de manifesto: `providerAuthEnvVars` para busca barata de autenticação de provider via env - antes do carregamento do runtime, `providerAuthAliases` para variantes de provider que compartilham - autenticação, `channelEnvVars` para busca barata de env/setup de canal antes do carregamento do runtime, - além de `providerAuthChoices` para rótulos baratos de onboarding/escolha de autenticação e - metadados de flags de CLI antes do carregamento do runtime -- hooks em tempo de configuração: `catalog` / legado `discovery` mais `applyConfigDefaults` +- metadados de manifesto: `providerAuthEnvVars` para busca barata de autenticação do provedor por ambiente + antes do carregamento do runtime, `providerAuthAliases` para variantes de provedor que compartilham + autenticação, `channelEnvVars` para busca barata de ambiente/configuração de canal antes do + carregamento do runtime, além de `providerAuthChoices` para rótulos baratos de onboarding/escolha de autenticação e + metadados de flags da CLI antes do carregamento do runtime +- hooks em tempo de configuração: `catalog` / `discovery` legado mais `applyConfigDefaults` - hooks de runtime: `normalizeModelId`, `normalizeTransport`, `normalizeConfig`, `applyNativeStreamingUsageCompat`, `resolveConfigApiKey`, @@ -654,90 +660,89 @@ Plugins de provider agora têm duas camadas: `buildReplayPolicy`, `sanitizeReplayHistory`, `validateReplayTurns`, `onModelSelected` -O OpenClaw continua sendo proprietário do loop genérico do agente, failover, tratamento de transcrição e -política de ferramentas. Esses hooks são a superfície de extensão para comportamento específico de provider sem +O OpenClaw continua sendo responsável pelo loop genérico do agente, failover, tratamento de transcrição e +política de ferramentas. Esses hooks são a superfície de extensão para comportamento específico do provedor sem precisar de um transporte de inferência totalmente personalizado. -Use o manifesto `providerAuthEnvVars` quando o provider tiver credenciais baseadas em env -que caminhos genéricos de autenticação/status/seletor de modelo devam enxergar sem carregar o runtime do Plugin. -Use o manifesto `providerAuthAliases` quando um id de provider deve reutilizar -as variáveis de ambiente, perfis de autenticação, autenticação baseada em config e escolha de onboarding de chave de API -de outro id de provider. Use o manifesto `providerAuthChoices` quando superfícies de CLI -de onboarding/escolha de autenticação devem conhecer o id de escolha do provider, rótulos de grupo e integração simples -de autenticação com uma única flag sem carregar o runtime do provider. Mantenha `envVars` do runtime do provider -para dicas voltadas ao operador, como rótulos de onboarding ou variáveis de configuração de -client-id/client-secret de OAuth. +Use o manifesto `providerAuthEnvVars` quando o provedor tiver credenciais baseadas em ambiente +que caminhos genéricos de autenticação/status/seletor de modelo devem enxergar sem carregar o runtime do plugin. +Use o manifesto `providerAuthAliases` quando um id de provedor deve reutilizar as variáveis de ambiente, +perfis de autenticação, autenticação baseada em configuração e a escolha de onboarding por chave de API de outro id de provedor. +Use o manifesto `providerAuthChoices` quando superfícies de CLI de onboarding/escolha de autenticação +devem conhecer o id de escolha do provedor, rótulos de grupo e a conexão simples de autenticação com uma única flag +sem carregar o runtime do provedor. Mantenha `envVars` do runtime do provedor para dicas voltadas ao operador, +como rótulos de onboarding ou variáveis de configuração de client-id/client-secret do OAuth. -Use o manifesto `channelEnvVars` quando um canal tiver autenticação ou setup orientados por env que -fallback genérico de env do shell, verificações de config/status ou prompts de setup devam enxergar +Use o manifesto `channelEnvVars` quando um canal tiver autenticação ou configuração orientada por ambiente que +fallback genérico de ambiente do shell, verificações de configuração/status ou prompts de configuração devam enxergar sem carregar o runtime do canal. ### Ordem e uso dos hooks -Para plugins de modelo/provider, o OpenClaw chama hooks aproximadamente nesta ordem. +Para plugins de modelo/provedor, o OpenClaw chama hooks aproximadamente nesta ordem. A coluna “Quando usar” é o guia rápido de decisão. -| # | Hook | O que faz | Quando usar | -| --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -| 1 | `catalog` | Publica a configuração do provider em `models.providers` durante a geração de `models.json` | O provider é proprietário de um catálogo ou de padrões de URL base | -| 2 | `applyConfigDefaults` | Aplica padrões globais de configuração pertencentes ao provider durante a materialização da configuração | Os padrões dependem do modo de autenticação, env ou da semântica da família de modelos do provider | -| -- | _(busca de modelo embutida)_ | O OpenClaw tenta primeiro o caminho normal de registro/catálogo | _(não é um hook de Plugin)_ | -| 3 | `normalizeModelId` | Normaliza aliases legados ou de preview de id de modelo antes da busca | O provider é proprietário da limpeza de aliases antes da resolução canônica do modelo | -| 4 | `normalizeTransport` | Normaliza `api` / `baseUrl` da família do provider antes da montagem genérica do modelo | O provider é proprietário da limpeza de transporte para ids de provider personalizados na mesma família de transporte | -| 5 | `normalizeConfig` | Normaliza `models.providers.` antes da resolução em runtime/do provider | O provider precisa de limpeza de configuração que deve ficar com o Plugin; helpers embutidos da família Google também dão suporte a entradas compatíveis de configuração do Google | -| 6 | `applyNativeStreamingUsageCompat` | Aplica reescritas de compatibilidade de uso de streaming nativo a providers de configuração | O provider precisa de correções de metadados de uso nativo de streaming orientadas por endpoint | -| 7 | `resolveConfigApiKey` | Resolve autenticação por marcador de env para providers de configuração antes do carregamento da autenticação em runtime | O provider tem resolução de chave de API por marcador de env pertencente ao provider; `amazon-bedrock` também tem aqui um resolvedor embutido de marcador de env da AWS | -| 8 | `resolveSyntheticAuth` | Expõe autenticação local/self-hosted ou baseada em configuração sem persistir texto simples | O provider pode operar com um marcador de credencial sintético/local | -| 9 | `resolveExternalAuthProfiles` | Sobrepõe perfis de autenticação externos pertencentes ao provider; o `persistence` padrão é `runtime-only` para credenciais pertencentes à CLI/app | O provider reutiliza credenciais de autenticação externas sem persistir tokens de refresh copiados | -| 10 | `shouldDeferSyntheticProfileAuth` | Rebaixa placeholders armazenados de perfil sintético atrás de autenticação baseada em env/config | O provider armazena perfis sintéticos placeholder que não devem ter precedência | -| 11 | `resolveDynamicModel` | Fallback síncrono para ids de modelo pertencentes ao provider que ainda não estão no registro local | O provider aceita ids arbitrários de modelos upstream | -| 12 | `prepareDynamicModel` | Aquecimento assíncrono; depois `resolveDynamicModel` é executado novamente | O provider precisa de metadados de rede antes de resolver ids desconhecidos | -| 13 | `normalizeResolvedModel` | Reescrita final antes de o runner embutido usar o modelo resolvido | O provider precisa de reescritas de transporte, mas ainda usa um transporte do core | -| 14 | `contributeResolvedModelCompat` | Contribui flags de compatibilidade para modelos do fornecedor por trás de outro transporte compatível | O provider reconhece seus próprios modelos em transportes proxy sem assumir o controle do provider | -| 15 | `capabilities` | Metadados de transcrição/ferramentas pertencentes ao provider usados pela lógica compartilhada do core | O provider precisa de particularidades de transcrição/família de provider | -| 16 | `normalizeToolSchemas` | Normaliza schemas de ferramentas antes que o runner embutido os veja | O provider precisa de limpeza de schema para a família de transporte | -| 17 | `inspectToolSchemas` | Expõe diagnósticos de schema pertencentes ao provider após a normalização | O provider quer avisos de palavra-chave sem ensinar regras específicas de provider ao core | -| 18 | `resolveReasoningOutputMode` | Seleciona contrato de saída de raciocínio nativo versus marcado | O provider precisa de saída final/raciocínio marcada em vez de campos nativos | -| 19 | `prepareExtraParams` | Normalização de parâmetros de solicitação antes dos wrappers genéricos de opção de stream | O provider precisa de parâmetros padrão de solicitação ou limpeza de parâmetros por provider | -| 20 | `createStreamFn` | Substitui completamente o caminho normal de stream por um transporte personalizado | O provider precisa de um protocolo wire personalizado, não apenas de um wrapper | -| 21 | `wrapStreamFn` | Wrapper de stream depois que wrappers genéricos são aplicados | O provider precisa de wrappers de compatibilidade para headers/corpo/modelo da solicitação sem um transporte personalizado | -| 22 | `resolveTransportTurnState` | Anexa headers ou metadados nativos por turno de transporte | O provider quer que transportes genéricos enviem identidade de turno nativa do provider | -| 23 | `resolveWebSocketSessionPolicy` | Anexa headers nativos de WebSocket ou política de resfriamento de sessão | O provider quer que transportes WS genéricos ajustem headers de sessão ou política de fallback | -| 24 | `formatApiKey` | Formatador de perfil de autenticação: o perfil armazenado se torna a string `apiKey` de runtime | O provider armazena metadados extras de autenticação e precisa de um formato de token de runtime personalizado | -| 25 | `refreshOAuth` | Substituição de refresh OAuth para endpoints de refresh personalizados ou política de falha no refresh | O provider não se encaixa nos refreshers compartilhados `pi-ai` | -| 26 | `buildAuthDoctorHint` | Dica de reparo anexada quando o refresh OAuth falha | O provider precisa de orientação de reparo de autenticação pertencente ao provider após falha no refresh | -| 27 | `matchesContextOverflowError` | Correspondência de overflow de janela de contexto pertencente ao provider | O provider tem erros brutos de overflow que as heurísticas genéricas não detectariam | -| 28 | `classifyFailoverReason` | Classificação de motivo de failover pertencente ao provider | O provider pode mapear erros brutos de API/transporte para limite de taxa/sobrecarga/etc. | -| 29 | `isCacheTtlEligible` | Política de cache de prompt para providers de proxy/backhaul | O provider precisa de gating de TTL de cache específico de proxy | -| 30 | `buildMissingAuthMessage` | Substituição para a mensagem genérica de recuperação de autenticação ausente | O provider precisa de uma dica de recuperação de autenticação ausente específica do provider | -| 31 | `suppressBuiltInModel` | Supressão de modelo upstream obsoleto mais dica opcional de erro voltada ao usuário | O provider precisa ocultar linhas upstream obsoletas ou substituí-las por uma dica do fornecedor | -| 32 | `augmentModelCatalog` | Linhas sintéticas/finais de catálogo anexadas após a descoberta | O provider precisa de linhas sintéticas de compatibilidade futura em `models list` e seletores | -| 33 | `isBinaryThinking` | Alternância de raciocínio ligado/desligado para providers com thinking binário | O provider expõe apenas thinking binário ligado/desligado | -| 34 | `supportsXHighThinking` | Suporte a raciocínio `xhigh` para modelos selecionados | O provider quer `xhigh` apenas em um subconjunto de modelos | -| 35 | `resolveDefaultThinkingLevel` | Nível padrão de `/think` para uma família de modelos específica | O provider é proprietário da política padrão de `/think` para uma família de modelos | -| 36 | `isModernModelRef` | Correspondência de modelo moderno para filtros de perfil ao vivo e seleção de smoke | O provider é proprietário da correspondência de modelo preferido para ao vivo/smoke | -| 37 | `prepareRuntimeAuth` | Troca uma credencial configurada pelo token/chave real de runtime logo antes da inferência | O provider precisa de uma troca de token ou de uma credencial de solicitação de curta duração | -| 38 | `resolveUsageAuth` | Resolve credenciais de uso/faturamento para `/usage` e superfícies de status relacionadas | O provider precisa de parsing personalizado de token de uso/cota ou de uma credencial de uso diferente | -| 39 | `fetchUsageSnapshot` | Busca e normaliza snapshots de uso/cota específicos do provider depois que a autenticação é resolvida | O provider precisa de um endpoint de uso específico do provider ou de um parser de payload | -| 40 | `createEmbeddingProvider` | Constrói um adaptador de embeddings pertencente ao provider para memória/pesquisa | O comportamento de embeddings de memória pertence ao Plugin do provider | -| 41 | `buildReplayPolicy` | Retorna uma política de replay que controla o tratamento da transcrição para o provider | O provider precisa de uma política de transcrição personalizada (por exemplo, remoção de blocos de thinking) | -| 42 | `sanitizeReplayHistory` | Reescreve o histórico de replay após a limpeza genérica da transcrição | O provider precisa de reescritas de replay específicas do provider além dos helpers compartilhados de Compaction | -| 43 | `validateReplayTurns` | Validação ou remodelagem final dos turnos de replay antes do runner embutido | O transporte do provider precisa de validação mais rígida dos turnos após a sanitização genérica | -| 44 | `onModelSelected` | Executa efeitos colaterais pós-seleção pertencentes ao provider | O provider precisa de telemetria ou estado pertencente ao provider quando um modelo se torna ativo | +| # | Hook | O que faz | Quando usar | +| --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | `catalog` | Publica a configuração do provedor em `models.providers` durante a geração de `models.json` | O provedor é responsável por um catálogo ou por padrões de URL base | +| 2 | `applyConfigDefaults` | Aplica padrões globais de configuração pertencentes ao provedor durante a materialização da configuração | Os padrões dependem do modo de autenticação, do ambiente ou da semântica da família de modelos do provedor | +| -- | _(built-in model lookup)_ | O OpenClaw tenta primeiro o caminho normal de registro/catálogo | _(não é um hook de plugin)_ | +| 3 | `normalizeModelId` | Normaliza aliases legados ou de preview de id de modelo antes da busca | O provedor é responsável pela limpeza de aliases antes da resolução canônica do modelo | +| 4 | `normalizeTransport` | Normaliza `api` / `baseUrl` da família do provedor antes da montagem genérica do modelo | O provedor é responsável pela limpeza do transporte para ids de provedor personalizados na mesma família de transporte | +| 5 | `normalizeConfig` | Normaliza `models.providers.` antes da resolução de runtime/provedor | O provedor precisa de limpeza de configuração que deve ficar com o plugin; auxiliares empacotados da família Google também dão suporte a entradas compatíveis de configuração do Google | +| 6 | `applyNativeStreamingUsageCompat` | Aplica reescritas de compatibilidade de uso de streaming nativo aos provedores de configuração | O provedor precisa de correções de metadados de uso de streaming nativo orientadas por endpoint | +| 7 | `resolveConfigApiKey` | Resolve autenticação por marcador de ambiente para provedores de configuração antes do carregamento da autenticação de runtime | O provedor tem resolução de chave de API por marcador de ambiente pertencente ao provedor; `amazon-bedrock` também tem aqui um resolvedor embutido de marcador de ambiente da AWS | +| 8 | `resolveSyntheticAuth` | Expõe autenticação local/self-hosted ou baseada em configuração sem persistir texto simples | O provedor pode operar com um marcador de credencial sintético/local | +| 9 | `resolveExternalAuthProfiles` | Sobrepõe perfis externos de autenticação pertencentes ao provedor; `persistence` padrão é `runtime-only` para credenciais pertencentes à CLI/app | O provedor reutiliza credenciais externas de autenticação sem persistir tokens de refresh copiados | +| 10 | `shouldDeferSyntheticProfileAuth` | Rebaixa placeholders sintéticos armazenados de perfil em favor de autenticação baseada em ambiente/configuração | O provedor armazena perfis sintéticos de placeholder que não devem ter precedência | +| 11 | `resolveDynamicModel` | Fallback síncrono para ids de modelo pertencentes ao provedor que ainda não estão no registro local | O provedor aceita ids arbitrários de modelos upstream | +| 12 | `prepareDynamicModel` | Aquecimento assíncrono; depois `resolveDynamicModel` é executado novamente | O provedor precisa de metadados de rede antes de resolver ids desconhecidos | +| 13 | `normalizeResolvedModel` | Reescrita final antes de o executor embutido usar o modelo resolvido | O provedor precisa de reescritas de transporte, mas ainda usa um transporte do core | +| 14 | `contributeResolvedModelCompat` | Contribui com flags de compatibilidade para modelos do fornecedor por trás de outro transporte compatível | O provedor reconhece seus próprios modelos em transportes proxy sem assumir o controle do provedor | +| 15 | `capabilities` | Metadados de transcrição/ferramentas pertencentes ao provedor usados pela lógica compartilhada do core | O provedor precisa lidar com particularidades de transcrição/família de provedor | +| 16 | `normalizeToolSchemas` | Normaliza schemas de ferramentas antes que o executor embutido os veja | O provedor precisa de limpeza de schema da família de transporte | +| 17 | `inspectToolSchemas` | Expõe diagnósticos de schema pertencentes ao provedor após a normalização | O provedor quer avisos de palavras-chave sem ensinar ao core regras específicas do provedor | +| 18 | `resolveReasoningOutputMode` | Seleciona contrato de saída de raciocínio nativo ou com tags | O provedor precisa de saída final/raciocínio com tags em vez de campos nativos | +| 19 | `prepareExtraParams` | Normalização de parâmetros de requisição antes dos wrappers genéricos de opção de stream | O provedor precisa de parâmetros padrão de requisição ou limpeza de parâmetros por provedor | +| 20 | `createStreamFn` | Substitui completamente o caminho normal de stream por um transporte personalizado | O provedor precisa de um protocolo de comunicação personalizado, não apenas de um wrapper | +| 21 | `wrapStreamFn` | Wrapper de stream após a aplicação dos wrappers genéricos | O provedor precisa de wrappers de compatibilidade para headers/corpo/modelo da requisição sem um transporte personalizado | +| 22 | `resolveTransportTurnState` | Anexa headers nativos por turno de transporte ou metadados | O provedor quer que transportes genéricos enviem identidade de turno nativa do provedor | +| 23 | `resolveWebSocketSessionPolicy` | Anexa headers nativos de WebSocket ou política de resfriamento de sessão | O provedor quer que transportes genéricos de WS ajustem headers de sessão ou política de fallback | +| 24 | `formatApiKey` | Formatador de perfil de autenticação: o perfil armazenado se torna a string `apiKey` de runtime | O provedor armazena metadados extras de autenticação e precisa de um formato personalizado de token em runtime | +| 25 | `refreshOAuth` | Substituição da atualização de OAuth para endpoints de atualização personalizados ou política de falha de atualização | O provedor não se encaixa nos atualizadores compartilhados de `pi-ai` | +| 26 | `buildAuthDoctorHint` | Dica de reparo anexada quando a atualização do OAuth falha | O provedor precisa de orientação de reparo de autenticação pertencente ao provedor após falha na atualização | +| 27 | `matchesContextOverflowError` | Correspondência de estouro de janela de contexto pertencente ao provedor | O provedor tem erros brutos de overflow que heurísticas genéricas não detectariam | +| 28 | `classifyFailoverReason` | Classificação de motivo de failover pertencente ao provedor | O provedor pode mapear erros brutos de API/transporte para rate limit/sobrecarga/etc. | +| 29 | `isCacheTtlEligible` | Política de cache de prompt para provedores proxy/backhaul | O provedor precisa de controle de TTL de cache específico para proxy | +| 30 | `buildMissingAuthMessage` | Substituição da mensagem genérica de recuperação para autenticação ausente | O provedor precisa de uma dica de recuperação de autenticação ausente específica do provedor | +| 31 | `suppressBuiltInModel` | Supressão de modelo upstream obsoleto com dica opcional de erro voltada ao usuário | O provedor precisa ocultar linhas upstream obsoletas ou substituí-las por uma dica do fornecedor | +| 32 | `augmentModelCatalog` | Linhas sintéticas/finais de catálogo anexadas após a descoberta | O provedor precisa de linhas sintéticas de compatibilidade futura em `models list` e seletores | +| 33 | `isBinaryThinking` | Alternância de raciocínio liga/desliga para provedores de raciocínio binário | O provedor expõe apenas raciocínio binário ligado/desligado | +| 34 | `supportsXHighThinking` | Suporte a raciocínio `xhigh` para modelos selecionados | O provedor quer `xhigh` apenas em um subconjunto de modelos | +| 35 | `resolveDefaultThinkingLevel` | Nível padrão de `/think` para uma família específica de modelos | O provedor é responsável pela política padrão de `/think` para uma família de modelos | +| 36 | `isModernModelRef` | Correspondência de modelo moderno para filtros de perfil ao vivo e seleção de smoke | O provedor é responsável pela correspondência de modelo preferido em live/smoke | +| 37 | `prepareRuntimeAuth` | Troca uma credencial configurada pelo token/chave real de runtime logo antes da inferência | O provedor precisa de uma troca de token ou de uma credencial de requisição de curta duração | +| 38 | `resolveUsageAuth` | Resolve credenciais de uso/faturamento para `/usage` e superfícies relacionadas de status | O provedor precisa de parsing personalizado de token de uso/cota ou de uma credencial de uso diferente | +| 39 | `fetchUsageSnapshot` | Busca e normaliza snapshots de uso/cota específicos do provedor depois que a autenticação é resolvida | O provedor precisa de um endpoint de uso específico do provedor ou de um parser de payload | +| 40 | `createEmbeddingProvider` | Constrói um adaptador de embeddings pertencente ao provedor para memória/pesquisa | O comportamento de embeddings de memória pertence ao plugin do provedor | +| 41 | `buildReplayPolicy` | Retorna uma política de replay que controla o tratamento de transcrição para o provedor | O provedor precisa de uma política personalizada de transcrição (por exemplo, remoção de blocos de raciocínio) | +| 42 | `sanitizeReplayHistory` | Reescreve o histórico de replay após a limpeza genérica da transcrição | O provedor precisa de reescritas específicas do provedor no replay além dos auxiliares compartilhados de Compaction | +| 43 | `validateReplayTurns` | Validação ou remodelagem final dos turnos de replay antes do executor embutido | O transporte do provedor precisa de validação mais rígida dos turnos após a sanitização genérica | +| 44 | `onModelSelected` | Executa efeitos colaterais pós-seleção pertencentes ao provedor | O provedor precisa de telemetria ou estado pertencente ao provedor quando um modelo se torna ativo | `normalizeModelId`, `normalizeTransport` e `normalizeConfig` primeiro verificam o -Plugin de provider correspondente e depois percorrem outros plugins de provider capazes de usar hooks -até que um deles realmente altere o id do modelo ou o transporte/configuração. Isso mantém -funcionando os shims de alias/provider compatível sem exigir que o chamador saiba qual -Plugin embutido é proprietário da reescrita. Se nenhum hook de provider reescrever uma entrada -compatível de configuração da família Google, o normalizador de configuração embutido do Google ainda aplica +plugin de provedor correspondente e, em seguida, passam pelos outros plugins de provedor capazes de usar hooks +até que um realmente altere o id do modelo ou o transporte/configuração. Isso mantém +funcionando os shims de alias/compatibilidade de provedor sem exigir que o chamador saiba qual +plugin empacotado é responsável pela reescrita. Se nenhum hook de provedor reescrever uma entrada +de configuração compatível da família Google, o normalizador de configuração do Google empacotado ainda aplica essa limpeza de compatibilidade. -Se o provider precisar de um protocolo wire totalmente personalizado ou de um executor de solicitação personalizado, -isso é uma classe diferente de extensão. Esses hooks são para comportamento de provider que -ainda é executado no loop normal de inferência do OpenClaw. +Se o provedor precisar de um protocolo de comunicação totalmente personalizado ou de um executor de requisições personalizado, +isso é uma classe diferente de extensão. Esses hooks são para comportamento de provedor +que ainda é executado no loop normal de inferência do OpenClaw. -### Exemplo de provider +### Exemplo de provedor ```ts api.registerProvider({ @@ -793,115 +798,118 @@ api.registerProvider({ ### Exemplos embutidos -- O Anthropic usa `resolveDynamicModel`, `capabilities`, `buildAuthDoctorHint`, +- Anthropic usa `resolveDynamicModel`, `capabilities`, `buildAuthDoctorHint`, `resolveUsageAuth`, `fetchUsageSnapshot`, `isCacheTtlEligible`, `resolveDefaultThinkingLevel`, `applyConfigDefaults`, `isModernModelRef` - e `wrapStreamFn` porque é proprietário da compatibilidade futura do Claude 4.6, - de dicas da família do provider, de orientação para reparo de autenticação, - da integração com endpoint de uso, da elegibilidade de cache de prompt, de padrões de configuração sensíveis à autenticação, da política - padrão/adaptativa de thinking do Claude e do modelamento de stream específico do Anthropic para - headers beta, `/fast` / `serviceTier` e `context1m`. -- Os helpers de stream específicos de Claude do Anthropic permanecem, por enquanto, no - próprio seam público `api.ts` / `contract-api.ts` do Plugin embutido. Essa superfície do pacote + e `wrapStreamFn` porque é responsável por compatibilidade futura do Claude 4.6, + dicas da família do provedor, orientação de reparo de autenticação, integração + com endpoint de uso, elegibilidade de cache de prompt, padrões de configuração + conscientes de autenticação, política padrão/adaptativa de raciocínio do Claude + e modelagem de stream específica do Anthropic para headers beta, + `/fast` / `serviceTier` e `context1m`. +- Os auxiliares de stream específicos do Claude da Anthropic permanecem por enquanto na própria + interface pública `api.ts` / `contract-api.ts` do plugin empacotado. Essa superfície do pacote exporta `wrapAnthropicProviderStream`, `resolveAnthropicBetas`, - `resolveAnthropicFastMode`, `resolveAnthropicServiceTier` e os builders de wrapper - de baixo nível do Anthropic, em vez de ampliar o SDK genérico em torno das regras de - header beta de um único provider. -- A OpenAI usa `resolveDynamicModel`, `normalizeResolvedModel` e + `resolveAnthropicFastMode`, `resolveAnthropicServiceTier` e os builders + de wrapper Anthropic de nível mais baixo, em vez de ampliar o SDK genérico com base nas + regras de header beta de um único provedor. +- OpenAI usa `resolveDynamicModel`, `normalizeResolvedModel` e `capabilities`, além de `buildMissingAuthMessage`, `suppressBuiltInModel`, `augmentModelCatalog`, `supportsXHighThinking` e `isModernModelRef` - porque é proprietária da compatibilidade futura do GPT-5.4, da normalização direta da OpenAI - `openai-completions` -> `openai-responses`, de dicas de autenticação compatíveis com Codex, - da supressão do Spark, de linhas sintéticas de lista da OpenAI e da política de thinking/modelo ao vivo do GPT-5; a família de stream `openai-responses-defaults` é proprietária dos - wrappers nativos compartilhados do OpenAI Responses para headers de atribuição, - `/fast`/`serviceTier`, verbosidade de texto, pesquisa na web nativa do Codex, + porque é responsável por compatibilidade futura do GPT-5.4, pela normalização direta + `openai-completions` -> `openai-responses` da OpenAI, dicas de autenticação + conscientes do Codex, supressão do Spark, linhas sintéticas da lista OpenAI e + política de raciocínio / modelo ao vivo do GPT-5; a família de stream `openai-responses-defaults` + é responsável pelos wrappers nativos compartilhados do OpenAI Responses para + headers de atribuição, `/fast`/`serviceTier`, verbosidade de texto, pesquisa web nativa do Codex, modelagem de payload compatível com raciocínio e gerenciamento de contexto do Responses. -- O OpenRouter usa `catalog`, além de `resolveDynamicModel` e - `prepareDynamicModel`, porque o provider é pass-through e pode expor novos - ids de modelo antes de o catálogo estático do OpenClaw ser atualizado; ele também usa +- OpenRouter usa `catalog`, além de `resolveDynamicModel` e + `prepareDynamicModel`, porque o provedor é pass-through e pode expor novos + ids de modelo antes da atualização do catálogo estático do OpenClaw; também usa `capabilities`, `wrapStreamFn` e `isCacheTtlEligible` para manter - headers de solicitação específicos do provider, metadados de roteamento, patches de raciocínio e - política de cache de prompt fora do core. Sua política de replay vem da + fora do core os headers de requisição específicos do provedor, metadados de roteamento, + patches de raciocínio e política de cache de prompt. Sua política de replay vem da família `passthrough-gemini`, enquanto a família de stream `openrouter-thinking` - é proprietária da injeção de raciocínio de proxy e dos skips de modelo não compatível / `auto`. -- O GitHub Copilot usa `catalog`, `auth`, `resolveDynamicModel` e + é responsável pela injeção de raciocínio por proxy e pelos skips de modelo não compatível / `auto`. +- GitHub Copilot usa `catalog`, `auth`, `resolveDynamicModel` e `capabilities`, além de `prepareRuntimeAuth` e `fetchUsageSnapshot`, porque - precisa de login por dispositivo pertencente ao provider, comportamento de fallback de modelo, particularidades de transcrição do Claude, - troca de token GitHub -> token Copilot e um endpoint de uso pertencente ao provider. -- O OpenAI Codex usa `catalog`, `resolveDynamicModel`, + precisa de login por dispositivo pertencente ao provedor, comportamento de fallback de modelo, + particularidades de transcrição do Claude, troca de token GitHub -> token Copilot e + um endpoint de uso pertencente ao provedor. +- OpenAI Codex usa `catalog`, `resolveDynamicModel`, `normalizeResolvedModel`, `refreshOAuth` e `augmentModelCatalog`, além de `prepareExtraParams`, `resolveUsageAuth` e `fetchUsageSnapshot`, porque - ainda é executado em transportes OpenAI do core, mas é proprietário da - normalização de seu transporte/URL base, da política de fallback de refresh OAuth, da escolha de transporte padrão, - de linhas sintéticas de catálogo do Codex e da integração com endpoint de uso do ChatGPT; ele - compartilha a mesma família de stream `openai-responses-defaults` da OpenAI direta. -- O Google AI Studio e o OAuth do Gemini CLI usam `resolveDynamicModel`, + ainda roda nos transportes OpenAI do core, mas é responsável por sua normalização + de transporte/URL base, política de fallback de atualização de OAuth, escolha + padrão de transporte, linhas sintéticas do catálogo Codex e integração com o endpoint de uso do ChatGPT; + ele compartilha a mesma família de stream `openai-responses-defaults` da OpenAI direta. +- Google AI Studio e Gemini CLI OAuth usam `resolveDynamicModel`, `buildReplayPolicy`, `sanitizeReplayHistory`, `resolveReasoningOutputMode`, `wrapStreamFn` e `isModernModelRef` porque a - família de replay `google-gemini` é proprietária do fallback de compatibilidade futura do Gemini 3.1, - da validação nativa de replay do Gemini, da sanitização de replay de bootstrap, do modo - de saída de raciocínio marcado e da correspondência de modelo moderno, enquanto a - família de stream `google-thinking` é proprietária da normalização do payload de thinking do Gemini; - o OAuth do Gemini CLI também usa `formatApiKey`, `resolveUsageAuth` e - `fetchUsageSnapshot` para formatação de token, parsing de token e integração com endpoint - de cota. -- O Anthropic Vertex usa `buildReplayPolicy` por meio da - família de replay `anthropic-by-model`, de forma que a limpeza de replay específica do Claude permaneça - limitada a ids de Claude, em vez de a todo transporte `anthropic-messages`. -- O Amazon Bedrock usa `buildReplayPolicy`, `matchesContextOverflowError`, - `classifyFailoverReason` e `resolveDefaultThinkingLevel` porque é proprietário - da classificação de erros específicos do Bedrock para throttle/not-ready/context-overflow - em tráfego Anthropic-on-Bedrock; sua política de replay ainda compartilha a mesma - proteção exclusiva de Claude `anthropic-by-model`. + família de replay `google-gemini` é responsável por fallback de compatibilidade futura do Gemini 3.1, + validação nativa de replay do Gemini, sanitização de replay de bootstrap, modo de saída + de raciocínio com tags e correspondência de modelo moderno, enquanto a + família de stream `google-thinking` é responsável pela normalização do payload de raciocínio do Gemini; + Gemini CLI OAuth também usa `formatApiKey`, `resolveUsageAuth` e + `fetchUsageSnapshot` para formatação de token, parsing de token e integração com o + endpoint de cota. +- Anthropic Vertex usa `buildReplayPolicy` por meio da + família de replay `anthropic-by-model`, para que a limpeza de replay específica do Claude permaneça + com escopo apenas nos ids Claude, em vez de em todo transporte `anthropic-messages`. +- Amazon Bedrock usa `buildReplayPolicy`, `matchesContextOverflowError`, + `classifyFailoverReason` e `resolveDefaultThinkingLevel` porque é responsável + pela classificação específica do Bedrock de erros de throttle/não pronto/estouro de contexto + para tráfego Anthropic-on-Bedrock; sua política de replay ainda compartilha a mesma + proteção `anthropic-by-model` exclusiva do Claude. - OpenRouter, Kilocode, Opencode e Opencode Go usam `buildReplayPolicy` - por meio da família de replay `passthrough-gemini`, porque fazem proxy de modelos Gemini - por transportes compatíveis com OpenAI e precisam de sanitização de - thought-signature do Gemini sem validação nativa de replay do Gemini nem - reescritas de bootstrap. -- O MiniMax usa `buildReplayPolicy` por meio da - família de replay `hybrid-anthropic-openai` porque um provider é proprietário tanto de semântica - Anthropic-message quanto de semântica compatível com OpenAI; ele mantém a remoção de - blocos de thinking exclusivos de Claude no lado Anthropic, ao mesmo tempo que substitui o modo de - saída de raciocínio de volta para nativo, e a família de stream `minimax-fast-mode` é proprietária das - reescritas de modelo de modo rápido no caminho de stream compartilhado. -- O Moonshot usa `catalog`, além de `wrapStreamFn`, porque ainda usa o transporte - OpenAI compartilhado, mas precisa de normalização de payload de thinking pertencente ao provider; a - família de stream `moonshot-thinking` mapeia configuração mais estado de `/think` para seu - payload nativo de thinking binário. -- O Kilocode usa `catalog`, `capabilities`, `wrapStreamFn` e - `isCacheTtlEligible` porque precisa de headers de solicitação pertencentes ao provider, - normalização de payload de raciocínio, dicas de transcrição do Gemini e gating de TTL de cache do Anthropic; a família de stream `kilocode-thinking` mantém a injeção de thinking do Kilo - no caminho de stream proxy compartilhado, ao mesmo tempo que pula `kilo/auto` e + por meio da família de replay `passthrough-gemini` porque fazem proxy de modelos Gemini + por transportes compatíveis com OpenAI e precisam de sanitização de assinatura de pensamento do Gemini + sem validação nativa de replay do Gemini nem reescritas de bootstrap. +- MiniMax usa `buildReplayPolicy` por meio da + família de replay `hybrid-anthropic-openai` porque um único provedor é responsável tanto por + semântica de mensagem Anthropic quanto por semântica compatível com OpenAI; ele mantém + a remoção de blocos de raciocínio exclusivos do Claude no lado Anthropic, enquanto substitui o modo de saída + de raciocínio de volta para o nativo, e a família de stream `minimax-fast-mode` é responsável pelas reescritas + de modelo em fast mode no caminho de stream compartilhado. +- Moonshot usa `catalog` junto com `wrapStreamFn` porque ainda usa o transporte + OpenAI compartilhado, mas precisa de normalização do payload de raciocínio pertencente ao provedor; a + família de stream `moonshot-thinking` mapeia configuração e estado de `/think` para seu + payload nativo de raciocínio binário. +- Kilocode usa `catalog`, `capabilities`, `wrapStreamFn` e + `isCacheTtlEligible` porque precisa de headers de requisição pertencentes ao provedor, + normalização de payload de raciocínio, dicas de transcrição do Gemini e controle de + TTL de cache do Anthropic; a família de stream `kilocode-thinking` mantém a injeção + de raciocínio do Kilo no caminho compartilhado de stream por proxy enquanto ignora `kilo/auto` e outros ids de modelo proxy que não oferecem suporte a payloads explícitos de raciocínio. -- O Z.AI usa `resolveDynamicModel`, `prepareExtraParams`, `wrapStreamFn`, +- Z.AI usa `resolveDynamicModel`, `prepareExtraParams`, `wrapStreamFn`, `isCacheTtlEligible`, `isBinaryThinking`, `isModernModelRef`, - `resolveUsageAuth` e `fetchUsageSnapshot` porque é proprietário do fallback do GLM-5, - dos padrões de `tool_stream`, da UX de thinking binário, da correspondência de modelo moderno e de - autenticação de uso + busca de cota; a família de stream `tool-stream-default-on` mantém o wrapper de `tool_stream` - ativado por padrão fora de glue manuscrito por provider. -- O xAI usa `normalizeResolvedModel`, `normalizeTransport`, + `resolveUsageAuth` e `fetchUsageSnapshot` porque é responsável por fallback de GLM-5, + padrões de `tool_stream`, UX de raciocínio binário, correspondência de modelo moderno e + tanto autenticação de uso quanto busca de cota; a família de stream `tool-stream-default-on` mantém + o wrapper `tool_stream` habilitado por padrão fora da cola manual escrita por provedor. +- xAI usa `normalizeResolvedModel`, `normalizeTransport`, `contributeResolvedModelCompat`, `prepareExtraParams`, `wrapStreamFn`, `resolveSyntheticAuth`, `resolveDynamicModel` e `isModernModelRef` - porque é proprietário da normalização do transporte nativo xAI Responses, das reescritas de alias de - modo rápido do Grok, de `tool_stream` por padrão, da limpeza rigorosa de ferramenta / payload - de raciocínio, da reutilização de autenticação fallback para ferramentas pertencentes ao Plugin, da resolução de modelo Grok com compatibilidade futura - e de patches de compatibilidade pertencentes ao provider, como perfil de schema de ferramenta do xAI, - palavras-chave de schema não compatíveis, `web_search` nativo e decodificação - de argumentos de chamada de ferramenta com entidade HTML. + porque é responsável pela normalização nativa de transporte do xAI Responses, reescritas + de alias em fast mode do Grok, `tool_stream` padrão, limpeza estrita de ferramenta / payload + de raciocínio, reutilização de autenticação de fallback para ferramentas pertencentes ao plugin, resolução + compatível com o futuro de modelos Grok e patches de compatibilidade pertencentes ao provedor, como perfil de + schema de ferramenta do xAI, palavras-chave de schema não compatíveis, `web_search` nativo e + decodificação de argumentos de chamada de ferramenta com entidades HTML. - Mistral, OpenCode Zen e OpenCode Go usam apenas `capabilities` para manter - particularidades de transcrição/ferramentas fora do core. -- Providers embutidos somente de catálogo, como `byteplus`, `cloudflare-ai-gateway`, + fora do core particularidades de transcrição/ferramentas. +- Provedores empacotados somente de catálogo, como `byteplus`, `cloudflare-ai-gateway`, `huggingface`, `kimi-coding`, `nvidia`, `qianfan`, `synthetic`, `together`, `venice`, `vercel-ai-gateway` e `volcengine`, usam apenas `catalog`. -- O Qwen usa `catalog` para seu provider de texto, além de registros compartilhados de entendimento de mídia e +- Qwen usa `catalog` para seu provedor de texto, além de registros compartilhados de compreensão de mídia e geração de vídeo para suas superfícies multimodais. -- MiniMax e Xiaomi usam `catalog`, além de hooks de uso, porque seu comportamento de `/usage` - pertence ao Plugin, embora a inferência ainda seja executada pelos transportes compartilhados. +- MiniMax e Xiaomi usam `catalog` mais hooks de uso porque seu comportamento de `/usage` + pertence ao plugin, embora a inferência ainda seja executada pelos transportes compartilhados. -## Helpers de runtime +## Auxiliares de runtime -Plugins podem acessar helpers selecionados do core via `api.runtime`. Para TTS: +Plugins podem acessar auxiliares selecionados do core via `api.runtime`. Para TTS: ```ts const clip = await api.runtime.tts.textToSpeech({ @@ -922,14 +930,14 @@ const voices = await api.runtime.tts.listVoices({ Observações: -- `textToSpeech` retorna o payload normal de saída de TTS do core para superfícies de arquivo/mensagem de voz. -- Usa a configuração `messages.tts` do core e a seleção de provider. -- Retorna buffer de áudio PCM + sample rate. Plugins devem fazer resample/encode para providers. -- `listVoices` é opcional por provider. Use-o para seletores de voz ou fluxos de setup pertencentes ao fornecedor. -- Listagens de voz podem incluir metadados mais ricos, como localidade, gênero e tags de personalidade para seletores sensíveis ao provider. -- OpenAI e ElevenLabs oferecem suporte a telefonia hoje. A Microsoft não. +- `textToSpeech` retorna a carga útil normal de saída de TTS do core para superfícies de arquivo/mensagem de voz. +- Usa a configuração `messages.tts` do core e a seleção de provedor. +- Retorna buffer de áudio PCM + taxa de amostragem. Plugins devem reamostrar/codificar para provedores. +- `listVoices` é opcional por provedor. Use para seletores de voz ou fluxos de configuração pertencentes ao fornecedor. +- As listas de vozes podem incluir metadados mais ricos, como locale, gênero e tags de personalidade para seletores conscientes do provedor. +- OpenAI e ElevenLabs oferecem suporte a telefonia hoje. Microsoft não. -Plugins também podem registrar providers de fala via `api.registerSpeechProvider(...)`. +Plugins também podem registrar provedores de fala via `api.registerSpeechProvider(...)`. ```ts api.registerSpeechProvider({ @@ -949,15 +957,15 @@ api.registerSpeechProvider({ Observações: -- Mantenha a política de TTS, fallback e entrega de resposta no core. -- Use providers de fala para comportamento de síntese pertencente ao fornecedor. -- A entrada legada `edge` da Microsoft é normalizada para o id de provider `microsoft`. -- O modelo de propriedade preferido é orientado por empresa: um Plugin de fornecedor pode ser proprietário de - texto, fala, imagem e providers de mídia futuros à medida que o OpenClaw adiciona esses +- Mantenha política de TTS, fallback e entrega de resposta no core. +- Use provedores de fala para comportamento de síntese pertencente ao fornecedor. +- A entrada legada `edge` da Microsoft é normalizada para o id de provedor `microsoft`. +- O modelo de propriedade preferido é orientado à empresa: um único plugin de fornecedor pode ser responsável por + provedores de texto, fala, imagem e mídia futura à medida que o OpenClaw adicionar esses contratos de capacidade. -Para entendimento de imagem/áudio/vídeo, plugins registram um provider tipado -de entendimento de mídia em vez de uma coleção genérica de chave/valor: +Para compreensão de imagem/áudio/vídeo, plugins registram um único provedor tipado de +compreensão de mídia em vez de uma coleção genérica de chave/valor: ```ts api.registerMediaUnderstandingProvider({ @@ -971,16 +979,16 @@ api.registerMediaUnderstandingProvider({ Observações: -- Mantenha a orquestração, fallback, configuração e integração com canais no core. -- Mantenha o comportamento do fornecedor no Plugin de provider. -- A expansão aditiva deve permanecer tipada: novos métodos opcionais, novos campos - opcionais de resultado, novas capacidades opcionais. +- Mantenha orquestração, fallback, configuração e integração com canais no core. +- Mantenha o comportamento do fornecedor no plugin do provedor. +- A expansão aditiva deve permanecer tipada: novos métodos opcionais, novos + campos opcionais de resultado, novas capacidades opcionais. - A geração de vídeo já segue o mesmo padrão: - - o core é proprietário do contrato de capacidade e do helper de runtime + - o core é responsável pelo contrato de capacidade e pelo auxiliar de runtime - plugins de fornecedor registram `api.registerVideoGenerationProvider(...)` - plugins de recurso/canal consomem `api.runtime.videoGeneration.*` -Para helpers de runtime de entendimento de mídia, plugins podem chamar: +Para auxiliares de runtime de compreensão de mídia, os plugins podem chamar: ```ts const image = await api.runtime.mediaUnderstanding.describeImageFile({ @@ -995,8 +1003,8 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({ }); ``` -Para transcrição de áudio, plugins podem usar o runtime de entendimento de mídia -ou o alias STT mais antigo: +Para transcrição de áudio, os plugins podem usar tanto o runtime de compreensão de mídia +quanto o alias legado de STT: ```ts const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ @@ -1010,10 +1018,10 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({ Observações: - `api.runtime.mediaUnderstanding.*` é a superfície compartilhada preferida para - entendimento de imagem/áudio/vídeo. -- Usa a configuração de áudio de entendimento de mídia do core (`tools.media.audio`) e a ordem de fallback de provider. + compreensão de imagem/áudio/vídeo. +- Usa a configuração de áudio de compreensão de mídia do core (`tools.media.audio`) e a ordem de fallback do provedor. - Retorna `{ text: undefined }` quando nenhuma saída de transcrição é produzida (por exemplo, entrada ignorada/não compatível). -- `api.runtime.stt.transcribeAudioFile(...)` continua como um alias de compatibilidade. +- `api.runtime.stt.transcribeAudioFile(...)` permanece como alias de compatibilidade. Plugins também podem iniciar execuções de subagentes em segundo plano por meio de `api.runtime.subagent`: @@ -1030,12 +1038,12 @@ const result = await api.runtime.subagent.run({ Observações: - `provider` e `model` são substituições opcionais por execução, não mudanças persistentes de sessão. -- O OpenClaw só aplica esses campos de substituição para chamadores confiáveis. -- Para execuções de fallback pertencentes ao Plugin, operadores precisam optar explicitamente por `plugins.entries..subagent.allowModelOverride: true`. +- O OpenClaw só respeita esses campos de substituição para chamadores confiáveis. +- Para execuções de fallback pertencentes ao plugin, os operadores precisam aderir explicitamente com `plugins.entries..subagent.allowModelOverride: true`. - Use `plugins.entries..subagent.allowedModels` para restringir plugins confiáveis a alvos canônicos específicos `provider/model`, ou `"*"` para permitir explicitamente qualquer alvo. -- Execuções de subagente de plugins não confiáveis continuam funcionando, mas solicitações de substituição são rejeitadas em vez de cair silenciosamente em fallback. +- Execuções de subagente de plugin não confiáveis ainda funcionam, mas as solicitações de substituição são rejeitadas em vez de silenciosamente voltarem para fallback. -Para pesquisa na web, plugins podem consumir o helper compartilhado de runtime em vez de +Para pesquisa na web, os plugins podem consumir o auxiliar de runtime compartilhado em vez de acessar diretamente a integração da ferramenta do agente: ```ts @@ -1052,14 +1060,14 @@ const result = await api.runtime.webSearch.search({ }); ``` -Plugins também podem registrar providers de pesquisa na web via +Os plugins também podem registrar provedores de pesquisa na web via `api.registerWebSearchProvider(...)`. Observações: -- Mantenha a seleção de provider, a resolução de credenciais e a semântica compartilhada de solicitação no core. -- Use providers de pesquisa na web para transportes de pesquisa específicos do fornecedor. -- `api.runtime.webSearch.*` é a superfície compartilhada preferida para plugins de recurso/canal que precisam de comportamento de pesquisa sem depender do wrapper da ferramenta do agente. +- Mantenha seleção de provedor, resolução de credenciais e semântica compartilhada de requisição no core. +- Use provedores de pesquisa na web para transportes de busca específicos do fornecedor. +- `api.runtime.webSearch.*` é a superfície compartilhada preferida para plugins de recurso/canal que precisam de comportamento de busca sem depender do wrapper da ferramenta do agente. ### `api.runtime.imageGeneration` @@ -1074,8 +1082,8 @@ const providers = api.runtime.imageGeneration.listProviders({ }); ``` -- `generate(...)`: gera uma imagem usando a cadeia configurada de provider de geração de imagem. -- `listProviders(...)`: lista providers de geração de imagem disponíveis e suas capacidades. +- `generate(...)`: gera uma imagem usando a cadeia configurada de provedores de geração de imagem. +- `listProviders(...)`: lista os provedores de geração de imagem disponíveis e suas capacidades. ## Rotas HTTP do Gateway @@ -1097,34 +1105,34 @@ api.registerHttpRoute({ Campos da rota: - `path`: caminho da rota sob o servidor HTTP do gateway. -- `auth`: obrigatório. Use `"gateway"` para exigir a autenticação normal do gateway, ou `"plugin"` para autenticação/validação de Webhook gerenciada pelo Plugin. +- `auth`: obrigatório. Use `"gateway"` para exigir autenticação normal do gateway ou `"plugin"` para autenticação/validação de Webhook gerenciada pelo plugin. - `match`: opcional. `"exact"` (padrão) ou `"prefix"`. -- `replaceExisting`: opcional. Permite que o mesmo Plugin substitua seu próprio registro de rota existente. -- `handler`: retorna `true` quando a rota tratou a solicitação. +- `replaceExisting`: opcional. Permite que o mesmo plugin substitua seu próprio registro de rota existente. +- `handler`: retorne `true` quando a rota tratar a requisição. Observações: -- `api.registerHttpHandler(...)` foi removido e causará um erro de carregamento do Plugin. Use `api.registerHttpRoute(...)` em vez disso. -- Rotas de Plugin devem declarar `auth` explicitamente. -- Conflitos exatos de `path + match` são rejeitados, a menos que `replaceExisting: true`, e um Plugin não pode substituir a rota de outro Plugin. -- Rotas sobrepostas com níveis diferentes de `auth` são rejeitadas. Mantenha cadeias de fallthrough `exact`/`prefix` apenas no mesmo nível de autenticação. -- Rotas `auth: "plugin"` **não** recebem automaticamente escopos de runtime do operador. Elas servem para Webhooks/validação de assinatura gerenciados pelo Plugin, não para chamadas privilegiadas a helpers do Gateway. -- Rotas `auth: "gateway"` executam dentro de um escopo de runtime de solicitação do Gateway, mas esse escopo é intencionalmente conservador: - - autenticação bearer por segredo compartilhado (`gateway.auth.mode = "token"` / `"password"`) mantém os escopos de runtime da rota de Plugin fixados em `operator.write`, mesmo que o chamador envie `x-openclaw-scopes` - - modos HTTP confiáveis com identidade (por exemplo, `trusted-proxy` ou `gateway.auth.mode = "none"` em uma entrada privada) só aplicam `x-openclaw-scopes` quando o header está explicitamente presente - - se `x-openclaw-scopes` estiver ausente nessas solicitações de rota de Plugin com identidade, o escopo de runtime recai em `operator.write` -- Regra prática: não assuma que uma rota de Plugin com autenticação de gateway é implicitamente uma superfície de administrador. Se sua rota precisar de comportamento exclusivo de administrador, exija um modo de autenticação com identidade e documente o contrato explícito do header `x-openclaw-scopes`. +- `api.registerHttpHandler(...)` foi removido e causará um erro de carregamento do plugin. Use `api.registerHttpRoute(...)` em vez disso. +- Rotas de plugin devem declarar `auth` explicitamente. +- Conflitos exatos de `path + match` são rejeitados, a menos que `replaceExisting: true`, e um plugin não pode substituir a rota de outro plugin. +- Rotas sobrepostas com diferentes níveis de `auth` são rejeitadas. Mantenha cadeias de fallback `exact`/`prefix` apenas no mesmo nível de autenticação. +- Rotas `auth: "plugin"` **não** recebem automaticamente escopos de runtime do operador. Elas servem para Webhooks gerenciados pelo plugin/validação de assinatura, não para chamadas privilegiadas de auxiliares do Gateway. +- Rotas `auth: "gateway"` são executadas dentro de um escopo de runtime de requisição do Gateway, mas esse escopo é intencionalmente conservador: + - autenticação bearer por segredo compartilhado (`gateway.auth.mode = "token"` / `"password"`) mantém os escopos de runtime da rota do plugin fixados em `operator.write`, mesmo que o chamador envie `x-openclaw-scopes` + - modos HTTP confiáveis com identidade explícita (por exemplo `trusted-proxy` ou `gateway.auth.mode = "none"` em uma entrada privada) respeitam `x-openclaw-scopes` apenas quando o header está explicitamente presente + - se `x-openclaw-scopes` estiver ausente nessas requisições de rota de plugin com identidade explícita, o escopo de runtime volta para `operator.write` +- Regra prática: não presuma que uma rota de plugin com autenticação de gateway seja uma superfície de administrador implícita. Se sua rota precisar de comportamento apenas de administrador, exija um modo de autenticação com identidade explícita e documente o contrato explícito do header `x-openclaw-scopes`. -## Caminhos de importação do SDK de Plugin +## Caminhos de importação do SDK de plugin Use subcaminhos do SDK em vez da importação monolítica `openclaw/plugin-sdk` ao criar plugins: -- `openclaw/plugin-sdk/plugin-entry` para primitivas de registro de Plugin. +- `openclaw/plugin-sdk/plugin-entry` para primitivas de registro de plugin. - `openclaw/plugin-sdk/core` para o contrato genérico compartilhado voltado a plugins. - `openclaw/plugin-sdk/config-schema` para a exportação do schema Zod raiz de `openclaw.json` (`OpenClawSchema`). -- Primitivas estáveis de canal, como `openclaw/plugin-sdk/channel-setup`, +- Primitivas estáveis de canal como `openclaw/plugin-sdk/channel-setup`, `openclaw/plugin-sdk/setup-runtime`, `openclaw/plugin-sdk/setup-adapter-runtime`, `openclaw/plugin-sdk/setup-tools`, @@ -1136,18 +1144,18 @@ criar plugins: `openclaw/plugin-sdk/channel-reply-pipeline`, `openclaw/plugin-sdk/command-auth`, `openclaw/plugin-sdk/secret-input` e - `openclaw/plugin-sdk/webhook-ingress` para a integração compartilhada de - setup/autenticação/resposta/Webhook. `channel-inbound` é a superfície compartilhada para debounce, correspondência de menções, - helpers de política de menção de entrada, formatação de envelope de entrada - e helpers de contexto de envelope de entrada. - `channel-setup` é o seam estreito de setup com instalação opcional. - `setup-runtime` é a superfície segura em runtime para setup usada por `setupEntry` / - inicialização adiada, incluindo os adaptadores de patch de setup seguros para importação. - `setup-adapter-runtime` é o seam de adaptador de setup de conta sensível a env. - `setup-tools` é o seam pequeno de helpers para CLI/arquivo/docs (`formatCliCommand`, + `openclaw/plugin-sdk/webhook-ingress` para integração compartilhada de + configuração/autenticação/resposta/Webhook. `channel-inbound` é o local compartilhado para debounce, correspondência de menções, + auxiliares de política de menção de entrada, formatação de envelope e + auxiliares de contexto de envelope de entrada. + `channel-setup` é a interface estreita de configuração para instalação opcional. + `setup-runtime` é a superfície de configuração segura em runtime usada por `setupEntry` / + inicialização adiada, incluindo os adaptadores de patch de configuração seguros para importação. + `setup-adapter-runtime` é a interface de adaptador de configuração de conta sensível ao ambiente. + `setup-tools` é a pequena interface de auxiliares de CLI/arquivo/docs (`formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR`). -- Subcaminhos de domínio, como `openclaw/plugin-sdk/channel-config-helpers`, +- Subcaminhos de domínio como `openclaw/plugin-sdk/channel-config-helpers`, `openclaw/plugin-sdk/allow-from`, `openclaw/plugin-sdk/channel-config-schema`, `openclaw/plugin-sdk/telegram-command-config`, @@ -1165,187 +1173,195 @@ criar plugins: `openclaw/plugin-sdk/status-helpers`, `openclaw/plugin-sdk/text-runtime`, `openclaw/plugin-sdk/runtime-store` e - `openclaw/plugin-sdk/directory-runtime` para helpers compartilhados de runtime/configuração. - `telegram-command-config` é o seam público estreito para normalização/validação de comandos personalizados do Telegram e permanece disponível mesmo se a superfície do contrato embutido do Telegram estiver temporariamente indisponível. - `text-runtime` é o seam compartilhado de texto/Markdown/logging, incluindo - remoção de texto visível ao assistente, helpers de renderização/chunking de Markdown, helpers de redação, - helpers de tag de diretiva e utilitários de texto seguro. -- Seams de canal específicos de aprovação devem preferir um único contrato `approvalCapability` - no Plugin. O core então lê autenticação, entrega, renderização, - roteamento nativo e comportamento lazy de handler nativo de aprovação por meio dessa única capacidade - em vez de misturar comportamento de aprovação em campos não relacionados do Plugin. + `openclaw/plugin-sdk/directory-runtime` para auxiliares compartilhados de runtime/configuração. + `telegram-command-config` é a interface pública estreita para normalização/validação de comandos + personalizados do Telegram e permanece disponível mesmo que a + superfície de contrato empacotada do Telegram fique temporariamente indisponível. + `text-runtime` é a interface compartilhada de texto/Markdown/logging, incluindo + remoção de texto visível ao assistente, auxiliares de renderização/fragmentação de Markdown, auxiliares de redação, + auxiliares de tags de diretiva e utilitários de texto seguro. +- Interfaces de canal específicas de aprovação devem preferir um único contrato + `approvalCapability` no plugin. O core então lê autenticação, entrega, renderização, + roteamento nativo e comportamento lazy de manipulador nativo de aprovação por meio dessa única capacidade + em vez de misturar comportamento de aprovação em campos não relacionados do plugin. - `openclaw/plugin-sdk/channel-runtime` está obsoleto e permanece apenas como um - shim de compatibilidade para plugins mais antigos. Código novo deve importar as primitivas genéricas mais estreitas, e o código do repositório não deve adicionar novas importações do + shim de compatibilidade para plugins mais antigos. Código novo deve importar as primitivas + genéricas mais estreitas, e o código do repositório não deve adicionar novas importações do shim. -- Internos de extensões embutidas continuam privados. Plugins externos devem usar apenas subcaminhos `openclaw/plugin-sdk/*`. Código de core/teste do OpenClaw pode usar os pontos de entrada públicos do repositório sob a raiz de um pacote de Plugin, como `index.js`, `api.js`, - `runtime-api.js`, `setup-entry.js` e arquivos de escopo estreito como - `login-qr-api.js`. Nunca importe `src/*` de um pacote de Plugin a partir do core ou de outra extensão. -- Divisão do ponto de entrada do repositório: - `/api.js` é o barrel de helpers/tipos, +- Internos de extensões empacotadas permanecem privados. Plugins externos devem usar apenas + subcaminhos `openclaw/plugin-sdk/*`. O código core/test do OpenClaw pode usar os + pontos de entrada públicos do repositório sob a raiz de um pacote de plugin, como `index.js`, `api.js`, + `runtime-api.js`, `setup-entry.js` e arquivos de escopo estreito, como + `login-qr-api.js`. Nunca importe `src/*` de um pacote de plugin a partir do core ou de + outra extensão. +- Divisão de ponto de entrada do repositório: + `/api.js` é o barrel de auxiliares/tipos, `/runtime-api.js` é o barrel apenas de runtime, - `/index.js` é a entrada do Plugin embutido, - e `/setup-entry.js` é a entrada do Plugin de setup. -- Exemplos atuais de providers embutidos: - - O Anthropic usa `api.js` / `contract-api.js` para helpers de stream do Claude, como - `wrapAnthropicProviderStream`, helpers de header beta e parsing de `service_tier`. - - A OpenAI usa `api.js` para builders de provider, helpers de modelo padrão e - builders de provider em tempo real. - - O OpenRouter usa `api.js` para seu builder de provider, além de helpers de onboarding/configuração, - enquanto `register.runtime.js` ainda pode reexportar helpers genéricos - `plugin-sdk/provider-stream` para uso local do repositório. -- Pontos de entrada públicos carregados por facade preferem o snapshot de configuração de runtime ativo - quando existir um, e então recorrem ao arquivo de configuração resolvido em disco quando - o OpenClaw ainda não estiver servindo um snapshot de runtime. + `/index.js` é a entrada do plugin empacotado + e `/setup-entry.js` é a entrada do plugin de configuração. +- Exemplos atuais de provedores empacotados: + - Anthropic usa `api.js` / `contract-api.js` para auxiliares de stream do Claude, como + `wrapAnthropicProviderStream`, auxiliares de header beta e parsing de + `service_tier`. + - OpenAI usa `api.js` para builders de provedor, auxiliares de modelo padrão e + builders de provedor em tempo real. + - OpenRouter usa `api.js` para seu builder de provedor, além de auxiliares de onboarding/configuração, + enquanto `register.runtime.js` ainda pode reexportar auxiliares genéricos + `plugin-sdk/provider-stream` para uso local no repositório. +- Pontos de entrada públicos carregados por façade preferem o snapshot ativo de configuração em runtime + quando ele existe e, caso contrário, recorrem ao arquivo de configuração resolvido em disco quando o + OpenClaw ainda não está servindo um snapshot de runtime. - Primitivas genéricas compartilhadas continuam sendo o contrato público preferido do SDK. Um pequeno - conjunto reservado de compatibilidade de seams de helpers de canal com marca embutida ainda - existe. Trate-os como seams de manutenção/compatibilidade embutidas, não como novos alvos de importação de terceiros; novos contratos entre canais ainda devem ser implementados em subcaminhos genéricos `plugin-sdk/*` ou nos barrels locais do Plugin `api.js` / + conjunto reservado de compatibilidade de interfaces auxiliares com marca de canais empacotados ainda + existe. Trate-os como interfaces de manutenção/compatibilidade de empacotados, não como novos alvos de importação para terceiros; novos contratos entre canais ainda devem ficar em + subcaminhos genéricos `plugin-sdk/*` ou nos barrels locais do plugin `api.js` / `runtime-api.js`. Observação de compatibilidade: - Evite o barrel raiz `openclaw/plugin-sdk` em código novo. -- Prefira primeiro as primitivas estáveis e estreitas. Os subcaminhos mais novos de setup/pairing/reply/ +- Prefira primeiro as primitivas estáveis e mais estreitas. Os subcaminhos mais novos de setup/pairing/reply/ feedback/contract/inbound/threading/command/secret-input/webhook/infra/ - allowlist/status/message-tool são o contrato pretendido para novo trabalho com - plugins embutidos e externos. - Parsing/correspondência de alvo pertencem a `openclaw/plugin-sdk/channel-targets`. - Portas de ação de mensagem e helpers de id de mensagem de reação pertencem a + allowlist/status/message-tool são o contrato pretendido para novo trabalho de plugins + empacotados e externos. + Parsing/correspondência de alvo pertence a `openclaw/plugin-sdk/channel-targets`. + Barreiras de ação de mensagem e auxiliares de id de mensagem de reação pertencem a `openclaw/plugin-sdk/channel-actions`. -- Barrels de helper específicos de extensões embutidas não são estáveis por padrão. Se um - helper for necessário apenas para uma extensão embutida, mantenha-o atrás do seam local - `api.js` ou `runtime-api.js` da extensão em vez de promovê-lo para +- Barrels auxiliares específicos de extensões empacotadas não são estáveis por padrão. Se um + auxiliar for necessário apenas para uma extensão empacotada, mantenha-o atrás da interface local + `api.js` ou `runtime-api.js` da extensão, em vez de promovê-lo para `openclaw/plugin-sdk/`. -- Novos seams de helper compartilhados devem ser genéricos, não com marca de canal. O parsing compartilhado - de alvo pertence a `openclaw/plugin-sdk/channel-targets`; internos específicos de canal - ficam atrás do seam local `api.js` ou `runtime-api.js` do Plugin proprietário. -- Subcaminhos específicos de capacidade, como `image-generation`, - `media-understanding` e `speech`, existem porque plugins nativos/embutidos os usam - hoje. A presença deles, por si só, não significa que todo helper exportado seja um - contrato externo congelado de longo prazo. +- Novas interfaces auxiliares compartilhadas devem ser genéricas, não marcadas por canal. O parsing + compartilhado de alvo pertence a `openclaw/plugin-sdk/channel-targets`; internos específicos de canal + ficam atrás da interface local `api.js` ou `runtime-api.js` do plugin proprietário. +- Subcaminhos específicos de capacidade como `image-generation`, + `media-understanding` e `speech` existem porque plugins nativos/empacotados os usam + hoje. A presença deles, por si só, não significa que todo auxiliar exportado seja um contrato externo congelado de longo prazo. ## Schemas da ferramenta de mensagem -Plugins devem ser proprietários das contribuições de schema específicas de canal em -`describeMessageTool(...)`. Mantenha campos específicos de provider no Plugin, não no core compartilhado. +Plugins devem ser responsáveis pelas contribuições de schema específicas de canal em +`describeMessageTool(...)`. Mantenha campos específicos de provedor no plugin, não no core compartilhado. -Para fragmentos portáveis de schema compartilhado, reutilize os helpers genéricos exportados por +Para fragmentos de schema portáveis compartilhados, reutilize os auxiliares genéricos exportados por `openclaw/plugin-sdk/channel-actions`: - `createMessageToolButtonsSchema()` para payloads no estilo grade de botões - `createMessageToolCardSchema()` para payloads estruturados de cartão -Se um formato de schema só fizer sentido para um provider, defina-o no -próprio código-fonte desse Plugin em vez de promovê-lo para o SDK compartilhado. +Se um formato de schema só fizer sentido para um provedor, defina-o no próprio +código-fonte desse plugin em vez de promovê-lo para o SDK compartilhado. ## Resolução de alvo de canal -Plugins de canal devem ser proprietários da semântica de alvo específica do canal. Mantenha o -host de saída compartilhado genérico e use a superfície do adaptador de mensagens para regras do provider: +Plugins de canal devem ser responsáveis pela semântica de alvo específica do canal. Mantenha o +host de saída compartilhado genérico e use a superfície do adaptador de mensagens para regras do provedor: - `messaging.inferTargetChatType({ to })` decide se um alvo normalizado deve ser tratado como `direct`, `group` ou `channel` antes da busca no diretório. - `messaging.targetResolver.looksLikeId(raw, normalized)` informa ao core se uma - entrada deve ir direto para resolução semelhante a id em vez de busca em diretório. -- `messaging.targetResolver.resolveTarget(...)` é o fallback do Plugin quando - o core precisa de uma resolução final pertencente ao provider após a normalização ou após uma - falha no diretório. -- `messaging.resolveOutboundSessionRoute(...)` é proprietário da construção de rota de sessão - específica do provider quando um alvo é resolvido. + entrada deve pular diretamente para a resolução como id, em vez de fazer busca no diretório. +- `messaging.targetResolver.resolveTarget(...)` é o fallback do plugin quando o + core precisa de uma resolução final pertencente ao provedor após a normalização ou depois de + uma falha no diretório. +- `messaging.resolveOutboundSessionRoute(...)` é responsável pela construção da rota de sessão + específica do provedor depois que um alvo é resolvido. Divisão recomendada: - Use `inferTargetChatType` para decisões de categoria que devem acontecer antes - da busca de pares/grupos. -- Use `looksLikeId` para verificações do tipo “trate isto como um id de alvo explícito/nativo”. -- Use `resolveTarget` para fallback de normalização específico do provider, não para - busca ampla em diretório. -- Mantenha ids nativos do provider, como ids de chat, ids de thread, JIDs, handles e - ids de sala, dentro de valores `target` ou parâmetros específicos do provider, não em campos genéricos do SDK. + da busca em peers/grupos. +- Use `looksLikeId` para verificações do tipo “trate isso como um id de alvo explícito/nativo”. +- Use `resolveTarget` para fallback de normalização específico do provedor, não para + busca ampla no diretório. +- Mantenha ids nativos do provedor, como ids de chat, ids de thread, JIDs, handles e ids de sala, + dentro de valores `target` ou parâmetros específicos do provedor, não em campos genéricos do SDK. ## Diretórios baseados em configuração Plugins que derivam entradas de diretório a partir da configuração devem manter essa lógica no -Plugin e reutilizar os helpers compartilhados de +plugin e reutilizar os auxiliares compartilhados de `openclaw/plugin-sdk/directory-runtime`. -Use isso quando um canal precisar de pares/grupos baseados em configuração, como: +Use isso quando um canal precisar de peers/grupos baseados em configuração, como: -- pares de DM orientados por allowlist +- peers de DM orientados por allowlist - mapas configurados de canal/grupo -- fallbacks estáticos de diretório com escopo de conta +- fallbacks estáticos de diretório com escopo por conta -Os helpers compartilhados em `directory-runtime` lidam apenas com operações genéricas: +Os auxiliares compartilhados em `directory-runtime` lidam apenas com operações genéricas: - filtragem de consulta - aplicação de limite -- helpers de deduplicação/normalização +- auxiliares de deduplicação/normalização - construção de `ChannelDirectoryEntry[]` -Inspeção de conta específica de canal e normalização de id devem permanecer na -implementação do Plugin. +Inspeção de conta específica do canal e normalização de id devem permanecer na +implementação do plugin. -## Catálogos de provider +## Catálogos de provedor -Plugins de provider podem definir catálogos de modelos para inferência com +Plugins de provedor podem definir catálogos de modelos para inferência com `registerProvider({ catalog: { run(...) { ... } } })`. `catalog.run(...)` retorna o mesmo formato que o OpenClaw grava em `models.providers`: -- `{ provider }` para uma entrada de provider -- `{ providers }` para múltiplas entradas de provider +- `{ provider }` para uma entrada de provedor +- `{ providers }` para várias entradas de provedor -Use `catalog` quando o Plugin for proprietário de ids de modelo específicos do provider, padrões de URL base -ou metadados de modelo condicionados à autenticação. +Use `catalog` quando o plugin for responsável por ids de modelo específicos do provedor, padrões de URL base +ou metadados de modelo condicionados por autenticação. -`catalog.order` controla quando o catálogo de um Plugin é mesclado em relação aos -providers implícitos embutidos do OpenClaw: +`catalog.order` controla quando o catálogo de um plugin é mesclado em relação aos +provedores implícitos embutidos do OpenClaw: -- `simple`: providers simples orientados por chave de API ou env -- `profile`: providers que aparecem quando perfis de autenticação existem -- `paired`: providers que sintetizam múltiplas entradas de provider relacionadas -- `late`: última etapa, depois de outros providers implícitos +- `simple`: provedores simples orientados por chave de API ou ambiente +- `profile`: provedores que aparecem quando existem perfis de autenticação +- `paired`: provedores que sintetizam várias entradas relacionadas de provedor +- `late`: última passagem, depois dos outros provedores implícitos -Providers posteriores vencem em caso de colisão de chave, então plugins podem substituir -intencionalmente uma entrada de provider embutida com o mesmo id de provider. +Provedores posteriores vencem em caso de colisão de chave, para que plugins possam +intencionalmente substituir uma entrada de provedor embutida com o mesmo id de provedor. Compatibilidade: -- `discovery` continua funcionando como alias legado +- `discovery` ainda funciona como alias legado - se `catalog` e `discovery` estiverem registrados, o OpenClaw usa `catalog` ## Inspeção somente leitura de canal -Se o seu Plugin registrar um canal, prefira implementar +Se seu plugin registrar um canal, prefira implementar `plugin.config.inspectAccount(cfg, accountId)` junto com `resolveAccount(...)`. Por quê: -- `resolveAccount(...)` é o caminho de runtime. Ele pode assumir que as credenciais +- `resolveAccount(...)` é o caminho de runtime. Ele pode presumir que as credenciais estão totalmente materializadas e pode falhar rapidamente quando segredos obrigatórios estiverem ausentes. - Caminhos de comando somente leitura, como `openclaw status`, `openclaw status --all`, - `openclaw channels status`, `openclaw channels resolve` e fluxos de reparo de doctor/configuração - não devem precisar materializar credenciais de runtime apenas para descrever a configuração. + `openclaw channels status`, `openclaw channels resolve` e fluxos de + reparo em doctor/config, não devem precisar materializar credenciais de runtime apenas para + descrever a configuração. Comportamento recomendado de `inspectAccount(...)`: - Retorne apenas o estado descritivo da conta. - Preserve `enabled` e `configured`. -- Inclua campos de origem/status de credencial quando relevantes, como: +- Inclua campos de origem/status de credenciais quando relevante, como: - `tokenSource`, `tokenStatus` - `botTokenSource`, `botTokenStatus` - `appTokenSource`, `appTokenStatus` - `signingSecretSource`, `signingSecretStatus` -- Você não precisa retornar valores brutos de token apenas para relatar disponibilidade somente leitura. Retornar `tokenStatus: "available"` (e o campo de origem correspondente) já é suficiente para comandos no estilo status. +- Você não precisa retornar valores brutos de token apenas para informar disponibilidade somente leitura. Retornar `tokenStatus: "available"` (e o campo de origem correspondente) já é suficiente para comandos no estilo de status. - Use `configured_unavailable` quando uma credencial estiver configurada via SecretRef, mas indisponível no caminho de comando atual. Isso permite que comandos somente leitura relatem “configurado, mas indisponível neste caminho de comando” -em vez de travar ou informar incorretamente que a conta não está configurada. +em vez de falhar ou informar incorretamente a conta como não configurada. -## Pacotes pack +## Pacotes agregadores -Um diretório de Plugin pode incluir um `package.json` com `openclaw.extensions`: +Um diretório de plugin pode incluir um `package.json` com `openclaw.extensions`: ```json { @@ -1357,65 +1373,65 @@ Um diretório de Plugin pode incluir um `package.json` com `openclaw.extensions` } ``` -Cada entrada se torna um Plugin. Se o pack listar múltiplas extensões, o id do Plugin -passa a ser `name/`. +Cada entrada se torna um plugin. Se o pacote listar várias extensões, o id do plugin +se torna `name/`. -Se seu Plugin importar dependências npm, instale-as nesse diretório para que +Se seu plugin importar dependências npm, instale-as nesse diretório para que `node_modules` esteja disponível (`npm install` / `pnpm install`). -Proteção de segurança: toda entrada em `openclaw.extensions` deve permanecer dentro do diretório do Plugin -após a resolução de symlink. Entradas que escapem do diretório do pacote são +Barreira de segurança: toda entrada `openclaw.extensions` deve permanecer dentro do diretório do plugin +após a resolução de symlink. Entradas que escaparem do diretório do pacote são rejeitadas. -Observação de segurança: `openclaw plugins install` instala dependências de Plugin com -`npm install --omit=dev --ignore-scripts` (sem scripts de ciclo de vida, sem dependências de desenvolvimento em runtime). Mantenha as árvores de dependência do Plugin em “JS/TS puro” e evite pacotes que exijam builds em `postinstall`. +Observação de segurança: `openclaw plugins install` instala dependências de plugin com +`npm install --omit=dev --ignore-scripts` (sem scripts de ciclo de vida, sem dependências de desenvolvimento em runtime). Mantenha as árvores de dependência de plugin em “JS/TS puro” e evite pacotes que exijam builds em `postinstall`. -Opcional: `openclaw.setupEntry` pode apontar para um módulo leve somente de setup. -Quando o OpenClaw precisa de superfícies de setup para um Plugin de canal desabilitado, ou -quando um Plugin de canal está habilitado, mas ainda não configurado, ele carrega `setupEntry` -em vez da entrada completa do Plugin. Isso mantém inicialização e setup mais leves -quando a entrada principal do Plugin também conecta ferramentas, hooks ou outro -código apenas de runtime. +Opcional: `openclaw.setupEntry` pode apontar para um módulo leve somente de configuração. +Quando o OpenClaw precisa de superfícies de configuração para um plugin de canal desabilitado, ou +quando um plugin de canal está habilitado, mas ainda não configurado, ele carrega `setupEntry` +em vez da entrada completa do plugin. Isso mantém a inicialização e a configuração mais leves +quando a entrada principal do seu plugin também conecta ferramentas, hooks ou outro código +exclusivo de runtime. Opcional: `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` -pode colocar um Plugin de canal no mesmo caminho `setupEntry` durante a fase -de inicialização pré-listen do gateway, mesmo quando o canal já estiver configurado. +pode habilitar um plugin de canal para usar esse mesmo caminho de `setupEntry` durante a fase de +inicialização pré-listen do gateway, mesmo quando o canal já está configurado. -Use isso apenas quando `setupEntry` cobrir completamente a superfície de inicialização que precisa existir -antes de o gateway começar a escutar. Na prática, isso significa que a entrada de setup +Use isso apenas quando `setupEntry` cobrir totalmente a superfície de inicialização que deve existir +antes de o gateway começar a escutar. Na prática, isso significa que a entrada de configuração deve registrar toda capacidade pertencente ao canal da qual a inicialização depende, como: - o próprio registro do canal - quaisquer rotas HTTP que precisem estar disponíveis antes de o gateway começar a escutar -- quaisquer métodos do gateway, ferramentas ou serviços que precisem existir nessa mesma janela +- quaisquer métodos, ferramentas ou serviços do gateway que precisem existir durante essa mesma janela -Se a entrada completa ainda for proprietária de alguma capacidade obrigatória de inicialização, não ative -essa flag. Mantenha o Plugin no comportamento padrão e deixe o OpenClaw carregar a +Se sua entrada completa ainda for responsável por alguma capacidade necessária na inicialização, não habilite +essa flag. Mantenha o plugin no comportamento padrão e deixe o OpenClaw carregar a entrada completa durante a inicialização. -Canais embutidos também podem publicar helpers de superfície de contrato somente de setup que o core +Canais empacotados também podem publicar auxiliares de superfície de contrato apenas para configuração, que o core pode consultar antes que o runtime completo do canal seja carregado. A superfície atual -de promoção de setup é: +de promoção de configuração é: - `singleAccountKeysToMove` - `namedAccountPromotionKeys` - `resolveSingleAccountPromotionTarget(...)` -O core usa essa superfície quando precisa promover uma configuração legada de canal de conta única para -`channels..accounts.*` sem carregar a entrada completa do Plugin. -O Matrix é o exemplo embutido atual: ele move apenas chaves de autenticação/bootstrap para uma -conta nomeada promovida quando contas nomeadas já existem, e pode preservar uma -chave de conta padrão configurada não canônica em vez de sempre criar +O core usa essa superfície quando precisa promover uma configuração legada de canal de conta única +para `channels..accounts.*` sem carregar a entrada completa do plugin. +Matrix é o exemplo empacotado atual: ele move apenas chaves de autenticação/bootstrap para uma +conta promovida nomeada quando já existem contas nomeadas, e pode preservar uma +chave configurada de conta padrão não canônica em vez de sempre criar `accounts.default`. -Esses adaptadores de patch de setup mantêm lazy a descoberta da superfície de contrato embutida. O tempo -de importação permanece leve; a superfície de promoção é carregada apenas no primeiro uso em vez de -reentrar na inicialização do canal embutido na importação do módulo. +Esses adaptadores de patch de configuração mantêm lazy a descoberta da superfície de contrato empacotada. O tempo +de importação permanece leve; a superfície de promoção é carregada apenas no primeiro uso, +em vez de reentrar na inicialização do canal empacotado na importação do módulo. -Quando essas superfícies de inicialização incluírem métodos RPC do Gateway, mantenha-os em um -prefixo específico do Plugin. Namespaces de administrador do core (`config.*`, -`exec.approvals.*`, `wizard.*`, `update.*`) continuam reservados e sempre resolvem -para `operator.admin`, mesmo que um Plugin solicite um escopo mais restrito. +Quando essas superfícies de inicialização incluem métodos RPC do Gateway, mantenha-os em um +prefixo específico do plugin. Namespaces de administração do core (`config.*`, +`exec.approvals.*`, `wizard.*`, `update.*`) permanecem reservados e sempre são resolvidos +para `operator.admin`, mesmo que um plugin solicite um escopo mais estreito. Exemplo: @@ -1434,8 +1450,8 @@ Exemplo: ### Metadados de catálogo de canal -Plugins de canal podem anunciar metadados de setup/descoberta via `openclaw.channel` e -dicas de instalação via `openclaw.install`. Isso mantém os dados do catálogo livres no core. +Plugins de canal podem anunciar metadados de configuração/descoberta via `openclaw.channel` e +dicas de instalação via `openclaw.install`. Isso mantém os dados de catálogo livres do core. Exemplo: @@ -1466,20 +1482,20 @@ Exemplo: Campos úteis de `openclaw.channel` além do exemplo mínimo: - `detailLabel`: rótulo secundário para superfícies mais ricas de catálogo/status -- `docsLabel`: substitui o texto do link para a documentação -- `preferOver`: ids de Plugin/canal de menor prioridade que esta entrada de catálogo deve superar -- `selectionDocsPrefix`, `selectionDocsOmitLabel`, `selectionExtras`: controles de texto da superfície de seleção +- `docsLabel`: substitui o texto do link para o link da documentação +- `preferOver`: ids de plugin/canal de prioridade mais baixa que esta entrada de catálogo deve superar +- `selectionDocsPrefix`, `selectionDocsOmitLabel`, `selectionExtras`: controles de cópia da superfície de seleção - `markdownCapable`: marca o canal como compatível com Markdown para decisões de formatação de saída -- `exposure.configured`: oculta o canal de superfícies de listagem de canais configurados quando definido como `false` -- `exposure.setup`: oculta o canal de seletores interativos de setup/configuração quando definido como `false` -- `exposure.docs`: marca o canal como interno/privado para superfícies de navegação da documentação +- `exposure.configured`: oculta o canal das superfícies de listagem de canais configurados quando definido como `false` +- `exposure.setup`: oculta o canal dos seletores interativos de configuração quando definido como `false` +- `exposure.docs`: marca o canal como interno/privado para superfícies de navegação de documentação - `showConfigured` / `showInSetup`: aliases legados ainda aceitos por compatibilidade; prefira `exposure` -- `quickstartAllowFrom`: coloca o canal no fluxo padrão `allowFrom` de início rápido -- `forceAccountBinding`: exige vínculo explícito de conta mesmo quando só existe uma conta -- `preferSessionLookupForAnnounceTarget`: prefere busca por sessão ao resolver alvos de anúncio +- `quickstartAllowFrom`: habilita o canal no fluxo padrão de quickstart `allowFrom` +- `forceAccountBinding`: exige vínculo explícito de conta mesmo quando existe apenas uma conta +- `preferSessionLookupForAnnounceTarget`: prefere busca de sessão ao resolver alvos de anúncio -O OpenClaw também pode mesclar **catálogos externos de canais** (por exemplo, uma -exportação de registro MPM). Solte um arquivo JSON em um destes caminhos: +O OpenClaw também pode mesclar **catálogos externos de canais** (por exemplo, uma exportação +de registro MPM). Coloque um arquivo JSON em um destes locais: - `~/.openclaw/mpm/plugins.json` - `~/.openclaw/mpm/catalog.json` @@ -1491,13 +1507,13 @@ conter `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, " ## Plugins de mecanismo de contexto -Plugins de mecanismo de contexto são proprietários da orquestração de contexto da sessão para ingestão, montagem -e Compaction. Registre-os a partir do seu Plugin com -`api.registerContextEngine(id, factory)` e então selecione o mecanismo ativo com +Plugins de mecanismo de contexto são responsáveis pela orquestração do contexto de sessão para ingestão, montagem +e Compaction. Registre-os a partir do seu plugin com +`api.registerContextEngine(id, factory)` e, em seguida, selecione o mecanismo ativo com `plugins.slots.contextEngine`. -Use isso quando seu Plugin precisar substituir ou estender o pipeline de contexto -padrão em vez de apenas adicionar pesquisa de memória ou hooks. +Use isso quando seu plugin precisar substituir ou estender o pipeline de contexto padrão +em vez de apenas adicionar pesquisa de memória ou hooks. ```ts import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core"; @@ -1525,7 +1541,7 @@ export default function (api) { } ``` -Se o seu mecanismo **não** for proprietário do algoritmo de Compaction, mantenha `compact()` +Se seu mecanismo **não** for responsável pelo algoritmo de Compaction, mantenha `compact()` implementado e delegue-o explicitamente: ```ts @@ -1563,28 +1579,28 @@ export default function (api) { ## Adicionando uma nova capacidade -Quando um Plugin precisar de um comportamento que não se encaixa na API atual, não contorne -o sistema de Plugin com um acesso privado. Adicione a capacidade ausente. +Quando um plugin precisar de um comportamento que não se encaixe na API atual, não ignore +o sistema de plugins com um acesso privado a partes internas. Adicione a capacidade ausente. Sequência recomendada: 1. defina o contrato do core - Decida qual comportamento compartilhado o core deve possuir: política, fallback, merge de configuração, - ciclo de vida, semântica voltada a canais e formato do helper de runtime. -2. adicione superfícies tipadas de registro/runtime de Plugin - Estenda `OpenClawPluginApi` e/ou `api.runtime` com a menor superfície tipada útil - de capacidade. -3. conecte consumidores de core + canal/recurso + Decida qual comportamento compartilhado o core deve possuir: política, fallback, mesclagem de configuração, + ciclo de vida, semântica voltada a canais e formato do auxiliar de runtime. +2. adicione superfícies tipadas de registro/runtime de plugin + Estenda `OpenClawPluginApi` e/ou `api.runtime` com a menor superfície útil + de capacidade tipada. +3. conecte consumidores do core + canal/recurso Canais e plugins de recurso devem consumir a nova capacidade por meio do core, não importando diretamente uma implementação de fornecedor. 4. registre implementações de fornecedor - Plugins de fornecedor então registram seus backends nessa capacidade. + Plugins de fornecedor então registram seus backends na capacidade. 5. adicione cobertura de contrato - Adicione testes para que a propriedade e o formato do registro permaneçam explícitos ao longo do tempo. + Adicione testes para que a forma de propriedade e registro permaneça explícita ao longo do tempo. -É assim que o OpenClaw permanece opinativo sem ficar rigidamente codificado à -visão de mundo de um único provider. Consulte o [Livro de receitas de capacidade](/pt-BR/plugins/architecture) -para uma checklist concreta de arquivos e um exemplo completo. +É assim que o OpenClaw continua opinativo sem ficar rigidamente preso à +visão de mundo de um único provedor. Veja o [Capability Cookbook](/pt-BR/plugins/architecture) +para um checklist concreto de arquivos e um exemplo prático. ### Checklist de capacidade @@ -1592,16 +1608,16 @@ Quando você adiciona uma nova capacidade, a implementação normalmente deve to superfícies em conjunto: - tipos de contrato do core em `src//types.ts` -- helper de runner/runtime do core em `src//runtime.ts` -- superfície de registro da API de Plugin em `src/plugins/types.ts` -- integração com o registro de plugins em `src/plugins/registry.ts` -- exposição de runtime de Plugin em `src/plugins/runtime/*` quando plugins de recurso/canal +- executor/auxiliar de runtime do core em `src//runtime.ts` +- superfície de registro da API de plugin em `src/plugins/types.ts` +- integração do registro de plugins em `src/plugins/registry.ts` +- exposição do runtime de plugin em `src/plugins/runtime/*` quando plugins de recurso/canal precisarem consumi-la -- helpers de captura/teste em `src/test-utils/plugin-registration.ts` -- asserções de propriedade/contrato em `src/plugins/contracts/registry.ts` -- documentação para operador/Plugin em `docs/` +- auxiliares de captura/teste em `src/test-utils/plugin-registration.ts` +- verificações de propriedade/contrato em `src/plugins/contracts/registry.ts` +- documentação para operador/plugin em `docs/` -Se uma dessas superfícies estiver ausente, isso normalmente é um sinal de que a capacidade +Se uma dessas superfícies estiver ausente, isso geralmente é um sinal de que a capacidade ainda não está totalmente integrada. ### Modelo de capacidade @@ -1640,7 +1656,7 @@ expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]); Isso mantém a regra simples: -- o core é proprietário do contrato de capacidade + orquestração -- plugins de fornecedor são proprietários das implementações do fornecedor -- plugins de recurso/canal consomem helpers de runtime +- o core é responsável pelo contrato de capacidade + orquestração +- plugins de fornecedor são responsáveis pelas implementações do fornecedor +- plugins de recurso/canal consomem auxiliares de runtime - testes de contrato mantêm a propriedade explícita diff --git a/docs/pt-BR/plugins/manifest.md b/docs/pt-BR/plugins/manifest.md index 9161d263e..58f257c99 100644 --- a/docs/pt-BR/plugins/manifest.md +++ b/docs/pt-BR/plugins/manifest.md @@ -1,65 +1,57 @@ --- read_when: - Você está criando um Plugin do OpenClaw - - Você precisa fornecer um schema de configuração do plugin ou depurar erros de validação do plugin -summary: Manifest do Plugin + requisitos do schema JSON (validação estrita de configuração) -title: Manifest do Plugin + - Você precisa entregar um esquema de configuração de Plugin ou depurar erros de validação de Plugin +summary: Manifesto do Plugin + requisitos do esquema JSON (validação estrita de configuração) +title: Manifesto do Plugin x-i18n: - generated_at: "2026-04-12T23:28:50Z" + generated_at: "2026-04-15T05:33:47Z" model: gpt-5.4 provider: openai - source_hash: 93b57c7373e4ccd521b10945346db67991543bd2bed4cc8b6641e1f215b48579 + source_hash: ba2183bfa8802871e4ef33a0ebea290606e8351e9e83e25ee72456addb768730 source_path: plugins/manifest.md workflow: 15 --- -# Manifest do Plugin (`openclaw.plugin.json`) +# Manifesto do Plugin (`openclaw.plugin.json`) -Esta página é apenas para o **manifest nativo de Plugin do OpenClaw**. +Esta página é apenas para o **manifesto de Plugin nativo do OpenClaw**. Para layouts de bundle compatíveis, consulte [Bundles de Plugin](/pt-BR/plugins/bundles). -Formatos de bundle compatíveis usam arquivos de manifest diferentes: +Formatos de bundle compatíveis usam arquivos de manifesto diferentes: - Bundle do Codex: `.codex-plugin/plugin.json` -- Bundle do Claude: `.claude-plugin/plugin.json` ou o layout padrão de componente do Claude - sem um manifest +- Bundle do Claude: `.claude-plugin/plugin.json` ou o layout de componente padrão do Claude sem manifesto - Bundle do Cursor: `.cursor-plugin/plugin.json` -O OpenClaw também detecta automaticamente esses layouts de bundle, mas eles não são validados -com base no schema de `openclaw.plugin.json` descrito aqui. +O OpenClaw também detecta automaticamente esses layouts de bundle, mas eles não são validados em relação ao esquema `openclaw.plugin.json` descrito aqui. -Para bundles compatíveis, o OpenClaw atualmente lê metadados do bundle mais as raízes de -Skills declaradas, raízes de comandos do Claude, padrões de `settings.json` do bundle Claude, -padrões de LSP do bundle Claude e pacotes de hooks suportados quando o layout corresponde -às expectativas de runtime do OpenClaw. +Para bundles compatíveis, o OpenClaw atualmente lê os metadados do bundle mais as raízes de Skills declaradas, raízes de comandos do Claude, padrões de `settings.json` do bundle do Claude, padrões de LSP do bundle do Claude e pacotes de hooks compatíveis quando o layout corresponde às expectativas de runtime do OpenClaw. -Todo Plugin nativo do OpenClaw **deve** incluir um arquivo `openclaw.plugin.json` na -**raiz do plugin**. O OpenClaw usa esse manifest para validar a configuração -**sem executar o código do plugin**. Manifests ausentes ou inválidos são tratados como -erros do plugin e bloqueiam a validação da configuração. +Todo Plugin nativo do OpenClaw **deve** incluir um arquivo `openclaw.plugin.json` na **raiz do Plugin**. O OpenClaw usa esse manifesto para validar a configuração **sem executar código do Plugin**. Manifestos ausentes ou inválidos são tratados como erros de Plugin e bloqueiam a validação da configuração. Consulte o guia completo do sistema de plugins: [Plugins](/pt-BR/tools/plugin). -Para o modelo de capacidades nativo e a orientação atual de compatibilidade externa: +Para o modelo nativo de capacidades e a orientação atual de compatibilidade externa: [Modelo de capacidades](/pt-BR/plugins/architecture#public-capability-model). ## O que este arquivo faz -`openclaw.plugin.json` são os metadados que o OpenClaw lê antes de carregar o -código do seu plugin. +`openclaw.plugin.json` é o metadado que o OpenClaw lê antes de carregar o código do seu Plugin. Use-o para: -- identidade do plugin +- identidade do Plugin - validação de configuração -- metadados de autenticação e onboarding que devem estar disponíveis sem iniciar o runtime do plugin +- metadados de autenticação e onboarding que devem estar disponíveis sem iniciar o runtime do Plugin - dicas baratas de ativação que superfícies do plano de controle podem inspecionar antes de o runtime carregar -- descritores baratos de setup que superfícies de setup/onboarding podem inspecionar antes de o runtime carregar -- metadados de alias e auto-habilitação que devem ser resolvidos antes de o runtime do plugin carregar -- metadados abreviados de propriedade de família de modelos que devem autoativar o plugin antes de o runtime carregar -- snapshots estáticos de propriedade de capacidades usados para wiring de compatibilidade de bundles e cobertura de contrato +- descritores baratos de configuração que superfícies de configuração/onboarding podem inspecionar antes de o runtime carregar +- metadados de alias e autoativação que devem ser resolvidos antes de o runtime do Plugin carregar +- metadados abreviados de propriedade de família de modelos que devem autoativar o Plugin antes de o runtime carregar +- snapshots estáticos de propriedade de capacidades usados para wiring de compatibilidade de bundles e cobertura de contratos +- metadados baratos do executor de QA que o host compartilhado `openclaw qa` pode inspecionar antes de o runtime do Plugin carregar - metadados de configuração específicos de canal que devem ser mesclados em superfícies de catálogo e validação sem carregar o runtime -- dicas de UI para configuração +- dicas de UI de configuração Não o use para: @@ -67,7 +59,7 @@ Não o use para: - declarar entrypoints de código - metadados de instalação npm -Esses pertencem ao código do seu plugin e ao `package.json`. +Esses pertencem ao código do seu Plugin e ao `package.json`. ## Exemplo mínimo @@ -88,7 +80,7 @@ Esses pertencem ao código do seu plugin e ao `package.json`. { "id": "openrouter", "name": "OpenRouter", - "description": "Plugin provider do OpenRouter", + "description": "OpenRouter provider plugin", "version": "1.0.0", "providers": ["openrouter"], "modelSupport": { @@ -109,19 +101,19 @@ Esses pertencem ao código do seu plugin e ao `package.json`. "provider": "openrouter", "method": "api-key", "choiceId": "openrouter-api-key", - "choiceLabel": "Chave de API do OpenRouter", + "choiceLabel": "OpenRouter API key", "groupId": "openrouter", "groupLabel": "OpenRouter", "optionKey": "openrouterApiKey", "cliFlag": "--openrouter-api-key", "cliOption": "--openrouter-api-key ", - "cliDescription": "Chave de API do OpenRouter", + "cliDescription": "OpenRouter API key", "onboardingScopes": ["text-inference"] } ], "uiHints": { "apiKey": { - "label": "Chave de API", + "label": "API key", "placeholder": "sk-or-v1-...", "sensitive": true } @@ -138,64 +130,65 @@ Esses pertencem ao código do seu plugin e ao `package.json`. } ``` -## Referência dos campos de nível superior +## Referência de campos de nível superior | Campo | Obrigatório | Tipo | O que significa | | ----------------------------------- | ----------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `id` | Sim | `string` | ID canônico do plugin. Este é o ID usado em `plugins.entries.`. | -| `configSchema` | Sim | `object` | Schema JSON inline para a configuração deste plugin. | -| `enabledByDefault` | Não | `true` | Marca um plugin empacotado como habilitado por padrão. Omita-o ou defina qualquer valor diferente de `true` para deixar o plugin desabilitado por padrão. | -| `legacyPluginIds` | Não | `string[]` | IDs legados que são normalizados para este ID canônico de plugin. | -| `autoEnableWhenConfiguredProviders` | Não | `string[]` | IDs de provider que devem auto-habilitar este plugin quando autenticação, configuração ou referências de modelo os mencionarem. | -| `kind` | Não | `"memory"` \| `"context-engine"` | Declara um tipo exclusivo de plugin usado por `plugins.slots.*`. | -| `channels` | Não | `string[]` | IDs de canal pertencentes a este plugin. Usados para descoberta e validação de configuração. | -| `providers` | Não | `string[]` | IDs de provider pertencentes a este plugin. | -| `modelSupport` | Não | `object` | Metadados abreviados de família de modelos pertencentes ao manifest usados para carregar automaticamente o plugin antes do runtime. | -| `cliBackends` | Não | `string[]` | IDs de backend de inferência da CLI pertencentes a este plugin. Usados para autoativação na inicialização a partir de referências explícitas na configuração. | -| `commandAliases` | Não | `object[]` | Nomes de comando pertencentes a este plugin que devem produzir diagnósticos de configuração e CLI conscientes do plugin antes de o runtime carregar. | -| `providerAuthEnvVars` | Não | `Record` | Metadados baratos de env de autenticação de provider que o OpenClaw pode inspecionar sem carregar o código do plugin. | -| `providerAuthAliases` | Não | `Record` | IDs de provider que devem reutilizar outro ID de provider para busca de autenticação, por exemplo um provider de coding que compartilha a chave de API do provider base e perfis de autenticação. | -| `channelEnvVars` | Não | `Record` | Metadados baratos de env de canal que o OpenClaw pode inspecionar sem carregar o código do plugin. Use isso para superfícies de setup ou autenticação de canal orientadas por env que helpers genéricos de inicialização/configuração devem enxergar. | -| `providerAuthChoices` | Não | `object[]` | Metadados baratos de escolhas de autenticação para seletores de onboarding, resolução de provider preferido e wiring simples de flags da CLI. | -| `activation` | Não | `object` | Dicas baratas de ativação para carregamento acionado por provider, comando, canal, rota e capacidade. Apenas metadados; o runtime do plugin ainda é dono do comportamento real. | -| `setup` | Não | `object` | Descritores baratos de setup/onboarding que superfícies de descoberta e setup podem inspecionar sem carregar o runtime do plugin. | -| `contracts` | Não | `object` | Snapshot estático de capacidades empacotadas para speech, transcrição em tempo real, voz em tempo real, media-understanding, geração de imagem, geração de música, geração de vídeo, web-fetch, busca na web e propriedade de ferramentas. | -| `channelConfigs` | Não | `Record` | Metadados de configuração de canal pertencentes ao manifest mesclados em superfícies de descoberta e validação antes de o runtime carregar. | -| `skills` | Não | `string[]` | Diretórios de Skills a serem carregados, relativos à raiz do plugin. | -| `name` | Não | `string` | Nome legível do plugin. | -| `description` | Não | `string` | Resumo curto exibido nas superfícies do plugin. | -| `version` | Não | `string` | Versão informativa do plugin. | +| `id` | Sim | `string` | ID canônico do Plugin. Este é o ID usado em `plugins.entries.`. | +| `configSchema` | Sim | `object` | Esquema JSON inline para a configuração deste Plugin. | +| `enabledByDefault` | Não | `true` | Marca um Plugin empacotado como habilitado por padrão. Omita-o, ou defina qualquer valor diferente de `true`, para deixar o Plugin desabilitado por padrão. | +| `legacyPluginIds` | Não | `string[]` | IDs legados que são normalizados para este ID canônico de Plugin. | +| `autoEnableWhenConfiguredProviders` | Não | `string[]` | IDs de provider que devem autoabilitar este Plugin quando autenticação, configuração ou referências de modelo os mencionarem. | +| `kind` | Não | `"memory"` \| `"context-engine"` | Declara um tipo exclusivo de Plugin usado por `plugins.slots.*`. | +| `channels` | Não | `string[]` | IDs de canal pertencentes a este Plugin. Usado para descoberta e validação de configuração. | +| `providers` | Não | `string[]` | IDs de provider pertencentes a este Plugin. | +| `modelSupport` | Não | `object` | Metadados abreviados de família de modelos pertencentes ao manifesto usados para carregar automaticamente o Plugin antes do runtime. | +| `cliBackends` | Não | `string[]` | IDs de backend de inferência da CLI pertencentes a este Plugin. Usado para autoativação na inicialização a partir de referências explícitas de configuração. | +| `commandAliases` | Não | `object[]` | Nomes de comando pertencentes a este Plugin que devem produzir configuração e diagnósticos de CLI cientes do Plugin antes de o runtime carregar. | +| `providerAuthEnvVars` | Não | `Record` | Metadados baratos de variáveis de ambiente para autenticação de provider que o OpenClaw pode inspecionar sem carregar o código do Plugin. | +| `providerAuthAliases` | Não | `Record` | IDs de provider que devem reutilizar outro ID de provider para busca de autenticação, por exemplo, um provider de coding que compartilha a chave de API e os perfis de autenticação do provider base. | +| `channelEnvVars` | Não | `Record` | Metadados baratos de variáveis de ambiente de canal que o OpenClaw pode inspecionar sem carregar o código do Plugin. Use isso para superfícies de configuração ou autenticação de canal orientadas por env que helpers genéricos de inicialização/configuração devem enxergar. | +| `providerAuthChoices` | Não | `object[]` | Metadados baratos de opções de autenticação para seletores de onboarding, resolução de provider preferido e wiring simples de flags da CLI. | +| `activation` | Não | `object` | Dicas baratas de ativação para carregamento acionado por provider, comando, canal, rota e capacidade. Apenas metadados; o runtime do Plugin ainda é dono do comportamento real. | +| `setup` | Não | `object` | Descritores baratos de configuração/onboarding que superfícies de descoberta e configuração podem inspecionar sem carregar o runtime do Plugin. | +| `qaRunners` | Não | `object[]` | Descritores baratos de executores de QA usados pelo host compartilhado `openclaw qa` antes de o runtime do Plugin carregar. | +| `contracts` | Não | `object` | Snapshot estático de capacidades empacotadas para fala, transcrição em tempo real, voz em tempo real, media-understanding, image-generation, music-generation, video-generation, web-fetch, busca na web e propriedade de ferramentas. | +| `channelConfigs` | Não | `Record` | Metadados de configuração de canal pertencentes ao manifesto, mesclados em superfícies de descoberta e validação antes de o runtime carregar. | +| `skills` | Não | `string[]` | Diretórios de Skills a serem carregados, relativos à raiz do Plugin. | +| `name` | Não | `string` | Nome legível do Plugin. | +| `description` | Não | `string` | Resumo curto exibido em superfícies de Plugin. | +| `version` | Não | `string` | Versão informativa do Plugin. | | `uiHints` | Não | `Record` | Rótulos de UI, placeholders e dicas de sensibilidade para campos de configuração. | ## Referência de `providerAuthChoices` -Cada entrada de `providerAuthChoices` descreve uma escolha de onboarding ou autenticação. +Cada entrada de `providerAuthChoices` descreve uma opção de onboarding ou autenticação. O OpenClaw lê isso antes de o runtime do provider carregar. -| Campo | Obrigatório | Tipo | O que significa | -| --------------------- | ----------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -| `provider` | Sim | `string` | ID do provider ao qual esta escolha pertence. | -| `method` | Sim | `string` | ID do método de autenticação para direcionamento. | -| `choiceId` | Sim | `string` | ID estável de escolha de autenticação usado pelos fluxos de onboarding e CLI. | +| Campo | Obrigatório | Tipo | O que significa | +| --------------------- | ----------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------- | +| `provider` | Sim | `string` | ID do provider ao qual esta opção pertence. | +| `method` | Sim | `string` | ID do método de autenticação para despacho. | +| `choiceId` | Sim | `string` | ID estável da opção de autenticação usado por fluxos de onboarding e CLI. | | `choiceLabel` | Não | `string` | Rótulo voltado ao usuário. Se omitido, o OpenClaw usa `choiceId` como fallback. | -| `choiceHint` | Não | `string` | Texto curto de ajuda para o seletor. | -| `assistantPriority` | Não | `number` | Valores menores aparecem antes em seletores interativos guiados pelo assistant. | -| `assistantVisibility` | Não | `"visible"` \| `"manual-only"` | Oculta a escolha dos seletores do assistant, enquanto ainda permite seleção manual pela CLI. | -| `deprecatedChoiceIds` | Não | `string[]` | IDs legados de escolha que devem redirecionar os usuários para esta escolha substituta. | -| `groupId` | Não | `string` | ID opcional de grupo para agrupar escolhas relacionadas. | -| `groupLabel` | Não | `string` | Rótulo voltado ao usuário para esse grupo. | -| `groupHint` | Não | `string` | Texto curto de ajuda para o grupo. | -| `optionKey` | Não | `string` | Chave de opção interna para fluxos simples de autenticação com uma única flag. | -| `cliFlag` | Não | `string` | Nome da flag da CLI, como `--openrouter-api-key`. | -| `cliOption` | Não | `string` | Formato completo da opção da CLI, como `--openrouter-api-key `. | -| `cliDescription` | Não | `string` | Descrição usada na ajuda da CLI. | -| `onboardingScopes` | Não | `Array<"text-inference" \| "image-generation">` | Em quais superfícies de onboarding esta escolha deve aparecer. Se omitido, o padrão é `["text-inference"]`. | +| `choiceHint` | Não | `string` | Texto auxiliar curto para o seletor. | +| `assistantPriority` | Não | `number` | Valores menores são ordenados primeiro em seletores interativos guiados pelo assistente. | +| `assistantVisibility` | Não | `"visible"` \| `"manual-only"` | Oculta a opção dos seletores do assistente, mas ainda permite seleção manual pela CLI. | +| `deprecatedChoiceIds` | Não | `string[]` | IDs legados de opção que devem redirecionar os usuários para esta opção de substituição. | +| `groupId` | Não | `string` | ID opcional de grupo para agrupar opções relacionadas. | +| `groupLabel` | Não | `string` | Rótulo voltado ao usuário para esse grupo. | +| `groupHint` | Não | `string` | Texto auxiliar curto para o grupo. | +| `optionKey` | Não | `string` | Chave interna de opção para fluxos de autenticação simples com uma única flag. | +| `cliFlag` | Não | `string` | Nome da flag da CLI, como `--openrouter-api-key`. | +| `cliOption` | Não | `string` | Formato completo da opção da CLI, como `--openrouter-api-key `. | +| `cliDescription` | Não | `string` | Descrição usada na ajuda da CLI. | +| `onboardingScopes` | Não | `Array<"text-inference" \| "image-generation">` | Em quais superfícies de onboarding esta opção deve aparecer. Se omitido, o padrão é `["text-inference"]`. | ## Referência de `commandAliases` -Use `commandAliases` quando um plugin é dono de um nome de comando de runtime que os usuários podem -colocar por engano em `plugins.allow` ou tentar executar como um comando raiz da CLI. O OpenClaw -usa esses metadados para diagnósticos sem importar o código de runtime do plugin. +Use `commandAliases` quando um Plugin é dono de um nome de comando de runtime que os usuários podem, por engano, +colocar em `plugins.allow` ou tentar executar como um comando raiz da CLI. O OpenClaw +usa esses metadados para diagnósticos sem importar o código de runtime do Plugin. ```json { @@ -209,22 +202,40 @@ usa esses metadados para diagnósticos sem importar o código de runtime do plug } ``` -| Campo | Obrigatório | Tipo | O que significa | -| ------------ | ----------- | ----------------- | ----------------------------------------------------------------------- | -| `name` | Sim | `string` | Nome do comando que pertence a este plugin. | +| Campo | Obrigatório | Tipo | O que significa | +| ------------ | ----------- | ----------------- | ------------------------------------------------------------------------- | +| `name` | Sim | `string` | Nome do comando que pertence a este Plugin. | | `kind` | Não | `"runtime-slash"` | Marca o alias como um comando slash de chat em vez de um comando raiz da CLI. | -| `cliCommand` | Não | `string` | Comando raiz relacionado da CLI a ser sugerido para operações da CLI, se existir. | +| `cliCommand` | Não | `string` | Comando raiz relacionado da CLI a ser sugerido para operações de CLI, se existir. | ## Referência de `activation` -Use `activation` quando o plugin puder declarar de forma barata quais eventos do plano de controle +Use `activation` quando o Plugin pode declarar de forma barata quais eventos do plano de controle devem ativá-lo depois. -Este bloco contém apenas metadados. Ele não registra comportamento de runtime e não -substitui `register(...)`, `setupEntry` nem outros entrypoints de runtime/plugin. -Os consumidores atuais o usam como uma dica de restrição antes de um carregamento mais amplo de plugins, então -a ausência de metadados de ativação normalmente só custa desempenho; ela não deve -mudar a correção enquanto ainda existirem fallbacks legados de propriedade no manifest. +## Referência de `qaRunners` + +Use `qaRunners` quando um Plugin contribui com um ou mais executores de transporte sob a raiz compartilhada `openclaw qa`. Mantenha esses metadados baratos e estáticos; o runtime do Plugin ainda é dono do registro real da CLI por meio de uma superfície leve `runtime-api.ts` que exporta `qaRunnerCliRegistrations`. + +```json +{ + "qaRunners": [ + { + "commandName": "matrix", + "description": "Run the Docker-backed Matrix live QA lane against a disposable homeserver" + } + ] +} +``` + +| Campo | Obrigatório | Tipo | O que significa | +| ------------- | ----------- | -------- | ------------------------------------------------------------------- | +| `commandName` | Sim | `string` | Subcomando montado sob `openclaw qa`, por exemplo `matrix`. | +| `description` | Não | `string` | Texto de ajuda de fallback usado quando o host compartilhado precisa de um comando stub. | + +Este bloco é apenas metadados. Ele não registra comportamento de runtime e não substitui `register(...)`, `setupEntry` nem outros entrypoints de runtime/Plugin. +Os consumidores atuais o usam como uma dica de refinamento antes de um carregamento mais amplo de Plugins, portanto a ausência de metadados de ativação normalmente só afeta o desempenho; ela não deve +alterar a correção enquanto os fallbacks legados de propriedade no manifesto ainda existirem. ```json { @@ -238,27 +249,26 @@ mudar a correção enquanto ainda existirem fallbacks legados de propriedade no } ``` -| Campo | Obrigatório | Tipo | O que significa | -| ---------------- | ----------- | ---------------------------------------------------- | ---------------------------------------------------------------- | -| `onProviders` | Não | `string[]` | IDs de provider que devem ativar este plugin quando solicitados. | -| `onCommands` | Não | `string[]` | IDs de comando que devem ativar este plugin. | -| `onChannels` | Não | `string[]` | IDs de canal que devem ativar este plugin. | -| `onRoutes` | Não | `string[]` | Tipos de rota que devem ativar este plugin. | +| Campo | Obrigatório | Tipo | O que significa | +| ---------------- | ----------- | ---------------------------------------------------- | ------------------------------------------------------------------ | +| `onProviders` | Não | `string[]` | IDs de provider que devem ativar este Plugin quando solicitados. | +| `onCommands` | Não | `string[]` | IDs de comando que devem ativar este Plugin. | +| `onChannels` | Não | `string[]` | IDs de canal que devem ativar este Plugin. | +| `onRoutes` | Não | `string[]` | Tipos de rota que devem ativar este Plugin. | | `onCapabilities` | Não | `Array<"provider" \| "channel" \| "tool" \| "hook">` | Dicas amplas de capacidade usadas pelo planejamento de ativação do plano de controle. | -Consumidores ativos atuais: +Consumidores ativos atualmente: -- o planejamento da CLI acionado por comando recorre a - `commandAliases[].cliCommand` ou `commandAliases[].name` legados -- o planejamento de setup/canal acionado por canal recorre à propriedade legada de `channels[]` - quando metadados explícitos de ativação de canal estão ausentes -- o planejamento de setup/runtime acionado por provider recorre à propriedade legada de - `providers[]` e `cliBackends[]` de nível superior quando metadados explícitos de ativação de provider - estão ausentes +- o planejamento da CLI acionado por comando usa como fallback + `commandAliases[].cliCommand` ou `commandAliases[].name` +- o planejamento de configuração/canal acionado por canal usa como fallback a propriedade legada de `channels[]` + quando faltam metadados explícitos de ativação de canal +- o planejamento de configuração/runtime acionado por provider usa como fallback a propriedade legada de + `providers[]` e `cliBackends[]` de nível superior quando faltam metadados explícitos de ativação de provider ## Referência de `setup` -Use `setup` quando as superfícies de setup e onboarding precisarem de metadados baratos pertencentes ao plugin +Use `setup` quando as superfícies de configuração e onboarding precisarem de metadados baratos pertencentes ao Plugin antes de o runtime carregar. ```json @@ -278,36 +288,28 @@ antes de o runtime carregar. } ``` -`cliBackends` de nível superior continua válido e continua descrevendo backends -de inferência da CLI. `setup.cliBackends` é a superfície de descritor específica de setup para -fluxos de setup/plano de controle que devem permanecer somente em metadados. +`cliBackends` de nível superior continua válido e segue descrevendo backends de inferência da CLI. `setup.cliBackends` é a superfície de descritor específica de configuração para fluxos de plano de controle/configuração que devem permanecer apenas como metadados. -Quando presentes, `setup.providers` e `setup.cliBackends` são a superfície preferida -de busca baseada primeiro em descritor para descoberta de setup. Se o descritor apenas restringir -o plugin candidato e o setup ainda precisar de hooks de runtime mais ricos em tempo de setup, -defina `requiresRuntime: true` e mantenha `setup-api` como o caminho de execução de fallback. +Quando presentes, `setup.providers` e `setup.cliBackends` são a superfície preferencial de busca guiada por descritores para descoberta de configuração. Se o descritor apenas restringir o Plugin candidato e a configuração ainda precisar de hooks de runtime mais ricos em tempo de configuração, defina `requiresRuntime: true` e mantenha `setup-api` como o caminho de execução de fallback. -Como a busca de setup pode executar código `setup-api` pertencente ao plugin, os valores normalizados de -`setup.providers[].id` e `setup.cliBackends[]` devem permanecer únicos entre os -plugins descobertos. Propriedade ambígua falha de forma conservadora em vez de escolher um -vencedor pela ordem de descoberta. +Como a busca de configuração pode executar código `setup-api` pertencente ao Plugin, os valores normalizados de `setup.providers[].id` e `setup.cliBackends[]` devem permanecer únicos entre os plugins descobertos. Propriedade ambígua falha em modo fechado em vez de escolher um vencedor pela ordem de descoberta. ### Referência de `setup.providers` -| Campo | Obrigatório | Tipo | O que significa | -| ------------- | ----------- | ---------- | --------------------------------------------------------------------------------------- | -| `id` | Sim | `string` | ID do provider exposto durante setup ou onboarding. Mantenha IDs normalizados globalmente únicos. | -| `authMethods` | Não | `string[]` | IDs de método de setup/autenticação que este provider suporta sem carregar o runtime completo. | -| `envVars` | Não | `string[]` | Variáveis de ambiente que superfícies genéricas de setup/status podem verificar antes de o runtime do plugin carregar. | +| Campo | Obrigatório | Tipo | O que significa | +| ------------- | ----------- | ---------- | ----------------------------------------------------------------------------------- | +| `id` | Sim | `string` | ID do provider exposto durante a configuração ou o onboarding. Mantenha IDs normalizados globalmente únicos. | +| `authMethods` | Não | `string[]` | IDs de método de configuração/autenticação compatíveis com este provider sem carregar o runtime completo. | +| `envVars` | Não | `string[]` | Variáveis de ambiente que superfícies genéricas de configuração/status podem verificar antes de o runtime do Plugin carregar. | ### Campos de `setup` -| Campo | Obrigatório | Tipo | O que significa | -| ------------------ | ----------- | ---------- | ------------------------------------------------------------------------------------------------------- | -| `providers` | Não | `object[]` | Descritores de setup de provider expostos durante setup e onboarding. | -| `cliBackends` | Não | `string[]` | IDs de backend em tempo de setup usados para busca de setup baseada primeiro em descritor. Mantenha IDs normalizados globalmente únicos. | -| `configMigrations` | Não | `string[]` | IDs de migração de configuração pertencentes à superfície de setup deste plugin. | -| `requiresRuntime` | Não | `boolean` | Se o setup ainda precisa da execução de `setup-api` após a busca por descritor. | +| Campo | Obrigatório | Tipo | O que significa | +| ------------------ | ----------- | ---------- | ---------------------------------------------------------------------------------------------------- | +| `providers` | Não | `object[]` | Descritores de configuração de provider expostos durante a configuração e o onboarding. | +| `cliBackends` | Não | `string[]` | IDs de backend em tempo de configuração usados para busca de configuração guiada por descritores. Mantenha IDs normalizados globalmente únicos. | +| `configMigrations` | Não | `string[]` | IDs de migração de configuração pertencentes à superfície de configuração deste Plugin. | +| `requiresRuntime` | Não | `boolean` | Se a configuração ainda precisa de execução de `setup-api` após a busca por descritor. | ## Referência de `uiHints` @@ -328,19 +330,19 @@ vencedor pela ordem de descoberta. Cada dica de campo pode incluir: -| Campo | Tipo | O que significa | -| ------------- | ---------- | -------------------------------------- | -| `label` | `string` | Rótulo do campo voltado ao usuário. | -| `help` | `string` | Texto curto de ajuda. | -| `tags` | `string[]` | Tags opcionais de UI. | -| `advanced` | `boolean` | Marca o campo como avançado. | +| Campo | Tipo | O que significa | +| ------------- | ---------- | --------------------------------------- | +| `label` | `string` | Rótulo do campo voltado ao usuário. | +| `help` | `string` | Texto auxiliar curto. | +| `tags` | `string[]` | Tags opcionais de UI. | +| `advanced` | `boolean` | Marca o campo como avançado. | | `sensitive` | `boolean` | Marca o campo como secreto ou sensível. | | `placeholder` | `string` | Texto de placeholder para entradas de formulário. | ## Referência de `contracts` -Use `contracts` apenas para metadados estáticos de propriedade de capacidade que o OpenClaw pode -ler sem importar o runtime do plugin. +Use `contracts` apenas para metadados estáticos de propriedade de capacidades que o OpenClaw pode +ler sem importar o runtime do Plugin. ```json { @@ -360,22 +362,21 @@ ler sem importar o runtime do plugin. Cada lista é opcional: -| Campo | Tipo | O que significa | -| -------------------------------- | ---------- | ---------------------------------------------------------------- | -| `speechProviders` | `string[]` | IDs de provider de speech pertencentes a este plugin. | -| `realtimeTranscriptionProviders` | `string[]` | IDs de provider de transcrição em tempo real pertencentes a este plugin. | -| `realtimeVoiceProviders` | `string[]` | IDs de provider de voz em tempo real pertencentes a este plugin. | -| `mediaUnderstandingProviders` | `string[]` | IDs de provider de media-understanding pertencentes a este plugin. | -| `imageGenerationProviders` | `string[]` | IDs de provider de geração de imagem pertencentes a este plugin. | -| `videoGenerationProviders` | `string[]` | IDs de provider de geração de vídeo pertencentes a este plugin. | -| `webFetchProviders` | `string[]` | IDs de provider de web-fetch pertencentes a este plugin. | -| `webSearchProviders` | `string[]` | IDs de provider de busca na web pertencentes a este plugin. | -| `tools` | `string[]` | Nomes de ferramentas do agente pertencentes a este plugin para verificações de contrato empacotado. | +| Campo | Tipo | O que significa | +| -------------------------------- | ---------- | ------------------------------------------------------------- | +| `speechProviders` | `string[]` | IDs de provider de fala pertencentes a este Plugin. | +| `realtimeTranscriptionProviders` | `string[]` | IDs de provider de transcrição em tempo real pertencentes a este Plugin. | +| `realtimeVoiceProviders` | `string[]` | IDs de provider de voz em tempo real pertencentes a este Plugin. | +| `mediaUnderstandingProviders` | `string[]` | IDs de provider de media-understanding pertencentes a este Plugin. | +| `imageGenerationProviders` | `string[]` | IDs de provider de geração de imagem pertencentes a este Plugin. | +| `videoGenerationProviders` | `string[]` | IDs de provider de geração de vídeo pertencentes a este Plugin. | +| `webFetchProviders` | `string[]` | IDs de provider de web-fetch pertencentes a este Plugin. | +| `webSearchProviders` | `string[]` | IDs de provider de busca na web pertencentes a este Plugin. | +| `tools` | `string[]` | Nomes de ferramentas de agente pertencentes a este Plugin para verificações de contrato de bundles. | ## Referência de `channelConfigs` -Use `channelConfigs` quando um plugin de canal precisar de metadados baratos de configuração antes de -o runtime carregar. +Use `channelConfigs` quando um Plugin de canal precisar de metadados baratos de configuração antes de o runtime carregar. ```json { @@ -404,19 +405,17 @@ o runtime carregar. Cada entrada de canal pode incluir: -| Campo | Tipo | O que significa | -| ------------- | ------------------------ | -------------------------------------------------------------------------------------------- | -| `schema` | `object` | Schema JSON para `channels.`. Obrigatório para cada entrada declarada de configuração de canal. | +| Campo | Tipo | O que significa | +| ------------- | ------------------------ | ---------------------------------------------------------------------------------------- | +| `schema` | `object` | Esquema JSON para `channels.`. Obrigatório para cada entrada declarada de configuração de canal. | | `uiHints` | `Record` | Rótulos/placeholders/dicas de sensibilidade de UI opcionais para essa seção de configuração de canal. | -| `label` | `string` | Rótulo do canal mesclado em superfícies de seleção e inspeção quando os metadados de runtime ainda não estiverem prontos. | -| `description` | `string` | Descrição curta do canal para superfícies de inspeção e catálogo. | -| `preferOver` | `string[]` | IDs de plugin legados ou de menor prioridade sobre os quais este canal deve ter precedência nas superfícies de seleção. | +| `label` | `string` | Rótulo do canal mesclado em superfícies de seletor e inspeção quando os metadados de runtime não estiverem prontos. | +| `description` | `string` | Descrição curta do canal para superfícies de inspeção e catálogo. | +| `preferOver` | `string[]` | IDs legados ou de menor prioridade de Plugin que este canal deve superar em superfícies de seleção. | ## Referência de `modelSupport` -Use `modelSupport` quando o OpenClaw precisar inferir seu plugin de provider a partir de -IDs abreviados de modelo como `gpt-5.4` ou `claude-sonnet-4.6` antes de o runtime do plugin -carregar. +Use `modelSupport` quando o OpenClaw precisar inferir seu Plugin de provider a partir de IDs abreviados de modelo, como `gpt-5.4` ou `claude-sonnet-4.6`, antes de o runtime do Plugin carregar. ```json { @@ -429,74 +428,58 @@ carregar. O OpenClaw aplica esta precedência: -- referências explícitas `provider/model` usam os metadados de manifest `providers` do plugin proprietário +- referências explícitas `provider/model` usam os metadados de manifesto `providers` do proprietário - `modelPatterns` têm precedência sobre `modelPrefixes` -- se um plugin não empacotado e um plugin empacotado corresponderem, o plugin não empacotado - vence +- se um Plugin não empacotado e um Plugin empacotado corresponderem, o Plugin não empacotado vence - ambiguidades restantes são ignoradas até que o usuário ou a configuração especifique um provider Campos: -| Campo | Tipo | O que significa | -| --------------- | ---------- | --------------------------------------------------------------------------------- | -| `modelPrefixes` | `string[]` | Prefixos comparados com `startsWith` em relação a IDs abreviados de modelo. | -| `modelPatterns` | `string[]` | Fontes de regex comparadas com IDs abreviados de modelo após a remoção do sufixo de perfil. | +| Campo | Tipo | O que significa | +| --------------- | ---------- | -------------------------------------------------------------------------------- | +| `modelPrefixes` | `string[]` | Prefixos correspondidos com `startsWith` em relação a IDs abreviados de modelo. | +| `modelPatterns` | `string[]` | Fontes de regex correspondidas em relação a IDs abreviados de modelo após a remoção do sufixo do perfil. | -As chaves legadas de capacidade de nível superior estão obsoletas. Use `openclaw doctor --fix` para -mover `speechProviders`, `realtimeTranscriptionProviders`, -`realtimeVoiceProviders`, `mediaUnderstandingProviders`, -`imageGenerationProviders`, `videoGenerationProviders`, -`webFetchProviders` e `webSearchProviders` para `contracts`; o carregamento normal -do manifest não trata mais esses campos de nível superior como propriedade -de capacidade. +Chaves legadas de capacidade de nível superior estão obsoletas. Use `openclaw doctor --fix` para mover `speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, `webFetchProviders` e `webSearchProviders` para `contracts`; o carregamento normal do manifesto não trata mais esses campos de nível superior como propriedade de capacidades. -## Manifest versus package.json +## Manifesto versus package.json -Os dois arquivos têm funções diferentes: +Os dois arquivos cumprem funções diferentes: -| Arquivo | Use para | -| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| `openclaw.plugin.json` | Descoberta, validação de configuração, metadados de escolha de autenticação e dicas de UI que precisam existir antes de o código do plugin rodar | -| `package.json` | Metadados npm, instalação de dependências e o bloco `openclaw` usado para entrypoints, controle de instalação, setup ou metadados de catálogo | +| Arquivo | Use para | +| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| `openclaw.plugin.json` | Descoberta, validação de configuração, metadados de opções de autenticação e dicas de UI que devem existir antes de o código do Plugin rodar | +| `package.json` | Metadados npm, instalação de dependências e o bloco `openclaw` usado para entrypoints, bloqueio de instalação, configuração ou metadados de catálogo | -Se você não tiver certeza de onde uma informação deve ficar, use esta regra: +Se você não tiver certeza de onde um metadado deve ficar, use esta regra: -- se o OpenClaw precisar conhecê-la antes de carregar o código do plugin, coloque-a em `openclaw.plugin.json` -- se for sobre empacotamento, arquivos de entrada ou comportamento de instalação do npm, coloque-a em `package.json` +- se o OpenClaw precisar conhecê-lo antes de carregar o código do Plugin, coloque-o em `openclaw.plugin.json` +- se for sobre empacotamento, arquivos de entrada ou comportamento de instalação do npm, coloque-o em `package.json` ### Campos de `package.json` que afetam a descoberta -Alguns metadados de plugin de pré-runtime intencionalmente ficam em `package.json` sob o bloco -`openclaw`, em vez de `openclaw.plugin.json`. +Alguns metadados de Plugin pré-runtime intencionalmente ficam em `package.json` sob o bloco `openclaw` em vez de `openclaw.plugin.json`. Exemplos importantes: -| Campo | O que significa | -| ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -| `openclaw.extensions` | Declara entrypoints de Plugin nativos. | -| `openclaw.setupEntry` | Entrypoint leve apenas de setup usado durante o onboarding e a inicialização adiada de canais. | -| `openclaw.channel` | Metadados baratos de catálogo de canal, como rótulos, caminhos de docs, aliases e textos de seleção. | -| `openclaw.channel.configuredState` | Metadados leves do verificador de estado configurado que podem responder "já existe setup somente por env?" sem carregar o runtime completo do canal. | -| `openclaw.channel.persistedAuthState` | Metadados leves do verificador de autenticação persistida que podem responder "já existe algo autenticado?" sem carregar o runtime completo do canal. | -| `openclaw.install.npmSpec` / `openclaw.install.localPath` | Dicas de instalação/atualização para plugins empacotados e publicados externamente. | -| `openclaw.install.defaultChoice` | Caminho de instalação preferido quando múltiplas fontes de instalação estão disponíveis. | -| `openclaw.install.minHostVersion` | Versão mínima suportada do host OpenClaw, usando um piso semver como `>=2026.3.22`. | -| `openclaw.install.allowInvalidConfigRecovery` | Permite um caminho restrito de recuperação por reinstalação de plugin empacotado quando a configuração é inválida. | -| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | Permite que superfícies de canal apenas de setup sejam carregadas antes do plugin de canal completo durante a inicialização. | +| Campo | O que significa | +| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `openclaw.extensions` | Declara entrypoints nativos de Plugin. | +| `openclaw.setupEntry` | Entrypoint leve apenas de configuração usado durante onboarding e inicialização adiada de canal. | +| `openclaw.channel` | Metadados baratos de catálogo de canal, como rótulos, caminhos de documentação, aliases e texto de seleção. | +| `openclaw.channel.configuredState` | Metadados leves de verificador de estado configurado que podem responder "já existe uma configuração apenas por env?" sem carregar o runtime completo do canal. | +| `openclaw.channel.persistedAuthState` | Metadados leves de verificador de autenticação persistida que podem responder "já existe algo autenticado?" sem carregar o runtime completo do canal. | +| `openclaw.install.npmSpec` / `openclaw.install.localPath` | Dicas de instalação/atualização para plugins empacotados e publicados externamente. | +| `openclaw.install.defaultChoice` | Caminho de instalação preferido quando várias fontes de instalação estão disponíveis. | +| `openclaw.install.minHostVersion` | Versão mínima compatível do host OpenClaw, usando um piso semver como `>=2026.3.22`. | +| `openclaw.install.allowInvalidConfigRecovery` | Permite um caminho restrito de recuperação por reinstalação de Plugin empacotado quando a configuração é inválida. | +| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | Permite que superfícies de canal apenas de configuração carreguem antes do Plugin de canal completo durante a inicialização. | -`openclaw.install.minHostVersion` é aplicado durante a instalação e o carregamento do -registro de manifests. Valores inválidos são rejeitados; valores mais novos, mas válidos, fazem o -plugin ser ignorado em hosts mais antigos. +`openclaw.install.minHostVersion` é aplicado durante a instalação e o carregamento do registro de manifestos. Valores inválidos são rejeitados; valores mais novos, porém válidos, fazem o Plugin ser ignorado em hosts mais antigos. -`openclaw.install.allowInvalidConfigRecovery` é intencionalmente restrito. Ele não torna -configurações quebradas arbitrárias instaláveis. Hoje, ele só permite que fluxos de instalação -se recuperem de falhas específicas e obsoletas de upgrade de plugin empacotado, como um -caminho ausente de plugin empacotado ou uma entrada obsoleta `channels.` para esse mesmo -plugin empacotado. Erros de configuração não relacionados ainda bloqueiam a instalação e direcionam os -operadores para `openclaw doctor --fix`. +`openclaw.install.allowInvalidConfigRecovery` é intencionalmente restrito. Ele não torna instaláveis configurações arbitrariamente quebradas. Hoje ele só permite que fluxos de instalação se recuperem de falhas específicas e antigas de upgrade de Plugin empacotado, como um caminho ausente de Plugin empacotado ou uma entrada antiga `channels.` para esse mesmo Plugin empacotado. Erros de configuração não relacionados ainda bloqueiam a instalação e enviam operadores para `openclaw doctor --fix`. -`openclaw.channel.persistedAuthState` é um metadado de pacote para um pequeno módulo -verificador: +`openclaw.channel.persistedAuthState` é um metadado de pacote para um pequeno módulo verificador: ```json { @@ -512,13 +495,9 @@ verificador: } ``` -Use-o quando fluxos de setup, doctor ou estado configurado precisarem de uma sondagem barata de autenticação -sim/não antes de o plugin de canal completo carregar. A exportação de destino deve ser uma -função pequena que leia apenas o estado persistido; não a encaminhe pelo barrel completo -do runtime do canal. +Use-o quando fluxos de configuração, doctor ou estado configurado precisarem de uma sondagem barata de autenticação sim/não antes de o Plugin de canal completo carregar. A exportação de destino deve ser uma função pequena que leia apenas o estado persistido; não a encaminhe pelo barrel completo de runtime do canal. -`openclaw.channel.configuredState` segue o mesmo formato para verificações baratas de estado -configurado apenas por env: +`openclaw.channel.configuredState` segue o mesmo formato para verificações baratas de estado configurado apenas por env: ```json { @@ -534,64 +513,45 @@ configurado apenas por env: } ``` -Use-o quando um canal puder responder ao estado configurado a partir de env ou de outras pequenas -entradas não relacionadas ao runtime. Se a verificação precisar da resolução completa de configuração ou do -runtime real do canal, mantenha essa lógica no hook `config.hasConfiguredState` do plugin. +Use-o quando um canal puder responder o estado configurado a partir de env ou outras entradas pequenas sem runtime. Se a verificação precisar da resolução completa da configuração ou do runtime real do canal, mantenha essa lógica no hook `config.hasConfiguredState` do Plugin. -## Requisitos do schema JSON +## Requisitos de JSON Schema -- **Todo plugin deve fornecer um schema JSON**, mesmo que ele não aceite configuração. -- Um schema vazio é aceitável (por exemplo, `{ "type": "object", "additionalProperties": false }`). -- Os schemas são validados no momento de leitura/gravação da configuração, não em runtime. +- **Todo Plugin deve incluir um JSON Schema**, mesmo que não aceite nenhuma configuração. +- Um esquema vazio é aceitável (por exemplo, `{ "type": "object", "additionalProperties": false }`). +- Os esquemas são validados no momento de leitura/gravação da configuração, não em runtime. ## Comportamento de validação -- Chaves desconhecidas em `channels.*` são **erros**, a menos que o ID do canal seja declarado por - um manifest de plugin. +- Chaves desconhecidas em `channels.*` são **erros**, a menos que o ID do canal seja declarado por um manifesto de Plugin. - `plugins.entries.`, `plugins.allow`, `plugins.deny` e `plugins.slots.*` - devem referenciar IDs de plugin **descobertos**. IDs desconhecidos são **erros**. -- Se um plugin estiver instalado, mas tiver um manifest ou schema quebrado ou ausente, - a validação falha e o Doctor relata o erro do plugin. -- Se a configuração do plugin existir, mas o plugin estiver **desabilitado**, a configuração é mantida e - um **aviso** é exibido no Doctor + logs. + devem referenciar IDs de Plugin **detectáveis**. IDs desconhecidos são **erros**. +- Se um Plugin estiver instalado, mas tiver um manifesto ou esquema ausente ou quebrado, + a validação falha e o Doctor relata o erro do Plugin. +- Se a configuração do Plugin existir, mas o Plugin estiver **desabilitado**, a configuração será mantida e um **aviso** será exibido no Doctor + logs. -Consulte a [Referência de configuração](/pt-BR/gateway/configuration) para todo o schema `plugins.*`. +Consulte [Referência de configuração](/pt-BR/gateway/configuration) para o esquema completo de `plugins.*`. ## Observações -- O manifest é **obrigatório para Plugins nativos do OpenClaw**, incluindo carregamentos locais do sistema de arquivos. -- O runtime ainda carrega o módulo do plugin separadamente; o manifest serve apenas para - descoberta + validação. -- Manifests nativos são analisados com JSON5, então comentários, vírgulas finais e - chaves sem aspas são aceitos, desde que o valor final ainda seja um objeto. -- Apenas os campos de manifest documentados são lidos pelo carregador de manifest. Evite adicionar - chaves personalizadas de nível superior aqui. -- `providerAuthEnvVars` é o caminho barato de metadados para sondagens de autenticação, validação - de marcadores de env e superfícies semelhantes de autenticação de provider que não devem iniciar o runtime do plugin - apenas para inspecionar nomes de env. -- `providerAuthAliases` permite que variantes de provider reutilizem as variáveis de ambiente de autenticação, - perfis de autenticação, autenticação baseada em configuração e escolha de onboarding por chave de API de outro provider - sem codificar essa relação diretamente no core. -- `channelEnvVars` é o caminho barato de metadados para fallback de env do shell, prompts de setup - e superfícies semelhantes de canal que não devem iniciar o runtime do plugin - apenas para inspecionar nomes de env. -- `providerAuthChoices` é o caminho barato de metadados para seletores de escolha de autenticação, - resolução de `--auth-choice`, mapeamento de provider preferido e registro simples de flags de CLI de onboarding - antes de o runtime do provider carregar. Para metadados de assistente de runtime - que exigem código do provider, consulte - [Hooks de runtime do provider](/pt-BR/plugins/architecture#provider-runtime-hooks). -- Tipos exclusivos de plugin são selecionados por meio de `plugins.slots.*`. +- O manifesto é **obrigatório para plugins nativos do OpenClaw**, incluindo carregamentos locais do sistema de arquivos. +- O runtime ainda carrega o módulo do Plugin separadamente; o manifesto é apenas para descoberta + validação. +- Manifestos nativos são analisados com JSON5, então comentários, vírgulas finais e chaves sem aspas são aceitos, desde que o valor final ainda seja um objeto. +- Apenas os campos de manifesto documentados são lidos pelo carregador de manifesto. Evite adicionar chaves personalizadas de nível superior aqui. +- `providerAuthEnvVars` é o caminho barato de metadados para sondagens de autenticação, validação de marcadores de env e superfícies semelhantes de autenticação de provider que não devem iniciar o runtime do Plugin apenas para inspecionar nomes de env. +- `providerAuthAliases` permite que variantes de provider reutilizem as variáveis de ambiente de autenticação, perfis de autenticação, autenticação baseada em configuração e a opção de onboarding com chave de API de outro provider sem hardcodar essa relação no core. +- `channelEnvVars` é o caminho barato de metadados para fallback de shell-env, prompts de configuração e superfícies de canal semelhantes que não devem iniciar o runtime do Plugin apenas para inspecionar nomes de env. +- `providerAuthChoices` é o caminho barato de metadados para seletores de opção de autenticação, resolução de `--auth-choice`, mapeamento de provider preferido e registro simples de flags de CLI de onboarding antes de o runtime do provider carregar. Para metadados de assistente de runtime que exigem código de provider, consulte [Hooks de runtime de provider](/pt-BR/plugins/architecture#provider-runtime-hooks). +- Tipos exclusivos de Plugin são selecionados por meio de `plugins.slots.*`. - `kind: "memory"` é selecionado por `plugins.slots.memory`. - `kind: "context-engine"` é selecionado por `plugins.slots.contextEngine` - (padrão: `legacy` builtin). -- `channels`, `providers`, `cliBackends` e `skills` podem ser omitidos quando um - plugin não precisar deles. -- Se seu plugin depender de módulos nativos, documente as etapas de build e quaisquer - requisitos de allowlist do gerenciador de pacotes (por exemplo, `allow-build-scripts` do pnpm + (padrão: `legacy` embutido). +- `channels`, `providers`, `cliBackends` e `skills` podem ser omitidos quando um Plugin não precisar deles. +- Se o seu Plugin depender de módulos nativos, documente as etapas de build e quaisquer requisitos de allowlist do gerenciador de pacotes (por exemplo, pnpm `allow-build-scripts` - `pnpm rebuild `). ## Relacionado -- [Criando Plugins](/pt-BR/plugins/building-plugins) — introdução a plugins -- [Arquitetura de Plugins](/pt-BR/plugins/architecture) — arquitetura interna -- [Visão geral do SDK](/pt-BR/plugins/sdk-overview) — referência do Plugin SDK +- [Criando Plugins](/pt-BR/plugins/building-plugins) — primeiros passos com plugins +- [Arquitetura de Plugin](/pt-BR/plugins/architecture) — arquitetura interna +- [Visão geral do SDK](/pt-BR/plugins/sdk-overview) — referência do SDK de Plugin diff --git a/docs/pt-BR/plugins/sdk-channel-plugins.md b/docs/pt-BR/plugins/sdk-channel-plugins.md index 4c8253818..6f3db3b69 100644 --- a/docs/pt-BR/plugins/sdk-channel-plugins.md +++ b/docs/pt-BR/plugins/sdk-channel-plugins.md @@ -1,99 +1,114 @@ --- read_when: - - Você está criando um novo plugin de canal de mensagens + - Você está criando um novo Plugin de canal de mensagens - Você quer conectar o OpenClaw a uma plataforma de mensagens - - Você precisa entender a superfície de adaptador `ChannelPlugin` + - Você precisa entender a superfície do adaptador `ChannelPlugin` sidebarTitle: Channel Plugins -summary: Guia passo a passo para criar um plugin de canal de mensagens para o OpenClaw -title: Criando plugins de canal +summary: Guia passo a passo para criar um Plugin de canal de mensagens para OpenClaw +title: Criando Plugins de canal x-i18n: - generated_at: "2026-04-11T02:46:22Z" + generated_at: "2026-04-15T05:33:50Z" model: gpt-5.4 provider: openai - source_hash: 8a026e924f9ae8a3ddd46287674443bcfccb0247be504261522b078e1f440aef + source_hash: a7f4c746fe3163a8880e14c433f4db4a1475535d91716a53fb879551d8d62f65 source_path: plugins/sdk-channel-plugins.md workflow: 15 --- -# Criando plugins de canal +# Criando Plugins de canal -Este guia mostra como criar um plugin de canal que conecta o OpenClaw a uma -plataforma de mensagens. Ao final, você terá um canal funcional com segurança de DM, -pareamento, encadeamento de respostas e envio de mensagens. +Este guia apresenta a criação de um Plugin de canal que conecta o OpenClaw a uma +plataforma de mensagens. Ao final, você terá um canal funcional com segurança em DM, +pareamento, encadeamento de respostas e mensagens de saída. - Se você ainda não criou nenhum plugin do OpenClaw, leia primeiro - [Primeiros passos](/pt-BR/plugins/building-plugins) para entender a estrutura básica - do pacote e a configuração do manifesto. + Se você ainda não criou nenhum Plugin do OpenClaw antes, leia + [Primeiros passos](/pt-BR/plugins/building-plugins) primeiro para entender a estrutura + básica do pacote e a configuração do manifesto. -## Como os plugins de canal funcionam +## Como os Plugins de canal funcionam Plugins de canal não precisam de suas próprias ferramentas de enviar/editar/reagir. O OpenClaw mantém uma -ferramenta `message` compartilhada no core. Seu plugin é responsável por: +ferramenta `message` compartilhada no core. Seu Plugin é responsável por: - **Configuração** — resolução de conta e assistente de configuração -- **Segurança** — política de DM e allowlists +- **Segurança** — política de DM e listas de permissão - **Pareamento** — fluxo de aprovação de DM -- **Gramática de sessão** — como ids de conversa específicos do provedor são mapeados para chats base, ids de thread e fallbacks de pai +- **Gramática de sessão** — como IDs de conversa específicos do provedor são mapeados para chats base, IDs de thread e fallbacks de pai - **Saída** — envio de texto, mídia e enquetes para a plataforma - **Encadeamento** — como as respostas são encadeadas -O core é responsável pela ferramenta de mensagem compartilhada, pela conexão com prompts, pelo formato externo da chave de sessão, -pela contabilidade genérica de `:thread:` e pelo despacho. +O core é responsável pela ferramenta `message` compartilhada, pelo encadeamento de prompts, pelo formato externo da chave de sessão, +pela contabilidade genérica de `:thread:` e pelo dispatch. -Se a sua plataforma armazena escopo extra dentro de ids de conversa, mantenha esse parsing -no plugin com `messaging.resolveSessionConversation(...)`. Esse é o -hook canônico para mapear `rawId` para o id base da conversa, id opcional -da thread, `baseConversationId` explícito e quaisquer `parentConversationCandidates`. -Ao retornar `parentConversationCandidates`, mantenha a ordem -do pai mais específico para o mais amplo/conversa base. +Se o seu canal adicionar parâmetros à ferramenta de mensagem que transportam origens de mídia, exponha esses +nomes de parâmetros por meio de `describeMessageTool(...).mediaSourceParams`. O core usa +essa lista explícita para normalização de caminho no sandbox e política de acesso a mídia de saída, +então Plugins não precisam de casos especiais no core compartilhado para parâmetros específicos do provedor +como avatar, anexo ou imagem de capa. +Prefira retornar um mapa indexado por ação, como +`{ "set-profile": ["avatarUrl", "avatarPath"] }`, para que ações não relacionadas não +herdem os argumentos de mídia de outra ação. Um array simples ainda funciona para parâmetros que +são intencionalmente compartilhados entre todas as ações expostas. -Plugins integrados que precisam do mesmo parsing antes de o registro do canal inicializar -também podem expor um arquivo `session-key-api.ts` de nível superior com um -export `resolveSessionConversation(...)` correspondente. O core usa essa superfície -segura para bootstrap apenas quando o registro de plugins em runtime ainda não está disponível. +Se a sua plataforma armazena escopo extra dentro de IDs de conversa, mantenha essa análise +no Plugin com `messaging.resolveSessionConversation(...)`. Esse é o hook canônico +para mapear `rawId` para o ID base da conversa, ID opcional de thread, +`baseConversationId` explícito e quaisquer `parentConversationCandidates`. +Ao retornar `parentConversationCandidates`, mantenha-os ordenados do +pai mais específico para a conversa pai mais ampla/base. -`messaging.resolveParentConversationCandidates(...)` continua disponível como fallback legado de compatibilidade quando um plugin precisa apenas de fallbacks de pai sobre o id genérico/raw. Se ambos os hooks existirem, o core usa primeiro -`resolveSessionConversation(...).parentConversationCandidates` e só +Plugins empacotados que precisam da mesma análise antes que o registro de canal seja inicializado +também podem expor um arquivo `session-key-api.ts` de nível superior com uma exportação +correspondente `resolveSessionConversation(...)`. O core usa essa superfície segura para bootstrap +apenas quando o registro de Plugins em runtime ainda não está disponível. + +`messaging.resolveParentConversationCandidates(...)` continua disponível como um +fallback legado de compatibilidade quando um Plugin só precisa de fallbacks de pai além +do ID genérico/bruto. Se ambos os hooks existirem, o core usa primeiro +`resolveSessionConversation(...).parentConversationCandidates` e só então recorre a `resolveParentConversationCandidates(...)` quando o hook canônico -os omite. +não os inclui. ## Aprovações e capacidades do canal -A maioria dos plugins de canal não precisa de código específico para aprovações. +A maioria dos Plugins de canal não precisa de código específico para aprovação. - O core é responsável por `/approve` no mesmo chat, payloads compartilhados de botão de aprovação e entrega genérica de fallback. -- Prefira um único objeto `approvalCapability` no plugin de canal quando o canal precisar de comportamento específico de aprovação. -- `ChannelPlugin.approvals` foi removido. Coloque fatos de entrega/aprovação nativa/renderização/autenticação em `approvalCapability`. +- Prefira um único objeto `approvalCapability` no Plugin de canal quando o canal precisar de comportamento específico de aprovação. +- `ChannelPlugin.approvals` foi removido. Coloque fatos de entrega/renderização/autenticação/aprovação nativa em `approvalCapability`. - `plugin.auth` é apenas para login/logout; o core não lê mais hooks de autenticação de aprovação desse objeto. -- `approvalCapability.authorizeActorAction` e `approvalCapability.getActionAvailabilityState` são a seam canônica de autenticação de aprovação. +- `approvalCapability.authorizeActorAction` e `approvalCapability.getActionAvailabilityState` são a interface canônica de autenticação de aprovação. - Use `approvalCapability.getActionAvailabilityState` para disponibilidade de autenticação de aprovação no mesmo chat. -- Se o seu canal expõe aprovações nativas de exec, use `approvalCapability.getExecInitiatingSurfaceState` para o estado da superfície iniciadora/cliente nativo quando ele diferir da autenticação de aprovação no mesmo chat. O core usa esse hook específico de exec para distinguir `enabled` de `disabled`, decidir se o canal iniciador oferece suporte a aprovações nativas de exec e incluir o canal nas orientações de fallback para cliente nativo. `createApproverRestrictedNativeApprovalCapability(...)` preenche isso para o caso comum. -- Use `outbound.shouldSuppressLocalPayloadPrompt` ou `outbound.beforeDeliverPayload` para comportamento específico do canal no ciclo de vida do payload, como ocultar prompts locais duplicados de aprovação ou enviar indicadores de digitação antes da entrega. +- Se o seu canal expõe aprovações nativas de execução, use `approvalCapability.getExecInitiatingSurfaceState` para o estado da superfície iniciadora/cliente nativo quando ele diferir da autenticação de aprovação no mesmo chat. O core usa esse hook específico de execução para distinguir `enabled` de `disabled`, decidir se o canal iniciador oferece suporte a aprovações nativas de execução e incluir o canal nas orientações de fallback de cliente nativo. `createApproverRestrictedNativeApprovalCapability(...)` preenche isso para o caso comum. +- Use `outbound.shouldSuppressLocalPayloadPrompt` ou `outbound.beforeDeliverPayload` para comportamento específico do canal no ciclo de vida do payload, como ocultar prompts locais de aprovação duplicados ou enviar indicadores de digitação antes da entrega. - Use `approvalCapability.delivery` apenas para roteamento de aprovação nativa ou supressão de fallback. -- Use `approvalCapability.nativeRuntime` para fatos de aprovação nativa sob responsabilidade do canal. Mantenha isso lazy em entrypoints quentes de canal com `createLazyChannelApprovalNativeRuntimeAdapter(...)`, que pode importar seu módulo de runtime sob demanda e ainda permitir que o core monte o ciclo de vida da aprovação. +- Use `approvalCapability.nativeRuntime` para fatos de aprovação nativa pertencentes ao canal. Mantenha isso lazy em entrypoints quentes do canal com `createLazyChannelApprovalNativeRuntimeAdapter(...)`, que pode importar seu módulo de runtime sob demanda enquanto ainda permite que o core monte o ciclo de vida de aprovação. - Use `approvalCapability.render` apenas quando um canal realmente precisar de payloads de aprovação personalizados em vez do renderizador compartilhado. -- Use `approvalCapability.describeExecApprovalSetup` quando o canal quiser que a resposta do caminho desativado explique os controles exatos de configuração necessários para ativar aprovações nativas de exec. O hook recebe `{ channel, channelLabel, accountId }`; canais com contas nomeadas devem renderizar caminhos com escopo de conta, como `channels..accounts..execApprovals.*`, em vez de padrões no nível superior. -- Se um canal puder inferir identidades estáveis semelhantes a proprietário em DMs a partir da configuração existente, use `createResolvedApproverActionAuthAdapter` de `openclaw/plugin-sdk/approval-runtime` para restringir `/approve` no mesmo chat sem adicionar lógica específica de aprovação ao core. -- Se um canal precisar de entrega nativa de aprovação, mantenha o código do canal focado em normalização de destino mais fatos de transporte/apresentação. Use `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver` e `createApproverRestrictedNativeApprovalCapability` de `openclaw/plugin-sdk/approval-runtime`. Coloque os fatos específicos do canal atrás de `approvalCapability.nativeRuntime`, idealmente por meio de `createChannelApprovalNativeRuntimeAdapter(...)` ou `createLazyChannelApprovalNativeRuntimeAdapter(...)`, para que o core possa montar o handler e assumir filtro de requisições, roteamento, deduplicação, expiração, assinatura do gateway e avisos de redirecionamento. `nativeRuntime` é dividido em algumas seams menores: +- Use `approvalCapability.describeExecApprovalSetup` quando o canal quiser que a resposta do caminho desabilitado explique exatamente quais controles de configuração são necessários para habilitar aprovações nativas de execução. O hook recebe `{ channel, channelLabel, accountId }`; canais com contas nomeadas devem renderizar caminhos com escopo por conta, como `channels..accounts..execApprovals.*`, em vez de padrões no nível superior. +- Se um canal puder inferir identidades estáveis de DM semelhantes a proprietário a partir da configuração existente, use `createResolvedApproverActionAuthAdapter` de `openclaw/plugin-sdk/approval-runtime` para restringir `/approve` no mesmo chat sem adicionar lógica específica de aprovação ao core. +- Se um canal precisar de entrega de aprovação nativa, mantenha o código do canal focado em normalização de destino e fatos de transporte/apresentação. Use `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver` e `createApproverRestrictedNativeApprovalCapability` de `openclaw/plugin-sdk/approval-runtime`. Coloque os fatos específicos do canal atrás de `approvalCapability.nativeRuntime`, idealmente por meio de `createChannelApprovalNativeRuntimeAdapter(...)` ou `createLazyChannelApprovalNativeRuntimeAdapter(...)`, para que o core possa montar o handler e controlar filtragem de requisições, roteamento, deduplicação, expiração, assinatura do Gateway e avisos de redirecionamento. `nativeRuntime` é dividido em algumas interfaces menores: - `availability` — se a conta está configurada e se uma requisição deve ser tratada -- `presentation` — mapeia o view model compartilhado de aprovação para payloads nativos pendentes/resolvidos/expirados ou ações finais -- `transport` — prepara destinos e envia/atualiza/exclui mensagens nativas de aprovação +- `presentation` — mapeia o modelo de visualização de aprovação compartilhado para payloads nativos pendentes/resolvidos/expirados ou ações finais +- `transport` — prepara destinos e envia/atualiza/remove mensagens nativas de aprovação - `interactions` — hooks opcionais de bind/unbind/clear-action para botões ou reações nativas - `observe` — hooks opcionais de diagnóstico de entrega -- Se o canal precisar de objetos sob responsabilidade do runtime, como um client, token, app Bolt ou receptor de webhook, registre-os por meio de `openclaw/plugin-sdk/channel-runtime-context`. O registro genérico de contexto de runtime permite que o core inicialize handlers orientados por capacidade a partir do estado de inicialização do canal sem adicionar glue wrapper específico de aprovação. -- Recorra ao nível mais baixo de `createChannelApprovalHandler` ou `createChannelNativeApprovalRuntime` apenas quando a seam orientada por capacidade ainda não for suficientemente expressiva. -- Canais de aprovação nativa devem rotear `accountId` e `approvalKind` por esses helpers. `accountId` mantém a política de aprovação multi-account no escopo correto da conta do bot, e `approvalKind` mantém o comportamento de aprovação de exec versus plugin disponível para o canal sem branches hardcoded no core. +- Se o canal precisar de objetos pertencentes ao runtime, como cliente, token, app Bolt ou receptor de Webhook, registre-os por meio de `openclaw/plugin-sdk/channel-runtime-context`. O registro genérico de contexto de runtime permite que o core inicialize handlers orientados por capacidade a partir do estado de inicialização do canal sem adicionar cola específica de aprovação. +- Recorra a `createChannelApprovalHandler` ou `createChannelNativeApprovalRuntime` de nível mais baixo apenas quando a interface orientada por capacidade ainda não for expressiva o suficiente. +- Canais de aprovação nativa devem rotear tanto `accountId` quanto `approvalKind` por meio desses helpers. `accountId` mantém a política de aprovação multiconta limitada à conta de bot correta, e `approvalKind` mantém o comportamento de aprovação de execução vs Plugin disponível para o canal sem ramificações codificadas no core. - O core agora também é responsável pelos avisos de redirecionamento de aprovação. Plugins de canal não devem enviar suas próprias mensagens de acompanhamento do tipo "a aprovação foi para DMs / outro canal" a partir de `createChannelNativeApprovalRuntime`; em vez disso, exponha roteamento preciso de origem + DM do aprovador por meio dos helpers compartilhados de capacidade de aprovação e deixe o core agregar as entregas reais antes de publicar qualquer aviso de volta no chat iniciador. -- Preserve o tipo de id de aprovação entregue de ponta a ponta. Clientes nativos não devem adivinhar nem reescrever o roteamento de aprovação de exec versus plugin a partir de estado local do canal. -- Diferentes tipos de aprovação podem expor intencionalmente superfícies nativas diferentes. - Exemplos integrados atuais: - - O Slack mantém o roteamento de aprovação nativa disponível tanto para ids de exec quanto de plugin. - - O Matrix mantém o mesmo roteamento nativo de DM/canal e UX de reação para aprovações de exec e plugin, ao mesmo tempo em que ainda permite que a autenticação varie por tipo de aprovação. -- `createApproverRestrictedNativeApprovalAdapter` ainda existe como wrapper de compatibilidade, mas código novo deve preferir o construtor de capability e expor `approvalCapability` no plugin. +- Preserve o tipo do ID de aprovação entregue de ponta a ponta. Clientes nativos não devem + adivinhar nem reescrever o roteamento de aprovação de execução vs Plugin com base no estado local do canal. +- Diferentes tipos de aprovação podem expor intencionalmente diferentes superfícies nativas. + Exemplos empacotados atuais: + - O Slack mantém o roteamento nativo de aprovação disponível tanto para IDs de execução quanto de Plugin. + - O Matrix mantém o mesmo roteamento nativo de DM/canal e a mesma UX de reação para aprovações de execução + e de Plugin, ao mesmo tempo que ainda permite que a autenticação varie por tipo de aprovação. +- `createApproverRestrictedNativeApprovalAdapter` ainda existe como wrapper de compatibilidade, mas novos códigos devem preferir o builder de capacidade e expor `approvalCapability` no Plugin. -Para entrypoints quentes de canal, prefira os subcaminhos de runtime mais estreitos quando precisar apenas de uma parte dessa família: +Para entrypoints quentes do canal, prefira os subcaminhos de runtime mais específicos quando você +precisar de apenas uma parte dessa família: - `openclaw/plugin-sdk/approval-auth-runtime` - `openclaw/plugin-sdk/approval-client-runtime` @@ -110,69 +125,76 @@ Da mesma forma, prefira `openclaw/plugin-sdk/setup-runtime`, `openclaw/plugin-sdk/reply-runtime`, `openclaw/plugin-sdk/reply-dispatch-runtime`, `openclaw/plugin-sdk/reply-reference` e -`openclaw/plugin-sdk/reply-chunking` quando você não precisar da -superfície mais ampla. +`openclaw/plugin-sdk/reply-chunking` quando você não precisar da superfície +guarda-chuva mais ampla. Especificamente para setup: - `openclaw/plugin-sdk/setup-runtime` cobre os helpers de setup seguros para runtime: adaptadores de patch de setup seguros para importação (`createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, - `createSetupInputPresenceValidator`), saída de nota de lookup, + `createSetupInputPresenceValidator`), saída de nota de consulta, `promptResolvedAllowFrom`, `splitSetupEntries` e os builders delegados de proxy de setup -- `openclaw/plugin-sdk/setup-adapter-runtime` é a seam estreita de adaptador - com suporte a env para `createEnvPatchedAccountSetupAdapter` -- `openclaw/plugin-sdk/channel-setup` cobre os builders de setup com instalação opcional - mais alguns primitivos seguros para setup: +- `openclaw/plugin-sdk/setup-adapter-runtime` é a interface estreita sensível a ambiente + para `createEnvPatchedAccountSetupAdapter` +- `openclaw/plugin-sdk/channel-setup` cobre os builders de setup de instalação opcional + além de alguns primitivos seguros para setup: `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, -Se o seu canal oferece suporte a setup ou autenticação orientados por env e fluxos genéricos de inicialização/configuração devem conhecer esses nomes de env antes de o runtime carregar, declare-os no manifesto do plugin com `channelEnvVars`. Mantenha `envVars` do runtime do canal ou constantes locais apenas para cópia voltada ao operador. +Se o seu canal oferece suporte a setup ou autenticação orientados por variáveis de ambiente e fluxos genéricos de inicialização/configuração +devem conhecer esses nomes de variáveis antes do carregamento em runtime, declare-os no +manifesto do Plugin com `channelEnvVars`. Mantenha `envVars` do runtime do canal ou constantes locais apenas para cópia voltada ao operador. `createOptionalChannelSetupWizard`, `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled` e `splitSetupEntries` -- use a seam mais ampla `openclaw/plugin-sdk/setup` apenas quando também precisar dos helpers compartilhados mais pesados de setup/configuração, como +- use a interface mais ampla `openclaw/plugin-sdk/setup` apenas quando também precisar dos + helpers compartilhados mais pesados de setup/configuração, como `moveSingleAccountChannelSectionToDefaultAccount(...)` -Se o seu canal só quiser anunciar "instale este plugin primeiro" em superfícies de setup, prefira `createOptionalChannelSetupSurface(...)`. O adaptador/assistente gerado falha de forma fechada em gravações de configuração e finalização, e reutiliza a mesma mensagem de instalação obrigatória em validação, finalização e cópia de links de documentação. +Se o seu canal só quiser anunciar "instale este Plugin primeiro" em superfícies +de setup, prefira `createOptionalChannelSetupSurface(...)`. O +adaptador/assistente gerado falha de forma fechada em gravações de configuração e finalização, e reutiliza +a mesma mensagem de instalação obrigatória em validação, finalização e texto de link da documentação. -Para outros caminhos quentes de canal, prefira os helpers estreitos em vez de superfícies legadas mais amplas: +Para outros caminhos quentes do canal, prefira os helpers estreitos em vez de superfícies +legadas mais amplas: - `openclaw/plugin-sdk/account-core`, `openclaw/plugin-sdk/account-id`, `openclaw/plugin-sdk/account-resolution` e - `openclaw/plugin-sdk/account-helpers` para configuração multi-account e + `openclaw/plugin-sdk/account-helpers` para configuração multiconta e fallback de conta padrão - `openclaw/plugin-sdk/inbound-envelope` e - `openclaw/plugin-sdk/inbound-reply-dispatch` para rota/envelope de entrada e - wiring de registrar e despachar -- `openclaw/plugin-sdk/messaging-targets` para parsing/correspondência de destinos + `openclaw/plugin-sdk/inbound-reply-dispatch` para encadeamento de rota/envelope de entrada e + record-and-dispatch +- `openclaw/plugin-sdk/messaging-targets` para análise e correspondência de destino - `openclaw/plugin-sdk/outbound-media` e - `openclaw/plugin-sdk/outbound-runtime` para carregamento de mídia mais - delegados de identidade/envio de saída -- `openclaw/plugin-sdk/thread-bindings-runtime` para ciclo de vida de thread-binding + `openclaw/plugin-sdk/outbound-runtime` para carregamento de mídia e delegates de + identidade/envio de saída +- `openclaw/plugin-sdk/thread-bindings-runtime` para ciclo de vida de vínculo de thread e registro de adaptador -- `openclaw/plugin-sdk/agent-media-payload` apenas quando ainda for necessário - um layout legado de campo de payload de agente/mídia -- `openclaw/plugin-sdk/telegram-command-config` para normalização de comandos personalizados do Telegram, validação de duplicatas/conflitos e um contrato estável de fallback para configuração de comandos +- `openclaw/plugin-sdk/agent-media-payload` apenas quando um layout legado de campo + de payload de agente/mídia ainda for necessário +- `openclaw/plugin-sdk/telegram-command-config` para normalização de comandos personalizados do Telegram, validação de duplicidade/conflito e um contrato de configuração de comando estável para fallback -Canais apenas de autenticação normalmente podem parar no caminho padrão: o core lida com aprovações e o plugin só expõe capacidades de saída/autenticação. Canais com aprovação nativa, como Matrix, Slack, Telegram e transportes de chat personalizados, devem usar os helpers nativos compartilhados em vez de implementar seu próprio ciclo de vida de aprovação. +Canais somente com autenticação geralmente podem parar no caminho padrão: o core lida com aprovações e o Plugin apenas expõe capacidades de saída/autenticação. Canais de aprovação nativa, como Matrix, Slack, Telegram e transportes de chat personalizados, devem usar os helpers nativos compartilhados em vez de implementar seu próprio ciclo de vida de aprovação. ## Política de menção de entrada Mantenha o tratamento de menções de entrada dividido em duas camadas: -- coleta de evidências sob responsabilidade do plugin -- avaliação compartilhada de política +- coleta de evidências pertencente ao Plugin +- avaliação de política compartilhada Use `openclaw/plugin-sdk/channel-inbound` para a camada compartilhada. -Bom ajuste para lógica local do plugin: +Bom ajuste para lógica local do Plugin: - detecção de resposta ao bot - detecção de citação do bot -- verificações de participação em thread +- verificações de participação na thread - exclusões de mensagens de serviço/sistema - caches nativos da plataforma necessários para comprovar a participação do bot @@ -180,7 +202,7 @@ Bom ajuste para o helper compartilhado: - `requireMention` - resultado explícito de menção -- allowlist de menção implícita +- lista de permissão de menção implícita - bypass de comando - decisão final de ignorar @@ -228,7 +250,7 @@ if (decision.shouldSkip) return; ``` `api.runtime.channel.mentions` expõe os mesmos helpers compartilhados de menção para -plugins de canal integrados que já dependem de injeção em runtime: +Plugins de canal empacotados que já dependem de injeção em runtime: - `buildMentionRegexes` - `matchesMentionPatterns` @@ -237,17 +259,17 @@ plugins de canal integrados que já dependem de injeção em runtime: - `resolveInboundMentionDecision` Os helpers mais antigos `resolveMentionGating*` permanecem em -`openclaw/plugin-sdk/channel-inbound` apenas como exports de compatibilidade. Código novo -deve usar `resolveInboundMentionDecision({ facts, policy })`. +`openclaw/plugin-sdk/channel-inbound` apenas como exportações de compatibilidade. Novos códigos +devem usar `resolveInboundMentionDecision({ facts, policy })`. ## Passo a passo - Crie os arquivos padrão do plugin. O campo `channel` em `package.json` é - o que faz deste um plugin de canal. Para a superfície completa de metadados - do pacote, veja [Setup e configuração de plugins](/pt-BR/plugins/sdk-setup#openclaw-channel): + Crie os arquivos padrão do Plugin. O campo `channel` em `package.json` é + o que torna este um Plugin de canal. Para a superfície completa de metadados do pacote, + consulte [Configuração e Setup de Plugin](/pt-BR/plugins/sdk-setup#openclaw-channel): ```json package.json @@ -261,7 +283,7 @@ deve usar `resolveInboundMentionDecision({ facts, policy })`. "channel": { "id": "acme-chat", "label": "Acme Chat", - "blurb": "Conecte o OpenClaw ao Acme Chat." + "blurb": "Connect OpenClaw to Acme Chat." } } } @@ -273,7 +295,7 @@ deve usar `resolveInboundMentionDecision({ facts, policy })`. "kind": "channel", "channels": ["acme-chat"], "name": "Acme Chat", - "description": "Plugin de canal Acme Chat", + "description": "Acme Chat channel plugin", "configSchema": { "type": "object", "additionalProperties": false, @@ -296,7 +318,7 @@ deve usar `resolveInboundMentionDecision({ facts, policy })`. - + A interface `ChannelPlugin` tem muitas superfícies opcionais de adaptador. Comece com o mínimo — `id` e `setup` — e adicione adaptadores conforme necessário. @@ -394,15 +416,15 @@ deve usar `resolveInboundMentionDecision({ facts, policy })`. ``` - Em vez de implementar manualmente interfaces de adaptador de baixo nível, você passa - opções declarativas e o builder compõe tudo: + Em vez de implementar interfaces de adaptador de baixo nível manualmente, você passa + opções declarativas e o builder as compõe: - | Option | O que ele conecta | + | Opção | O que ela conecta | | --- | --- | | `security.dm` | Resolver de segurança de DM com escopo a partir de campos de configuração | | `pairing.text` | Fluxo de pareamento de DM baseado em texto com troca de código | - | `threading` | Resolver do modo reply-to (fixo, com escopo de conta ou personalizado) | - | `outbound.attachedResults` | Funções de envio que retornam metadados do resultado (ids de mensagem) | + | `threading` | Resolver de modo reply-to (fixo, com escopo por conta ou personalizado) | + | `outbound.attachedResults` | Funções de envio que retornam metadados de resultado (IDs de mensagem) | Você também pode passar objetos brutos de adaptador em vez de opções declarativas se precisar de controle total. @@ -420,20 +442,20 @@ deve usar `resolveInboundMentionDecision({ facts, policy })`. export default defineChannelPluginEntry({ id: "acme-chat", name: "Acme Chat", - description: "Plugin de canal Acme Chat", + description: "Acme Chat channel plugin", plugin: acmeChatPlugin, registerCliMetadata(api) { api.registerCli( ({ program }) => { program .command("acme-chat") - .description("Gerenciamento do Acme Chat"); + .description("Acme Chat management"); }, { descriptors: [ { name: "acme-chat", - description: "Gerenciamento do Acme Chat", + description: "Acme Chat management", hasSubcommands: false, }, ], @@ -446,15 +468,15 @@ deve usar `resolveInboundMentionDecision({ facts, policy })`. }); ``` - Coloque descritores de CLI sob responsabilidade do canal em `registerCliMetadata(...)` para que o OpenClaw + Coloque descritores de CLI pertencentes ao canal em `registerCliMetadata(...)` para que o OpenClaw possa mostrá-los na ajuda raiz sem ativar o runtime completo do canal, - enquanto carregamentos completos normais ainda capturam os mesmos descritores para o registro real de comandos. - Mantenha `registerFull(...)` para trabalho apenas de runtime. - Se `registerFull(...)` registrar métodos RPC do gateway, use um - prefixo específico do plugin. Namespaces de administração do core (`config.*`, + enquanto carregamentos completos normais ainda capturam os mesmos descritores para o registro + real dos comandos. Mantenha `registerFull(...)` para trabalho exclusivo de runtime. + Se `registerFull(...)` registrar métodos RPC do Gateway, use um + prefixo específico do Plugin. Namespaces administrativos do core (`config.*`, `exec.approvals.*`, `wizard.*`, `update.*`) permanecem reservados e sempre resolvem para `operator.admin`. - `defineChannelPluginEntry` lida automaticamente com a separação entre modos de registro. Veja + `defineChannelPluginEntry` lida automaticamente com a divisão de modo de registro. Consulte [Pontos de entrada](/pt-BR/plugins/sdk-entrypoints#definechannelpluginentry) para todas as opções. @@ -470,15 +492,15 @@ deve usar `resolveInboundMentionDecision({ facts, policy })`. export default defineSetupPluginEntry(acmeChatPlugin); ``` - O OpenClaw carrega isso em vez da entrada completa quando o canal está desativado + O OpenClaw carrega isso em vez da entrada completa quando o canal está desabilitado ou não configurado. Isso evita puxar código pesado de runtime durante fluxos de setup. - Veja [Setup e configuração](/pt-BR/plugins/sdk-setup#setup-entry) para detalhes. + Consulte [Setup e Configuração](/pt-BR/plugins/sdk-setup#setup-entry) para detalhes. - - Seu plugin precisa receber mensagens da plataforma e encaminhá-las para - o OpenClaw. O padrão típico é um webhook que verifica a requisição e + + Seu Plugin precisa receber mensagens da plataforma e encaminhá-las ao + OpenClaw. O padrão típico é um Webhook que verifica a requisição e a despacha por meio do handler de entrada do seu canal: ```typescript @@ -503,16 +525,16 @@ deve usar `resolveInboundMentionDecision({ facts, policy })`. ``` - O tratamento de mensagens de entrada é específico de cada canal. Cada plugin de canal é responsável - pelo seu próprio pipeline de entrada. Veja plugins de canal integrados - (por exemplo, o pacote de plugin do Microsoft Teams ou do Google Chat) para padrões reais. + O tratamento de mensagens de entrada é específico de cada canal. Cada Plugin de canal é responsável + pelo seu próprio pipeline de entrada. Veja Plugins de canal empacotados + (por exemplo, o pacote de Plugin do Microsoft Teams ou do Google Chat) para padrões reais. -Escreva testes colocados junto do código em `src/channel.test.ts`: +Escreva testes colocados ao lado do código em `src/channel.test.ts`: ```typescript src/channel.test.ts import { describe, it, expect } from "vitest"; @@ -550,7 +572,7 @@ Escreva testes colocados junto do código em `src/channel.test.ts`: pnpm test -- /acme-chat/ ``` - Para helpers de teste compartilhados, veja [Testes](/pt-BR/plugins/sdk-testing). + Para helpers de teste compartilhados, consulte [Testes](/pt-BR/plugins/sdk-testing). @@ -559,16 +581,16 @@ Escreva testes colocados junto do código em `src/channel.test.ts`: ``` /acme-chat/ -├── package.json # metadados openclaw.channel -├── openclaw.plugin.json # Manifesto com esquema de configuração +├── package.json # metadados de openclaw.channel +├── openclaw.plugin.json # Manifesto com schema de configuração ├── index.ts # defineChannelPluginEntry ├── setup-entry.ts # defineSetupPluginEntry -├── api.ts # Exports públicos (opcional) -├── runtime-api.ts # Exports internos de runtime (opcional) +├── api.ts # Exportações públicas (opcional) +├── runtime-api.ts # Exportações internas de runtime (opcional) └── src/ ├── channel.ts # ChannelPlugin via createChatChannelPlugin ├── channel.test.ts # Testes - ├── client.ts # Client da API da plataforma + ├── client.ts # Cliente de API da plataforma └── runtime.ts # Armazenamento de runtime (se necessário) ``` @@ -576,9 +598,9 @@ Escreva testes colocados junto do código em `src/channel.test.ts`: - Modos de resposta fixos, com escopo de conta ou personalizados + Modos de resposta fixos, com escopo por conta ou personalizados - + describeMessageTool e descoberta de ações @@ -590,15 +612,15 @@ Escreva testes colocados junto do código em `src/channel.test.ts`: -Algumas seams auxiliares integradas ainda existem para manutenção de bundled-plugin e -compatibilidade. Elas não são o padrão recomendado para novos plugins de canal; -prefira os subcaminhos genéricos de channel/setup/reply/runtime da superfície -comum do SDK, a menos que você esteja mantendo diretamente essa família de bundled plugin. +Algumas interfaces auxiliares empacotadas ainda existem para manutenção e +compatibilidade de Plugins empacotados. Elas não são o padrão recomendado para novos Plugins de canal; +prefira os subcaminhos genéricos de canal/setup/resposta/runtime da superfície +comum do SDK, a menos que você esteja mantendo diretamente essa família de Plugins empacotados. ## Próximos passos -- [Plugins de provedor](/pt-BR/plugins/sdk-provider-plugins) — se o seu plugin também fornece modelos -- [Visão geral do SDK](/pt-BR/plugins/sdk-overview) — referência completa de imports por subcaminho +- [Plugins de provedor](/pt-BR/plugins/sdk-provider-plugins) — se o seu Plugin também fornece modelos +- [Visão geral do SDK](/pt-BR/plugins/sdk-overview) — referência completa de importação de subcaminhos - [Testes do SDK](/pt-BR/plugins/sdk-testing) — utilitários de teste e testes de contrato -- [Manifesto de plugin](/pt-BR/plugins/manifest) — esquema completo do manifesto +- [Manifesto de Plugin](/pt-BR/plugins/manifest) — schema completo do manifesto diff --git a/docs/pt-BR/reference/RELEASING.md b/docs/pt-BR/reference/RELEASING.md index dee7a3e2a..f70722071 100644 --- a/docs/pt-BR/reference/RELEASING.md +++ b/docs/pt-BR/reference/RELEASING.md @@ -5,21 +5,21 @@ read_when: summary: Canais de lançamento públicos, nomenclatura de versões e cadência title: Política de lançamento x-i18n: - generated_at: "2026-04-14T05:33:33Z" + generated_at: "2026-04-15T05:33:47Z" model: gpt-5.4 provider: openai - source_hash: 3eaf9f1786b8c9fd4f5a9c657b623cb69d1a485958e1a9b8f108511839b63587 + source_hash: 88724307269ab783a9fbf8a0540fea198d8a3add68457f4e64d5707114fa518c source_path: reference/RELEASING.md workflow: 15 --- # Política de lançamento -O OpenClaw tem três linhas públicas de lançamento: +O OpenClaw tem três faixas públicas de lançamento: - stable: lançamentos com tag que publicam no npm `beta` por padrão, ou no npm `latest` quando solicitado explicitamente - beta: tags de pré-lançamento que publicam no npm `beta` -- dev: a ponta móvel de `main` +- dev: a ponta móvel da `main` ## Nomenclatura de versões @@ -29,122 +29,137 @@ O OpenClaw tem três linhas públicas de lançamento: - Tag Git: `vYYYY.M.D-N` - Versão de pré-lançamento beta: `YYYY.M.D-beta.N` - Tag Git: `vYYYY.M.D-beta.N` -- Não use preenchimento com zero para mês ou dia -- `latest` significa o lançamento stable promovido atual do npm +- Não preencha mês ou dia com zeros à esquerda +- `latest` significa o lançamento npm stable promovido atual - `beta` significa o destino de instalação beta atual -- Lançamentos stable e de correção stable publicam no npm `beta` por padrão; operadores de lançamento podem direcionar para `latest` explicitamente, ou promover depois uma build beta validada -- Todo lançamento do OpenClaw envia o pacote npm e o app macOS juntos +- Lançamentos stable e correções stable publicam no npm `beta` por padrão; operadores de lançamento podem direcionar explicitamente para `latest` ou promover uma build beta validada depois +- Todo lançamento do OpenClaw entrega o pacote npm e o app macOS juntos -## Cadência de lançamento +## Cadência de lançamentos -- Os lançamentos passam primeiro por beta -- stable vem somente depois que o beta mais recente é validado -- O procedimento detalhado de lançamento, aprovações, credenciais e notas de recuperação é exclusivo para mantenedores +- Os lançamentos seguem primeiro para beta +- stable só vem depois que a beta mais recente é validada +- Procedimento detalhado de lançamento, aprovações, credenciais e notas de recuperação são exclusivos para maintainers -## Verificações prévias de lançamento +## Pré-verificação de lançamento - Execute `pnpm build && pnpm ui:build` antes de `pnpm release:check` para que os artefatos de lançamento esperados em `dist/*` e o bundle da Control UI existam para a etapa de validação do pack - Execute `pnpm release:check` antes de todo lançamento com tag - As verificações de lançamento agora são executadas em um workflow manual separado: `OpenClaw Release Checks` -- Essa separação é intencional: mantém o caminho real de lançamento no npm curto, - determinístico e focado em artefatos, enquanto verificações live mais lentas ficam em sua própria linha para não atrasar nem bloquear a publicação -- As verificações de lançamento devem ser disparadas a partir da ref de workflow `main` para que a lógica do workflow e os segredos permaneçam canônicos -- Esse workflow aceita uma tag de lançamento existente ou o SHA completo de 40 caracteres do commit atual de `main` -- No modo de commit SHA, ele aceita apenas o HEAD atual de `origin/main`; use uma tag de lançamento para commits de lançamento mais antigos -- A validação prévia apenas de validação de `OpenClaw NPM Release` também aceita o SHA completo de 40 caracteres do commit atual de `main` sem exigir uma tag enviada -- Esse caminho por SHA é apenas para validação e não pode ser promovido para uma publicação real -- No modo SHA, o workflow sintetiza `v` apenas para a verificação dos metadados do pacote; a publicação real ainda exige uma tag de lançamento real +- A validação de runtime de instalação e upgrade entre sistemas operacionais é despachada a partir do workflow chamador privado + `openclaw/releases-private/.github/workflows/openclaw-cross-os-release-checks.yml`, + que invoca o workflow público reutilizável + `.github/workflows/openclaw-cross-os-release-checks-reusable.yml` +- Essa divisão é intencional: mantém o caminho real de lançamento no npm curto, + determinístico e focado em artefatos, enquanto as verificações ao vivo mais lentas ficam em sua própria faixa para não atrasarem nem bloquearem a publicação +- As verificações de lançamento devem ser despachadas a partir da referência de workflow `main` para que a lógica do workflow e os segredos permaneçam canônicos +- Esse workflow aceita uma tag de lançamento existente ou o SHA completo atual de 40 caracteres do commit da `main` +- No modo SHA de commit, ele aceita apenas o HEAD atual de `origin/main`; use uma tag de lançamento para commits de lançamento mais antigos +- A pré-verificação somente de validação de `OpenClaw NPM Release` também aceita o SHA completo atual de 40 caracteres do commit da `main` sem exigir uma tag enviada +- Esse caminho por SHA é apenas de validação e não pode ser promovido para uma publicação real +- No modo SHA, o workflow sintetiza `v` apenas para a verificação de metadados do pacote; a publicação real ainda exige uma tag de lançamento real - Ambos os workflows mantêm o caminho real de publicação e promoção em runners hospedados pelo GitHub, enquanto o caminho de validação não mutável pode usar os runners Linux maiores da Blacksmith - Esse workflow executa `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache` usando os segredos de workflow `OPENAI_API_KEY` e `ANTHROPIC_API_KEY` -- A validação prévia de lançamento no npm não espera mais pela linha separada de verificações de lançamento +- A pré-verificação de lançamento npm não espera mais pela faixa separada de verificações de lançamento - Execute `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts` (ou a tag beta/correção correspondente) antes da aprovação -- Depois da publicação no npm, execute +- Após a publicação no npm, execute `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D` (ou a versão beta/correção correspondente) para verificar o caminho de instalação publicado no registro em um prefixo temporário novo -- A automação de lançamento dos mantenedores agora usa pré-verificação seguida de promoção: - - a publicação real no npm deve passar por um `preflight_run_id` bem-sucedido +- A automação de lançamento de maintainers agora usa pré-verificação seguida de promoção: + - a publicação real no npm deve passar por um `preflight_run_id` bem-sucedido do npm - lançamentos npm stable usam `beta` por padrão - - a publicação npm stable pode direcionar para `latest` explicitamente por meio da entrada do workflow - - a promoção npm stable de `beta` para `latest` continua disponível como um modo manual explícito no workflow confiável `OpenClaw NPM Release` - - publicações stable diretas também podem executar um modo explícito de sincronização de dist-tag que aponta `latest` e `beta` para a versão stable já publicada - - esses modos de dist-tag ainda precisam de um `NPM_TOKEN` válido no ambiente `npm-release`, porque o gerenciamento de `npm dist-tag` é separado da publicação confiável - - `macOS Release` público é somente para validação + - a publicação npm stable pode direcionar explicitamente para `latest` por entrada do workflow + - a mutação de dist-tag do npm baseada em token agora fica em + `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` + por segurança, porque `npm dist-tag add` ainda precisa de `NPM_TOKEN`, enquanto o repositório público mantém publicação somente com OIDC + - o `macOS Release` público é apenas de validação - a publicação real privada do mac deve passar por `preflight_run_id` e `validate_run_id` privados do mac bem-sucedidos - os caminhos de publicação reais promovem artefatos preparados em vez de reconstruí-los novamente -- Para lançamentos de correção stable como `YYYY.M.D-N`, o verificador pós-publicação também verifica o mesmo caminho de upgrade em prefixo temporário de `YYYY.M.D` para `YYYY.M.D-N`, para que correções de lançamento não possam deixar silenciosamente instalações globais antigas na carga stable base -- A validação prévia de lançamento no npm falha em modo fechado, a menos que o tarball inclua `dist/control-ui/index.html` e uma carga `dist/control-ui/assets/` não vazia, para que não enviemos novamente um painel do navegador vazio -- `pnpm test:install:smoke` também impõe o orçamento de `unpackedSize` do `npm pack` no tarball de atualização candidato, para que o e2e do instalador detecte aumento acidental do pack antes do caminho de publicação de lançamento -- Se o trabalho de lançamento tiver alterado o planejamento de CI, manifestos de tempo de extensões ou matrizes de teste de extensões, regenere e revise as saídas da matriz de workflow `checks-node-extensions` de propriedade do planejador a partir de `.github/workflows/ci.yml` antes da aprovação, para que as notas de lançamento não descrevam um layout de CI desatualizado -- A prontidão de lançamento stable do macOS também inclui as superfícies do atualizador: +- Para lançamentos de correção stable como `YYYY.M.D-N`, o verificador pós-publicação + também verifica o mesmo caminho de upgrade em prefixo temporário de `YYYY.M.D` para `YYYY.M.D-N`, + para que correções de lançamento não deixem silenciosamente instalações globais mais antigas na carga stable base +- A pré-verificação de lançamento npm falha de forma fechada, a menos que o tarball inclua `dist/control-ui/index.html` e uma carga útil não vazia em `dist/control-ui/assets/`, + para que não entreguemos novamente um dashboard de navegador vazio +- `pnpm test:install:smoke` também impõe o orçamento de `unpackedSize` do npm pack no tarball candidato de atualização, + para que o e2e do instalador detecte aumento acidental do pack antes do caminho de publicação do lançamento +- Se o trabalho de lançamento tocou no planejamento de CI, manifestos de tempo de extensões ou matrizes de teste de extensões, regenere e revise as saídas da matriz de workflow `checks-node-extensions`, de propriedade do planner, em `.github/workflows/ci.yml` + antes da aprovação, para que as notas de lançamento não descrevam um layout de CI desatualizado +- A prontidão de lançamento stable no macOS também inclui as superfícies do atualizador: - o lançamento no GitHub deve terminar com os arquivos empacotados `.zip`, `.dmg` e `.dSYM.zip` - - `appcast.xml` em `main` deve apontar para o novo zip stable após a publicação - - o app empacotado deve manter um bundle id que não seja de depuração, uma URL de feed Sparkle não vazia e um `CFBundleVersion` igual ou superior ao piso canônico de build do Sparkle para essa versão de lançamento + - `appcast.xml` na `main` deve apontar para o novo zip stable após a publicação + - o app empacotado deve manter um bundle id não debug, uma URL de feed Sparkle não vazia + e um `CFBundleVersion` igual ou acima do piso canônico de build do Sparkle + para essa versão de lançamento -## Entradas de workflow do npm +## Entradas do workflow de NPM `OpenClaw NPM Release` aceita estas entradas controladas pelo operador: -- `tag`: tag de lançamento obrigatória, como `v2026.4.2`, `v2026.4.2-1` ou - `v2026.4.2-beta.1`; quando `preflight_only=true`, também pode ser o SHA completo de 40 caracteres do commit atual de `main` para uma validação prévia somente de validação -- `preflight_only`: `true` para apenas validação/build/package, `false` para o caminho de publicação real -- `preflight_run_id`: obrigatório no caminho de publicação real para que o workflow reutilize o tarball preparado da execução de pré-verificação bem-sucedida -- `npm_dist_tag`: tag de destino do npm para o caminho de publicação; o padrão é `beta` -- `promote_beta_to_latest`: `true` para pular a publicação e mover uma build stable `beta` já publicada para `latest` -- `sync_stable_dist_tags`: `true` para pular a publicação e apontar `latest` e `beta` para uma versão stable já publicada +- `tag`: tag de lançamento obrigatória como `v2026.4.2`, `v2026.4.2-1` ou + `v2026.4.2-beta.1`; quando `preflight_only=true`, também pode ser o + SHA completo atual de 40 caracteres do commit da `main` para pré-verificação apenas de validação +- `preflight_only`: `true` apenas para validação/build/package, `false` para o + caminho de publicação real +- `preflight_run_id`: obrigatório no caminho de publicação real para que o workflow reutilize + o tarball preparado da execução de pré-verificação bem-sucedida +- `npm_dist_tag`: tag de destino no npm para o caminho de publicação; o padrão é `beta` `OpenClaw Release Checks` aceita estas entradas controladas pelo operador: -- `ref`: tag de lançamento existente ou o SHA completo de 40 caracteres do commit atual de `main` para validar +- `ref`: tag de lançamento existente ou o SHA completo atual de 40 caracteres do commit da `main` + para validar Regras: - Tags stable e de correção podem publicar em `beta` ou `latest` -- Tags de pré-lançamento beta podem publicar somente em `beta` +- Tags de pré-lançamento beta podem publicar apenas em `beta` - A entrada de SHA completo de commit é permitida apenas quando `preflight_only=true` -- O modo por commit SHA das verificações de lançamento também exige o HEAD atual de `origin/main` -- O caminho de publicação real deve usar o mesmo `npm_dist_tag` usado durante a pré-verificação; o workflow verifica esses metadados antes de a publicação continuar -- O modo de promoção deve usar uma tag stable ou de correção, `preflight_only=false`, - `preflight_run_id` vazio e `npm_dist_tag=beta` -- O modo de sincronização de dist-tag deve usar uma tag stable ou de correção, - `preflight_only=false`, `preflight_run_id` vazio, `npm_dist_tag=latest`, - e `promote_beta_to_latest=false` -- Os modos de promoção e sincronização de dist-tag também exigem um `NPM_TOKEN` válido porque `npm dist-tag add` ainda precisa de autenticação npm normal; a publicação confiável cobre apenas o caminho de publicação do pacote +- O modo SHA de commit das verificações de lançamento também exige o HEAD atual de `origin/main` +- O caminho de publicação real deve usar o mesmo `npm_dist_tag` usado durante a pré-verificação; + o workflow verifica esses metadados antes de a publicação continuar ## Sequência de lançamento npm stable Ao criar um lançamento npm stable: 1. Execute `OpenClaw NPM Release` com `preflight_only=true` - - Antes de existir uma tag, você pode usar o SHA completo atual de `main` para uma simulação somente de validação do workflow de pré-verificação -2. Escolha `npm_dist_tag=beta` para o fluxo normal beta-first, ou `latest` somente quando quiser intencionalmente uma publicação stable direta -3. Execute `OpenClaw Release Checks` separadamente com a mesma tag ou o SHA completo atual de `main` quando quiser cobertura live de cache de prompt - - Isso é separado de propósito para que a cobertura live continue disponível sem reacoplar verificações demoradas ou instáveis ao workflow de publicação + - Antes de existir uma tag, você pode usar o SHA completo atual da `main` para uma execução de teste apenas de validação do workflow de pré-verificação +2. Escolha `npm_dist_tag=beta` para o fluxo normal beta-first, ou `latest` apenas + quando você quiser intencionalmente uma publicação stable direta +3. Execute `OpenClaw Release Checks` separadamente com a mesma tag ou o + SHA completo atual da `main` quando quiser cobertura ao vivo do cache de prompt + - Isso é separado de propósito para que a cobertura ao vivo continue disponível sem + reacoplar verificações longas ou instáveis ao workflow de publicação 4. Salve o `preflight_run_id` bem-sucedido 5. Execute `OpenClaw NPM Release` novamente com `preflight_only=false`, a mesma `tag`, o mesmo `npm_dist_tag` e o `preflight_run_id` salvo -6. Se o lançamento chegou a `beta`, execute `OpenClaw NPM Release` mais tarde com a mesma `tag` stable, `promote_beta_to_latest=true`, `preflight_only=false`, - `preflight_run_id` vazio e `npm_dist_tag=beta` quando quiser mover essa build publicada para `latest` -7. Se o lançamento foi intencionalmente publicado diretamente em `latest` e `beta` - deve seguir a mesma build stable, execute `OpenClaw NPM Release` com a mesma - `tag` stable, `sync_stable_dist_tags=true`, `promote_beta_to_latest=false`, - `preflight_only=false`, `preflight_run_id` vazio e `npm_dist_tag=latest` +6. Se o lançamento caiu em `beta`, use o workflow privado + `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` + para promover essa versão stable de `beta` para `latest` +7. Se o lançamento foi publicado intencionalmente diretamente em `latest` e `beta` + deve seguir imediatamente a mesma build stable, use esse mesmo workflow privado + para apontar ambas as dist-tags para a versão stable, ou deixe sua sincronização + automática agendada mover `beta` depois -Os modos de promoção e sincronização de dist-tag ainda exigem a aprovação do ambiente `npm-release` e um `NPM_TOKEN` válido acessível a essa execução de workflow. +A mutação de dist-tag fica no repositório privado por segurança porque ainda +exige `NPM_TOKEN`, enquanto o repositório público mantém publicação somente com OIDC. -Isso mantém o caminho de publicação direta e o caminho de promoção beta-first ambos documentados e visíveis para o operador. +Isso mantém tanto o caminho de publicação direta quanto o caminho de promoção beta-first +documentados e visíveis para o operador. ## Referências públicas - [`.github/workflows/openclaw-npm-release.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/openclaw-npm-release.yml) - [`.github/workflows/openclaw-release-checks.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/openclaw-release-checks.yml) +- [`.github/workflows/openclaw-cross-os-release-checks-reusable.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/openclaw-cross-os-release-checks-reusable.yml) - [`scripts/openclaw-npm-release-check.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/openclaw-npm-release-check.ts) - [`scripts/package-mac-dist.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/package-mac-dist.sh) - [`scripts/make_appcast.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/make_appcast.sh) -Os mantenedores usam a documentação privada de lançamento em +Maintainers usam a documentação privada de lançamento em [`openclaw/maintainers/release/README.md`](https://github.com/openclaw/maintainers/blob/main/release/README.md) para o runbook real. diff --git a/docs/pt-BR/reference/secretref-credential-surface.md b/docs/pt-BR/reference/secretref-credential-surface.md index 7183faa01..532679435 100644 --- a/docs/pt-BR/reference/secretref-credential-surface.md +++ b/docs/pt-BR/reference/secretref-credential-surface.md @@ -3,13 +3,13 @@ read_when: - Verificando a cobertura de credenciais SecretRef - Auditando se uma credencial é elegível para `secrets configure` ou `secrets apply` - Verificando por que uma credencial está fora da superfície suportada -summary: Superfície canônica de credenciais SecretRef suportadas vs. não suportadas +summary: Superfície canônica suportada vs. não suportada de credenciais SecretRef title: Superfície de credenciais SecretRef x-i18n: - generated_at: "2026-04-07T05:31:11Z" + generated_at: "2026-04-15T05:34:18Z" model: gpt-5.4 provider: openai - source_hash: 211f4b504c5808f7790683066fc2c8b700c705c598f220a264daf971b81cc593 + source_hash: dd0b9c379236b17a72f552d6360b8b5a2269009e019c138c6bb50f4f7328ddaf source_path: reference/secretref-credential-surface.md workflow: 15 --- @@ -18,7 +18,7 @@ x-i18n: Esta página define a superfície canônica de credenciais SecretRef. -Intenção de escopo: +Intenção do escopo: - No escopo: credenciais estritamente fornecidas pelo usuário que o OpenClaw não emite nem rotaciona. - Fora do escopo: credenciais emitidas em runtime ou rotativas, material de refresh OAuth e artefatos semelhantes a sessão. @@ -49,6 +49,7 @@ Intenção de escopo: - `messages.tts.providers.*.apiKey` - `tools.web.fetch.firecrawl.apiKey` - `plugins.entries.brave.config.webSearch.apiKey` +- `plugins.entries.exa.config.webSearch.apiKey` - `plugins.entries.google.config.webSearch.apiKey` - `plugins.entries.xai.config.webSearch.apiKey` - `plugins.entries.moonshot.config.webSearch.apiKey` @@ -122,14 +123,14 @@ Observações: - Alvos de plano de perfil de autenticação exigem `agentId`. - Entradas de plano têm como alvo `profiles.*.key` / `profiles.*.token` e gravam refs irmãs (`keyRef` / `tokenRef`). - Refs de perfil de autenticação estão incluídas na resolução em runtime e na cobertura de auditoria. -- Regra de proteção da política OAuth: `auth.profiles..mode = "oauth"` não pode ser combinado com entradas SecretRef para esse perfil. Inicialização/recarga e resolução de perfil de autenticação falham rapidamente quando essa política é violada. -- Para provedores de modelo gerenciados por SecretRef, entradas geradas em `agents/*/agent/models.json` persistem marcadores não secretos (não valores secretos resolvidos) para superfícies `apiKey`/header. -- A persistência de marcadores é autoritativa pela origem: o OpenClaw grava marcadores a partir do snapshot de configuração da origem ativa (pré-resolução), não a partir de valores secretos resolvidos em runtime. -- Para pesquisa na web: +- Proteção de política OAuth: `auth.profiles..mode = "oauth"` não pode ser combinado com entradas SecretRef para esse perfil. Inicialização/reload e resolução de perfil de autenticação falham rapidamente quando essa política é violada. +- Para provedores de modelo gerenciados por SecretRef, entradas geradas em `agents/*/agent/models.json` persistem marcadores não secretos (não valores secretos resolvidos) para superfícies de `apiKey`/cabeçalhos. +- A persistência de marcadores é autoritativa em relação à origem: o OpenClaw grava marcadores a partir do snapshot da configuração da fonte ativa (pré-resolução), não a partir de valores secretos resolvidos em runtime. +- Para busca na web: - No modo de provedor explícito (`tools.web.search.provider` definido), apenas a chave do provedor selecionado fica ativa. - - No modo automático (`tools.web.search.provider` não definido), apenas a primeira chave de provedor resolvida por precedência fica ativa. + - No modo automático (`tools.web.search.provider` não definido), apenas a primeira chave de provedor que for resolvida por precedência fica ativa. - No modo automático, refs de provedores não selecionados são tratadas como inativas até serem selecionadas. - - Caminhos legados de provedor `tools.web.search.*` ainda resolvem durante a janela de compatibilidade, mas a superfície canônica de SecretRef é `plugins.entries..config.webSearch.*`. + - Caminhos legados de provedor em `tools.web.search.*` ainda são resolvidos durante a janela de compatibilidade, mas a superfície canônica de SecretRef é `plugins.entries..config.webSearch.*`. ## Credenciais não suportadas @@ -151,4 +152,4 @@ Credenciais fora do escopo incluem: Justificativa: -- Essas credenciais são emitidas, rotacionadas, carregam sessão ou pertencem a classes duráveis de OAuth que não se encaixam na resolução externa somente leitura de SecretRef. +- Essas credenciais são emitidas, rotacionadas, carregam sessão ou pertencem a classes duráveis de OAuth que não se encaixam na resolução externa de SecretRef somente leitura. diff --git a/docs/pt-BR/start/showcase.md b/docs/pt-BR/start/showcase.md index 7d6b6011b..e06b7b557 100644 --- a/docs/pt-BR/start/showcase.md +++ b/docs/pt-BR/start/showcase.md @@ -1,104 +1,131 @@ --- +description: Real-world OpenClaw projects from the community read_when: - Procurando exemplos reais de uso do OpenClaw - - Atualizando os destaques de projetos da comunidade -summary: Projetos e integrações criados pela comunidade com OpenClaw + - Atualizando destaques de projetos da comunidade +summary: Projetos e integrações criados pela comunidade com tecnologia OpenClaw title: Vitrine x-i18n: - generated_at: "2026-04-05T12:54:13Z" + generated_at: "2026-04-15T05:34:17Z" model: gpt-5.4 provider: openai - source_hash: 2917e9a476ef527ddb3e51c610bbafbd145e705c9cc29f191639fb63d238ef70 + source_hash: 797d0b85c9eca920240c79d870eb9636216714f3eba871c5ebd0f7f40cf7bbf1 source_path: start/showcase.md workflow: 15 --- + + # Vitrine -Projetos reais da comunidade. Veja o que as pessoas estão criando com OpenClaw. +
+

Criado em chats, terminais, navegadores e salas de estar

+

+ Os projetos OpenClaw não são demos de brinquedo. As pessoas estão colocando em produção ciclos de revisão de PR, aplicativos móveis, automação residencial, + sistemas de voz, ferramentas de desenvolvimento e fluxos de trabalho intensivos em memória a partir dos canais que já usam. +

+ +
+
+ Criações nativas de chat + Fluxos de trabalho com Telegram, WhatsApp, Discord, Beeper, chat web e terminal em primeiro lugar. +
+
+ Automação real + Reservas, compras, suporte, relatórios e controle de navegador sem esperar por uma API. +
+
+ Mundo local + físico + Impressoras, aspiradores, câmeras, dados de saúde, sistemas domésticos e bases de conhecimento pessoais. +
+
+
**Quer aparecer aqui?** Compartilhe seu projeto em [#self-promotion no Discord](https://discord.gg/clawd) ou [marque @openclaw no X](https://x.com/openclaw). -## 🎥 OpenClaw em ação - -Passo a passo completo de configuração (28 min) por VelvetShark. - -
-