Gateway
Backends de CLI
OpenClaw pode executar uma CLI de IA local como alternativa somente de texto quando os provedores de API estão indisponíveis, sujeitos a limites de taxa ou apresentando mau funcionamento. Essa alternativa é intencionalmente conservadora:
- As ferramentas do OpenClaw não são injetadas diretamente, mas um backend com
bundleMcp: truepode receber ferramentas do Gateway por meio de uma ponte MCP de loopback. - Streaming JSONL para CLIs compatíveis.
- Há suporte a sessões, portanto, os turnos subsequentes permanecem coerentes.
- As imagens são repassadas se a CLI aceitar caminhos de imagem.
Use essa alternativa como uma rede de segurança para respostas de texto que "sempre funcionam", não como caminho principal. Para um runtime de harness completo com controles de sessão ACP, tarefas em segundo plano, vinculação de thread/conversa e sessões externas persistentes de programação, use Agentes ACP; backends de CLI não são ACP.
Início rápido
O Plugin Anthropic incluído registra um backend claude-cli padrão, portanto, ele funciona sem nenhuma configuração além de ter o Claude Code instalado e com login realizado:
openclaw agent --agent main --message "hi" --model claude-cli/claude-sonnet-4-6main é o ID de agente padrão quando nenhuma lista explícita de agentes está configurada; caso contrário, substitua-o pelo seu próprio ID de agente.
Se o Gateway for executado pelo launchd/systemd com um PATH mínimo, especifique explicitamente o caminho para o binário:
{ agents: { defaults: { cliBackends: { "claude-cli": { command: "/opt/homebrew/bin/claude", }, }, }, },}Se você usar um backend de CLI incluído como provedor principal de mensagens em um host do Gateway, o OpenClaw carregará automaticamente o Plugin incluído que o controla quando sua configuração referenciar esse backend em uma referência de modelo ou em agents.defaults.cliBackends.
Uso como alternativa
Adicione o backend de CLI à sua lista de alternativas para que ele seja executado somente quando os modelos principais falharem:
{ agents: { defaults: { model: { primary: "anthropic/claude-opus-4-6", fallbacks: ["claude-cli/claude-sonnet-4-6"], }, models: { "anthropic/claude-opus-4-6": { alias: "Opus" }, "claude-cli/claude-sonnet-4-6": {}, }, }, },}Se você usar agents.defaults.models como lista de permissões, inclua também nela os modelos do seu backend de CLI. Quando o provedor principal falha (autenticação, limites de taxa, tempos limite), o OpenClaw tenta o backend de CLI em seguida.
Configuração
Todos os backends de CLI ficam em agents.defaults.cliBackends, indexados pelo ID do provedor (por exemplo, claude-cli, my-cli). O ID do provedor se torna o lado esquerdo da referência do modelo: <provider>/<model>.
{ agents: { defaults: { cliBackends: { "my-cli": { command: "my-cli", args: ["--json"], output: "json", input: "arg", modelArg: "--model", modelAliases: { "claude-opus-4-6": "opus", "claude-sonnet-4-6": "sonnet", }, sessionArg: "--session", sessionMode: "existing", sessionIdFields: ["session_id", "conversation_id"], systemPromptArg: "--system", // Sinalizador dedicado de arquivo de prompt: // systemPromptFileArg: "--system-file", // Em vez disso, sinalizador de substituição de configuração no estilo do Codex: // systemPromptFileConfigArg: "-c", // systemPromptFileConfigKey: "model_instructions_file", systemPromptWhen: "first", imageArg: "--image", imageMode: "repeat", // Ative somente se este backend puder reinicializar sessões invalidadas // usando o histórico bruto e limitado da transcrição do OpenClaw antes da Compaction. reseedFromRawTranscriptWhenUncompacted: true, serialize: true, }, }, }, },}Como funciona
- Seleciona um backend pelo prefixo do provedor (
claude-cli/...). - Cria um prompt de sistema usando o mesmo prompt e contexto do espaço de trabalho do OpenClaw.
- Executa a CLI com um ID de sessão (se houver suporte) para manter o histórico consistente. O backend
claude-cliincluído mantém um processo stdio do Claude ativo por sessão do OpenClaw e envia turnos subsequentes pela entrada padrão stream-json. - Analisa a saída (JSON ou texto simples) e retorna o texto final.
- Persiste IDs de sessão por backend para que os turnos subsequentes reutilizem a mesma sessão da CLI.
Particularidades da CLI do Claude
O backend claude-cli incluído prioriza o resolvedor nativo de Skills do Claude Code. Quando o snapshot atual de Skills tem pelo menos uma Skill selecionada com um caminho materializado, o OpenClaw transmite um Plugin temporário do Claude Code por meio de --plugin-dir e omite do prompt de sistema anexado o catálogo duplicado de Skills do OpenClaw. Sem uma Skill de Plugin materializada, o OpenClaw mantém o catálogo do prompt como alternativa. As substituições de variáveis de ambiente/chaves de API das Skills ainda se aplicam ao ambiente do processo filho durante a execução.
A CLI do Claude tem seu próprio modo de permissão não interativo; o OpenClaw o mapeia para a política de execução existente, em vez de adicionar uma configuração específica do Claude. Para sessões ativas do Claude gerenciadas pelo OpenClaw, a política de execução efetiva é determinante: YOLO (tools.exec.security: "full" e tools.exec.ask: "off") normalmente inicia o Claude com --permission-mode bypassPermissions, enquanto uma política restritiva o inicia com --permission-mode default. Gateways executados como root também usam default, pois o Claude Code rejeita o modo de desvio para root; o OpenClaw ainda responde às solicitações de controle de ferramentas via stdio do Claude de acordo com a política de execução configurada. As configurações agents.list[].tools.exec por agente substituem o tools.exec global para esse agente. Os argumentos brutos do backend ainda podem incluir --permission-mode, mas as inicializações ativas do Claude normalizam esse sinalizador para corresponder à política efetiva e à restrição do host.
O backend também mapeia os níveis /think do OpenClaw para o sinalizador nativo --effort do Claude Code: minimal/low -> low, medium -> medium, e high/xhigh/max são repassados diretamente. Isso mantém os níveis de esforço compatíveis do Fable 5 iguais nas rotas da CLI do Claude baseadas em assinatura e nas rotas de chave de API. adaptive remove os sinalizadores --effort configurados e não fornece substituto, portanto, o Claude Code determina o esforço efetivo com base em seu próprio ambiente, suas configurações e os padrões do modelo. Outros backends de CLI precisam que o Plugin responsável declare um mapeador de argv equivalente antes que /think afete a CLI iniciada.
Antes que o OpenClaw possa usar claude-cli, o próprio Claude Code precisa estar autenticado no mesmo host:
claude auth loginclaude auth status --textopenclaw models auth login --provider anthropic --method cli --set-defaultInstalações com Docker precisam ter o Claude Code instalado e autenticado no diretório inicial persistente do contêiner, não apenas no host; consulte Backend da CLI do Claude no Docker.
Defina agents.defaults.cliBackends.claude-cli.command somente quando o binário claude ainda não estiver em PATH.
Sessões
- Se a CLI for compatível com sessões, defina
sessionArg(por exemplo,--session-id) ousessionArgs(placeholder{sessionId}) quando o ID precisar ser inserido em vários sinalizadores. - Se a CLI usar um subcomando de retomada com sinalizadores diferentes, defina
resumeArgs(substituiargsao retomar) e, opcionalmente,resumeOutputpara retomadas que não sejam JSON. sessionMode:always: sempre envia um ID de sessão (um novo UUID se nenhum estiver armazenado).existing: envia um ID de sessão somente se já houver um armazenado.none: nunca envia um ID de sessão.
claude-cliusa por padrãoliveSession: "claude-stdio",output: "jsonl"einput: "stdin", portanto, os turnos subsequentes reutilizam o processo ativo do Claude enquanto ele estiver em execução, inclusive em configurações personalizadas que omitam campos de transporte. Se o Gateway for reiniciado ou o processo ocioso for encerrado, o OpenClaw retomará a partir do ID de sessão armazenado do Claude. Os IDs de sessão armazenados são verificados em relação a uma transcrição de projeto legível antes da retomada; a ausência de uma transcrição remove a vinculação (registrada comoreason=transcript-missing) em vez de iniciar silenciosamente uma nova sessão em--resume.- As sessões ativas do Claude mantêm proteções limitadas para a saída JSONL: 8 MiB e 20,000 linhas JSONL brutas por turno, por padrão. Aumente esses valores por backend com
agents.defaults.cliBackends.claude-cli.reliability.outputLimits.maxTurnRawCharsemaxTurnLines; o OpenClaw limita essas configurações a 64 MiB e 100,000 linhas. - As sessões de CLI armazenadas são uma continuidade controlada pelo provedor. A redefinição diária implícita da sessão não as interrompe;
/resete políticas explícitas desession.resetainda o fazem. - Novas sessões de CLI normalmente são reinicializadas somente com o resumo de Compaction do OpenClaw e o trecho posterior à Compaction. Para recuperar sessões curtas invalidadas antes da Compaction, um backend pode ativar
reseedFromRawTranscriptWhenUncompacted: true. A reinicialização pela transcrição bruta permanece limitada e restrita a invalidações seguras, como ausência de transcrição da CLI, trecho órfão de uso de ferramenta, alterações na política de mensagens/no prompt de sistema/no cwd/no MCP ou uma nova tentativa após expiração da sessão; alterações no perfil de autenticação ou na época das credenciais nunca reinicializam o histórico bruto da transcrição.
Serialização: serialize: true mantém as execuções da mesma faixa em ordem (a maioria das CLIs serializa em uma única faixa do provedor). O OpenClaw também deixa de reutilizar a sessão de CLI armazenada quando a identidade de autenticação selecionada muda, incluindo alteração do ID do perfil de autenticação, da chave de API estática, do token estático ou da identidade da conta OAuth quando a CLI disponibiliza uma; a simples rotação de tokens OAuth de acesso/atualização não interrompe a sessão. Se uma CLI não tiver um ID estável de conta OAuth, o OpenClaw permite que essa CLI aplique suas próprias permissões de retomada.
Preâmbulo de alternativa proveniente de sessões claude-cli
Quando uma tentativa claude-cli alterna para um candidato que não seja CLI em agents.defaults.model.fallbacks, o OpenClaw inicializa a próxima tentativa com um preâmbulo de contexto coletado da transcrição JSONL local do Claude Code (em ~/.claude/projects/, indexado por espaço de trabalho). Sem essa inicialização, o provedor alternativo começa sem contexto, pois a própria transcrição de sessão do OpenClaw está vazia para execuções claude-cli.
- O preâmbulo prioriza o resumo
/compactou o marcadorcompact_boundarymais recente e, em seguida, anexa os turnos mais recentes após o limite até atingir um orçamento de caracteres. Os turnos anteriores ao limite são descartados porque o resumo já os representa. - Os blocos de ferramentas são agrupados em dicas compactas
(tool call: name)e(tool result: …)para manter o orçamento do prompt preciso; um resumo grande demais é truncado e rotulado como(truncated). - Alternativas do mesmo provedor de
claude-cliparaclaude-clidependem do próprio--resumedo Claude e ignoram o preâmbulo. - A inicialização reutiliza a validação existente do caminho do arquivo de sessão do Claude, portanto, não é possível ler caminhos arbitrários.
Imagens
Se sua CLI aceitar caminhos de imagem, defina imageArg:
imageArg: "--image",imageMode: "repeat"O OpenClaw grava imagens em base64 em arquivos temporários. Se imageArg estiver definido, esses caminhos serão transmitidos como argumentos da CLI; caso contrário, o OpenClaw anexará os caminhos dos arquivos ao prompt (injeção de caminho), o que funciona com CLIs que carregam automaticamente arquivos locais a partir de caminhos simples.
Entradas e saídas
output: "text"(padrão) trata stdout como a resposta final.output: "json"tenta analisar JSON e extrair o texto e um ID de sessão.output: "jsonl"analisa um fluxo JSONL e extrai a mensagem final do agente e os identificadores de sessão, quando presentes.- Para a saída JSON da CLI do Gemini, o OpenClaw lê o texto da resposta em
responsee o uso emstatsquandousageestá ausente ou vazio. O padrão incluído da CLI do Gemini usastream-json; substituições antigas de--output-format jsonainda usam o analisador JSON.
Modos de entrada:
input: "arg"(padrão) passa o prompt como o último argumento da CLI.input: "stdin"envia o prompt via stdin.- Se o prompt for muito longo e
maxPromptArgCharsestiver definido, stdin será usado em vez disso.
Padrões pertencentes ao plugin
Os padrões do backend da CLI fazem parte da superfície do plugin:
- Os plugins os registram com
api.registerCliBackend(...). - O
iddo backend se torna o prefixo do provedor nas referências de modelo. - A configuração do usuário em
agents.defaults.cliBackends.<id>ainda substitui o padrão do plugin. - A limpeza de configuração específica do backend continua pertencendo ao plugin por meio do gancho opcional
normalizeConfig.
A Anthropic é responsável por claude-cli, e o Google é responsável por google-gemini-cli. As execuções do agente OpenAI Codex usam o harness do servidor de aplicativo Codex por meio de openai/*; o OpenClaw não registra mais um backend codex-cli incluído.
O plugin Anthropic incluído registra o seguinte para claude-cli:
| Chave | Valor |
|---|---|
command |
claude |
args |
-p --output-format stream-json --include-partial-messages --verbose --setting-sources user --allowedTools mcp__openclaw__* --disallowedTools ScheduleWakeup,CronCreate,Bash(run_in_background:true),Monitor |
output |
jsonl |
input |
stdin |
modelArg |
--model |
sessionArg |
--session-id |
sessionMode |
always |
imageArg |
@ |
imagePathScope |
workspace |
systemPromptFileArg |
--append-system-prompt-file |
systemPromptMode |
append |
O plugin Google incluído registra o seguinte para google-gemini-cli:
| Chave | Valor |
|---|---|
command |
gemini |
args |
--skip-trust --approval-mode auto_edit --output-format stream-json --prompt {prompt} |
resumeArgs |
o mesmo, com --resume {sessionId} |
output / resumeOutput |
jsonl |
jsonlDialect |
gemini-stream-json |
imageArg |
@ |
imagePathScope |
workspace |
modelArg |
--model |
sessionMode |
existing |
sessionIdFields |
["session_id", "sessionId"] |
Pré-requisito: a Gemini CLI local deve estar instalada e disponível em PATH como gemini (brew install gemini-cli ou npm install -g @google/gemini-cli).
Observações sobre a saída da Gemini CLI:
- O analisador
stream-jsonpadrão lê eventosmessagedo assistente, eventos de ferramentas, o uso final deresulte eventos de erros fatais do Gemini. - Se os argumentos do Gemini forem substituídos por
--output-format json, o OpenClaw normalizará esse backend de volta paraoutput: "json"e lerá o texto da resposta no campo JSONresponse. - O uso recorrerá a
statsquandousageestiver ausente ou vazio;stats.cachedserá normalizado paracacheReaddo OpenClaw e, sestats.inputestiver ausente, os tokens de entrada serão derivados destats.input_tokens - stats.cached.
Substitua os padrões somente se necessário (mais comumente, por um caminho absoluto em command).
Sobreposições de transformação de texto
Os plugins que precisam de pequenos shims de compatibilidade de prompts/mensagens podem declarar transformações de texto bidirecionais sem substituir um provedor ou backend da CLI:
api.registerTextTransforms({ input: [{ from: /red basket/g, to: "blue basket" }], output: [{ from: /blue basket/g, to: "red basket" }],});input reescreve o prompt do sistema e o prompt do usuário passados para a CLI. output reescreve o texto transmitido do assistente e o texto final analisado antes que o OpenClaw processe seus próprios marcadores de controle e faça a entrega ao canal; em chamadas de modelo apoiadas por provedores, também restaura valores de string dentro dos argumentos estruturados de chamadas de ferramenta após o reparo do fluxo e antes da execução da ferramenta. Os fragmentos JSON brutos do provedor permanecem inalterados; os consumidores devem usar a carga útil estruturada parcial, final ou de resultado.
Para CLIs que emitem eventos JSONL específicos do provedor, defina jsonlDialect na configuração desse backend: claude-stream-json para fluxos compatíveis com Claude Code, gemini-stream-json para eventos stream-json da Gemini CLI.
Propriedade da compactação nativa
Alguns backends da CLI executam um agente que compacta a própria transcrição, portanto o OpenClaw não deve executar seu sumarizador de proteção sobre eles — isso entra em conflito com a própria compactação do backend e pode causar uma falha irrecuperável no turno.
claude-cli não tem endpoint de harness (o Claude Code compacta internamente), portanto declara ownsNativeCompaction: true, e o caminho de compactação do OpenClaw retorna a entrada da sessão sem alterações. O OpenClaw passa o orçamento de contexto efetivo da execução pela variável CLAUDE_CODE_AUTO_COMPACT_WINDOW documentada do Claude Code, mantendo a compactação automática nativa alinhada aos limites configurados de contextTokens da Anthropic. Sessões com harness nativo, como o Codex, continuam sendo encaminhadas ao endpoint de compactação do harness.
api.registerCliBackend({ id: "my-cli", ownsNativeCompaction: true /* ... */ });Declare ownsNativeCompaction somente para um backend que realmente seja responsável pela compactação: ele deve limitar de forma confiável sua própria transcrição nas proximidades da janela de contexto e persistir uma sessão retomável (por exemplo, --resume / --session-id); caso contrário, uma sessão adiada pode permanecer acima do orçamento.
Sobreposições de MCP do pacote
Os backends da CLI não recebem chamadas de ferramenta do OpenClaw diretamente, mas um backend pode optar por uma sobreposição de configuração MCP gerada com bundleMcp: true. Comportamento atual dos componentes incluídos:
claude-cli: arquivo de configuração MCP estrita gerado.google-gemini-cli: arquivo de configurações do sistema Gemini gerado.
Quando o MCP do pacote está ativado, o OpenClaw:
- inicia um servidor MCP HTTP de loopback que expõe ferramentas do Gateway ao processo da CLI, autenticado com uma concessão de contexto por execução (
OPENCLAW_MCP_TOKEN) ativa somente para a tentativa de execução atual; - vincula o acesso às ferramentas à sessão, à conta e ao contexto do canal selecionados pelo Gateway, em vez de confiar nos cabeçalhos do processo filho;
- carrega os servidores MCP do pacote ativados para o workspace atual e os combina com qualquer formato existente de configuração/definições MCP do backend;
- reescreve a configuração de inicialização usando o modo de integração pertencente ao backend, definido pelo plugin responsável.
Se nenhum servidor MCP estiver ativado, o OpenClaw ainda injetará uma configuração estrita quando um backend optar pelo MCP do pacote, para que as execuções em segundo plano permaneçam isoladas.
Os runtimes MCP incluídos com escopo de sessão são armazenados em cache para reutilização dentro de uma sessão e, em seguida, encerrados após mcp.sessionIdleTtlMs milissegundos de inatividade (padrão de 10 minutos; defina 0 para desativar). Execuções incorporadas de uso único, como sondagens de autenticação, geração de slugs e recuperação da Active Memory, solicitam limpeza ao final da execução para que processos filhos stdio e fluxos HTTP/SSE Streamable não sobrevivam à execução.
Limite do histórico de reinicialização
Quando uma nova sessão da CLI é inicializada a partir de uma transcrição anterior do OpenClaw (por exemplo, após uma nova tentativa de session_expired), o bloco <conversation_history> renderizado é limitado para impedir que os prompts de reinicialização cresçam excessivamente. O padrão é 12.288 caracteres (cerca de 3.000 tokens).
Os backends da CLI do Claude dimensionam esse limite de acordo com a janela de contexto resolvida do Claude: janelas de contexto maiores recebem uma fatia maior do histórico anterior, até um teto fixo; outros backends da CLI mantêm o padrão conservador. Esse limite controla somente o bloco de histórico anterior do prompt de reinicialização — os limites de saída da sessão ativa são ajustados separadamente em reliability.outputLimits (consulte Sessões).
Limitações
- Sem chamadas diretas de ferramentas do OpenClaw: o OpenClaw não injeta chamadas de ferramentas no protocolo do backend da CLI. Os backends só veem ferramentas do Gateway quando optam por
bundleMcp: true. - A transmissão é específica do backend: alguns backends transmitem JSONL, enquanto outros armazenam em buffer até a saída.
- As saídas estruturadas dependem do formato JSON da própria CLI.
Solução de problemas
| Sintoma | Correção |
|---|---|
| CLI não encontrada | Defina command como um caminho completo. |
| Nome de modelo incorreto | Use modelAliases para mapear provider/model para o ID de modelo da CLI. |
| Sem continuidade de sessão | Verifique se sessionArg está definido e se sessionMode não é none. |
| Imagens ignoradas | Defina imageArg e verifique se a CLI oferece suporte a caminhos de arquivos. |