diff --git a/docs/pt-BR/concepts/qa-e2e-automation.md b/docs/pt-BR/concepts/qa-e2e-automation.md index a324a1138..9ba79dcf8 100644 --- a/docs/pt-BR/concepts/qa-e2e-automation.md +++ b/docs/pt-BR/concepts/qa-e2e-automation.md @@ -1,37 +1,37 @@ --- read_when: - Estendendo qa-lab ou qa-channel - - Adicionando cenários de QA com suporte do repositório - - Criando automação de QA de maior realismo em torno do painel do Gateway -summary: Estrutura privada de automação de QA para qa-lab, qa-channel, cenários com seed e relatórios de protocolo -title: Automação E2E de QA + - Adicionando cenários de QA respaldados pelo repositório + - Criando automação de QA mais realista em torno do painel do Gateway +summary: Formato da automação de QA privada para qa-lab, qa-channel, cenários com seed e relatórios de protocolo +title: Automação de QA E2E x-i18n: - generated_at: "2026-04-12T23:28:13Z" + generated_at: "2026-04-13T05:41:50Z" model: gpt-5.4 provider: openai - source_hash: b9fe27dc049823d5e3eb7ae1eac6aad21ed9e917425611fb1dbcb28ab9210d5e + source_hash: a4a4f5c765163565c95c2a071f201775fd9d8d60cad4ff25d71e4710559c1570 source_path: concepts/qa-e2e-automation.md workflow: 15 --- -# Automação E2E de QA +# Automação de QA E2E -A stack privada de QA foi criada para exercitar o OpenClaw de uma forma mais realista, +A pilha privada de QA foi feita para exercitar o OpenClaw de uma forma mais realista, com formato de canal, do que um único teste unitário consegue. -Peças atuais: +Partes atuais: - `extensions/qa-channel`: canal de mensagens sintético com superfícies de DM, canal, thread, reação, edição e exclusão. -- `extensions/qa-lab`: interface de depuração e barramento de QA para observar a transcrição, - injetar mensagens de entrada e exportar um relatório em Markdown. -- `qa/`: recursos seed com suporte do repositório para a tarefa inicial e cenários - de QA de linha de base. +- `extensions/qa-lab`: UI de depuração e barramento de QA para observar a transcrição, + injetar mensagens recebidas e exportar um relatório em Markdown. +- `qa/`: recursos de seed respaldados pelo repositório para a tarefa inicial e + cenários básicos de QA. O fluxo atual do operador de QA é um site de QA com dois painéis: - Esquerda: painel do Gateway (Control UI) com o agente. -- Direita: QA Lab, mostrando a transcrição em estilo Slack e o plano do cenário. +- Direita: QA Lab, mostrando a transcrição em estilo Slack e o plano de cenário. Execute com: @@ -39,13 +39,13 @@ Execute com: pnpm qa:lab:up ``` -Isso compila o site de QA, inicia a lane do gateway com Docker e expõe a -página do QA Lab, onde um operador ou loop de automação pode dar ao agente uma -missão de QA, observar o comportamento real do canal e registrar o que funcionou, falhou -ou continuou bloqueado. +Isso compila o site de QA, inicia a lane de Gateway com Docker em segundo plano e expõe a +página do QA Lab onde um operador ou loop de automação pode dar ao agente uma +missão de QA, observar o comportamento real do canal e registrar o que funcionou, +falhou ou permaneceu bloqueado. -Para uma iteração mais rápida da interface do QA Lab sem recompilar a imagem Docker a cada vez, -inicie a stack com um bundle do QA Lab montado por bind mount: +Para uma iteração mais rápida da UI do QA Lab sem reconstruir a imagem Docker toda vez, +inicie a pilha com um bundle do QA Lab montado por bind mount: ```bash pnpm openclaw qa docker-build-image @@ -56,91 +56,96 @@ pnpm qa:lab:watch `qa:lab:up:fast` mantém os serviços Docker em uma imagem pré-compilada e faz bind mount de `extensions/qa-lab/web/dist` no contêiner `qa-lab`. `qa:lab:watch` -recompila esse bundle quando há mudanças, e o navegador recarrega automaticamente quando o hash +recompila esse bundle quando houver mudanças, e o navegador recarrega automaticamente quando o hash do recurso do QA Lab muda. -Para uma lane de smoke de Matrix com transporte real, execute: +Para uma lane de smoke Matrix com transporte real, execute: ```bash pnpm openclaw qa matrix ``` -Essa lane provisiona um homeserver Tuwunel descartável no Docker, registra -usuários temporários de driver, SUT e observador, cria uma sala privada, e então executa -o Plugin real do Matrix dentro de um processo filho do gateway de QA. A lane de transporte ao vivo mantém -a configuração do processo filho limitada ao transporte em teste, de modo que o Matrix funcione sem -`qa-channel` na configuração do processo filho. +Essa lane provisiona um homeserver Tuwunel descartável em Docker, registra +usuários temporários de driver, SUT e observador, cria uma sala privada e então executa +o Plugin Matrix real dentro de um processo filho do Gateway de QA. A lane de transporte ao vivo mantém +a configuração filha limitada ao transporte em teste, para que o Matrix funcione sem +`qa-channel` na configuração filha. -Para uma lane de smoke de Telegram com transporte real, execute: +Para uma lane de smoke Telegram com transporte real, execute: ```bash pnpm openclaw qa telegram ``` -Essa lane usa um grupo privado real do Telegram em vez de provisionar um -servidor descartável. Ela exige `OPENCLAW_QA_TELEGRAM_GROUP_ID`, +Essa lane usa um grupo privado real do Telegram em vez de provisionar um servidor +descartável. Ela requer `OPENCLAW_QA_TELEGRAM_GROUP_ID`, `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` e `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`, além de dois bots distintos no mesmo -grupo privado. O bot SUT deve ter um nome de usuário no Telegram, e a observação -entre bots funciona melhor quando ambos os bots têm o modo de comunicação Bot-to-Bot -habilitado no `@BotFather`. +grupo privado. O bot SUT precisa ter um nome de usuário no Telegram, e a observação +entre bots funciona melhor quando ambos os bots têm o Modo de Comunicação Bot-to-Bot +ativado no `@BotFather`. As lanes de transporte ao vivo agora compartilham um contrato menor em vez de cada uma -inventar seu próprio formato de lista de cenários: +inventar seu próprio formato de lista de cenários. `qa-channel` continua sendo a suíte ampla de comportamento sintético do produto e não faz parte da matriz de cobertura de transporte ao vivo. | Lane | Canary | Bloqueio por menção | Bloqueio por allowlist | Resposta de nível superior | Retomada após reinício | Follow-up 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 | +| -------- | ------ | ------------------- | ---------------------- | -------------------------- | ---------------------- | ------------------- | -------------------- | ------------------- | ---------------- | +| Matrix | x | x | x | x | x | x | x | x | | +| Telegram | x | | | | | | | | x | Isso mantém `qa-channel` como a suíte ampla de comportamento do produto, enquanto Matrix, Telegram e futuros transportes ao vivo compartilham uma checklist explícita de contrato de transporte. -Para uma lane descartável de VM Linux sem trazer o Docker para o fluxo de QA, execute: +Para uma lane descartável de VM Linux sem colocar Docker no caminho do QA, execute: ```bash pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline ``` -Isso inicializa um guest novo do Multipass, instala dependências, compila o OpenClaw -dentro do guest, executa `qa suite` e então copia o relatório e o resumo normais de QA -de volta para `.artifacts/qa-e2e/...` no host. -Ele reutiliza o mesmo comportamento de seleção de cenário que `qa suite` no host. +Isso inicializa um guest Multipass novo, instala as dependências, compila o OpenClaw +dentro do guest, executa `qa suite` e depois copia o relatório e +resumo normais de QA de volta para `.artifacts/qa-e2e/...` no host. +Ele reutiliza o mesmo comportamento de seleção de cenários que `qa suite` no host. As execuções da suíte no host e no Multipass executam vários cenários selecionados em paralelo -com workers isolados de gateway por padrão, até 64 workers ou a contagem de cenários -selecionados. Use `--concurrency ` para ajustar a quantidade de workers, ou +com workers de Gateway isolados por padrão, até 64 workers ou a contagem de cenários +selecionada. Use `--concurrency ` para ajustar a contagem de workers, ou `--concurrency 1` para execução serial. -Execuções ao vivo encaminham as entradas de autenticação de QA compatíveis que são práticas -para o guest: chaves de provedor via env, o caminho da configuração do provedor ao vivo de QA e +As execuções ao vivo encaminham as entradas de autenticação de QA compatíveis que são práticas para o +guest: chaves de provedor baseadas em variáveis de ambiente, o caminho de configuração do provedor ao vivo de QA e `CODEX_HOME` quando presente. Mantenha `--output-dir` sob a raiz do repositório para que o guest -possa gravar de volta por meio do workspace montado. +possa gravar de volta pelo workspace montado. -## Seeds com suporte do repositório +## Seeds respaldados pelo repositório -Os recursos seed ficam em `qa/`: +Os recursos de seed ficam em `qa/`: - `qa/scenarios/index.md` - `qa/scenarios/*.md` -Eles ficam intencionalmente no git para que o plano de QA seja visível tanto para humanos quanto para -o agente. +Eles ficam intencionalmente no git para que o plano de QA seja visível tanto para humanos quanto para o +agente. `qa-lab` deve continuar sendo um executor genérico de Markdown. Cada arquivo Markdown de cenário é -a fonte da verdade para uma execução de teste e deve definir: +a fonte de verdade para uma execução de teste e deve definir: - metadados do cenário - referências de documentação e código - requisitos opcionais de Plugin -- patch opcional de configuração do gateway +- patch opcional de configuração do Gateway - o `qa-flow` executável -A lista de linha de base deve permanecer ampla o suficiente para cobrir: +A superfície de runtime reutilizável que dá suporte ao `qa-flow` pode continuar genérica +e transversal. Por exemplo, cenários em Markdown podem combinar helpers do lado do transporte +com helpers do lado do navegador que controlam a Control UI embutida por meio da superfície +`browser.request` do Gateway sem adicionar um executor com caso especial. -- chat em DM e em canal +A lista básica deve continuar ampla o suficiente para cobrir: + +- chat em DM e canal - comportamento de thread - ciclo de vida de ações de mensagem - callbacks de Cron @@ -148,22 +153,22 @@ A lista de linha de base deve permanecer ampla o suficiente para cobrir: - troca de modelo - handoff para subagente - leitura do repositório e da documentação -- uma pequena tarefa de build, como Lobster Invaders +- uma pequena tarefa de build como Lobster Invaders ## Adaptadores de transporte -`qa-lab` é responsável por uma interface genérica de transporte para cenários de QA em Markdown. -`qa-channel` é o primeiro adaptador nessa interface, mas o objetivo do design é mais amplo: -canais futuros, reais ou sintéticos, devem se conectar ao mesmo executor de suíte -em vez de adicionar um executor de QA específico para cada transporte. +`qa-lab` é dono de uma superfície de transporte genérica para cenários de QA em Markdown. +`qa-channel` é o primeiro adaptador nessa superfície, mas o alvo do design é mais amplo: +futuros canais reais ou sintéticos devem se conectar ao mesmo executor de suíte +em vez de adicionar um executor de QA específico por transporte. No nível de arquitetura, a divisão é: -- `qa-lab` é responsável pela execução genérica de cenários, concorrência de workers, gravação de artefatos e relatórios. -- o adaptador de transporte é responsável pela configuração do gateway, prontidão, observação de entrada e saída, ações de transporte e estado de transporte normalizado. -- arquivos Markdown de cenário em `qa/scenarios/` definem a execução de teste; `qa-lab` fornece a superfície de runtime reutilizável que os executa. +- `qa-lab` é dono da execução genérica de cenários, concorrência de workers, gravação de artefatos e relatórios. +- o adaptador de transporte é dono da configuração do gateway, prontidão, observação de entrada e saída, ações de transporte e estado de transporte normalizado. +- os arquivos de cenário em Markdown sob `qa/scenarios/` definem a execução de teste; `qa-lab` fornece a superfície de runtime reutilizável que os executa. -A orientação de adoção voltada para maintainers para novos adaptadores de canal está em +A orientação de adoção voltada para mantenedores para novos adaptadores de canal fica em [Testing](/pt-BR/help/testing#adding-a-channel-to-qa). ## Relatórios @@ -173,11 +178,11 @@ O relatório deve responder: - O que funcionou - O que falhou -- O que continuou bloqueado -- Quais cenários de follow-up valem a pena adicionar +- O que permaneceu bloqueado +- Quais cenários de acompanhamento valem a pena adicionar -Para verificações de caráter e estilo, execute o mesmo cenário em várias referências de modelo ao vivo -e gere um relatório em Markdown avaliado: +Para verificações de caráter e estilo, execute o mesmo cenário em várias refs de modelos ao vivo +e grave um relatório em Markdown avaliado: ```bash pnpm openclaw qa character-eval \ @@ -196,36 +201,36 @@ pnpm openclaw qa character-eval \ --judge-concurrency 16 ``` -O comando executa processos filhos locais do gateway de QA, não Docker. Cenários de avaliação -de caráter devem definir a persona por meio de `SOUL.md` e então executar turnos comuns de usuário, -como chat, ajuda de workspace e pequenas tarefas com arquivos. O modelo candidato -não deve ser informado de que está sendo avaliado. O comando preserva cada transcrição -completa, registra estatísticas básicas da execução e então solicita aos modelos juízes em modo rápido com -raciocínio `xhigh` que classifiquem as execuções por naturalidade, vibe e humor. -Use `--blind-judge-models` ao comparar provedores: o prompt do juiz ainda recebe -cada transcrição e status da execução, mas as referências candidatas são substituídas por rótulos neutros -como `candidate-01`; o relatório mapeia as classificações de volta para as referências reais após +O comando executa processos filhos locais do Gateway de QA, não Docker. Os cenários de avaliação de caráter +devem definir a persona por meio de `SOUL.md` e então executar turnos normais de usuário, +como chat, ajuda com workspace e pequenas tarefas em arquivos. O modelo candidato não +deve ser informado de que está sendo avaliado. O comando preserva cada transcrição +completa, registra estatísticas básicas da execução e então pede aos modelos julgadores em modo fast com +raciocínio `xhigh` para classificar as execuções por naturalidade, vibe e humor. +Use `--blind-judge-models` ao comparar provedores: o prompt do julgador ainda recebe +cada transcrição e status de execução, mas as refs dos candidatos são substituídas por rótulos +neutros como `candidate-01`; o relatório mapeia as classificações de volta para as refs reais após a análise. -As execuções de candidatos usam `high` thinking por padrão, com `xhigh` para modelos OpenAI que -o suportam. Substitua um candidato específico inline com -`--model provider/model,thinking=`. `--thinking ` continua definindo um fallback -global, e o formato antigo `--model-thinking ` é mantido por -compatibilidade. -As referências candidatas da OpenAI usam modo rápido por padrão para que o processamento prioritário -seja usado quando o provedor oferecer suporte. Adicione `,fast`, `,no-fast` ou `,fast=false` inline quando -um único candidato ou juiz precisar de uma substituição. Passe `--fast` somente quando quiser -forçar o modo rápido para todos os modelos candidatos. As durações de candidatos e juízes são -registradas no relatório para análise de benchmark, mas os prompts dos juízes dizem explicitamente -para não classificar por velocidade. -As execuções de modelos candidatos e juízes usam concorrência 16 por padrão. Reduza -`--concurrency` ou `--judge-concurrency` quando limites do provedor ou pressão no gateway local -tornarem a execução muito ruidosa. -Quando nenhum `--model` candidato é informado, a avaliação de caráter usa por padrão +As execuções dos candidatos usam `high` thinking por padrão, com `xhigh` para modelos OpenAI que +oferecem suporte. Substitua um candidato específico inline com +`--model provider/model,thinking=`. `--thinking ` ainda define um +fallback global, e o formato antigo `--model-thinking ` é +mantido por compatibilidade. +As refs candidatas OpenAI usam o modo fast por padrão para que o processamento prioritário seja usado onde +o provedor oferecer suporte. Adicione `,fast`, `,no-fast` ou `,fast=false` inline quando um +candidato ou julgador específico precisar de uma substituição. Passe `--fast` apenas quando quiser +forçar o modo fast para todos os modelos candidatos. As durações de candidatos e julgadores são +registradas no relatório para análise de benchmark, mas os prompts dos julgadores dizem explicitamente +para não classificar pela velocidade. +As execuções dos modelos candidatos e julgadores usam concorrência 16 por padrão. Reduza +`--concurrency` ou `--judge-concurrency` quando limites do provedor ou pressão no Gateway local +tornarem uma execução barulhenta demais. +Quando nenhum candidato `--model` é passado, a avaliação de caráter usa por padrão `openai/gpt-5.4`, `openai/gpt-5.2`, `openai/gpt-5`, `anthropic/claude-opus-4-6`, `anthropic/claude-sonnet-4-6`, `zai/glm-5.1`, `moonshot/kimi-k2.5` e -`google/gemini-3.1-pro-preview` quando nenhum `--model` é informado. -Quando nenhum `--judge-model` é informado, os juízes usam por padrão +`google/gemini-3.1-pro-preview` quando nenhum `--model` é passado. +Quando nenhum `--judge-model` é passado, os julgadores usam por padrão `openai/gpt-5.4,thinking=xhigh,fast` e `anthropic/claude-opus-4-6,thinking=high`. diff --git a/docs/pt-BR/help/testing.md b/docs/pt-BR/help/testing.md index 75ea738a2..c6ccb7347 100644 --- a/docs/pt-BR/help/testing.md +++ b/docs/pt-BR/help/testing.md @@ -1,27 +1,27 @@ --- read_when: - - Executando testes localmente ou no CI + - 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, runners Docker e o que cada teste cobre' +summary: 'Kit de testes: suítes unit/e2e/live, executores Docker e o que cada teste cobre' title: Testes x-i18n: - generated_at: "2026-04-12T23:28:28Z" + generated_at: "2026-04-13T05:41:51Z" model: gpt-5.4 provider: openai - source_hash: a66ea672c386094ab4a8035a082c8a85d508a14301ad44b628d2a10d9cec3a52 + source_hash: 3db91b4bc36f626cd014958ec66b08b9cecd9faaa20a5746cd3a49ad4b0b1c38 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 runners Docker. +O OpenClaw tem três suítes Vitest (unit/integration, e2e, live) 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 comuns (local, pré-push, depuração) +- Quais comandos executar para fluxos de trabalho comuns (local, pré-push, depuração) - Como os testes live descobrem credenciais e selecionam modelos/provedores - Como adicionar regressões para problemas reais de modelo/provedor @@ -29,64 +29,139 @@ Este documento é um guia de “como testamos”: Na maioria dos dias: -- Gate completo (esperado antes de fazer push): `pnpm build && pnpm check && pnpm test` -- Execução completa mais rápida da suíte local em uma máquina com bastante recurso: `pnpm test:max` +- 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ões/canais: `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` -- Prefira primeiro execuções direcionadas quando estiver iterando em uma única falha. +- 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` -- Lane de QA com suporte de VM Linux: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` +- Faixa de QA com suporte de VM Linux: `pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` -Quando você mexer nos testes ou quiser mais confiança: +Quando você altera testes ou quer confiança extra: - Gate de cobertura: `pnpm test:coverage` - Suíte E2E: `pnpm test:e2e` Ao depurar provedores/modelos reais (requer credenciais reais): -- Suíte live (modelos + sondas de ferramenta/imagem do Gateway): `pnpm test:live` +- 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` -Dica: quando você só precisa de um caso com falha, prefira restringir os testes live com as variáveis de ambiente de allowlist descritas abaixo. +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. -## Runners específicos de QA +## 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 com suporte 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 contagem de cenários selecionados. Use `--concurrency ` para ajustar a quantidade de workers, ou `--concurrency 1` para a lane serial mais antiga. + - 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. - `pnpm openclaw qa suite --runner multipass` - Executa a mesma suíte de QA dentro de uma VM Linux Multipass descartável. - Mantém o mesmo comportamento de seleção de cenários que `qa suite` no host. - - Reutiliza os mesmos 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 guest: - chaves de provedor baseadas em env, o caminho de configuração do provedor live de QA e `CODEX_HOME`, quando presente. - - Os diretórios de saída precisam permanecer sob a raiz do repositório para que a guest possa gravar de volta por meio do workspace montado. - - Grava o relatório + resumo normais de QA, além dos logs do Multipass, em + - 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. + - 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 `.artifacts/qa-e2e/...`. - `pnpm qa:lab:up` - Inicia o site de QA com suporte de Docker para trabalho de QA no estilo operador. - `pnpm openclaw qa matrix` - - Executa a lane live de QA do Matrix contra um homeserver Tuwunel descartável com suporte de Docker. - - Provisiona três usuários Matrix temporários (`driver`, `sut`, `observer`) mais uma sala privada, depois inicia um processo filho do Gateway de QA com o plugin Matrix real como transporte do SUT. - - Usa por padrão a imagem estável fixa do Tuwunel `ghcr.io/matrix-construct/tuwunel:v1.5.1`. Substitua com `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE` quando precisar testar uma imagem diferente. - - Grava um relatório, resumo e artefato de eventos observados do Matrix QA em `.artifacts/qa-e2e/...`. + - 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/...`. - `pnpm openclaw qa telegram` - - Executa a lane live de QA do Telegram contra um grupo privado real usando os tokens de bot do driver e do SUT vindos do env. - - 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. + - 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. + - 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. - Requer dois bots distintos no mesmo grupo privado, com o bot SUT expondo um nome de usuário do Telegram. - - Para uma observação estável de bot para bot, habilite o Modo de Comunicação Bot-to-Bot em `@BotFather` para ambos os bots e garanta que o bot driver consiga observar o tráfego de bots no grupo. - - Grava um relatório, resumo e artefato de mensagens observadas do Telegram QA em `.artifacts/qa-e2e/...`. + - 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/...`. -As lanes de transporte live compartilham um contrato padrão para que novos transportes não saiam do padrão: +As faixas de transporte live compartilham um contrato padrão para que novos transportes não sofram desvio: `qa-channel` continua sendo a suíte ampla de QA sintética e não faz parte da matriz de cobertura de transporte live. -| Lane | Canary | Gate de menção | Bloco de allowlist | Resposta de nível superior | Retomada após reinício | Follow-up 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 | 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 | + +### 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. + +Estrutura de referência do projeto Convex: + +- `qa/convex-credential-broker/` + +Variáveis de ambiente obrigatórias: + +- `OPENCLAW_QA_CONVEX_SITE_URL` (por exemplo `https://your-deployment.convex.site`) +- Um segredo para o papel selecionado: + - `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` para `maintainer` + - `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`) + +Variáveis de ambiente opcionais: + +- `OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS` (padrão `1200000`) +- `OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS` (padrão `30000`) +- `OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS` (padrão `90000`) +- `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_CONVEX_SITE_URL` deve usar `https://` em operação normal. + +Comandos administrativos de mantenedor (adicionar/remover/listar pool) exigem +`OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` especificamente. + +Helpers de CLI para mantenedores: + +```bash +pnpm openclaw qa credentials add --kind telegram --payload-file qa/telegram-credential.json +pnpm openclaw qa credentials list --kind telegram +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`): + +- `POST /acquire` + - Requisição: `{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }` + - Sucesso: `{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? }` + - Esgotado/repetível: `{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }` +- `POST /heartbeat` + - Requisição: `{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs }` + - Sucesso: `{ status: "ok" }` (ou `2xx` vazio) +- `POST /release` + - Requisição: `{ kind, ownerId, actorRole, credentialId, leaseToken }` + - Sucesso: `{ status: "ok" }` (ou `2xx` vazio) +- `POST /admin/add` (somente segredo de mantenedor) + - Requisição: `{ kind, actorId, payload, note?, status? }` + - Sucesso: `{ status: "ok", credential }` +- `POST /admin/remove` (somente 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) + - Requisição: `{ kind?, status?, includePayload?, limit? }` + - Sucesso: `{ status: "ok", credentials, count }` + +Formato de 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. +- `admin/add` valida esse formato para `kind: "telegram"` e rejeita payloads malformados. ### Adicionando um canal ao QA @@ -95,9 +170,9 @@ 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 runner de QA específico do canal quando o runner compartilhado `qa-lab` puder ser dono do fluxo. +Não adicione um executor de QA específico do canal quando o executor compartilhado `qa-lab` puder assumir o fluxo. -`qa-lab` é dono da mecânica compartilhada: +`qa-lab` é responsável pela mecânica compartilhada: - inicialização e encerramento da suíte - concorrência de workers @@ -106,33 +181,33 @@ Não adicione um runner de QA específico do canal quando o runner compartilhado - execução de cenários - aliases de compatibilidade para cenários antigos de `qa-channel` -O adaptador de canal é dono do contrato de transporte: +O adaptador de canal é responsável pelo contrato de transporte: -- como o Gateway é configurado para esse transporte +- 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 normalizado do transporte são expostos -- como ações com suporte do transporte são executadas -- como reset ou limpeza específicos do transporte são tratados +- 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 -O nível mínimo de adoção para um novo canal é: +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ários para novos cenários. +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. A regra de decisão é estrita: -- Se o comportamento puder ser expresso uma vez no `qa-lab`, coloque-o no `qa-lab`. -- Se o comportamento depender de um transporte de canal, mantenha-o nesse adaptador ou harness de plugin. +- 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 daquele transporte e deixe isso explícito no contrato do cenário. +- 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. -Nomes preferenciais de helpers genéricos para novos cenários: +Os nomes preferidos para novos helpers genéricos de cenário são: - `waitForTransportReady` - `waitForChannelReady` @@ -155,66 +230,66 @@ Aliases de compatibilidade continuam disponíveis para cenários existentes, inc - `formatConversationTranscript` - `resetBus` -Novos trabalhos de canal devem usar os nomes genéricos dos helpers. -Os aliases de compatibilidade existem para evitar uma migração de uma vez só, não como modelo para a criação de novos cenários. +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. ## Suítes de teste (o que roda onde) -Pense nas suítes como “realismo crescente” (e custo/instabilidade crescentes): +Pense nas suítes como “realismo crescente” (e também instabilidade/custo crescentes): ### Unit / integration (padrão) - Comando: `pnpm test` -- Configuração: dez execuções sequenciais em 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 permitidos de `ui` cobertos por `vitest.unit.config.ts` +- 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` - Escopo: - Testes unitários puros - - Testes de integração em processo (auth do Gateway, roteamento, ferramentas, parsing, config) + - Testes de integração in-process (autenticação do gateway, roteamento, ferramentas, parsing, configuração) - Regressões determinísticas para bugs conhecidos - Expectativas: - - Roda em CI + - Executa na CI - Não requer chaves reais - Deve ser rápido e estável - Observação sobre projetos: - - `pnpm test` sem direcionamento agora executa onze configurações menores em shards (`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 deixe outras suítes sem recursos. + - `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 --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 primeiro alvos explícitos de arquivo/diretório por lanes 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 lanes com escopo quando o diff toca apenas arquivos de origem/teste roteáveis; edições de config/setup ainda fazem fallback para a nova execuçã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 lane `unit-fast`, que ignora `test/setup-openclaw-runtime.ts`; arquivos stateful/pesados de runtime permanecem nas lanes existentes. - - Alguns arquivos-fonte auxiliares selecionados de `plugin-sdk` e `commands` também mapeiam execuções em modo changed para testes irmãos explícitos nessas lanes leves, para que edições em helpers evitem reexecutar a suíte pesada completa daquele 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 runner embutido: - - Quando você alterar entradas de descoberta de ferramentas de mensagem ou o contexto de runtime de compaction, + - `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. +- 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. - - Adicione regressões focadas de helper para limites puros de roteamento/normalização. - - Também mantenha saudáveis as suítes de integração do runner embutido: + - 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`, `src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` e `src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`. - - Essas suítes verificam que IDs com escopo e o comportamento de compaction ainda passam - pelos caminhos reais `run.ts` / `compact.ts`; testes apenas de helper não são um + - Essas suítes verificam que ids com escopo e o comportamento de Compaction ainda fluem + pelos caminhos reais de `run.ts` / `compact.ts`; testes apenas de helper não são um 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 runner não isolado nos projetos da raiz, nas configs e2e e live. - - A lane UI da raiz mantém sua configuração e otimizador `jsdom`, mas agora também roda no runner compartilhado não isolado. + - 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. - Cada shard de `pnpm test` herda os mesmos padrões `threads` + `isolate: false` da configuração compartilhada do Vitest. - - O launcher compartilhado `scripts/run-vitest.mjs` agora também adiciona `--no-maglev` por padrão para processos Node filhos do Vitest, para reduzir o 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. + - 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. - Observação sobre iteração local rápida: - - `pnpm test:changed` encaminha por lanes com escopo quando os caminhos alterados mapeiam de forma limpa para uma suíte menor. + - `pnpm test:changed` encaminha por faixas com escopo quando os caminhos alterados mapeiam claramente 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, para que múltiplas execuções simultâneas do Vitest causem menos impacto por padrão. - - A configuração base do Vitest marca os projetos/arquivos de configuração como `forceRerunTriggers` para que novas execuções em modo changed permaneçam corretas quando a fiação de testes muda. + - 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. - 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 relatórios de duração de importação do Vitest mais a saída de detalhamento de importação. - - `pnpm test:perf:imports:changed` limita 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 mostra wall time 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 config raiz do Vitest. + - `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: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: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 runner para a suíte unit com paralelismo de arquivos desabilitado. + - `pnpm test:perf:profile:runner` grava perfis de CPU+heap do executor para a suíte unitária com o paralelismo de arquivos desabilitado. -### E2E (smoke do Gateway) +### E2E (smoke do gateway) - Comando: `pnpm test:e2e` - Configuração: `vitest.e2e.config.ts` @@ -222,15 +297,15 @@ Pense nas suítes como “realismo crescente” (e custo/instabilidade crescente - Padrões de runtime: - Usa `threads` do Vitest com `isolate: false`, em linha com o restante do repositório. - Usa workers adaptativos (CI: até 2, local: 1 por padrão). - - Roda em modo silencioso por padrão para reduzir a sobrecarga de E/S do console. + - Executa em modo silencioso por padrão para reduzir a sobrecarga de E/S no console. - Substituições úteis: - `OPENCLAW_E2E_WORKERS=` para forçar a contagem de workers (limitada a 16). - - `OPENCLAW_E2E_VERBOSE=1` para reativar saída detalhada do console. + - `OPENCLAW_E2E_VERBOSE=1` para reativar 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 networking mais pesado + - Comportamento end-to-end do gateway com múltiplas instâncias + - Superfícies WebSocket/HTTP, pareamento de Node e rede mais pesada - Expectativas: - - Roda em CI (quando habilitado no pipeline) + - Executa 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) @@ -239,14 +314,14 @@ Pense nas suítes como “realismo crescente” (e custo/instabilidade crescente - Comando: `pnpm test:e2e:openshell` - Arquivo: `test/openshell-sandbox.e2e.test.ts` - Escopo: - - Inicia um Gateway OpenShell isolado no host via Docker + - 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` real + execução SSH - - Verifica o comportamento canônico remoto do sistema de arquivos por meio da bridge de fs do sandbox + - 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 - Expectativas: - - Somente opt-in; não faz parte da execução padrão de `pnpm test:e2e` - - Requer uma CLI `openshell` local mais um daemon Docker funcional - - Usa `HOME` / `XDG_CONFIG_HOME` isolados e então destrói o Gateway e o sandbox de teste + - 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 - 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 @@ -259,93 +334,93 @@ Pense nas suítes como “realismo crescente” (e custo/instabilidade crescente - 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, quirks de chamada de ferramentas, problemas de auth e comportamento de limite de taxa + - Detectar mudanças de formato do provedor, peculiaridades de chamada de ferramenta, problemas de autenticação e comportamento de rate limit - Expectativas: - - Não é estável para CI por definição (redes reais, políticas reais de provedor, cotas, indisponibilidades) - - Custa dinheiro / usa limites de taxa - - Prefira executar subconjuntos limitados em vez de “tudo” -- 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/auth para um home temporário de teste para que fixtures unit não alterem seu `~/.openclaw` real. -- Defina `OPENCLAW_LIVE_USE_REAL_HOME=1` apenas 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 de 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 limite de taxa. -- Saída de progresso/heartbeat: - - As suítes live agora emitem linhas de progresso para stderr para que chamadas longas de 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 de provedor/Gateway sejam transmitidas imediatamente durante execuções live. - - Ajuste heartbeats de modelo direto com `OPENCLAW_LIVE_HEARTBEAT_MS`. - - Ajuste heartbeats de Gateway/sonda com `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS`. + - Não é estável em CI por definição (redes reais, políticas reais de provedores, cotas, indisponibilidades) + - Custa dinheiro / usa rate limits + - 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. +- 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. + - Ajuste Heartbeats de modelo direto com `OPENCLAW_LIVE_HEARTBEAT_MS`. + - Ajuste Heartbeats de gateway/probe 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 mudou muita coisa) -- Tocando em networking do Gateway / protocolo WS / pareamento: adicione `pnpm test:e2e` -- Depurando “meu bot caiu” / falhas específicas de provedor / chamada de ferramentas: execute um `pnpm test:live` limitado +- 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 -## Live: varredura de capacidades do Node Android +## Live: varredura de capacidade 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. - Escopo: - - Pré-configurado/manual (a suíte não instala/executa/pareia o app). - - Validação `node.invoke` do Gateway comando por comando para o Node Android selecionado. + - 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 com o Gateway. + - App Android já conectado + pareado ao 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: - `OPENCLAW_ANDROID_NODE_ID` ou `OPENCLAW_ANDROID_NODE_NAME`. - `OPENCLAW_ANDROID_GATEWAY_URL` / `OPENCLAW_ANDROID_GATEWAY_TOKEN` / `OPENCLAW_ANDROID_GATEWAY_PASSWORD`. -- Detalhes completos de configuração do Android: [App Android](/pt-BR/platforms/android) +- Detalhes completos de configuração do Android: [Android App](/pt-BR/platforms/android) ## Live: smoke de modelo (chaves de perfil) Os testes live são divididos em duas camadas para que possamos isolar falhas: -- “Modelo direto” nos diz se o provedor/modelo consegue responder com aquela chave. -- “Smoke do Gateway” nos diz se o pipeline completo de Gateway+agente funciona para aquele modelo (sessões, histórico, ferramentas, política de sandbox etc.). +- “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.). -### Camada 1: completion direta do modelo (sem Gateway) +### Camada 1: conclusão direta de 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 - - Executar uma pequena completion por modelo (e regressões direcionadas quando necessário) + - 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 selecionado de alto sinal; defina `OPENCLAW_LIVE_MAX_MODELS=0` para uma varredura moderna exaustiva ou um número positivo para um limite menor. + - 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. - 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 exigir **apenas armazenamento de perfis** + - Defina `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para impor **somente armazenamento de perfis** - Por que isso existe: - - Separa “a API do provedor está quebrada / a chave é inválida” de “o pipeline do agente Gateway está quebrado” - - Contém regressões pequenas e isoladas (exemplo: replay de reasoning do OpenAI Responses/Codex Responses + fluxos de chamada de ferramentas) + - 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) -### Camada 2: smoke do Gateway + agente dev (o que o "@openclaw" realmente faz) +### Camada 2: smoke do Gateway + agente dev (o que `@openclaw` realmente faz) - Teste: `src/gateway/gateway-models.profiles.live.test.ts` - Objetivo: - - Subir um Gateway em processo - - Criar/aplicar patch em uma sessão `agent:dev:*` (substituição de modelo por execução) - - Iterar pelos modelos com chaves e validar: + - 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: - resposta “significativa” (sem ferramentas) - - 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 → follow-up) continuam funcionando -- Detalhes das sondas (para que você possa explicar falhas rapidamente): - - sonda `read`: o teste grava um arquivo nonce no workspace e pede ao agente para fazer `read` dele e retornar o nonce. - - sonda `exec+read`: o teste pede ao agente para gravar um nonce em um arquivo temporário com `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 `. + - 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 `. - 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) @@ -353,46 +428,46 @@ Os testes live são divididos em duas camadas para que possamos isolar falhas: - 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 selecionado 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 (evitar “OpenRouter tudo”): + - 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”): - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"` (allowlist separada por vírgulas) -- Sondas de ferramenta + imagem estão sempre ativas neste teste live: - - sonda `read` + sonda `exec+read` (stress de ferramentas) - - a sonda de imagem roda quando o modelo anuncia suporte a entrada de imagem +- 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 - Fluxo (alto nível): - - O teste gera um PNG minúsculo com “CAT” + código aleatório (`src/gateway/live-image-probe.ts`) + - O teste gera um PNG pequeno com “CAT” + código aleatório (`src/gateway/live-image-probe.ts`) - Envia via `agent` `attachments: [{ mimeType: "image/png", content: "" }]` - - O Gateway faz parse dos anexos em `images[]` (`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`) - - O agente embutido encaminha uma mensagem de usuário multimodal ao modelo + - 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) -Dica: para ver o que você pode testar na sua máquina (e os IDs exatos `provider/model`), execute: +Dica: para ver o que você pode testar na sua máquina (e os ids exatos `provider/model`), execute: ```bash openclaw models list openclaw models list --json ``` -## Live: smoke do backend CLI (Claude, Codex, Gemini ou outras CLIs locais) +## Live: 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 de Gateway + agente usando um backend CLI local, sem tocar na sua config padrão. -- Os padrões de smoke específicos do backend ficam na definição `cli-backend.ts` da extensão proprietária. +- 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. - 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` - - Comportamento de comando/args/imagem vem dos metadados do plugin proprietário do backend CLI. -- Substituições (opcionais): + - O comportamento de comando/args/imagem vem dos metadados do Plugin proprietário do backend de CLI. +- 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 arquivo de imagem como args da CLI em vez de injeção no prompt. - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"` (ou `"list"`) para controlar como os args de imagem são passados quando `IMAGE_ARG` está definido. + - `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_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 a sonda padrão de continuidade na mesma sessão Claude Sonnet -> Opus (defina como `1` para forçá-la quando o modelo selecionado oferecer suporte a um alvo de troca). + - `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). Exemplo: @@ -408,7 +483,7 @@ Receita Docker: pnpm test:docker:live-cli-backend ``` -Receitas Docker de provedor único: +Receitas Docker para um único provedor: ```bash pnpm test:docker:live-cli-backend:claude @@ -417,23 +492,23 @@ pnpm test:docker:live-cli-backend:codex pnpm test:docker:live-cli-backend:gemini ``` -Observações: +Notas: -- O runner Docker fica em `scripts/test-live-cli-backend-docker.sh`. -- Ele executa o smoke live do backend CLI dentro da imagem Docker do repositório como o usuário não root `node`. -- Ele resolve metadados do smoke da CLI a partir da extensão proprietária e então instala o pacote Linux 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 por meio de `~/.claude/.credentials.json` com `claudeAiOauth.subscriptionType` ou `CLAUDE_CODE_OAUTH_TOKEN` vindo de `claude setup-token`. Primeiro ele prova `claude -p` direto no Docker, depois executa dois turnos do backend CLI do Gateway sem preservar variáveis de env de chave de API da Anthropic. Essa lane de assinatura desabilita por padrão as sondas Claude MCP/tool e de imagem 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 live do backend CLI agora exercita o mesmo fluxo end-to-end para Claude, Codex e Gemini: turno de texto, turno de classificação de imagem e, em seguida, chamada da ferramenta MCP `cron` validada pelo Gateway CLI. -- O smoke padrão do Claude também aplica patch da sessão de Sonnet para Opus e verifica que a sessão retomada ainda se lembra de uma observação anterior. +- 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. ## Live: smoke de bind ACP (`/acp spawn ... --bind here`) - Teste: `src/gateway/gateway-acp-bind.live.test.ts` -- Objetivo: validar o fluxo real de bind de conversa ACP com um agente ACP live: +- Objetivo: validar o fluxo real de conversation-bind do ACP com um agente ACP live: - enviar `/acp spawn --bind here` - - fazer bind de uma conversa sintética de canal de mensagens no lugar - - enviar um follow-up normal nessa mesma conversa - - verificar que o follow-up chega à transcrição da sessão ACP vinculada + - vincular no local uma conversa sintética de canal de mensagens + - enviar um acompanhamento normal nessa mesma conversa + - validar 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` @@ -448,9 +523,9 @@ Observações: - `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@'` -- Observações: - - Essa lane usa a superfície `chat.send` do Gateway com campos sintéticos de rota de origem apenas para administrador 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 embutido de agentes do plugin `acpx` para o agente do harness ACP selecionado. +- 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. Exemplo: @@ -466,7 +541,7 @@ Receita Docker: pnpm test:docker:live-acp-bind ``` -Receitas Docker de agente único: +Receitas Docker para um único agente: ```bash pnpm test:docker:live-acp-bind:claude @@ -474,34 +549,34 @@ pnpm test:docker:live-acp-bind:codex pnpm test:docker:live-acp-bind:gemini ``` -Observações sobre Docker: +Notas sobre Docker: -- O runner Docker fica em `scripts/test-live-acp-bind-docker.sh`. -- Por padrão, ele executa o smoke de bind ACP contra todos os agentes CLI live compatíveis em sequência: `claude`, `codex` e depois `gemini`. +- 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`. - 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 auth da CLI correspondente dentro do 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 runner define `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx` para que o acpx mantenha as variáveis de env 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 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. ## Live: smoke do harness app-server do Codex -- Objetivo: validar o harness do Codex pertencente ao plugin por meio do método - `agent` normal do Gateway: - - carregar o plugin `codex` empacotado +- Objetivo: validar o harness Codex de propriedade do Plugin por meio do método + `agent` normal do gateway: + - carregar o Plugin agrupado `codex` - selecionar `OPENCLAW_AGENT_RUNTIME=codex` - - enviar um primeiro turno de agente do Gateway para `codex/gpt-5.4` - - enviar um segundo turno para a mesma sessão OpenClaw e verificar que a thread do app-server - pode ser retomada - - executar `/codex status` e `/codex models` pelo mesmo caminho - de comando do Gateway + - 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 + 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` -- Sonda de imagem opcional: `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1` -- Sonda opcional de MCP/ferramenta: `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1` +- 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 - com problema não consiga passar ao fazer fallback silencioso para PI. -- Auth: `OPENAI_API_KEY` do shell/profile, mais os opcionais copiados - `~/.codex/auth.json` e `~/.codex/config.toml` + 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 Receita local: @@ -521,62 +596,65 @@ source ~/.profile pnpm test:docker:live-codex-harness ``` -Observações sobre Docker: +Notas sobre Docker: -- O runner Docker fica em `scripts/test-live-codex-harness-docker.sh`. -- Ele carrega o `~/.profile` montado, passa `OPENAI_API_KEY`, copia arquivos de auth da CLI Codex quando presentes, instala `@openai/codex` em um prefixo npm montado e gravável, prepara a árvore-fonte e então executa apenas o teste live do harness Codex. -- O Docker habilita por padrão as sondas de imagem e MCP/ferramenta. Defina +- 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 `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 config - do teste live para que fallback para `openai-codex/*` ou PI não consiga esconder uma regressão do harness Codex. +- 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. ### Receitas live recomendadas Allowlists restritas e explícitas são mais rápidas e menos instáveis: -- Modelo único, direto (sem Gateway): +- Modelo único, direto (sem gateway): - `OPENCLAW_LIVE_MODELS="openai/gpt-5.4" pnpm test:live src/agents/models.profiles.live.test.ts` -- Modelo único, smoke do Gateway: +- 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 ferramentas em vários provedores: +- Chamada de ferramenta 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): - 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` -Observações: +Notas: - `google/...` usa a API Gemini (chave de API). -- `google-antigravity/...` usa a bridge OAuth Antigravity (endpoint de agente no estilo Cloud Code Assist). -- `google-gemini-cli/...` usa a CLI Gemini local na sua máquina (auth separada + quirks próprios de tooling). +- `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). - API Gemini vs CLI Gemini: - - API: o OpenClaw chama a API Gemini hospedada do Google via HTTP (auth por chave de API / perfil); é isso que a maioria dos usuários quer dizer com “Gemini”. - - CLI: o OpenClaw executa um binário `gemini` local; ele tem sua própria auth e pode se comportar de forma diferente (streaming/suporte a ferramentas/descompasso de versão). + - 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). ## Live: matriz de modelos (o que cobrimos) -Não existe uma “lista fixa de modelos de 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 da CI” (live é opt-in), mas estes são os modelos **recomendados** para cobrir regularmente em uma máquina de desenvolvimento com chaves. -### Conjunto smoke moderno (chamada de ferramentas + imagem) +### Conjunto de smoke moderno (chamada de ferramenta + 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 antigos Gemini 2.x) +- Google (API Gemini): `google/gemini-3.1-pro-preview` e `google/gemini-3-flash-preview` (evite modelos Gemini 2.x mais antigos) - 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` -Execute o smoke do Gateway com ferramentas + imagem: +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 ferramentas (Read + Exec opcional) +### Linha de base: chamada de ferramenta (Read + Exec opcional) Escolha pelo menos um por família de provedor: @@ -588,28 +666,28 @@ Escolha pelo menos um por família de provedor: Cobertura adicional opcional (bom ter): -- xAI: `xai/grok-4` (ou o mais recente disponível) -- Mistral: `mistral/`… (escolha um modelo com suporte a “tools” que você tenha habilitado) +- xAI: `xai/grok-4` (ou a versã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 ferramentas depende do modo da API) +- LM Studio: `lmstudio/`… (local; a chamada de ferramenta 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` (Claude/Gemini/variantes OpenAI com suporte a visão etc.) para exercitar a sonda de imagem. +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. ### Agregadores / gateways alternativos 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 suporte a tool+image) -- OpenCode: `opencode/...` para Zen e `opencode-go/...` para Go (auth via `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY`) +- 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/config): +Mais provedores que você pode incluir na matriz live (se tiver credenciais/configuração): -- Integrados: `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` (cloud/API), além de qualquer proxy compatível com OpenAI/Anthropic (LM Studio, vLLM, LiteLLM etc.) +- 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 fixar “todos os modelos” na documentação. A lista autoritativa é tudo o que `discoverModels(...)` retornar na sua máquina + todas as chaves disponíveis. +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. ## Credenciais (nunca faça commit) @@ -618,57 +696,57 @@ Os testes live descobrem credenciais da mesma forma que a CLI. Implicações pr - 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. -- Perfis de auth por agente: `~/.openclaw/agents//agent/auth-profiles.json` (é isso que “chaves de perfil” significa nos testes live) -- Config: `~/.openclaw/openclaw.json` (ou `OPENCLAW_CONFIG_PATH`) +- Perfis de autenticação por agente: `~/.openclaw/agents//agent/auth-profiles.json` (é isso que “profile keys” significa nos testes live) +- 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 config ativa, os arquivos `auth-profiles.json` por agente, o `credentials/` legado e diretórios de auth externos compatíveis para um home temporário de teste; os homes live preparados ignoram `workspace/` e `sandboxes/`, e substituições de caminho `agents.*.workspace` / `agentDir` são removidas para que as sondas fiquem fora do seu workspace real do host. +- 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. -Se você quiser depender de chaves em env (por exemplo, exportadas no seu `~/.profile`), execute os testes locais depois de `source ~/.profile`, ou use os runners Docker abaixo (eles podem montar `~/.profile` no contêiner). +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). -## Live Deepgram (transcrição de áudio) +## Live 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 BytePlus coding plan +## Live 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 de workflow do ComfyUI +## Live de mídia do fluxo de trabalho do 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 empacotados do comfy para imagem, vídeo e `music_generate` + - 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 workflow do comfy, polling, downloads ou registro de plugin + - Útil após alterar envio de fluxo de trabalho do comfy, polling, downloads ou registro de Plugin -## Live de geração de imagens +## Live de geração de imagem - 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 todos os plugins de provedores de geração de imagem registrados - - Carrega variáveis de env de provedores ausentes do seu shell de login (`~/.profile`) antes de sondar - - Usa chaves de API live/env antes dos perfis de auth armazenados por padrão, para que chaves de teste obsoletas em `auth-profiles.json` não escondam credenciais reais do shell - - Ignora provedores sem auth/perfil/modelo utilizável - - Executa as variantes padrão de geração de imagens pela capacidade compartilhada de runtime: + - 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 + - Ignora provedores sem autenticação/perfil/modelo utilizável + - Executa as variantes padrão de geração de imagem pela capacidade compartilhada de runtime: - `google:flash-generate` - `google:pro-generate` - `google:pro-edit` - `openai:default-generate` -- Provedores empacotados atualmente cobertos: +- Provedores agrupados atualmente cobertos: - `openai` - `google` - Restrição opcional: - `OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS="openai,google"` - `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 auth: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para forçar auth do armazenamento de perfis e ignorar substituições apenas por env +- 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 ## Live de geração de música @@ -676,23 +754,23 @@ Se você quiser depender de chaves em env (por exemplo, exportadas no seu `~/.pr - 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 empacotado de provedores de geração de música + - Exercita o caminho compartilhado agrupado de provedor de geração de música - Atualmente cobre Google e MiniMax - - Carrega variáveis de env de provedores do seu shell de login (`~/.profile`) antes de sondar - - Usa chaves de API live/env antes dos perfis de auth armazenados por padrão, para que chaves de teste obsoletas em `auth-profiles.json` não escondam credenciais reais do shell - - Ignora provedores sem auth/perfil/modelo utilizável + - 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 + - Ignora provedores sem autenticação/perfil/modelo utilizável - Executa ambos os modos de runtime declarados quando disponíveis: - - `generate` com entrada apenas por prompt + - `generate` com entrada somente de prompt - `edit` quando o provedor declara `capabilities.edit.enabled` - - Cobertura atual da lane compartilhada: + - Cobertura atual da faixa compartilhada: - `google`: `generate`, `edit` - `minimax`: `generate` - `comfy`: arquivo live 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 auth: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para forçar auth do armazenamento de perfis e ignorar substituições apenas por env +- 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 ## Live de geração de vídeo @@ -700,166 +778,166 @@ Se você quiser depender de chaves em env (por exemplo, exportadas no seu `~/.pr - 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 empacotado de provedores de geração de vídeo - - Carrega variáveis de env de provedores do seu shell de login (`~/.profile`) antes de sondar - - Usa chaves de API live/env antes dos perfis de auth armazenados por padrão, para que chaves de teste obsoletas em `auth-profiles.json` não escondam credenciais reais do shell - - Ignora provedores sem auth/perfil/modelo utilizável + - 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 + - Ignora provedores sem autenticação/perfil/modelo utilizável - Executa ambos os modos de runtime declarados quando disponíveis: - - `generate` com entrada apenas por prompt - - `imageToVideo` quando o provedor declara `capabilities.imageToVideo.enabled` e o provedor/modelo selecionado aceita entrada local baseada em buffer na varredura compartilhada - - `videoToVideo` quando o provedor declara `capabilities.videoToVideo.enabled` e o provedor/modelo selecionado aceita entrada local baseada em buffer na varredura compartilhada - - Provedores atualmente declarados, mas ignorados em `imageToVideo` na varredura compartilhada: - - `vydra` porque o `veo3` empacotado é apenas texto e o `kling` empacotado exige uma URL de imagem remota - - Cobertura específica de provedor Vydra: + - `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: - `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 lane `kling` que usa por padrão um fixture de URL de imagem remota + - 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`: - - apenas `runway` quando o modelo selecionado é `runway/gen4_aleph` - - Provedores atualmente declarados, mas ignorados em `videoToVideo` na varredura compartilhada: + - `runway` apenas 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 lane Gemini/Veo compartilhada atual usa entrada local baseada em buffer e esse caminho não é aceito na varredura compartilhada - - `openai` porque a lane compartilhada atual não garante acesso específico por organização a inpaint/remix de vídeo + - `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 - 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"` -- Comportamento opcional de auth: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` para forçar auth do armazenamento de perfis e ignorar substituições apenas por env +- 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 ## Harness live de mídia - Comando: `pnpm test:live:media` -- Finalidade: - - Executa as suítes live compartilhadas de imagem, música e vídeo por um único entrypoint nativo do repositório - - Carrega automaticamente variáveis de env ausentes de provedores a partir de `~/.profile` - - Restringe automaticamente por padrão cada suíte aos provedores que atualmente têm auth utilizável - - Reutiliza `scripts/test-live.mjs`, para que o comportamento de heartbeat e modo silencioso permaneça consistente +- Objetivo: + - Executa as suítes live compartilhadas de imagem, música e vídeo por um único ponto de entrada 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 + - Reutiliza `scripts/test-live.mjs`, para que o comportamento de Heartbeat e modo silencioso permaneça consistente - Exemplos: - `pnpm test:live:media` - `pnpm test:live:media image video --providers openai,google,minimax` - `pnpm test:live:media video --video-providers openai,runway --all-providers` - `pnpm test:live:media music --quiet` -## Runners Docker (verificações opcionais de "funciona no Linux") +## Executores Docker (verificações opcionais de “funciona em Linux”) -Esses runners Docker se dividem em dois grupos: +Esses executores Docker se dividem em dois grupos: -- Runners de 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 de config 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 runners live em Docker usam por padrão um limite smoke menor para que uma varredura Docker completa continue prática: +- 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: `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 env quando - quiser explicitamente a varredura maior e exaustiva. -- `test:docker:all` constrói a imagem Docker live uma vez via `test:docker:live-build` e então a reutiliza para as duas lanes live em Docker. -- Runners 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. + `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. -Os runners Docker de live-model também fazem bind-mount apenas dos homes de auth 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 da CLI externa possa atualizar tokens sem alterar o armazenamento de auth do host: +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: - 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 backend CLI: `pnpm test:docker:live-cli-backend` (script: `scripts/test-live-cli-backend-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`) - Assistente de onboarding (TTY, scaffolding completo): `pnpm test:docker:onboard` (script: `scripts/e2e/onboard-docker.sh`) -- Networking do Gateway (dois contêineres, auth WS + health): `pnpm test:docker:gateway-network` (script: `scripts/e2e/gateway-network-docker.sh`) -- Bridge de canal MCP (Gateway semeado + bridge stdio + smoke bruto de frame de notificação do Claude): `pnpm test:docker:mcp-channels` (script: `scripts/e2e/mcp-channels-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`) -Os runners Docker de live-model 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 e ainda assim executa o Vitest contra seu código-fonte/config local exato. -A etapa de preparação ignora grandes caches apenas locais e saídas de build de apps, como -`.pnpm-store`, `.worktrees`, `__openclaw_vitest__` e diretórios locais de saída `.build` ou +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 artefatos específicos da máquina. -Eles também definem `OPENCLAW_SKIP_CHANNELS=1` para que sondas live do Gateway não iniciem -workers reais de canais Telegram/Discord/etc. dentro do contêiner. +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 cobertura live do Gateway -dessa lane Docker. +`OPENCLAW_LIVE_GATEWAY_*` quando precisar restringir ou excluir a cobertura live +do gateway dessa faixa Docker. `test:docker:openwebui` é um smoke de compatibilidade de nível mais alto: ele inicia um -contêiner do Gateway OpenClaw com os endpoints HTTP compatíveis com OpenAI habilitados, -inicia um contêiner fixo do Open WebUI contra esse Gateway, faz login pelo -Open WebUI, verifica se `/api/models` expõe `openclaw/default` e então envia uma +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 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 terminar sua própria configuração de cold start. -Essa lane espera uma chave de modelo live utilizável, e `OPENCLAW_PROFILE_FILE` -(`~/.profile` por padrão) é a forma principal de fornecê-la em execuções Dockerizadas. -Execuções bem-sucedidas imprimem um pequeno payload JSON como `{ "ok": true, "model": +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` +(`~/.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 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 live, roteamento de envio de saída e notificações +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 +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. 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 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 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. -Variáveis de env úteis: +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 CLI em cache dentro do Docker -- Diretórios/arquivos de auth de CLI externa sob `$HOME` são montados como somente leitura em `/host-auth...` e então copiados para `/home/node/...` antes de os testes começarem +- `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 - 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 de provedor restrito montam apenas os diretórios/arquivos necessários inferidos de `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` + - Execuções restritas por provedor montam apenas os diretórios/arquivos necessários inferidos de `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` - Substitua manualmente com `OPENCLAW_DOCKER_AUTH_DIRS=all`, `OPENCLAW_DOCKER_AUTH_DIRS=none` ou uma lista separada por vírgulas como `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex` - `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 precisam de rebuild -- `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_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_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 fixa do Open WebUI +- `OPENWEBUI_IMAGE=...` para substituir a tag de imagem fixada do Open WebUI ## Sanidade da documentação -Execute as verificações de documentação após editar docs: `pnpm check:docs`. -Execute a validação completa de âncoras do Mintlify quando também precisar de verificações de títulos na página: `pnpm docs:check-links:anchors`. +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`. ## Regressão offline (segura para CI) Estas são regressões de “pipeline real” sem provedores reais: -- Chamada de ferramentas do Gateway (OpenAI simulado, Gateway real + loop do 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 config + auth obrigatórios): `src/gateway/gateway.test.ts` (caso: "runs wizard over ws and writes auth token config") +- 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") -## Avaliações de confiabilidade do agente (Skills) +## Evals de confiabilidade do agente (Skills) -Já temos alguns testes seguros para CI que se comportam como “avaliações de confiabilidade do agente”: +Já temos alguns testes seguros para CI que se comportam como “evals de confiabilidade do agente”: -- Chamada simulada de ferramentas pelo Gateway real + loop do agente (`src/gateway/gateway.test.ts`). -- Fluxos end-to-end do assistente que validam a fiação da sessão e os efeitos de config (`src/gateway/gateway.test.ts`). +- 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`). 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 certa (ou evita as irrelevantes)? -- **Conformidade:** o agente lê `SKILL.md` antes de usar e segue as etapas/args obrigatórios? -- **Contratos de workflow:** cenários de múltiplos turnos que validam ordem de ferramentas, persistência de histórico de sessão e limites de sandbox. +- **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. -As futuras avaliações devem continuar determinísticas primeiro: +Evals futuros devem continuar determinísticos primeiro: -- Um runner de cenários usando provedores simulados para validar chamadas de ferramentas + ordem, leituras de arquivos de skill e fiação de sessão. -- Um pequeno conjunto de cenários focados em skills (usar vs evitar, gate, injeção de prompt). -- Avaliações live opcionais (opt-in, controladas por env) apenas depois que a suíte segura para CI estiver pronta. +- 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. -## Testes de contrato (forma de plugin e canal) +## Testes de contrato (formato de Plugin e canal) -Os 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 -validações de forma e comportamento. A lane unit padrão de `pnpm test` intencionalmente -ignora esses arquivos compartilhados de seam e smoke; execute os comandos de contrato explicitamente +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. ### Comandos @@ -872,53 +950,53 @@ quando tocar em superfícies compartilhadas de canal ou provedor. Localizados em `src/channels/plugins/contracts/*.contract.test.ts`: -- **plugin** - Forma básica do plugin (id, nome, capacidades) +- **plugin** - Formato básico do Plugin (id, nome, capacidades) - **setup** - Contrato do assistente de configuração -- **session-binding** - Comportamento de binding de sessão -- **outbound-payload** - Estrutura da carga de mensagem -- **inbound** - Tratamento de mensagens de entrada -- **actions** - Handlers de ações do canal -- **threading** - Tratamento de ID de thread +- **session-binding** - Comportamento de vinculação de sessão +- **outbound-payload** - Estrutura de payload de mensagem +- **inbound** - Manipulação de mensagens de entrada +- **actions** - Handlers de ação de canal +- **threading** - Manipulação de id de thread - **directory** - API de diretório/lista - **group-policy** - Aplicação de política de grupo -### Contratos de status de provedor +### Contratos de status do provedor Localizados em `src/plugins/contracts/*.contract.test.ts`. -- **status** - Sondas de status de canal -- **registry** - Forma do registro de plugins +- **status** - Probes de status de canal +- **registry** - Formato do registro de Plugins ### Contratos de provedor Localizados em `src/plugins/contracts/*.contract.test.ts`: -- **auth** - Contrato do fluxo de auth -- **auth-choice** - Escolha/seleção de auth +- **auth** - Contrato do fluxo de autenticação +- **auth-choice** - Escolha/seleção de autenticação - **catalog** - API de catálogo de modelos -- **discovery** - Descoberta de plugins -- **loader** - Carregamento de plugins +- **discovery** - Descoberta de Plugin +- **loader** - Carregamento de Plugin - **runtime** - Runtime do provedor -- **shape** - Forma/interface do plugin +- **shape** - Formato/interface do Plugin - **wizard** - Assistente de configuração ### Quando executar -- Depois de alterar exports ou subpaths do Plugin SDK -- Depois de adicionar ou modificar um plugin de canal ou provedor -- Depois de refatorar registro ou descoberta de plugin +- Após alterar exports ou subpaths do plugin-sdk +- Após adicionar ou modificar um Plugin de canal ou provedor +- Após refatorar registro ou descoberta de Plugin -Os testes de contrato rodam em CI e não requerem chaves de API reais. +Os testes de contrato executam na CI e não exigem chaves reais de API. ## Adicionando regressões (orientação) -Quando você corrigir um problema de provedor/modelo descoberto em live: +Ao corrigir um problema de provedor/modelo descoberto em live: - 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 (limites de taxa, políticas de auth), mantenha o teste live restrito e opt-in por meio de variáveis de env -- Prefira mirar na menor camada que detecta o bug: - - bug de conversão/replay de requisição do provedor → teste de modelos diretos - - bug do pipeline de sessão/histórico/ferramentas do Gateway → smoke live do Gateway ou teste mock do Gateway seguro para CI -- Guardrail de travessia de SecretRef: - - `src/secrets/exec-secret-ref-id-parity.test.ts` deriva um alvo de amostra por classe de SecretRef a partir dos metadados do registro (`listSecretTargetRegistryEntries()`), então valida que ids de exec de segmento de travessia são rejeitados. - - Se você adicionar uma nova família de alvo 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 em silêncio. +- 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.