# Environment Variables Reference (Português (Portugal))
🌐 **Languages:** 🇺🇸 [English](../../../../reference/ENVIRONMENT.md) · 🇪🇹 [am](../../../am/docs/reference/ENVIRONMENT.md) · 🇸🇦 [ar](../../../ar/docs/reference/ENVIRONMENT.md) · 🇦🇿 [az](../../../az/docs/reference/ENVIRONMENT.md) · 🇧🇬 [bg](../../../bg/docs/reference/ENVIRONMENT.md) · 🇧🇩 [bn](../../../bn/docs/reference/ENVIRONMENT.md) · 🇧🇦 [bs](../../../bs/docs/reference/ENVIRONMENT.md) · 🇨🇿 [cs](../../../cs/docs/reference/ENVIRONMENT.md) · 🇩🇰 [da](../../../da/docs/reference/ENVIRONMENT.md) · 🇩🇪 [de](../../../de/docs/reference/ENVIRONMENT.md) · 🇬🇷 [el](../../../el/docs/reference/ENVIRONMENT.md) · 🇪🇸 [es](../../../es/docs/reference/ENVIRONMENT.md) · 🇪🇪 [et](../../../et/docs/reference/ENVIRONMENT.md) · 🇮🇷 [fa](../../../fa/docs/reference/ENVIRONMENT.md) · 🇫🇮 [fi](../../../fi/docs/reference/ENVIRONMENT.md) · 🇫🇷 [fr](../../../fr/docs/reference/ENVIRONMENT.md) · 🇮🇪 [ga](../../../ga/docs/reference/ENVIRONMENT.md) · 🇮🇳 [gu](../../../gu/docs/reference/ENVIRONMENT.md) · 🇳🇬 [ha](../../../ha/docs/reference/ENVIRONMENT.md) · 🇮🇱 [he](../../../he/docs/reference/ENVIRONMENT.md) · 🇮🇳 [hi](../../../hi/docs/reference/ENVIRONMENT.md) · 🇭🇷 [hr](../../../hr/docs/reference/ENVIRONMENT.md) · 🇭🇺 [hu](../../../hu/docs/reference/ENVIRONMENT.md) · 🇦🇲 [hy](../../../hy/docs/reference/ENVIRONMENT.md) · 🇮🇩 [id](../../../id/docs/reference/ENVIRONMENT.md) · 🇳🇬 [ig](../../../ig/docs/reference/ENVIRONMENT.md) · 🇮🇹 [it](../../../it/docs/reference/ENVIRONMENT.md) · 🇯🇵 [ja](../../../ja/docs/reference/ENVIRONMENT.md) · 🇬🇪 [ka](../../../ka/docs/reference/ENVIRONMENT.md) · 🇰🇭 [km](../../../km/docs/reference/ENVIRONMENT.md) · 🇮🇳 [kn](../../../kn/docs/reference/ENVIRONMENT.md) · 🇰🇷 [ko](../../../ko/docs/reference/ENVIRONMENT.md) · 🇱🇹 [lt](../../../lt/docs/reference/ENVIRONMENT.md) · 🇱🇻 [lv](../../../lv/docs/reference/ENVIRONMENT.md) · 🇮🇳 [ml](../../../ml/docs/reference/ENVIRONMENT.md) · 🇮🇳 [mr](../../../mr/docs/reference/ENVIRONMENT.md) · 🇲🇾 [ms](../../../ms/docs/reference/ENVIRONMENT.md) · 🇲🇹 [mt](../../../mt/docs/reference/ENVIRONMENT.md) · 🇲🇲 [my](../../../my/docs/reference/ENVIRONMENT.md) · 🇳🇵 [ne](../../../ne/docs/reference/ENVIRONMENT.md) · 🇳🇱 [nl](../../../nl/docs/reference/ENVIRONMENT.md) · 🇳🇴 [no](../../../no/docs/reference/ENVIRONMENT.md) · 🇮🇳 [or](../../../or/docs/reference/ENVIRONMENT.md) · 🇮🇳 [pa](../../../pa/docs/reference/ENVIRONMENT.md) · 🇵🇭 [phi](../../../phi/docs/reference/ENVIRONMENT.md) · 🇵🇱 [pl](../../../pl/docs/reference/ENVIRONMENT.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/reference/ENVIRONMENT.md) · 🇷🇴 [ro](../../../ro/docs/reference/ENVIRONMENT.md) · 🇷🇺 [ru](../../../ru/docs/reference/ENVIRONMENT.md) · 🇱🇰 [si](../../../si/docs/reference/ENVIRONMENT.md) · 🇸🇰 [sk](../../../sk/docs/reference/ENVIRONMENT.md) · 🇸🇮 [sl](../../../sl/docs/reference/ENVIRONMENT.md) · 🇷🇸 [sr](../../../sr/docs/reference/ENVIRONMENT.md) · 🇸🇪 [sv](../../../sv/docs/reference/ENVIRONMENT.md) · 🇰🇪 [sw](../../../sw/docs/reference/ENVIRONMENT.md) · 🇮🇳 [ta](../../../ta/docs/reference/ENVIRONMENT.md) · 🇮🇳 [te](../../../te/docs/reference/ENVIRONMENT.md) · 🇹🇭 [th](../../../th/docs/reference/ENVIRONMENT.md) · 🇹🇷 [tr](../../../tr/docs/reference/ENVIRONMENT.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/reference/ENVIRONMENT.md) · 🇵🇰 [ur](../../../ur/docs/reference/ENVIRONMENT.md) · 🇺🇿 [uz](../../../uz/docs/reference/ENVIRONMENT.md) · 🇻🇳 [vi](../../../vi/docs/reference/ENVIRONMENT.md) · 🇳🇬 [yo](../../../yo/docs/reference/ENVIRONMENT.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/reference/ENVIRONMENT.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/reference/ENVIRONMENT.md)
---
> Referência completa de todas as variáveis de ambiente reconhecidas pelo OmniRoute.
> Para obter um modelo de início rápido, consulte [`.env.example`](../../.env.example).
> [!IMPORTANT]
> Todas as variáveis documentadas aqui também têm de constar em `.env.example`, e
> todas as variáveis em `.env.example` têm de constar aqui. `npm run check:env-doc-sync`
> valida esta correspondência em cada commit e na CI. Para omitir intencionalmente uma variável, adicione-a à
> lista de permissões em `scripts/check/check-env-doc-sync.mjs`.
---
## Índice
- [1. Segredos obrigatórios](#1-segredos-obrigatórios)
- [2. Armazenamento e base de dados](#2-armazenamento-e-base-de-dados)
- [3. Rede e portas](#3-rede-e-portas)
- [4. Segurança e autenticação](#4-segurança-e-autenticação)
- [5. Sanitização de entradas e proteção de PII](#5-sanitização-de-entradas-e-proteção-de-pii)
- [6. Políticas de ferramentas e encaminhamento](#6-políticas-de-ferramentas-e-encaminhamento)
- [7. URLs e sincronização com a nuvem](#7-urls-e-sincronização-com-a-nuvem)
- [8. Proxy de saída](#8-proxy-de-saída)
- [9. Integração de ferramentas de CLI](#9-integração-de-ferramentas-de-cli)
- [10. Integrações internas de agentes e MCP](#10-integrações-internas-de-agentes-e-mcp)
- [11. Credenciais de fornecedores OAuth](#11-credenciais-de-fornecedores-oauth)
- [12. Substituições de User-Agent dos fornecedores](#12-substituições-de-user-agent-dos-fornecedores)
- [13. Compatibilidade de impressão digital da CLI](#13-compatibilidade-de-impressão-digital-da-cli)
- [14. Fornecedores de chaves de API](#14-fornecedores-de-chaves-de-api)
- [15. Definições de tempo limite](#15-definições-de-tempo-limite)
- [16. Registo](#16-registo)
- [17. Otimização da memória](#17-otimização-da-memória)
- [18. Sincronização de preços](#18-sincronização-de-preços)
- [19. Sincronização de modelos (desenvolvimento)](#19-sincronização-de-modelos-desenvolvimento)
- [20. Definições específicas dos fornecedores](#20-definições-específicas-dos-fornecedores)
- [21. Estado do proxy](#21-estado-do-proxy)
- [22. Depuração](#22-depuração)
- [23. Integração com o GitHub](#23-integração-com-o-github)
- [24. Sandbox de competências (v3.8.0+)](#24-sandbox-de-competências-v380)
- [27. Feed do Radar (alojamento próprio)](#27-feed-do-radar-alojamento-próprio)
- [Cenários de implementação](#cenários-de-implementação)
- [Auditoria: variáveis removidas/inativas](#auditoria-variáveis-removidas--inativas)
---
## 1. Segredos Obrigatórios
Os segredos por definir marcados com **Sim** são gerados automaticamente na primeira execução (`JWT_SECRET`, `API_KEY_SECRET`) e persistidos no `server.env` do diretório de dados — defina-os explicitamente quando esse diretório for efémero. A exceção é o `OMNIROUTE_WS_BRIDGE_SECRET`: não é persistido no `server.env` — os pontos de entrada do servidor geram um valor efémero a cada arranque que apenas a bridge no mesmo processo consegue usar, pelo que os clientes externos da bridge precisam de o definir explicitamente.
| Variável | Obrigatória | Predefinição | Ficheiro de Origem | Descrição |
| ---------------------------- | ------------------ | ------------------------------ | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `JWT_SECRET` | **Sim** | _(nenhum)_ | `src/lib/auth` | Assina/verifica todos os cookies de sessão do painel (JWT). Gere com `openssl rand -base64 48`. |
| `API_KEY_SECRET` | **Sim** | _(nenhum)_ | `src/lib/db/apiKeys.ts` | Chave de encriptação AES para os valores das chaves API em repouso no SQLite. Gere com `openssl rand -hex 32`. |
| `INITIAL_PASSWORD` | Não | _(indefinido)_ | `src/lib/auth/managementPassword.ts` | Define a palavra-passe do painel no arranque, enquanto ainda não estiver guardada nenhuma; é ignorada depois de uma palavra-passe ser guardada. As instalações via npm e a partir do código-fonte copiam o `.env.example` para `.env`, pelo que começam com o seu placeholder publicamente conhecido `CHANGEME`: substitua-o antes do primeiro arranque, ou defina `INITIAL_PASSWORD=` (vazio) nesse `.env` para criar a palavra-passe no assistente de configuração inicial na primeira visita, tal como acontece com um valor indefinido (a predefinição da imagem Docker). Altere uma palavra-passe guardada em Painel → Definições → Segurança, ou execute `omniroute reset-password` (`node bin/reset-password.mjs` numa cópia do código-fonte) com `DATA_DIR` definido para o diretório de dados do servidor. |
| `OMNIROUTE_WS_BRIDGE_SECRET` | **Sim** (produção) | _(indefinido)_ | `src/app/api/internal/codex-responses-ws/route.ts` | Segredo partilhado para a bridge WebSocket interna do Codex Responses. Autentica os pedidos da bridge entre o relay WS do Electron/navegador e o OmniRoute. ⚠️ **OBRIGATÓRIO em produção — quando indefinido, todos os pedidos da bridge WS são rejeitados.** Gere com `openssl rand -base64 32`. |
| `OMNIROUTE_SW_BUILD_ID` | Não | _(git SHA)_ | `next.config.mjs`, `scripts/build/assembleStandalone.mjs` | ID explícito de quebra de cache do service worker para a shell da PWA (#11779); primeiro na cadeia de resolução. |
| `SOURCE_VERSION` | Não | _(indefinido)_ | `next.config.mjs`, `scripts/build/assembleStandalone.mjs` | Segundo na cadeia — definido por builders de PaaS (por ex., ao estilo do Heroku) como o commit implementado. |
| `NEXT_PUBLIC_SW_BUILD_ID` | Não | _(derivado)_ | `src/shared/components/PwaRegister.tsx` | Valor público definido em tempo de build que o cliente usa para registar `/sw.js?v=…`; derivado dos dois anteriores e, em último caso, do SHA do git. |
| `OMNIROUTE_PEER_STAMP_TOKEN` | Não (automático) | _(automático a cada arranque)_ | `src/server/authz/policies/management.ts` | Segredo por processo que comprova que o selo confiável de IP do par veio do próprio servidor HTTP do OmniRoute (`scripts/dev/peer-stamp.mjs`). O middleware de autorização só confia na localidade do pedido (a restrição por loopback/LAN das rotas LOCAL_ONLY) quando o selo transporta este token. Gerado automaticamente a cada arranque — deixe-o indefinido; fixe-o apenas em configurações multi-processo que tenham de partilhar o selo. |
| `OMNIROUTE_TRUSTED_PROXIES` | Não | _(indefinido)_ | `scripts/dev/peer-stamp.mjs` | IPs separados por vírgulas ou intervalos CIDR de proxies reversos em cujos cabeçalhos `X-Forwarded-For` / `X-Real-IP` a lista de permissão/bloqueio de IPs pode confiar, para além do loopback, dos endereços de redes privadas e dos edges da Cloudflare, que são sempre confiáveis. Necessário apenas para um proxy noutro endereço público qualquer; caso contrário, é o próprio endereço desse proxy que o filtro avalia. A limitação de taxa por cliente do relay (`/api/v1/relay/chat/completions`) usa como chave o mesmo endereço de cliente resolvido, nunca apenas os cabeçalhos de encaminhamento. |
### Comandos de Geração
```bash
# Gera os quatro segredos de uma só vez:
echo "JWT_SECRET=$(openssl rand -base64 48)"
echo "API_KEY_SECRET=$(openssl rand -hex 32)"
echo "INITIAL_PASSWORD=$(openssl rand -base64 16)"
echo "OMNIROUTE_WS_BRIDGE_SECRET=$(openssl rand -base64 32)"
```
> [!CAUTION]
> Nunca faça commit de ficheiros `.env` com segredos reais para o controlo de versões. O `.gitignore` já exclui o `.env`, mas verifique antes de fazer push.
---
## 2. Armazenamento e Base de Dados
O OmniRoute usa **SQLite** (via `better-sqlite3`) para toda a persistência. Estas variáveis controlam a localização dos dados, a encriptação e o ciclo de vida.
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ------------------------------------------ | ----------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DATA_DIR` | `~/.omniroute/` | `src/lib/db/core.ts` | Diretório raiz para a base de dados SQLite, backups e ficheiros de dados. Substitua para volumes Docker ou caminhos personalizados. |
| `OMNIROUTE_ALLOW_DEFAULT_DATA_DIR` | _(não definido)_ | `src/lib/dataPaths.ts` | Válvula de escape para a proteção de DATA_DIR em testes/eval (#10428). Os testes e as sondas eval/print do Node (`-e`/`--eval`/`-p`/`--print`, incluindo as formas `--eval=`/`--print=`) sem `DATA_DIR` são redirecionados para um diretório temporário descartável, para que não possam abrir a base de dados real do operador; defina como `1` para voltar a optar pelo diretório real. |
| `OMNIROUTE_BUILD_SHA` | _(não definido)_ | `src/lib/monitoring/buildSha.ts` | SHA do Git do artefacto em execução. Carimbado por `npm run build:release`; injetável em contentores distribuídos sem o sentinela `dist/BUILD_SHA`. Exposto como `system.buildSha` em `/api/monitoring/health`. |
| `OMNIROUTE_RELEASE_REF` | `origin/main` | `scripts/build/buildProvenance.ts` | Ref contra o qual o gate de proveniência do empacotamento do artefacto verifica o SHA de build (#10427). |
| `OMNIROUTE_ALLOW_CANARY_BUILD` | _(não definido)_ | `scripts/build/buildProvenance.ts` | Defina como `1` para permitir empacotar um build cujo SHA não está na linha de release, registando-o como um canary deliberado em vez de falhar o gate (#10427). |
| `OMNIROUTE_SMOKE_API_KEY` | _(não definido)_ | `scripts/ops/deploy-canary.mjs` | Chave de API para a sonda de smoke do deploy canary, enviada como `Authorization: Bearer` em `/v1/chat/completions`. Usada apenas pelo script de deploy (#10429), nunca pelo servidor. Não relacionada com as variáveis `OMNIROUTE_SMOKE_*` do harness de smoke CLI opt-in (`RUN_CLI_SMOKE=1`, `OMNIROUTE_SMOKE_BASE_URL/MODEL/API_KEY_ENV/TARGETS/TIMEOUT_MS` em `tests/integration/upstream-cli-smoke.int.test.ts`) — consulte [Integrações CLI → Varredura de smoke real](../guides/CLI-INTEGRATIONS.md). |
| `OMNIROUTE_BUILDING` | _(não definido)_ | `src/lib/buildPhase.ts` | Sinal de fase de build (#10060): definido como `1` por `scripts/build/build-next-isolated.mjs` e herdado por cada worker de build gerado, para que a camada de base de dados devolva um stub no-op em vez de carregar o addon nativo better-sqlite3 (que aborta o worker ao terminar). Nunca definido para o servidor em execução. |
| `OMNIROUTE_SKIP_NATIVE_DEP_CHECK` | `0` | `scripts/check/check-native-deps.mjs` | Defina como `1` para ignorar a verificação opcional de pré-build de dependências nativas em árvores vendored exóticas. Isto não torna compilável uma dependência em falta; use apenas quando as dependências nativas são fornecidas por via externa. |
| `OMNIROUTE_DATA_DIR` | _(não definido)_ | `open-sse/executors/promptql/threadSticky.ts` | **Alias de fallback** para `DATA_DIR`, verificado apenas quando `DATA_DIR` não está definido. Usado para localizar a cache em disco de sessões thread-sticky do executor PromptQL (`
/promptql-thread-sessions.json`); se nenhuma das variáveis estiver definida, a cache permanece apenas em memória (não persiste entre reinícios). |
| `OMNIROUTE_PLUGINS_DIR` | _(não definido)_ | `src/lib/plugins/scanner.ts` | Diretório que o **scanner de plugins em runtime** lê — e a raiz onde o gestor de plugins instala — substituindo a predefinição derivada do home (#11827). Aponte-o para a árvore de plugins montada via bind em Docker/K8s em vez de mover o HOME apenas para relocar o caminho de scan (o HOME também rege todos os outros comportamentos relativos ao home). Não definido = `~/.omniroute/plugins`, ou `/tmp/.omniroute/plugins` quando o processo não exporta qualquer home — a não-descoberta silenciosa que esta variável elimina. O diretório resolvido é registado uma vez no arranque como `scanner.dir_resolved` com a entrada que prevaleceu. Apenas no lado do servidor: os plugins de comandos CLI mantêm o seu próprio `OMNIROUTE_PLUGIN_PATH` (secção 9). |
| `STORAGE_ENCRYPTION_KEY` | _(vazio = desativado)_ | `src/lib/db/encryption.ts` | Chave AES para encriptação completa da base de dados SQLite em repouso. Gere com `openssl rand -hex 32`. |
| `STORAGE_ENCRYPTION_KEY_VERSION` | `v1` | `scripts/build/bootstrap-env.mjs`, `electron/main.js` | Etiqueta de versão para a chave de encriptação. Incremente ao realizar a rotação de chaves para suportar a desencriptação de backups antigos. |
| `DISABLE_SQLITE_AUTO_BACKUP` | `false` | `src/lib/db/backup.ts` | Quando `true`, ignora os backups de ficheiros SQLite de rotina/pré-escrita (guardar/limpar preços do models.dev, escritas de definições). Os backups manuais e pré-restauro continuam a ser executados. **Não** desativa o snapshot de segurança durável obrigatório do executor de migrações nem a proteção contra migrações em massa para uma base de dados persistente existente. Os backups não manuais são limitados a no máximo uma vez por 60 minutos. O painel **Definições → Armazenamento** pode desativar o backup automático de rotina de forma independente. |
| `OMNIROUTE_SQLITE_SLOW_MS` | _(não definido/desativado)_ | `src/lib/db/adapters/slowDiagnostics.ts` | Milissegundos; valores abaixo de 1 ou não numéricos permanecem desativados; avisa no máximo uma vez por 10s; a linha de log contém apenas driver, operação e elapsedMs. |
| `OMNIROUTE_CRYPT_KEY` | _(não definido)_ | `src/lib/db/encryption.ts` | **Alias legado** de `STORAGE_ENCRYPTION_KEY`. Aceite como alternativa quando a variável principal está ausente. |
| `OMNIROUTE_API_KEY_BASE64` | _(não definido)_ | `src/lib/db/encryption.ts` | **Alias legado** (formato codificado em Base64) aceite como alternativa. Descodificado automaticamente antes da utilização. |
| `OMNIROUTE_DB_HEALTHCHECK_INTERVAL_MS` | _(não definido)_ | `src/lib/db/core.ts` | Substitui o intervalo periódico de verificação de integridade do SQLite (ms). Quando não definido, os valores predefinidos são derivados de `NODE_ENV`. |
| `OMNIROUTE_WAL_TRUNCATE_INTERVAL_MS` | _(removido)_ | `src/lib/db/walMaintenance.ts` | **Removido.** Um `wal_checkpoint(TRUNCATE)` periódico em execução pode invalidar o mapeamento partilhado do wal-index e provocar a falha do processo com SIGBUS (#13973), pelo que o agendador deixou de existir. A variável é inerte: um valor positivo regista um aviso de depreciação único, enquanto `0` ou não definido permanece silencioso. O WAL é mantido por checkpoints PASSIVE (abaixo) e truncado pelo checkpoint de encerramento. |
| `OMNIROUTE_WAL_PASSIVE_INTERVAL_MS` | `300000` (5m) | `src/lib/db/walMaintenance.ts` | Substitui o intervalo frequente de `wal_checkpoint(PASSIVE)` (ms). Mantém os frames WAL pendentes pequenos para que os checkpoints permaneçam rápidos e o ficheiro WAL se mantenha limitado entre as truncagens de encerramento. `0` desativa. |
| `OMNIROUTE_WAL_GUARD_MAX_MB` | `256` | `src/lib/db/walMaintenance.ts` | Quando um tick PASSIVE encontra o ficheiro WAL acima deste tamanho, executa `wal_checkpoint(RESTART)` para que o WAL recomece sem reescrever o wal-index mapeado. Os checkpoints em modo truncate em execução foram removidos (consulte a linha `OMNIROUTE_WAL_TRUNCATE_INTERVAL_MS`). |
| `OMNIROUTE_PRESSURE_SELF_RESTART` | `false` | `open-sse/utils/resourcePressure.ts` | Defina como `1`/`true`/`yes`/`on` para terminar o processo após pressão crítica de recursos sustentada durante `OMNIROUTE_PRESSURE_SELF_RESTART_AFTER_MS`, permitindo que um supervisor (systemd `Restart=always`, política de reinício do Docker) recupere um processo limpo em vez de servir erros 503 indefinidamente. |
| `OMNIROUTE_PRESSURE_SELF_RESTART_AFTER_MS` | `120000` (2m) | `open-sse/utils/resourcePressure.ts` | Durante quanto tempo a pressão crítica deve persistir antes de ser acionada a saída para autorreinício. |
| `OMNIROUTE_PRESSURE_PSI_DISABLED` | `false` | `open-sse/utils/resourcePressurePolicy.ts` | Defina como `1`/`true`/`yes`/`on` para ignorar o `/proc/pressure/memory` de todo o host (`psi_some` / `psi_full`) quando um vizinho ruidoso provoca erros 503 enquanto este processo está bem (#13124). As proteções de cgroup e de heap V8 permanecem ativas. O PSI também deixa de contar como prova de estrangulamento do kernel para `cgroup_high`: um total de cgroup acima de `memory.high` só se torna crítico com um aumento `high`/`max` em `memory.events`. Sem `memory.events`, a proporção bruta é mantida. |
| `OMNIROUTE_SQLJS_WASM_PATH` | _(deteção automática)_ | `src/lib/db/adapters/sqljsAdapter.ts` | Caminho explícito (absoluto ou relativo ao cwd) para `sql-wasm.wasm` ao utilizar o adaptador de recurso WASM `sql.js`. Detetado automaticamente através das dependências do pacote e de layouts candidatos quando não definido. |
| `OMNIROUTE_BATCH_RETENTION_DAYS` | `30` | `src/lib/db/cleanup.ts` | Dias durante os quais os checkpoints, os ficheiros de entrada/saída/erro referenciados e a linha de uma tarefa terminal (completed/failed/cancelled/expired) da Batch API são mantidos pela limpeza automática antes da eliminação. Só produz efeito quando `BATCH_AND_FILE_AUTO_CLEANUP_ENABLED` está ativada; corresponde à janela de retenção de saída da própria Batch API da OpenAI. Não afeta a rota `DELETE /api/v1/batches/delete-completed` acionada pelo operador, que permanece incondicional (sem filtro de idade) por conceção. |
| `BATCH_AND_FILE_AUTO_CLEANUP_ENABLED` | `false` | `src/lib/db/cleanup.ts` | Quando `true`, permite que a limpeza automática elimine tarefas terminais da Batch API (e os respetivos checkpoints) após `OMNIROUTE_BATCH_RETENTION_DAYS`, e limpe o conteúdo BLOB dos ficheiros carregados após o seu próprio `expires_at`. Desativada por predefinição: cada instalação existente mantém estes dados exatamente como antes até que um operador opte por ativar. Também é uma feature flag editável no dashboard — consulte `docs/reference/FEATURE_FLAGS.md` → Runtime. |
| `OMNIROUTE_SKIP_DB_HEALTHCHECK` | `0` | `src/lib/db/core.ts`, `src/lib/db/healthCheck.ts` | Defina como `1` para ignorar totalmente o healthcheck da base de dados no arranque. Útil para tarefas de curta duração e testes de integração. |
| `OMNIROUTE_FORCE_DB_HEALTHCHECK` | `0` | `src/lib/db/core.ts` | Defina como `1` para forçar a ativação do ciclo de healthcheck da base de dados, mesmo quando este seria normalmente ignorado (p. ex., tarefas de curta duração). |
| `OMNIROUTE_SKIP_POSTINSTALL` | `0` | `scripts/postinstall.mjs` | Defina como `1` para ignorar o warm-up do runtime nativo durante o `npm install`. Útil em instalações CI/headless onde o sqlite já está compilado. |
| `OMNIROUTE_MIGRATIONS_DIR` | _(deteção automática)_ | `src/lib/db/migrationRunner.ts` | Substitui o diretório analisado pelo executor de migrações. Útil ao incluir migrações integradas em builds personalizados. |
| `OMNIROUTE_EXTRA_MIGRATIONS_DIRS` | _(não definido)_ | `src/lib/db/migrationRunner/extraDirs.ts` | Diretórios de migrações adicionais como entradas `namespace=dir` separadas pelo delimitador de caminho da plataforma (p. ex. `ee=/opt/app/enterprise/db/migrations`). Os ficheiros aí encontrados são registados como `-`, pelo que uma distribuição que inclua as suas próprias migrações nunca colide com os slots numéricos do upstream. Uma entrada malformada, um namespace inválido ou um diretório inexistente lança um erro no arranque, em vez de ignorar silenciosamente o esquema. |
| `OMNIROUTE_MAX_PENDING_MIGRATIONS` | `50` | `src/lib/db/migrationRunner.ts` | Limiar de segurança para migrações pendentes em massa (#3416). O arranque é abortado se houver mais do que este número de migrações pendentes numa base de dados existente (protege contra uma tabela de rastreio apagada). Aumente-o para restaurar um backup mais antigo; defina como `0` para desativar a verificação. |
| `OMNIROUTE_INSTALL_UPGRADE_WORKDIR` | _(`/.install-upgrade`)_ | `scripts/check/check-install-upgrade.mjs` | Diretório de trabalho para o gate de release `check:install-upgrade`. Precisa de cerca de 12 GB (duas árvores de instalação de ~3 GB mais o tarball), pelo que não deve ser executado num tmpfs pequeno — no runner self-hosted, `/tmp` é um tmpfs de 12 GB suportado por RAM e o gate esgotou-o, truncando o pacote. |
| `OMNIROUTE_SPEND_FLUSH_INTERVAL_MS` | _(predefinição no código)_ | `src/lib/spend/batchWriter.ts` | Intervalo de flush (ms) para o gravador de gastos/custos em lote. Valores mais baixos reduzem a coalescência de escritas; valores mais altos reduzem a contenção na base de dados. |
| `OMNIROUTE_SPEND_MAX_BUFFER_SIZE` | _(predefinição no código)_ | `src/lib/spend/batchWriter.ts` | Número máximo de entradas de gastos em buffer antes de um flush forçado. Aumente em implantações com QPS elevado; diminua quando a memória limitada for mais importante. |
| `OMNIROUTE_PROXY_FETCH_DEBUG` | _(não definido)_ | `open-sse/utils/proxyFetch.ts` | Defina como `"true"` para emitir logs de depuração `[ProxyFetch]` no caminho de relay da Vercel. Desativado por predefinição para evitar revelar indicações de encaminhamento. |
| `OMNIROUTE_PROXY_CORE_BINARY_PATH` | _(não definido)_ | `src/lib/proxySubscription/coreConfig/sync.ts` | Caminho absoluto do binário local do núcleo de proxy (um ficheiro chamado `sing-box`) que verifica uma configuração de núcleo gerada antes de esta substituir o ficheiro adotado. Se não estiver definido, escreve apenas `.generated` junto ao ficheiro adotado. Apenas no ambiente do anfitrião: nunca é armazenado na base de dados nem aceite através da API de gestão, porque o binário é executado. |
| `OMNIROUTE_PROXY_CORE_RELOAD_COMMAND` | _(não definido)_ | `src/lib/proxySubscription/coreConfig/reload.ts` | Como o núcleo de proxy local recarrega após uma substituição de configuração verificada: um array JSON de argumentos executado sem shell, ou exatamente `external` quando um observador externo aplica o ficheiro. Nunca é armazenado na base de dados nem exposto através da API. |
| `PROXY_LOG_INCLUDE_IPS` | `false` | `src/lib/proxyLogger.ts` | Defina como `"true"` ou `"1"` para incluir os IPs de cliente/saída e o prefixo da conta na linha detalhada `[ProxyEgress]` do registo de processo. Mantido DESATIVADO por predefinição para que o registo de processo não divulgue IPs nem o prefixo da conta. |
| `OMNIROUTE_DEBUG` | _(não definido)_ | `bin/cli/commands/quota.mjs` | Defina como `1` para imprimir diagnósticos de temporização por pedido (`[omniroute] GET completed in Nms`) dos comandos CLI de quota para o stderr. |
| `OMNIROUTE_HEALTHCHECK_PATH` | _(automático)_ | `scripts/dev/healthcheck.mjs` | Caminho explícito verificado pela verificação de integridade do contentor. Se não estiver definido, a sonda deriva-o de `OMNIROUTE_BASE_PATH`; ao defini-lo, volta a optar pelo endpoint de monitorização profunda. |
| `OMNIROUTE_DEBUG_COMPLETION` | _(não definido)_ | `bin/cli/commands/completion.mjs` | Defina com qualquer valor não vazio para emitir diagnósticos `[omniroute completion]` a partir dos caminhos de cache de completação de shell do CLI (leitura/atualização/escrita). Desativado por predefinição — essas caches falham silenciosamente, pelo que uma cache em falta/corrompida nunca interrompe a completação com Tab. |
| `BATCH_RETRY_DURATION_MS` | `86400000` (24h) | `open-sse/services/batchProcessor.ts` | Janela máxima de repetição para itens individuais do lote (ms). Os itens que excedam esta duração são marcados como falhados. |
| `BATCH_BACKOFF_BASE_MS` | `5000` | `open-sse/services/batchProcessor.ts` | Atraso base (ms) para o backoff exponencial nas repetições de itens do lote. |
| `BATCH_BACKOFF_MAX_MS` | `3600000` (1h) | `open-sse/services/batchProcessor.ts` | Limite máximo (ms) para o backoff exponencial entre repetições de itens do lote. |
| `BATCH_MAX_CONCURRENT` | `1` | `open-sse/services/batchProcessor.ts` | Número máximo de lotes processados em simultâneo. Aumente para maior débito; mantenha baixo para evitar tempestades de limitação de taxa. |
> [!IMPORTANT]
> Antes de alterar uma base de dados persistente existente, o executor de migrações publica um
> snapshot completo, endereçado por conteúdo, em `DATA_DIR/db_backups/`. A publicação requer um
> sistema de ficheiros que suporte hard links no mesmo sistema de ficheiros e sem sobreposição,
> além de sincronização duradoura de ficheiros. Os anfitriões POSIX também requerem sincronização
> de diretórios; no Windows, o Node pode rejeitar handles de diretório, pelo que o OmniRoute faz
> flush do ficheiro publicado e trata a sincronização de entradas de diretório como melhor esforço.
> Se o `DATA_DIR` montado não puder fornecer essas garantias, o arranque falha em modo fechado
> antes de aplicar uma migração. Mova o `DATA_DIR` para um volume com essas primitivas; não utilize
> `DISABLE_SQLITE_AUTO_BACKUP` para contornar a segurança das migrações.
### Cenários
| Cenário | Configuração |
| ------------------------- | -------------------------------------------------------------------------------------------------- |
| **Desenvolvimento local** | Mantenha todas as predefinições. A BD fica em `~/.omniroute/omniroute.db`. |
| **Docker** | `DATA_DIR=/data` + monte um volume em `/data`. |
| **Encriptado em repouso** | Defina `STORAGE_ENCRYPTION_KEY` + guarde cópias de segurança da chave! Perdê-la = perder os dados. |
| **CI/Testes** | `DATA_DIR=/tmp/omniroute-test` — efémero, sem necessidade de encriptação. |
---
## 3. Rede e Portas
| Variable | Default | Source File | Description |
| ------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PORT` | `20128` | `src/lib/runtime/ports.ts` | Porta principal tanto para a IU do Dashboard como para os endpoints da API (modo de porta única). |
| `OMNIROUTE_BASE_PATH` | _(vazio = raiz)_ | `next.config.mjs`, `scripts/docker/ensure-docker-base-path.mjs` | Subcaminho de URL para servir o OmniRoute atrás de um proxy reverso (define o `basePath` do Next.js; os redirecionamentos de autenticação têm em conta o basePath). Ex.: `/omniroute`. No Docker, o valor é incorporado durante o `docker build` (`ARG OMNIROUTE_BASE_PATH`); as imagens raiz pré-compiladas podem aplicar um valor de execução diferente uma única vez no arranque do contentor, antes de o Next.js iniciar. Defina `NEXT_PUBLIC_BASE_URL` para a origem pública incluindo o mesmo subcaminho. |
| `NEXT_PUBLIC_OMNIROUTE_BASE_PATH` | _(vazio = raiz)_ | `src/shared/hooks/useDisplayBaseUrl.ts` | Espelho visível no navegador de `OMNIROUTE_BASE_PATH`, incorporado em linha no momento da compilação para que a apresentação do endpoint no dashboard mostre `https://host/omniroute/v1` em vez de `https://host/v1`. Recorre a `OMNIROUTE_BASE_PATH` quando não definido. Recompile após alterar (o `basePath` do Next é definido no momento da compilação). |
| `DASHBOARD_ALLOW_EMBED` | _(não definido = nunca enquadrável)_ | `next.config.mjs`, `scripts/build/dashboardEmbed.mjs` | Incorporação opcional (opt-in) em iframe das páginas HTML. Quando não definido, todas as rotas enviam `frame-ancestors 'none'` + `X-Frame-Options: DENY`. Defina para `vscode` para servir as páginas (dashboard, login, docs, landing) com `frame-ancestors 'self' vscode-webview:` e sem `X-Frame-Options`, para que o Simple Browser do VS Code as possa renderizar (modo `dashboardOpen: "editor"` do OmniCopilot). A superfície da API (`/api`, `/v1`, `/v1beta`, `/a2a`, `/healthz`, aliases ao nível da raiz) mantém os cabeçalhos restritos em qualquer caso. Apenas `vscode` é reconhecido — `1`/`true` não o ativam. Momento da compilação: recompile após alterar (`docker build --build-arg DASHBOARD_ALLOW_EMBED=vscode` para imagens; defini-lo numa instalação pré-compilada não tem efeito). |
| `API_PORT` | _(não definido)_ | `src/lib/runtime/ports.ts` | Quando definido, serve a API proxy `/v1/*` nesta porta separada. |
| `API_HOST` | `0.0.0.0` | `src/lib/runtime/ports.ts` | Endereço de escuta (bind) para a porta da API. |
| `DASHBOARD_PORT` | _(não definido)_ | `src/lib/runtime/ports.ts` | Quando definido, serve a IU do Dashboard nesta porta separada. |
| `OMNI_MAX_CONCURRENT_CONNECTIONS` | `0` _(desativado)_ | `src/sse/utils/backpressure.ts` | Limita as ligações de chat simultâneas em curso; os pedidos acima do limite recebem `503` com `Retry-After`. Um inteiro positivo ativa a proteção; não definido/`0` desativa-a. |
| `OMNIROUTE_INSTANCE_ID` | _(não definido)_ | `src/shared/resilience/peerRouting.ts` | ID estável e único para este gateway ao encadear instâncias OmniRoute. Ativa as verificações de loop entre pares (peer-loop) de entrada. Carateres permitidos: letras, dígitos, `.`, `_`, `:` e `-`; máximo de 64 carateres. |
| `OMNIROUTE_PEER_URLS` | _(não definido)_ | `src/shared/resilience/peerRouting.ts`, `open-sse/executors/base.ts` | URLs base do OmniRoute separados por vírgulas que podem receber `X-OmniRoute-Peer-Trace`. Apenas os URLs upstream explicitamente autorizados recebem metadados de pares; todos os outros fornecedores permanecem inalterados. |
| `OMNIROUTE_PEER_MAX_HOPS` | `4` | `src/shared/resilience/peerRouting.ts` | Número máximo de instâncias OmniRoute previamente visitadas aceites num pedido encadeado (`1`-`32`). Instâncias repetidas ou um limite esgotado devolvem HTTP `508 Loop Detected`. |
| `PROD_DASHBOARD_PORT` | `20130` | `docker-compose.prod.yml` | Porta publicada no lado do anfitrião para o Dashboard no modo de produção Docker. |
| `PROD_API_PORT` | `20131` | `docker-compose.prod.yml` | Porta publicada no lado do anfitrião para a API no modo de produção Docker. |
| `OMNIROUTE_PORT` | _(não definido)_ | `src/lib/runtime/ports.ts` | Tem precedência sobre `PORT` quando executado dentro do Electron ou de outros wrappers. |
| `LIVE_WS_PORT` | `20129` | `src/server/ws/liveServer.ts` | Porta para o servidor WebSocket de monitorização em tempo real. |
| `LIVE_WS_HOST` | `127.0.0.1` | `src/server/ws/liveServer.ts` | Endereço de bind para o servidor WebSocket em tempo real. Defina como `0.0.0.0` para expor na LAN (configure também `LIVE_WS_ALLOWED_ORIGINS`). As ligações autenticam-se com o cookie de sessão do dashboard ou uma chave de API Bearer com um âmbito de gestão (`manage`/`admin`). |
| `LIVE_WS_ALLOWED_ORIGINS` | _(não definido)_ | `src/server/ws/liveServer.ts` | Origens adicionais separadas por vírgulas autorizadas a abrir um WebSocket em tempo real. As origens de loopback do dashboard já são permitidas por predefinição. |
| `LIVE_WS_ALLOWED_HOSTS` | _(não definido)_ | `src/server/ws/liveServerAllowList.ts` | Nomes de anfitrião adicionais separados por vírgulas permitidos para origens WebSocket em tempo real. Ao contrário de `LIVE_WS_ALLOWED_ORIGINS` (URLs de origem completos), corresponde apenas à parte do anfitrião — útil para configurações LAN/Tailscale. |
| `NEXT_PUBLIC_LIVE_WS_PUBLIC_URL` | _(não definido)_ | `src/hooks/useLiveDashboard.ts` | URL público para o WebSocket do dashboard em tempo real (lado do navegador). Defina quando o servidor WS está atrás de um proxy reverso ou Cloudflare Tunnel (ex.: `wss://ws.my-ai.com/live-ws`); o navegador liga-se aí em vez de `ws://hostname:20132`. A parte do pathname também é usada como caminho de upgrade do WebSocket (predefinição: `/live-ws`). |
| `OMNIROUTE_ENABLE_LIVE_WS` | `true` | `src/server/ws/liveServer.ts` e `scripts/start-ws-server.mjs` | Defina como `0` ou `false` para desativar o servidor WebSocket em tempo real (ativado por predefinição, associado ao loopback). Alternador de CI/harness que desativa o script auxiliar autónomo do WebSocket em tempo real. |
| `RELAY_IP_PER_MINUTE` | `30` | `src/app/api/v1/relay/chat/completions/route.ts` | Limite de taxa de relay por (token, IP), pedidos/minuto. Em memória, por instância. `0` ou negativo desativa a restrição da dimensão IP (o limite de base de dados por token continua a aplicar-se). |
| `NODE_ENV` | `production` | Núcleo do Next.js | Controla a verbosidade do registo, a colocação em cache, a exposição de detalhes de erros e as otimizações do Next.js. |
| `OMNIROUTE_USE_TURBOPACK` | `1` (Turbopack — predefinição do código) | `package.json` / Next.js 16 | O Turbopack é o bundler predefinido para `npm run dev` e `npm run build` (compilações 2-3× mais rápidas, medidas em benchmark). Defina como `0` para reverter para o webpack no Windows, ao deparar-se com incompatibilidades de bindings nativos / de compatibilidade do bundler, **ou em máquinas com RAM limitada** — sabe-se a montante que as compilações de produção do Turbopack nesta linha de versões do Next.js (16.2.x) atingem picos de memória muito superiores aos do webpack em grafos de módulos grandes (a correção de expulsão de memória do Turbopack do Next 16.3 ainda não está estável); a reversão para webpack atinge picos muito mais baixos. Ver #6409. **As compilações de imagens Docker têm `0` (webpack) como predefinição**: o `Dockerfile` declara `ARG OMNIROUTE_USE_TURBOPACK=0` para que um simples `docker build .` (Railway e outros alojamentos de um clique, autoalojadores ad-hoc) não seja terminado por OOM num builder com memória limitada; passe `--build-arg OMNIROUTE_USE_TURBOPACK=1` para compilar a imagem com o Turbopack. Ver `docs/guides/DOCKER_GUIDE.md` → Recursos em tempo de compilação. |
| `OMNIROUTE_SKIP_DB_HEALTHCHECK` | _(não definida)_ | `src/lib/db/core.ts` / `src/lib/db/healthCheck.ts` | Defina como `1` para ignorar a verificação de integridade do SQLite no arranque. Útil para um arranque mais rápido em bases de dados grandes. |
| `NOTIFY_SOCKET` | _(não definida)_ | systemd (protocolo sd_notify) | Definida pelo systemd quando o processo é executado sob uma unidade de serviço com integração sd_notify; o OmniRoute lê-a (ver `OMNIROUTE_DISABLE_SD_NOTIFY`) para enviar notificações READY/WATCHDOG. Nunca é definida pelo utilizador. |
| `OMNIROUTE_DISABLE_SD_NOTIFY` | _(não definida)_ | `scripts/dev/systemd-notify.mjs` | Defina como `1` para desativar o sd_notify do systemd (Type=notify / WatchdogSec=) mesmo quando executado sob uma unidade systemd. O notificador é inócuo fora do systemd, independentemente. |
| `CREDENTIAL_HEALTH_CHECK_INTERVAL` | `3600000` | `open-sse/config/constants.ts` / `src/lib/credentialHealth/scheduler.ts` | Intervalo (ms) para o agendador de verificação do estado das credenciais em segundo plano. Mínimo: 10000 (10s). |
| `CREDENTIAL_HEALTH_CACHE_TTL` | `300000` | `open-sse/config/constants.ts` / `src/lib/credentialHealth/cache.ts` | TTL (ms) para o estado das credenciais em cache. |
| `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` | `false` | `src/lib/credentialHealth/scheduler.ts` | Defina como `1` ou `true` para desativar o teste periódico em segundo plano das ligações aos fornecedores. Os fornecedores de pesquisa (SEARCH_VALIDATOR_CONFIGS em `src/lib/providers/validation/searchProviders.ts`, p. ex. `tavily-search`) estão sempre excluídos da varredura — a sua "validação" é uma consulta real e faturada a montante, pelo que nunca são submetidos a verificação de estado por temporizador (#9970). |
| `DEEP_HEALTH_CHECK_ENABLED` | `0` | `src/app/api/monitoring/health/route.ts` | Defina como `1` para permitir que um chamador autenticado solicite `/api/monitoring/health?deep=1`, que amostra a superfície de completions uma vez por TTL. Os chamadores anónimos nunca acionam a sonda. |
| `OMNIROUTE_EVENT_LOOP_STALL_THRESHOLD_MS` | `5000` | `src/lib/healthzLag.ts` | Limiar de bloqueio (ms) para o gravador do event loop no arranque: um congelamento superior a este valor regista uma linha `event loop stalled` ao retomar, com contagens de memória e de pedidos em curso, e incrementa o contador/máximo `eventLoopStall` em `/api/monitoring/health`. Defina como `0` para desativar; um valor ilegível ou negativo reverte para `5000`. |
| `HOST` | `0.0.0.0` | `scripts/dev/run-next.mjs` | Endereço de escuta do servidor dev/start do Next.js. Substitui a predefinição `0.0.0.0` quando definido. |
| `HOSTNAME` | `127.0.0.1` | `scripts/dev/run-next-playwright.mjs` | Endereço de escuta utilizado pelo executor do Playwright ao iniciar o Next.js. A predefinição é `127.0.0.1` para testes herméticos. **Não utilizar para `omniroute serve`** — utilize antes `OMNIROUTE_SERVER_HOST` (os shells POSIX definem automaticamente `HOSTNAME` com o nome da máquina; o `.env` não o consegue substituir). |
| `OMNIROUTE_SERVER_HOST` | `0.0.0.0` | `bin/cli/commands/serve.mjs` | Endereço de escuta para `omniroute serve`. Evita a colisão com a variável `HOSTNAME` do shell POSIX (sempre definida com o nome da máquina pelo bash/zsh). Recorre a `0.0.0.0` quando não definida. (#6194) |
### Modos de Porta
```
┌───────────────────────── Porta Única (predefinição) ────────────────────────┐
│ PORT=20128 │
│ → Dashboard: http://localhost:20128 │
│ → API: http://localhost:20128/v1/chat/completions │
└─────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────── Portas Separadas ─────────────────────────────┐
│ DASHBOARD_PORT=20128 │
│ API_PORT=20129 │
│ API_HOST=0.0.0.0 │
│ → Dashboard: http://localhost:20128 │
│ → API: http://0.0.0.0:20129/v1/chat/completions │
│ Caso de uso: expor a API à LAN e restringir o Dashboard ao localhost. │
└─────────────────────────────────────────────────────────────────────────────┘
┌────────────────────────────── Produção Docker ──────────────────────────────┐
│ PROD_DASHBOARD_PORT=443 PROD_API_PORT=8443 │
│ → Mapeia portas do contentor para o anfitrião (docker-compose.prod.yml). │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## 4. Segurança e Autenticação
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ------------------------------------------- | ----------------------------------------------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MACHINE_ID_SALT` | `endpoint-proxy-salt` | `src/lib/auth` | Salt combinado com identificadores de hardware para fingerprinting da máquina. Altere em cada implementação para isolamento. |
| `OMNIROUTE_CLI_SALT` | _(não definido = salt aleatório por instalação persistido em `/cli-token-salt.json`)_ | `src/lib/machineToken.ts` | Salt HMAC para derivar o token de autenticação local da CLI. Definir este valor faz rodar todos os tokens CLI na máquina e tem sempre prioridade sobre o salt persistido. Consulte `docs/security/CLI_TOKEN.md`. |
| `AUTH_COOKIE_SECURE` | `false` | `src/lib/auth` | Define a flag `Secure` nos cookies de sessão. **Tem de ser `true`** quando em execução atrás de HTTPS. |
| `REQUIRE_API_KEY` | `false` | Middleware da API | Quando `true`, todos os pedidos de proxy `/v1/*` têm de incluir uma chave de API válida. **Esta flag não controla o acesso a `GET /v1/models`**, que segue antes a postura de login do Dashboard (`requireAuthForModels`) — pelo que um `401` de `/v1/models` NÃO significa que a inferência está protegida. Consulte `docs/security/INFERENCE_AUTH_POSTURE.md` (#13695). |
| `ALLOW_API_KEY_REVEAL` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Permite revelar os valores completos das chaves de API na IU do Dashboard. Configurável a partir das Feature Flags do Dashboard; risco de segurança em instâncias partilhadas. |
| `NO_LOG_API_KEY_IDS` | _(vazio)_ | `src/lib/compliance/index.ts` | IDs de chaves de API separados por vírgulas que contornam o registo de pedidos (conformidade com o RGPD). |
| `DEFAULT_RATE_LIMIT_PER_DAY` | _(não definido = ilimitado)_ | `src/shared/utils/apiKeyPolicy.ts` | Quota diária de pedidos de recurso aplicada a chaves de API cuja coluna `rate_limits` é null. Não definido ou vazio: sem limite implícito (#2289, #11017). `0` equivale ao mesmo (ilimitado). Um inteiro positivo N ativa N/dia, 5N/semana, 20N/mês. Valores não vazios mal formados revertem para as janelas legadas de 1000/dia, 5000/semana, 20000/mês. |
| `MAX_BODY_SIZE_BYTES` | `10485760` (10 MB) | `src/shared/middleware/bodySizeGuard.ts` | Tamanho máximo permitido do corpo do pedido. Rejeita payloads que excedam este limite. |
| `OMNIROUTE_CHAT_LARGE_BODY_BYTES` | `262144` (256 KB) | `src/shared/middleware/chatBodyAdmission.ts` | Corpos de pedido reais iguais ou superiores a este limiar adquirem a concessão atómica de admissão pesada, local ao processo, antes da análise do JSON (caminho BYTE, incluindo `POST /v1/responses`). O mesmo escape de margem saudável de [#10437](https://github.com/diegosouzapw/OmniRoute/pull/10437) que no caso structure-heavy; continua limitado por `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` / [#10110](https://github.com/diegosouzapw/OmniRoute/issues/10110) para que [#7849](https://github.com/diegosouzapw/OmniRoute/issues/7849) não regresse. |
| `OMNIROUTE_CHAT_HARD_MAX_BODY_BYTES` | `52428800` (50 MB) | `src/shared/middleware/chatBodyAdmission.ts` | Limite rígido da rota de chat aplicado aos bytes lidos durante a ingestão limitada, incluindo pedidos com `Content-Length` em falta, inválido ou enganoso; o excesso recebe `413`. |
| `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` | _(não definido — sem limite de contagem de pedidos)_ | `src/shared/middleware/chatBodyAdmission.ts` | **#503-fanout:** este limite legado de CONTAGEM de pedidos só se aplica quando definido explicitamente. Se não for definido (a predefinição), a admissão de chat pesado passa a ser controlada por `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` — um orçamento de BYTES derivado automaticamente, dimensionado a partir do limite real de memória do processo em **um processo** (um heap V8). Dois `/v1/responses` sobrepostos de ~750 mil tokens abortam heaps de ~12 Gi (#7849) — um aviso de **orçamento de memória**, não um máximo rígido de produto de 2. Um processo saudável (heap abaixo do rácio de descarte) PODE admitir mais `/v1/responses` longos concorrentes através de `OMNIROUTE_CHAT_ADMISSION_HEALTHY_HEADROOM`. Dezenas de clientes SSE longos (40–50) correspondem a heap + `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` / #10110, não a “máx. 2”. Aumentar isto cegamente para “usar o host” reintroduz #7849. Multiplique **heaps** com **N `DATA_DIR`s independentes** (#11024); nunca `replicas>1` num único ficheiro SQLite. |
| `OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES` | _(derivado automaticamente)_ | `src/shared/middleware/admissionBudget.ts` | **#503-fanout:** substituição do orçamento de bytes de ingestão derivado automaticamente (25% do limite de memória mais restritivo entre V8/cgroup, dividido por uma amplificação transitória de 8x). Os valores derivados e explícitos são fixados entre 8 MiB–2 GiB. Um corpo maior que o orçamento efetivo falha imediatamente com `413 body_exceeds_budget`; a contenção entre corpos individualmente servíveis continua a resultar num `503` repetível. 40–50 clientes SSE longos concorrentes correspondem a este orçamento + heap, não a um “máx. 2” rígido. Leia `chatAdmission.maxInflightBytes` / `budgetSource` / `pressureSeverity` em `/api/monitoring/health` antes de afinar. |
| `OMNIROUTE_CHAT_ADMISSION_HEAP_SHED_RATIO` | `0.75` | `src/shared/middleware/chatBodyAdmission.ts` | Rácio de descarte por pressão do heap (`heapUsed / heap_size_limit`) para a admissão de pedidos pesados BYTE e STRUCTURE (#10183, #10268, #10437). Um pedido pesado concorrente acima de `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` só é descartado com o `503` repetível quando o heap TAMBÉM está neste rácio ou acima dele; num heap saudável, é admitido através da margem de heap saudável (healthy-headroom). |
| `OMNIROUTE_CHAT_ADMISSION_HEALTHY_HEADROOM` | `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` (predefinição `1`) | `src/shared/middleware/chatBodyAdmission.ts` | Capacidade extra limitada para o caminho rápido de heap saudável (#10437) em **ambos** STRUCTURE e BYTE (`admitChatRequest`, incluindo corpos ≥ `OMNIROUTE_CHAT_LARGE_BODY_BYTES`). Sem este limite, todos os pedidos com sistema ocupado mas heap saudável contornavam a admissão sem qualquer teto. Assim que este número de concessões concorrentes estiver ativo através do caminho de heap saudável, os pedidos ocupados adicionais passam para o MESMO caminho de espera limitada/descarte usado sob pressão real do heap. `0` desativa completamente o desvio. |
| `OMNIROUTE_CHAT_HEAVY_MESSAGE_COUNT` | `200` | `src/shared/middleware/chatBodyAdmission.ts` | Número de mensagens que classifica um pedido de chat como pesado, mesmo quando o seu corpo está abaixo do limiar de bytes. |
| `OMNIROUTE_CHAT_HEAVY_TOOL_COUNT` | `64` | `src/shared/middleware/chatBodyAdmission.ts` | Número de ferramentas que classifica um pedido de chat como pesado, mesmo quando o seu corpo está abaixo do limiar de bytes. |
| `OMNIROUTE_CHAT_HEAVY_ESTIMATED_TOKENS` | `32000` | `src/shared/middleware/chatBodyAdmission.ts` | Estimativa conservadora de tokens pelo tamanho da string, que classifica um pedido como pesado; trata-se de um indicador do custo de admissão, não da tokenização de faturação do fornecedor. |
| `OMNIROUTE_CHAT_HARD_MAX_MESSAGES` | `0` (desativado) | `src/shared/middleware/chatBodyAdmission.ts` | Limite opcional (opt-in) do histórico de chat. Desativado por predefinição: a contagem de mensagens é uma política de implementação, não uma propriedade universal de um pedido, e limitar aqui rejeita conversas com um `413` terminal antes de o pipeline de compressão as poder tornar servíveis. O crescimento do heap é limitado por `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` e pelo descarte por pressão do heap. Defina um valor positivo em implementações com memória limitada que precisem de um teto rígido; o excesso recebe então um `413` estruturado com indicação de compactação necessária. |
| `OMNIROUTE_MAX_NONSTREAMING_RESPONSE_BYTES` | `67108864` (64 MB) | `open-sse/handlers/chatCore/nonStreamingResponseBody.ts` | Limite rígido para uma resposta upstream sem streaming, totalmente colocada em buffer na memória. Acima deste valor, o leitor upstream é cancelado e o pedido falha rapidamente, em vez de fazer crescer uma string ilimitada até esgotar o heap. |
| `OMNIROUTE_FORWARDING_HEADER_BUDGET_BYTES` | `768` | `open-sse/handlers/chatCore/responseHeaders.ts` | Número máximo de bytes em fio reencaminhados a partir dos cabeçalhos de resposta do upstream. Quando o orçamento é excedido, os cabeçalhos de menor prioridade (por exemplo, `x-codex-*` personalizados, `x-oai-request-id`) são descartados para se manterem dentro dos limites habituais dos cabeçalhos de proxy reverso. Defina um valor mais elevado para reencaminhar mais metadados do upstream, à custa de um tamanho maior dos cabeçalhos de resposta. |
| `CORS_ORIGIN` | _(não definido)_ | `src/server/cors/origins.ts` | Lista de permissões CORS legada de origem única. Para novas implementações, prefira `CORS_ALLOWED_ORIGINS`. O CORS destina-se apenas a clientes de API de browser de origem cruzada; as escritas autenticadas do dashboard utilizam, em vez disso, pedidos da mesma origem, juntamente com proteção CSRF associada à sessão. |
| `CORS_ALLOWED_ORIGINS` | _(não definido)_ | `src/server/cors/origins.ts` | Lista de permissões CORS separada por vírgulas. Não é enviado nenhum wildcard, a menos que `CORS_ALLOW_ALL=true` esteja explicitamente configurado. |
| `CORS_ALLOW_ALL` | `false` | `src/server/cors/origins.ts` | Válvula de escape apenas para desenvolvimento que replica qualquer `Origin` do browser. Não ative em implementações partilhadas ou de produção. |
| `OUTBOUND_SSRF_GUARD_ENABLED` | `true` | `src/shared/network/outboundUrlGuardPolicy.ts` | Alias legado. O respetivo toggle do dashboard (uma substituição na BD) é lido antes deste valor de ambiente; `false`, `0`, `no` ou `off` em qualquer um deles desativa as verificações de host da mesma forma que `OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS=true`, mesmo quando o toggle do dashboard dessa flag está guardado como desativado; os restantes valores deixam a proteção ao critério das duas flags abaixo. |
| `OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS` | `false` | `src/shared/network/outboundUrlGuardPolicy.ts` | Desativa as verificações de host da proteção de URLs de saída, incluindo o bloqueio de metadados da cloud (todo o intervalo 169.254.0.0/16, metadata.google.internal), nos caminhos de fornecedor que seguem o modo de proteção: validação de URL, descoberta de modelos, URLs base de nós de fornecedor (incluindo nós de rerank remotos) e o teste de fallback do proxy, entre outros caminhos de saída adjacentes a fornecedores, como a obtenção remota de imagens/conteúdos multimédia. Permite também destinos de webhook privados, exceto endpoints de metadados da cloud/link-local, que continuam bloqueados mesmo com esta flag ativa. Os pedidos de chat enviados através de `BaseExecutor.execute()` mantêm a verificação de metadados da cloud. Os fornecedores locais funcionam com os valores predefinidos: `OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS` (predefinição `true`) já permite URLs locais e de LAN nos caminhos de validação, descoberta e nós de fornecedor; o teste de fallback do proxy e os destinos de webhook privados consultam apenas esta flag e bloqueiam hosts locais/de LAN enquanto estiver desativada. Substitui `OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS=false`. Um valor guardado a partir do toggle do dashboard tem precedência sobre esta variável. |
| `OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS` | `true` | `src/shared/network/outboundUrlGuardPolicy.ts` | Permite URLs de fornecedor em endereços locais/privados (127.0.0.1, localhost, LAN, intervalos privados) para validação de fornecedores, descoberta de modelos, chat e os restantes caminhos de saída adjacentes a fornecedores regidos pelo modo de proteção. **Predefinição `true`** (local-first): a proteção bloqueia então os endpoints de metadados da cloud — todo o intervalo 169.254.0.0/16, além dos nomes de host de metadados conhecidos (metadata.google.internal, metadata.goog, Alibaba/Azure/Oracle IMDS, fd00:ec2::254). Defina `false` para o modo apenas público, que também bloqueia hosts privados e de loopback. A proteção verifica o nome de host ou o literal de IP tal como está escrito, antes de qualquer pesquisa de DNS; no modo apenas público, o wrapper de obtenção segura resolve adicionalmente o nome de host e recusa qualquer resposta privada. `OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS=true` desativa estas verificações nos caminhos listados na respetiva linha. Os fornecedores locais integrados, como LM Studio, Ollama, vLLM, Llamafile e Triton, ignoram todas as verificações de host para validação de chaves e chat. Um valor guardado a partir do toggle do dashboard tem precedência sobre esta variável. (#5066) |
| `AUDIO_REMOTE_PROVIDER_NODES` | `false` | `src/app/api/v1/_shared/audioProviderNodes.ts` | Permite que as rotas `/v1/audio/*` (transcrições, voz, traduções) utilizem um nó de fornecedor compatível com OpenAI alojado fora do localhost. Desativado por predefinição — encaminhar áudio para um host remoto altera a identidade de saída e tem de ser uma decisão explícita do operador. Os nós de loopback/privados (localhost, 127.0.0.1, 172.16-31.x) são sempre permitidos e não são afetados. (#3963) |
| `RERANK_REMOTE_PROVIDER_NODES` | `false` | `src/app/api/v1/_shared/rerankProviderNodes.ts` | Permite que `POST /v1/rerank` (e o passo de rerank em loopback do motor de memória) utilize um nó de fornecedor compatível com OpenAI alojado fora do localhost — uma máquina na LAN ou um par Tailscale a executar TEI, Infinity, vLLM, etc. Desativado por predefinição — encaminhar para um host remoto altera a identidade de saída e tem de ser uma decisão explícita do operador. Os nós de loopback (localhost, 127.0.0.1, 172.16-31.x) são sempre permitidos e não são afetados. O URL base de um nó remoto também tem de passar a política de URLs de saída do fornecedor (`OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS` / `OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS`). |
| `OMNIROUTE_LOCAL_PROVIDER_NODE_HOSTS` | _(vazio)_ | `src/shared/network/localNodeHosts.ts` | Hostnames (separados por vírgulas ou espaços em branco) que o encaminhamento de nós de fornecedor trata como locais — tipicamente o nome do serviço Docker/Compose de um reranker, TEI ou sidecar de áudio na própria rede Docker do OmniRoute (`http://reranker:8080/v1`), para que o nó não necessite de um IP de contentor fixo. Os hosts listados são elegíveis para `/v1/rerank`, `/v1/audio/*` e para a verificação de estado local sem ativar `RERANK_REMOTE_PROVIDER_NODES` / `AUDIO_REMOTE_PROVIDER_NODES` para todos os nós remotos, e são chamados diretamente — nunca através de `HTTP(S)_PROXY` nem de um proxy fixado na ligação. Continuam a enviar a chave de API da ligação. Apenas são aceites nomes de etiqueta única e nomes `.internal`/`.local`; FQDNs públicos, literais de IP e nomes de metadados da cloud são ignorados com um aviso. (#14635) |
| `OMNIROUTE_OIDC_DISABLE_PASSWORD_LOGIN` | `false` | `src/app/api/auth/login/route.ts` | Quando o OIDC está ativado, desativa o início de sessão por palavra-passe para que os utilizadores só se possam autenticar através do OIDC Single Sign-On. O alias simples `OIDC_DISABLE_PASSWORD_LOGIN` também é aceite; a Feature Flag do Dashboard com a mesma chave tem precedência. (#10889) |
| `OIDC_DISABLE_PASSWORD_LOGIN` | `false` | `src/app/api/auth/login/route.ts` | Alias simples de `OMNIROUTE_OIDC_DISABLE_PASSWORD_LOGIN` (#10889). |
### Lista de Verificação de Hardening
```bash
# Mínimo de segurança para produção:
AUTH_COOKIE_SECURE=true # Requer HTTPS
REQUIRE_API_KEY=true # Autenticar todas as chamadas ao proxy
ALLOW_API_KEY_REVEAL=false # Nunca expor chaves na UI
CORS_ALLOWED_ORIGINS=https://your.domain.com
MAX_BODY_SIZE_BYTES=5242880 # Limite de 5 MB
```
---
## 5. Saneamento de entradas e proteção de PII
O OmniRoute fornece uma defesa em duas camadas: análise de injeções do lado dos pedidos e remoção de PII do lado das respostas.
> **⚠️ Limitações:** Estas proteções são deteções heurísticas de _melhor esforço_, não uma firewall completa contra injeções de prompts nem um sistema DLP de PII. Podem produzir falsos positivos (prompts inofensivos de personas/RPG sinalizados) e falsos negativos (leetspeak, espaçamento, padrões não ingleses). Por si só, não são suficientes para garantir a conformidade. Ajuste os modos e teste-os com o seu tráfego antes de confiar neles.
### Lado dos pedidos: proteção contra injeção de prompts
| Variável | Predefinição | Ficheiro de origem | Descrição |
| --------------------------------- | ---------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `INPUT_SANITIZER_ENABLED` | `true` | `src/middleware/promptInjectionGuard.ts` | Ativa a análise das mensagens recebidas para detetar padrões de injeção de prompts. |
| `INPUT_SANITIZER_MODE` | `warn` | `src/middleware/promptInjectionGuard.ts` | Política de injeção: `warn` = apenas registar, `block` = rejeitar o pedido com 400. O modo legado `redact` **não** remove texto de injeção; utilize `PII_REDACTION_ENABLED` para reescrever PII nos pedidos. |
| `INJECTION_GUARD_MODE` | _(não definido)_ | `src/middleware/promptInjectionGuard.ts` | Nome alternativo legado de `INPUT_SANITIZER_MODE` — mesmo comportamento. |
| `INPUT_SANITIZER_BLOCK_THRESHOLD` | `high` | `src/shared/utils/injectionSeverity.ts` | Gravidade mínima rejeitada por `MODE=block`: `high` (predefinição), `medium` ou `low`. Os padrões de gravidade média são apenas observados, a menos que o limiar seja reduzido. |
| `INJECTION_GUARD_BLOCK_THRESHOLD` | _(não definido)_ | `src/shared/utils/injectionSeverity.ts` | Nome alternativo legado de `INPUT_SANITIZER_BLOCK_THRESHOLD` — mesmo comportamento. |
| `PII_REDACTION_ENABLED` | `false` | `src/lib/guardrails/piiMasker.ts` | Quando definido como `true`, oculta PII nos pedidos recebidos (independentemente do modo de injeção). |
| `CREDENTIAL_REDACTION_ENABLED` | `false` | `src/lib/guardrails/credentialMasker.ts` | Oculta padrões conhecidos de chaves de API/tokens secretos dos conteúdos dos pedidos e das respostas. Opcional; reflete `PII_REDACTION_ENABLED`. |
### Lado das respostas: saneador de PII
| Variável | Predefinição | Ficheiro de origem | Descrição |
| -------------------------------- | ------------ | ------------------------- | ---------------------------------------------------------------------------------------- |
| `PII_RESPONSE_SANITIZATION` | `false` | `src/lib/piiSanitizer.ts` | Analisa as respostas do LLM para detetar PII divulgadas antes de as devolver ao cliente. |
| `PII_RESPONSE_SANITIZATION_MODE` | `redact` | `src/lib/piiSanitizer.ts` | `redact` = ocultar PII, `warn` = apenas registar, `block` = descartar toda a resposta. |
### Saneador de contexto de rotas tokenizadas do VS Code
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ----------------------------------- | ------------ | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_VSCODE_SANITIZE_CONTEXT` | `1` | `src/app/api/v1/vscode/contextSanitizer.ts` | Remove o contexto implícito do editor ativo (`editorContext`, `activeEditor`, `currentFile`, `selection`, `openTabs`…) dos pedidos para `/v1/vscode/[token]/*` e oculta o conteúdo de ficheiros sensíveis anexados explicitamente. Seguro por predefinição; defina como `0` para desativar. |
### Cenários
| Cenário | Configuração |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Conformidade empresarial** | `INPUT_SANITIZER_ENABLED=true`, `INPUT_SANITIZER_MODE=block`, `PII_REDACTION_ENABLED=true`, `PII_RESPONSE_SANITIZATION=true` (bloqueio de injeções + ocultação de PII nos pedidos/respostas; os modos são independentes) |
| **Apenas monitorização** | `INPUT_SANITIZER_ENABLED=true`, `INPUT_SANITIZER_MODE=warn` — regista, mas nunca bloqueia |
| **Utilização pessoal** | Deixe tudo desativado — sobrecarga nula |
---
## 6. Políticas de Ferramentas e Encaminhamento
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ----------------------------------------------------------- | ------------------------------ | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `TOOL_POLICY_MODE` | `disabled` | `src/lib/toolPolicy.ts` | Controla o acesso a ferramentas/chamadas de funções do LLM. `allowlist` = apenas as ferramentas listadas, `denylist` = todas exceto as listadas, `disabled` = sem restrições. |
| `OMNIROUTE_PAYLOAD_RULES_PATH` | `./config/payloadRules.json` | `open-sse/services/payloadRules.ts` | Caminho para o ficheiro JSON de regras de manipulação de payloads (ajustes upstream por modelo/protocolo). |
| `OMNIROUTE_PAYLOAD_RULES_RELOAD_MS` | `5000` | `open-sse/services/payloadRules.ts` | Intervalo de recarregamento (ms) para o hot-reloading do ficheiro de regras de payload. Mínimo `1000`. |
| `OMNIROUTE_PREFER_CLAUDE_CODE_FOR_UNPREFIXED_CLAUDE_MODELS` | `false` | `open-sse/services/model.ts` | Opção voluntária: encaminha IDs de modelos `claude-*` sem prefixo provenientes de clientes Claude Code através da conta OAuth do Claude Code, em vez de exigir um prefixo de fornecedor. Prefixos de fornecedor explícitos continuam a ter prioridade. Também configurável através de um interruptor no dashboard na página do fornecedor Claude. |
| `OMNIROUTE_REDACT_THINKING` | `true` | `open-sse/executors/base/redactThinkingBeta.ts` | Defina como `false` para impedir que o OmniRoute adicione por si próprio a beta `redact-thinking-2026-02-12` da Anthropic (blocos de pensamento vazios, apenas com assinatura). Pedidos com `thinking.display: "summarized"` ignoram-na independentemente; uma beta de redação negociada pelo cliente ou uma ativação de `requestDefaults.redactThinking` compatível com CC mantém-na. Os pedidos OAuth do Claude mantêm a beta (faz parte da impressão digital OAuth do Claude Code), exceto se a feature flag `CLAUDE_OAUTH_SUMMARIZED_THINKING_UNREDACTED`, desativada por predefinição, estiver ativa. |
| `BARE_MODEL_DEFAULT_OVERRIDE_LEGACY` | `false` | `open-sse/services/model.ts` | Comportamento legado de `resolveBareModelToConnectionDefault` (#4825): substitui qualquer nome de modelo sem prefixo pelo `defaultModel` da ligação selecionada. Desativado por predefinição; apenas `auto` ou um modelo vazio é substituído; regista um aviso por par quando ativo. |
| `COMBO_CONCURRENCY_PER_MODEL` | `3` | `open-sse/services/comboConfig.ts` | Limite de concorrência por modelo para combos round-robin (#9100). O semáforo do combo round-robin tinha um limite fixo de 3 pedidos simultâneos por modelo sem possibilidade de alteração, serializando tráfego de maior concorrência atrás desse limite. Validado para `>= 1`, limitado a `<= 32`. |
| `DISABLE_CONTEXT_WINDOW_CHECKS` | `false` | `open-sse/handlers/chatCore.ts` | Opção voluntária perigosa que ignora a verificação local da janela de contexto / máximo de tokens de entrada do OmniRoute para pedidos diretos de modelo único. Os fornecedores upstream continuam a aplicar os seus limites reais; a compressão de prompts e o limite de tokens de saída do próprio modelo permanecem ativos. A precedência efetiva é Feature Flags DB override > variável de ambiente > predefinição; não é necessário reiniciar. |
| `OMNIROUTE_SELF_HOSTED_PROVIDERS` | _(não definido)_ | `open-sse/services/selfHostedEntry.ts` | Documento YAML inline `providers:` (RIC-738, D4). Quando definido (com ou sem um bloco `strategy:`), `/v1/chat/completions` é desviado para a entrada unificada self-hosted compatível com OpenAI em vez do pipeline na cloud. Não definido (a predefinição): a rota passa diretamente para o pipeline na cloud existente. Consulte `docs/routing/SELF_HOSTED_OPENAI_ENTRY.md`. |
| `OMNIROUTE_SELF_HOSTED_PROVIDERS_FILE` | _(não definido)_ | `open-sse/services/selfHostedEntry.ts` | Caminho para um ficheiro YAML que contém o mesmo documento `providers:` que `OMNIROUTE_SELF_HOSTED_PROVIDERS`, para implementações que preferem um ficheiro em vez de uma variável de ambiente inline. Qualquer uma das opções ativa a entrada self-hosted. |
| `OMNIROUTE_SELF_HOSTED_API_KEY` | _(não definido — rota aberta)_ | `open-sse/services/selfHostedEntry.ts` | Chave de API partilhada opcional para a entrada unificada self-hosted (scaffold D5, reservado para o sistema de quotas por chave). Quando definida, os pedidos devem incluir `Authorization: Bearer `. Não definida: a rota fica aberta, seguindo o padrão existente de fornecedores locais self-hosted (implementação em loopback/rede de confiança). |
| `OMNIROUTE_SELF_HOSTED_STRATEGY` | _(não definido)_ | `open-sse/services/routingStrategies.ts` | Documento YAML inline `strategy:` para o motor de encaminhamento determinístico (M2/RIC-740, D3) — blacklist/whitelist, disjuntor de cooldown, prioridade por custo, sensibilidade à latência, cadeia de fallback. Substitui, por chave, um bloco `strategy:` inline aninhado dentro de `OMNIROUTE_SELF_HOSTED_PROVIDERS`. Consulte `docs/routing/DETERMINISTIC_ROUTING.md`. |
| `OMNIROUTE_SELF_HOSTED_STRATEGY_FILE` | _(não definido)_ | `open-sse/services/routingStrategies.ts` | Caminho para um ficheiro YAML com o mesmo documento `strategy:` de `OMNIROUTE_SELF_HOSTED_STRATEGY`, para implementações que preferem um ficheiro em vez de uma variável de ambiente inline. |
| `OMNIROUTE_DISABLE_CONVERSATION_TRACKING` | _(não definido)_ | `open-sse/services/conversationTracker.ts` | Defina `1` para deixar de recolher o histórico de conversas. `resolveConversationId()` devolve um resultado não monitorizado antes de ler o SQLite ou analisar o histórico de mensagens, e os IDs de sessão fornecidos pelo cliente também estão abrangidos. O tratamento das sessões de encaminhamento permanece inalterado e os registos existentes não são eliminados. Destina-se a implementações que não utilizam a vista de conversas do dashboard e pretendem que a tabela de turnos deixe de crescer. |
| `OMNIROUTE_NADIR_API_KEY` | _(não definido)_ | `open-sse/services/autoCombo/nadirStrategy.ts` | Chave de API para a estratégia opt-in de router auto-combo `nadir`, utilizada quando o `config.nadir.apiKey` do próprio combo não está definido. Opcional: as chamadas sem chave recaem no escalão anónimo do Nadir, que é sujeito a limitação de taxa por IP e, por isso, não é utilizável atrás de um gateway partilhado. Sensível; prefira o campo por combo quando os combos utilizam contas diferentes. |
| `OMNIROUTE_NADIR_BASE_URL` | `https://api.getnadir.com` | `open-sse/services/autoCombo/nadirStrategy.ts` | Origem base da API de decisão do Nadir, utilizada quando o `config.nadir.baseUrl` do próprio combo não está definido. Apenas necessário para um Nadir autoalojado, que mantém os prefixos dos prompts dentro da sua própria rede. Um `/v1` final é tolerado e removido. |
| `OMNIROUTE_API_KEY_WEEKLY_WINDOW` | `provider` | `src/lib/usage/apiKeyUsageLimits.ts` | Janela semanal para os limites de utilização em USD por chave de API (aplicação nos pedidos, `GET /api/keys/{id}/usage-limits`, `@@om-usage`). `provider`: a semana termina na primeira reposição semanal de entre as ligações upstream a que a chave tem acesso, ou corresponde a um período móvel de 7 dias quando nenhuma é conhecida. `calendar`: a semana local de segunda-feira às 00:00 até à segunda-feira seguinte às 00:00, idêntica para todas as chaves. `calendar` é recomendado quando um conjunto de contas upstream é partilhado por muitas chaves com orçamentos individuais. Valores inválidos revertem para `provider`. |
| `OMNIROUTE_API_KEY_WEEKLY_WINDOW_TIMEZONE` | _(fuso horário do processo)_ | `src/lib/usage/apiKeyUsageLimits.ts` | Fuso horário IANA (por exemplo `Asia/Shanghai`) que define segunda-feira às 00:00 para a janela semanal `calendar`. Não definido ou inválido: o fuso horário do processo OmniRoute (o `TZ` do anfitrião ou do contentor, que frequentemente não está definido — ou seja, Tempo Universal Coordenado — nas imagens de contentor). Ignorado no modo `provider`. |
| `OMNIROUTE_MAX_TOOLS_LIMIT` | `128` | `open-sse/config/constants.ts` | Número máximo predefinido de ferramentas permitidas num pedido (predefinição da OpenAI). Apenas inteiros positivos; valores não definidos ou inválidos mantêm `128`. Um fornecedor com um limite conhecido/proactivo (`grok-cli` 200, `nvidia` 1536) continua a aplicar o seu próprio limite máximo — isto apenas altera o teto predefinido. |
| `OMNIROUTE_PROMPT_EMULATE_TOOLS` | _(on)_ | `open-sse/executors/syntxChat.ts` | Chamada de ferramentas emulada por prompt do SYNTX.ai: não definido ou `1`/`true`/`on`/`yes` injeta o catálogo local de ferramentas no prompt; qualquer outro valor (por exemplo `0`) omite essa injeção. |
---
## 7. URLs e sincronização na nuvem
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `BASE_URL` | `http://localhost:20128` | `src/lib/cloudSync.ts` | URL do lado do servidor utilizada pelas tarefas internas de sincronização para chamar `/api/sync/cloud`. Mantenha-a como um URL de loopback/contentor, mesmo quando a aplicação é disponibilizada publicamente através de um proxy. |
| `CLOUD_URL` | _(vazio)_ | `src/lib/cloudSync.ts` | URL do endpoint de retransmissão na nuvem (funcionalidade premium). |
| `CLOUD_SYNC_TIMEOUT_MS` | `12000` | `src/lib/cloudSync.ts` | Tempo limite HTTP para pedidos de sincronização na nuvem. |
| `OMNIROUTE_BUILD_PROFILE` | `full` | Configuração de compilação do Webpack | Perfil de compilação (defina como `minimal` para excluir fisicamente os módulos privilegiados do bundle). |
| `OMNIROUTE_STANDALONE_DIR` | _.build/ saída standalone_ | `scripts/build/colocate-standalone.mjs` | Substituição, em tempo de compilação, do diretório de saída standalone utilizado pelo passo de colocação posterior à compilação. Não é uma definição de tempo de execução. |
| `OMNIROUTE_CLOUD_SYNC_SECRET` | _(vazio)_ | `src/lib/cloudSync.ts` | Segredo partilhado utilizado para verificar a assinatura HMAC-SHA256 das respostas da sincronização na nuvem. |
| `OMNIROUTE_CLOUD_SYNC_SECRETS` | `false` | `src/lib/cloudSync.ts` | Defina como `true` para permitir que o endpoint de sincronização na nuvem substitua as credenciais locais. A predefinição é `false`. |
| `OMNIROUTE_CLOUD_SYNC_ENFORCE_SIGNATURE` | `false` | `src/lib/cloudSync.ts` | Defina como `true` para rejeitar uma resposta de sincronização na nuvem sem assinatura quando não estiver configurado qualquer segredo local (#13679). Uma assinatura presente é sempre verificada — e sempre rejeitada quando `OMNIROUTE_CLOUD_SYNC_SECRET` não está definido — independentemente desta opção. Na v3.9, a predefinição passa a exigir a assinatura. |
| `OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEP` | `false` | `src/app/api/providers/zed/import/route.ts` | Defina como `true` para reverter para o comportamento de um único passo "importar tudo" da v3.8.5, sem confirmação do utilizador. |
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | OAuth, Painel, sincronização | URL pública para o redirect_uri do OAuth, ligações do Painel e URLs públicas geradas. Defina-a como o URL público estável quando os callbacks do OAuth ou as ligações geradas para o navegador tiverem de utilizar um anfitrião canónico de proxy inverso. |
| `NEXT_PUBLIC_CLOUD_URL` | _(vazio)_ | Lado do cliente | Espelho de `CLOUD_URL` no lado do cliente. |
| `NEXT_PUBLIC_APP_URL` | _(não definido)_ | `src/shared/services/cloudSyncScheduler.ts` | Alternativa legada para `NEXT_PUBLIC_BASE_URL`. |
| `NEXT_PUBLIC_PORT` | _(não definido — recorre a `PORT`)_ | `src/shared/hooks/useDisplayBaseUrl.ts` | Porta alternativa do lado do cliente para URLs de apresentação quando não é conhecida nenhuma origem (SSR/testes); lida antes de `PORT`. |
| `OMNIROUTE_PUBLIC_BASE_URL` | _(não definido)_ | Resolvedor de origem pública, URLs de imagens | Origem do OmniRoute destinada ao browser com a prioridade mais alta, utilizada para a geração de URLs públicas e a validação da origem do browser fora do dashboard. Defina esta variável quando o OpenWebUI ou outro relay aceder ao OmniRoute através de um URL interno, mas o browser do utilizador tiver de obter os conteúdos multimédia gerados a partir de uma origem LAN, de túnel ou pública. **Não** inclua `/v1`. |
| `OMNIROUTE_PROVIDER_MANIFEST_URL` | _(não definido)_ | `open-sse/config/providerPluginManifestUrl.ts` | URL absoluto do manifesto de plugins de fornecedores anunciado aos clientes sidecar. Quando não está definido, o OmniRoute deriva `/api/v1/provider-plugin-manifest` da origem do pedido ou de HOST/PORT. |
| `OMNIROUTE_PUBLIC_PROTOCOL` | `http` | `open-sse/config/providerPluginManifestUrl.ts` | Protocolo utilizado ao derivar o URL do manifesto de plugins de fornecedores a partir de HOST/PORT sem uma origem do pedido. Defina como `https` atrás de um proxy público que termine TLS quando não estiver definido nenhum `OMNIROUTE_PROVIDER_MANIFEST_URL` explícito. |
| `OMNIROUTE_TRUST_PROXY` | _(não definido)_ | `src/server/origin/publicOrigin.ts` | Modo de confiança opcional para cabeçalhos de origem pública reencaminhados. Não definido = não confiar em `Forwarded` / `X-Forwarded-*` para decisões de segurança. `true` / `loopback` confia no anfitrião/protocolo reencaminhado apenas a partir de um proxy de loopback marcado com um token. `private` / `lan` também confia em peers de proxy de LAN privada e permite que a bridge `API_PORT` mantenha o `X-Forwarded-For` desse peer. Em produção, dê preferência a um `NEXT_PUBLIC_BASE_URL` explícito. |
| `KIE_CALLBACK_URL` | _(não definido)_ | `open-sse/utils/kieTask.ts` | URL público de callback para tarefas assíncronas do kie.ai. Substituição com prioridade mais alta, antes de `OMNIROUTE_KIE_CALLBACK_URL` e `OMNIROUTE_PUBLIC_URL`. |
| `OMNIROUTE_KIE_CALLBACK_URL` | _(não definido)_ | `open-sse/utils/kieTask.ts` | Nome alternativo de `KIE_CALLBACK_URL`. É utilizado como alternativa quando a variável principal não está definida. |
| `OMNIROUTE_PUBLIC_URL` | _(não definido)_ | `open-sse/utils/kieTask.ts` | Origem pública utilizada para compor URLs de callback assíncronos. Alternativa de prioridade mais baixa para callbacks do kie.ai; também utilizada como URL público genérico para outros relays. |
| `OMNIROUTE_CROF_USAGE_URL` | `https://crof.ai/usage_api/` | `open-sse/services/usage.ts` | Endpoint de consulta de quotas do CrofAI utilizado pela página Utilização. Substitua-o para relays / fixtures de teste. |
| `OMNIROUTE_CLINEPASS_USAGE_URL` | `https://api.cline.bot/api/v1/users/me/plan/usage-limits` | `open-sse/services/usage/clinepass.ts` | Endpoint de quotas de 5 horas / semanais / mensais do ClinePass utilizado pela página Utilização. Substitua-o para relays / fixtures de teste. |
| `OMNIROUTE_OPENCODE_QUOTA_URL` | `https://opencode.ai/zen/go/v1/usage` | `open-sse/services/opencodeQuotaFetcher.ts` | Endpoint oficial de utilização do OpenCode Go, autenticado por chave de API, utilizado pela página Utilização. Substitua-o para relays / fixtures de teste. |
| `OPENCODE_SYNTHESIZE_CLI_HEADERS` | `true` | `open-sse/executors/opencode.ts` | Sintetiza cabeçalhos de identidade da CLI do OpenCode (User-Agent, x-opencode-client/project, UUIDs de pedido/sessão) em pedidos upstream do opencode-go/zen que não tenham sido enviados pelo cliente, para que a Cloudflare os aceite no tráfego de saída de VPS (#6210/#5997). Ativo por predefinição desde #10571; desative com `false`/`0`/`no`/`off`. |
| `OPENCODE_USER_AGENT` | `opencode/1.18.31` | `open-sse/utils/opencodeHeaders.ts` | User-Agent predefinido utilizado quando `OPENCODE_SYNTHESIZE_CLI_HEADERS` está ativado e não está definida nenhuma substituição `_USER_AGENT` por fornecedor. Aplicado apenas a executores opencode. Num pedido sem chave que seja bloqueado pelos controlos a montante, um valor configurado que não contenha `opencode/= 1.17>` é substituído por esta predefinição, em vez de ser recusado. |
| `OMNIROUTE_FORWARD_ATTRIBUTION` | `1` (ativado) | `open-sse/utils/opencodeHeaders.ts` | Reencaminha os cabeçalhos de atribuição da aplicação cliente (`x-session-id`, `x-title`, `http-referer`) para os fornecedores a montante, para que um pedido iniciado dentro de uma aplicação cliente listada mantenha a respetiva identidade através do router (os controlos de publicador do OpenRouter baseiam-se nestes cabeçalhos). `0`/`false`/`no`/`off` mantém a identidade do registo/operador e descarta os valores fornecidos pelo cliente. Os cabeçalhos personalizados configurados pelo operador têm sempre precedência sobre os valores do cliente. |
| `OPENCODE_CLIENT` | `desktop` | `open-sse/executors/opencode.ts` | Valor para o cabeçalho `x-opencode-client` sintetizado quando `OPENCODE_SYNTHESIZE_CLI_HEADERS` está ativado. |
| `OPENCODE_PROJECT` | `global` | `open-sse/executors/opencode.ts` | Valor para o cabeçalho `x-opencode-project` sintetizado quando `OPENCODE_SYNTHESIZE_CLI_HEADERS` está ativado. |
| `OMNIROUTE_EGRESS_IP_LOCK_PROVIDERS` | _(não definido)_ | `open-sse/config/providerErrorRules.ts` | Conjunto efetivo de fornecedores cujas falhas a montante são agrupadas por IP de saída (um erro 429 suspende todas as ligações relacionadas que partilhem esse IP). Quando não definido, utiliza a predefinição do escalão gratuito `opencode,opencode-go,opencode-cli`; `none`/`off`/`false`/`0` desativa totalmente a cascata; uma lista separada por vírgulas substitui o conjunto. Os planos pagos são agrupados por conta a montante e podem desativá-la em segurança (#9611). |
| `OMNIROUTE_EGRESS_QUOTA_ROTATION_PROVIDERS` | _(não definido)_ | `open-sse/config/providerErrorRules.ts` | Âmbito da rotação da saída em caso de recusa por quota. Quando não definido, coloca um membro do conjunto de parte após um erro 429 apenas para a família agrupada por IP acima; `all` estende essa escrita a todos os fornecedores, pelo que um limite de taxa recebido através de um membro faz com que a seleção seguinte utilize outra saída. Qualquer valor diferente de `all` é ignorado. Requer `PROXY_SKIP_RECENTLY_FAILED` (ativado por predefinição). O armazenamento é indexado pelo endereço de saída, não por (fornecedor, endereço), pelo que um erro 429 com âmbito alargado suspende esse membro para todos os fornecedores até o período terminar (5 min, duplicando para 15). É lido após o resultado de cada resposta, pelo que uma alteração é aplicada sem reiniciar. |
| `OPENCODE_FREE_TIER_REQUEST_CONTRACT` | _(não definido)_ | `open-sse/executors/opencodeFreeTierContract.ts` | Defina como `off` para deixar de ajustar o corpo dos pedidos OpenCode sem chave (sinalizador de streaming e lista de ferramentas). Os cabeçalhos continuam a ser aplicados. É lido em cada pedido, pelo que uma alteração entra imediatamente em vigor. |
| `OPENCODE_FREE_TIER_PLACEHOLDER_TOOLS` | _(não definido)_ | `open-sse/executors/opencodeFreeTierContract.ts` | Nomes de ferramentas separados por vírgulas a declarar num pedido OpenCode sem chave que não contenha nenhuma, quando ainda nada tiver sido observado para esse modelo. Se estiver vazio, recorre a um único marcador de posição que o modelo é instruído a não invocar. No máximo 32 entradas, `[A-Za-z_][A-Za-z0-9_-]{0,63}`; as entradas inválidas são ignoradas. |
| `OMNIROUTE_OLLAMA_CLOUD_USAGE_URL` | `https://ollama.com/settings` | `open-sse/services/usage.ts` | URL das definições do Ollama Cloud utilizada para extrair a quota. Substitua-a para relays/fixtures de teste. |
| `OMNIROUTE_OLLAMA_CLOUD_BALANCE_URL` | `https://ollama.com/api/balance` | `open-sse/services/ollamaCloudBalance.ts` | Endpoint de saldo a montante documentado do Ollama Cloud (`GET https://ollama.com/api/balance`, `Authorization: Bearer `). Lido uma vez durante o carregamento do módulo. É utilizado primeiro para a quota do Ollama Cloud quando a ligação tem uma chave de API; o extrator de cookies da página de definições permanece como alternativa. Substitua-o para relays/fixtures de teste. |
| `OLLAMA_USAGE_COOKIE` | _(não definido)_ | `open-sse/services/usage.ts` | Cookie `__Secure-session` do Ollama Cloud utilizado para extrair a quota da página de definições. Confidencial; quando estiverem configuradas várias contas, dê preferência ao campo por ligação no Dashboard. |
| `OLLAMA_CLOUD_USAGE_COOKIE` | _(não definido)_ | `open-sse/services/usage.ts` | Variável de ambiente alternativa para o cookie `__Secure-session` do Ollama Cloud. Confidencial; quando estiverem configuradas várias contas, dê preferência ao campo por ligação no Dashboard. |
| `OMNIROUTE_OLLAMA_USAGE_COOKIE` | _(não definido)_ | `open-sse/services/usage.ts` | Variável de ambiente alternativa para o cookie `__Secure-session` do Ollama Cloud, utilizada antes dos aliases mais curtos. Sensível; prefira o campo por ligação no Dashboard quando estiverem configuradas várias contas. |
| `OMNIROUTE_CODEWHISPERER_BASE_URL` | `https://codewhisperer.us-east-1.amazonaws.com` | `open-sse/services/usage.ts` | Endpoint dos limites de utilização do CodeWhisperer (AWS Kiro). Substitua-o para relays / fixtures de teste. |
> [!IMPORTANT]
> Ao implementar atrás de um proxy inverso (nginx, Caddy), defina `NEXT_PUBLIC_BASE_URL` como o seu URL público estável (por exemplo, `https://omniroute.example.com`) quando os callbacks OAuth ou as ligações públicas geradas tiverem de utilizar esse nome de anfitrião. Sem esta definição, os callbacks OAuth podem falhar porque o redirect_uri não corresponde, e as ligações públicas geradas podem apontar para a origem interna do contentor.
>
> Mantenha `BASE_URL` como um URL interno de loopback/contentor para tarefas servidor-a-servidor. Não utilize um `Origin` do navegador nem um nome de anfitrião público para auto-obtenções internas que transportem credenciais.
>
> As escritas autenticadas no Dashboard não requerem um URL base público estático: o Dashboard envia pedidos não seguros para a mesma origem com um token CSRF associado à sessão. O OmniRoute continua a centralizar a validação da origem pública para integrações de navegador que não sejam do Dashboard: as variáveis de ambiente de URL público explícitas são consideradas fidedignas em primeiro lugar; os cabeçalhos `Forwarded` / `X-Forwarded-*` em bruto são ignorados, a menos que `OMNIROUTE_TRUST_PROXY` esteja ativado e o par proxy imediato esteja marcado com um token como fidedigno. Não utilize definições de CORS para corrigir pedidos do Dashboard da mesma origem; o CORS destina-se apenas a clientes de navegador entre origens diferentes.
---
## 8. Proxy de Saída
Encaminhe as chamadas aos fornecedores de LLM upstream através de um proxy HTTP ou SOCKS5 para controlo de egresso, geo-encaminhamento ou mascaramento de IP.
`OMNIROUTE_UPSTREAM_HTTP2_ENABLED` tem como predefinição `true`. Defina-a como `false`, `0`, `no` ou
`off` para forçar HTTP/1.1 nos dispatchers do Undici em `open-sse/utils/proxyDispatcher.ts`
e `open-sse/utils/proxyFetch.ts`: egresso direto, proxies HTTP(S)/SOCKS, relays e
as suas tentativas de repetição com sockets novos. Isto preserva a verificação de certificados TLS, a autenticação de proxy, os limites de ligações e as definições de keep-alive. Reinicie o OmniRoute depois
de a alterar, porque os dispatchers são colocados em cache e os agentes de relay são criados no arranque.
Este interruptor não controla o TLS fingerprinting do wreq nem os transportes específicos de cada fornecedor.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ---------------------------------------- | ---------------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ENABLE_SOCKS5_PROXY` | `true` | `open-sse/executors` | Ativa o agente de proxy SOCKS5 para as chamadas ao upstream. Para desativar, utilize `false`. |
| `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` | `true` | Lado do cliente | Indicação, no lado do cliente, da disponibilidade de SOCKS5. |
| `PROXY_SKIP_RECENTLY_FAILED` | `true` | `src/shared/utils/featureFlags.ts` | Flag de funcionalidade ativa por predefinição (ver [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); uma substituição na base de dados do dashboard prevalece). Os pools de proxies e a rotação por conta deixam de voltar a servir um membro que acabou de falhar (sonda TCP recusada, ou um 429 através dele) durante um período que duplica a cada repetição, até a um limite máximo. `false` restaura a seleção simples. |
| `SELECTOR_CONTROL_ALLOWLIST` | _(não definido)_ | `src/lib/proxySubscription/selectorGuard.ts` | Lista de permissões para destinos de controlo de seletores do núcleo local além do loopback (hosts ou IPs separados por vírgula/espaço; `*` abre para endereços LAN/privados, mas nunca para metadata/link-local). O loopback através de http/https é permitido por predefinição. Um valor na base de dados do dashboard prevalece sobre esta variável quando definido e não vazio. |
| `PROXY_QUOTA_429_BASE_MS` | `300000` | `open-sse/utils/proxyRefusalMemory.ts` | Período base (ms) do afastamento por 429, duplicado a cada repetição. Lido uma vez no arranque. Limitado a `1000..3600000`; um valor fora do intervalo ou ilegível reverte para a predefinição com um aviso. |
| `PROXY_QUOTA_429_MAX_MS` | `900000` | `open-sse/utils/proxyRefusalMemory.ts` | Limite máximo (ms) do afastamento por 429. Lido uma vez no arranque. Limitado a `1000..3600000`; um valor fora do intervalo ou ilegível reverte para a predefinição com um aviso. Quando o limite máximo é inferior ao valor base, reverte para a predefinição. Reduzir o limite máximo também encurta o esquecimento de sequências: as entradas são purgadas ao fim de `2 x max` após a expiração. |
| `PROXY_POOL_SHARED_EGRESS_ORDER` | `false` | `src/shared/utils/featureFlags.ts` | Flag de funcionalidade de ativação opcional (ver [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); uma substituição na base de dados do dashboard prevalece). Para fornecedores cuja quota é agrupada por endereço de saída (egress), classifica um membro do pool que partilhe o endereço de saída observado de um membro recentemente recusado imediatamente abaixo dos membros saudáveis. Apenas ordenação, nunca exclusão. Requer `PROXY_SKIP_RECENTLY_FAILED`, que produz o sinal de recusa que esta flag lê. |
| `PROXY_WEBHOOK_REBOUND_MS` | `300000` | `src/lib/proxyEvents/proxyTransitionBridge.ts` | Janela de repique (ms) que limita os alertas webhook `proxy.set_aside` repetidos por membro do pool, de modo a que uma rajada de recusas envie apenas um evento. Lida em cada emissão. Limitada a `1000..3600000`; um valor fora do intervalo ou ilegível reverte silenciosamente para a predefinição. |
| `HTTP_PROXY` | _(não definido)_ | Padrão do Node.js | Proxy HTTP para as chamadas ao upstream. |
| `HTTPS_PROXY` | _(não definido)_ | Padrão do Node.js | Proxy HTTPS para as chamadas ao upstream. |
| `ALL_PROXY` | _(não definido)_ | Padrão do Node.js | Proxy universal (suporta `socks5://`). |
| `OMNIROUTE_PROXY_ECHO_URL` | _(não definido)_ | `src/lib/proxyEchoTarget.ts` | Fixa o alvo echo-IP usado pelas sondas de saída do proxy num único URL. Se não estiver definido, a sonda tenta `api64.ipify.org` e depois `api4.ipify.org`, para que túneis apenas IPv4 não sejam reportados como inativos (#9694). |
| `NO_PROXY` | _(não definido)_ | Padrão do Node.js | Nomes de anfitrião/IPs separados por vírgulas que devem contornar o proxy. |
| `OMNIROUTE_PROXY_DISPATCHER_CONNECTIONS` | `32` | `open-sse/utils/proxyDispatcher.ts` | Número máximo de sockets concorrentes por dispatcher de proxy HTTP/SOCKS em cache. Fluxos SSE de longa duração, como o `/v1/responses` do Codex, precisam de mais do que uma ligação quando vários pedidos partilham o mesmo proxy ao nível da conta. Valores acima de `256` são limitados. |
| `SOCKS_HANDSHAKE_TIMEOUT_MS` | `10000` | `open-sse/utils/socksConnectorWithFamily.ts` | Tempo limite do handshake SOCKS5 (ligação) em ms. Aumente-o quando um único anfitrião de gateway residencial está sob elevada concorrência (ex.: 100 pedidos simultâneos) — o handshake real pode exceder 10s com um pool saturado, mesmo que o proxy esteja acessível, o que de outra forma surge como um falso `[Proxy Fast-Fail] Proxy unreachable`. Limitado a `120000`. |
| `PROXY_FAIL_OPEN` | `false` | `src/sse/handlers/chatHelpers.ts` | Quando `false` (predefinição), um pedido cujo proxy atribuído não pode ser resolvido é **recusado (fail-closed)** em vez de recorrer a uma ligação direta — previne fugas do IP real. Defina como `true` para restaurar o fallback DIRECT legado. |
| `ENABLE_TLS_FINGERPRINT` | `false` | `open-sse/executors` | Falsifica a fingerprint TLS com wreq-js (imita o Chrome 124). Contraria o bloqueio JA3/JA4. |
| `TLS_FINGERPRINT_PROVIDERS` | _(não definido)_ | `open-sse/utils/proxyFetch.ts` | Lista de permissões de fornecedores separada por vírgulas para o novo encaminhamento TLS via proxy (`open-sse/utils/proxyFetch.ts`). O TLS direto mantém o comportamento legado quando não está definido; apenas estes fornecedores são encaminhados através da ponte de fingerprint Chrome 124. O Groq (`api.groq.com`) é excluído mesmo quando a lista de permissões não está definida, porque o JA3 do Chrome despoleta o erro 1010 do Cloudflare, enquanto o undici nativo alcança a API. |
| `OMNIROUTE_TURNSTILE_IGNORE_TLS_ERRORS` | `false` | `open-sse/services/claudeTurnstileSolver.ts` | Permite que o contexto de browser Playwright do Claude Turnstile ignore erros de certificados HTTPS. |
### Cenários
| Cenário | Configuração |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **SOCKS5 através de túnel SSH** | `ALL_PROXY=socks5://127.0.0.1:7890`, `ENABLE_SOCKS5_PROXY=true` |
| **Proxy HTTP empresarial** | `HTTP_PROXY=http://proxy.corp.com:3128`, `HTTPS_PROXY=http://proxy.corp.com:3128`, `NO_PROXY=localhost,internal.corp.com` |
| **Anti-fingerprint** | `ENABLE_TLS_FINGERPRINT=true` — requer `wreq-js` (incluído) |
| **Saída controlada / sem acesso direto** | Mantenha `PROXY_FAIL_OPEN=false` (predefinição). Os pedidos falham de imediato quando o proxy está indisponível, em vez de haver fuga através de uma ligação direta. |
| **Legado / dev — permitir fallback direto** | `PROXY_FAIL_OPEN=true`. Restaura o comportamento anterior ao hardening: é usada uma ligação direta quando a resolução do proxy falha. |
> **Nota (bypass de validação da NVIDIA — #3226):** O endpoint de validação de chave de API
> da NVIDIA bloqueia quando encaminhado através do fetch global com proxy/TLS modificado
> (dispatcher undici → 504). O `src/lib/providers/validation.ts::directHttpsRequest()`
> contorna intencionalmente o patch de proxy apenas para essa chamada de validação, usando
> `safeOutboundFetch({ bypassProxyPatch: true })`. Trata-se de uma exceção documentada e
> delimitada — **não** afeta a saída de chat/utilização. O bypass é fixado ao seu âmbito
> pelo teste `tests/unit/proxy-bypass-scope-guard-3226.test.ts`.
---
## 9. Integração de Ferramentas CLI
Controla como o OmniRoute descobre e inicia sidecars CLI (Claude Code, Codex, etc.).
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| --------------------------------- | -------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CLI_MODE` | `auto` | `src/shared/services/cliRuntime.ts` | `auto` = procurar no PATH do sistema; `manual` = usar apenas caminhos explícitos. |
| `CLI_EXTRA_PATHS` | _(não definido)_ | `src/shared/services/cliRuntime.ts` | Entradas de PATH adicionais para a deteção de binários CLI (separadas por dois pontos). |
| `CLI_CONFIG_HOME` | _(não definido)_ | `src/shared/services/cliRuntime.ts` | Substitui o diretório home para a leitura das configurações CLI (`~/.claude`, `~/.codex`). Tem de ser absoluto e estar dentro do home do processo — **ou**, num contentor, um caminho montado por bind (é assim que `/host-home` funciona). Qualquer outro valor recorre ao diretório home. |
| `CLI_ALLOW_CONFIG_WRITES` | `true` | `src/shared/services/cliRuntime.ts` | Permite que o OmniRoute escreva ficheiros de configuração CLI (renovação de tokens, dados de sessão). Defina como `false` para que todas as escritas de configuração CLI falhem com um erro explícito de "writes disabled" (escritas desativadas). |
| `CLI_CLAUDE_BIN` | `claude` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Claude CLI. |
| `CLI_CODEX_BIN` | `codex` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Codex CLI. |
| `CLI_DROID_BIN` | `droid` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Droid CLI. |
| `CLI_OPENCLAW_BIN` | `openclaw` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do OpenClaw CLI. |
| `CLI_CURSOR_BIN` | `agent`, depois `cursor` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do agente Cursor. Sem ele, a deteção tenta primeiro `agent` e recorre a `cursor`. |
| `CLI_CLINE_BIN` | `cline` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Cline CLI. |
| `CLI_5DIVE_BIN` | `5dive` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do 5dive CLI. |
| `CLI_5DIVE_STATE_DIR` | `/var/lib/5dive` | `src/shared/services/cliRuntime.ts` | Diretório de estado do sistema do 5dive (perfis de autenticação pertencentes ao root); reflete a predefinição de STATE_DIR do próprio 5dive. |
| `CLI_CONTINUE_BIN` | `cn` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Continue CLI. |
| `CLI_QODER_BIN` | `qodercli` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Qoder CLI. |
| `CLI_QWEN_BIN` | `qwen` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Qwen Code CLI. |
| `CLI_AIDER_BIN` | `aider` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Aider CLI. |
| `CLI_GOOSE_BIN` | `goose` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Goose CLI. |
| `CLI_GEMINI_BIN` | `gemini` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Google Gemini CLI — apenas para deteção/verificações de integridade no lado do servidor; `omniroute run gemini` resolve o binário `gemini` a partir do PATH do sistema. |
| `CLI_KILO_BIN` | `kilocode` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Kilo Code CLI. |
| `CLI_OPENCODE_BIN` | `opencode` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do OpenCode CLI. |
| `CLI_HERMES_BIN` | `hermes` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Hermes. Partilhado por ambas as entradas do catálogo (`hermes` e `hermes-agent`). |
| `CLI_FORGE_BIN` | `forge` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do CLI ForgeCode. |
| `CLI_JCODE_BIN` | `jcode` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do CLI jcode. |
| `CLI_DEEPSEEK_TUI_BIN` | `deepseek-tui` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do TUI DeepSeek. |
| `CLI_CODEWHALE_BIN` | `codewhale` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do CLI CodeWhale. |
| `CLI_SMELT_BIN` | `smelt` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do CLI Smelt. |
| `CLI_PI_BIN` | `pi` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Pi (pi-coding-agent). |
| `CLI_CRUSH_BIN` | `crush` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do CLI Crush. |
| `CLI_OMP_BIN` | `omp` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do agente Oh My Pi (`omp`). |
| `CLI_LETTA_BIN` | `letta` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do CLI Letta. |
| `CLI_PRIME_AGENT_BIN` | `prime-agent` | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Prime Agent (Prime Intellect). |
| `CLI_WINDSURF_BIN` | _(nenhum)_ | `src/shared/services/cliRuntime.ts` | Caminho personalizado para o binário do Windsurf. O Windsurf é distribuído **sem comando predefinido** — a deteção do binário permanece desativada até esta variável ser definida. |
| `CLI_DEVIN_BIN` | `devin` | `open-sse/executors/devin-cli.ts` | Caminho personalizado para o binário do CLI Devin (v3.8.0). Utilizado pelo executor Windsurf/Devin. |
| `DEVIN_DESKTOP_VERSION` | `3.6.27` | `open-sse/executors/devin-desktop.ts` | O `ide_version` do Devin Desktop. As substituições têm de utilizar o formato `x.y.z`; valores inválidos revertem para a predefinição verificada. |
| `DEVIN_DESKTOP_EXTENSION_VERSION` | `1.48.2` | `open-sse/executors/devin-desktop.ts` | O `extension_version` do Codeium/language-server incluído, distinto do `ide_version` do Desktop. As substituições têm de utilizar `x.y.z`; valores inválidos utilizam a predefinição incluída. |
| `CLI_DEVIN_AGENTIC_BIN` | `devin` | `open-sse/executors/devin-cli-agentic.ts` | Substituição do CLI Devin aplicável apenas à ponte agentic. O executor aceita apenas o upstream ACP stdio local. |
| `DEVIN_AGENTIC_HOME` | _(obrigatório)_ | `open-sse/executors/devin-cli-agentic.ts` | Diretório home absoluto e isolado para o subprocesso Devin agentic; os caminhos de ponte aceites são `/home/bridge` e caminhos `.sandbox` locais da tarefa (no Windows, `C:\...\.sandbox\...`). |
| `DEVIN_AGENTIC_ACP_TIMEOUT_MS` | `120000` | `open-sse/executors/devin-cli-agentic.ts` | Duração máxima de um turno ACP do Devin antes de a ponte terminar o processo filho e devolver um timeout explícito. |
| `DEVIN_BRIDGE_MODEL` | `devin-cli-agentic/swe-1-7` | `docker/devin-bridge/compose.yml` | Alias do modelo principal do Claude Code para a ponte isolada. O harness real substitui o exemplo por um modelo devolvido pela conta Devin atual. |
| `DEVIN_BRIDGE_SONNET_MODEL` | `DEVIN_BRIDGE_MODEL` | `docker/devin-bridge/compose.yml` | Alias da ponte isolada utilizado quando o Claude Code solicita a sua predefinição Sonnet. |
| `DEVIN_BRIDGE_OPUS_MODEL` | `DEVIN_BRIDGE_MODEL` | `docker/devin-bridge/compose.yml` | Alias da ponte isolada utilizado quando o Claude Code solicita a sua predefinição Opus. |
| `DEVIN_BRIDGE_HAIKU_MODEL` | `DEVIN_BRIDGE_MODEL` | `docker/devin-bridge/compose.yml` | Alias da ponte isolada utilizado quando o Claude Code solicita a sua predefinição Haiku. |
| `DEVIN_BRIDGE_SUBAGENT_MODEL` | `DEVIN_BRIDGE_MODEL` | `docker/devin-bridge/compose.yml` | Alias da ponte isolada utilizado para subagentes do Claude Code. |
| `DEVIN_SEAT_API_URL` | `https://server.codeium.com` | `open-sse/services/usage/devinCli.ts` | Substituição opcional da API de gestão de seats do Codeium utilizada pela quota do Devin CLI (`GetUserStatus`). |
| `AUGGIE_BIN` | `auggie` | `open-sse/executors/auggie.ts` | Substituição do caminho absoluto do binário CLI do Augment (Auggie) utilizado pelo fornecedor local `auggie`. Recorre a `CLI_AUGGIE_BIN` e, de seguida, a uma pesquisa no PATH. |
| `CLI_AUGGIE_BIN` | `auggie` | `open-sse/executors/auggie.ts` | Substituição alternativa (alias) do caminho do binário CLI do Augment (Auggie) (verificada após `AUGGIE_BIN`). |
| `ZCODE_BIN` | `zcode` | `open-sse/executors/zcode.ts` | Binário utilizado pelo cliente stdio do fornecedor local `zcode`. Recorre a `zcode` no PATH. |
| `ZCODE_ARGS` | — | `open-sse/executors/zcode.ts` | Array JSON (≤16 strings) de argumentos adicionais passados ao binário `zcode` quando iniciado através de `cliTools`. |
| `ZCODE_CWD` | `process.cwd()` | `open-sse/executors/zcode.ts` | Diretório de trabalho do subprocesso do app-server do ZCode. |
| `ZCODE_PROVIDER_ID` | `builtin:zai-coding-plan` | `open-sse/executors/zcode.ts` | Substituição do id de fornecedor enviado ao app-server. |
| `ZCODE_SERVER_RUNTIME_ROOT` | `~/.zcode/server` | `open-sse/executors/zcode.ts` | Raiz do runtime do app-server do ZCode (onde residem o `node` incluído e o `zcode-server.cjs`). |
| `ZCODE_SERVER_NODE` | `/node` | `open-sse/executors/zcode.ts` | Executável Node utilizado para alojar o app-server do ZCode. |
| `ZCODE_SERVER_ENTRY` | `/zcode-server.cjs` | `open-sse/executors/zcode.ts` | Script de entrada do app-server utilizado para alojar o servidor ZCode. |
| `ZCODE_STARTUP_TIMEOUT_MS` | `10000` | `open-sse/executors/zcode.ts` | Tempo limite de arranque (ms) antes de o lançamento do app-server do ZCode ser considerado falhado. |
| `ZCODE_RPC_TIMEOUT_MS` | `30000` | `open-sse/executors/zcode.ts` | Tempo limite de RPC por pedido (ms) para uma chamada ao app-server do ZCode. |
| `ZCODE_TURN_TIMEOUT_MS` | `120000` | `open-sse/executors/zcode.ts` | Duração máxima (ms) de um turno do ZCode antes de o supervisor o terminar por tempo limite excedido. |
| `ZCODE_POLL_INTERVAL_MS` | `250` | `open-sse/executors/zcode.ts` | Intervalo de polling (ms) para a conclusão de um turno do ZCode. |
| `HERMES_HOME` | `~/.hermes` | `src/lib/cli-helper/config-generator/hermesHome.ts` | Diretório base do Hermes Agent onde o OmniRoute lê/escreve a configuração do Hermes CLI. Corresponde à variável de ambiente que o instalador PowerShell do Hermes define no Windows (`%LOCALAPPDATA%\hermes`). |
### Sincronização Automática de Perfis CLI
Estes feature flags são de ativação opcional (opt-in) e estão desativados por predefinição. Também podem ser alternados a partir do painel do CLI Code.
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ------------------------------------- | ------------ | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_AUTO_SYNC_CODEX_PROFILES` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Após uma sincronização de modelos de fornecedor, reescreve automaticamente os ficheiros de perfil `~/.codex/*.config.toml` a partir do catálogo atual. Requer `CLI_ALLOW_CONFIG_WRITES`; nunca altera a configuração ativa/predefinida do Codex, a autenticação, as definições do Codex-lb nem a escolha de fornecedor. |
| `OMNIROUTE_AUTO_SYNC_CLAUDE_PROFILES` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Após uma sincronização de modelos de fornecedor, reescreve automaticamente os ficheiros de perfil do Claude Code `~/.claude/profiles//settings.json` a partir do catálogo atual. Requer `CLI_ALLOW_CONFIG_WRITES`; nunca altera a configuração ativa/predefinida do Claude, a autenticação nem a escolha de fornecedor. |
### Exemplo Docker
```bash
# Monta os binários do anfitrião no contentor e indica ao OmniRoute onde se encontram:
CLI_EXTRA_PATHS=/host-cli/bin
CLI_CONFIG_HOME=/host-home
CLI_ALLOW_CONFIG_WRITES=true
CLI_CLAUDE_BIN=/host-cli/bin/claude
```
`CLI_CONFIG_HOME` só tem efeito quando o caminho está efetivamente montado por bind-mount a partir do
anfitrião — combine-o com montagens como `~/.codex:/host-home/.codex:rw` (ver o
perfil `host` em `docker-compose.yml`). Um caminho que não esteja nem dentro da
home do utilizador do contentor nem num bind mount é ignorado, porque qualquer escrita aí
seria descartada quando o contentor fosse recriado.
A imagem é executada como `USER node`, pelo que um `/root` não montado **não** é uma
substituição válida.
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ---------------------------------------- | -------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `OMNIROUTE_CONTAINER` | _(automático)_ | `src/shared/utils/containerEnv.ts` | Força a deteção de contentor para ligado (`1`/`true`) ou desligado (`0`/`false`). Apenas necessário em runtimes que a deteção automática não identifica. |
| `OMNIROUTE_ALLOW_CONTAINER_CONFIG_WRITE` | `false` | `src/shared/services/cliRuntime.ts` | Permite mesmo assim escritas de configuração de ferramentas CLI num caminho não montado do contentor. O equivalente na CLI é `--allow-container-write`. |
| `DOCKER_UPDATE_TRIGGER_FILE` | não definido | `src/lib/system/autoUpdate.ts` | Apenas imagem Docker: o **Atualizar agora** do painel escreve um pedido JSON neste ficheiro (tem de estar dentro de `DATA_DIR`) para que um observador no anfitrião faça pull e recrie o contentor. Consulte o [Guia Docker](../guides/DOCKER_GUIDE.md#dashboard-updates-in-docker). |
### Auxiliares do binário CLI (`omniroute`)
Estas variáveis ajustam o comportamento do próprio binário CLI `omniroute` (não a deteção
de sidecar acima).
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ------------------------------------- | --------------------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_LANG` | _(sistema)_ | `bin/cli/i18n.mjs` | Força o idioma de saída da CLI. Locale BCP-47 (ex.: `en`, `pt-BR`). Substitui as variáveis de ambiente de locale do sistema (LC_ALL, LC_MESSAGES). |
| `OMNIROUTE_SHOW_LOG` | _(não definido)_ | `bin/cli/runtime/processSupervisor.mjs` | Defina como `1` para encaminhar o stdout/stderr do servidor para o terminal em modo supervisionado. Equivalente à flag `--log` em `omniroute serve`. |
| `OMNIROUTE_CLI_TOKEN` | _(não definido)_ | `bin/cli/api.mjs` | Token de autenticação de máquina injetado como cabeçalho `x-omniroute-cli-token`. Gerado automaticamente na tarefa 8.12. |
| `GEMINI_CLI_HOME` | _(não definido)_ | `bin/cli/commands/setup-gemini.mjs` | Raiz home persistente do Gemini; uma execução pontual (one-shot) utiliza uma home temporária isolada. |
| `OMNIROUTE_CHILD_SIGNAL_TIMEOUT_MS` | `5000` | `bin/cli/commands/run.mjs` | Período de tolerância em milissegundos antes de forçar a terminação de um processo filho CLI sinalizado. |
| `OMNIROUTE_CLI_SKIP_DEFAULT_DATA_ENV` | _(não definido)_ | `bin/omniroute.mjs` | Defina como 1 com um DATA_DIR explícito para ignorar o ficheiro de ambiente do diretório de dados do utilizador predefinido. |
| `OMNIROUTE_SYNC_TOKEN` | _(não definido)_ | `bin/cli/commands/sync.mjs` | Token de sincronização para `omniroute sync bundle` (`GET /api/sync/bundle` aceita apenas um token de sincronização, não uma chave de API). Equivalente a `--token`. |
| `OMNIROUTE_HTTP_TIMEOUT_MS` | `30000` | `bin/cli/api.mjs` | Timeout HTTP por tentativa (ms) para pedidos CLI → servidor. |
| `OMNIROUTE_READY_TIMEOUT_MS` | `60000` | `bin/cli/utils/pid.mjs` | Tempo máximo (ms) que a CLI aguarda pelo endpoint de saúde do servidor antes de imprimir um aviso de timeout. Útil para arranques a frio lentos (ex.: Windows). Também configurável através de `--ready-timeout`. |
| `OMNIROUTE_VERBOSE` | `0` | `bin/cli/api.mjs` | Defina como `1` para imprimir diagnósticos de retry/backoff no stderr durante os comandos CLI. |
| `OMNIROUTE_PLUGIN_PATH` | _(não definido)_ | `bin/cli/plugins.mjs` | Diretório personalizado para a descoberta de plugins CLI (pacotes `omniroute-cmd-*`). Predefinição de `~/.omniroute/plugins/` quando não definido. Apenas CLI — nunca chega ao scanner de plugins do lado do servidor, que é indicado por `OMNIROUTE_PLUGINS_DIR` (secção 2). |
| `OMNIROUTE_NO_UPDATE_NOTIFIER` | _(não definido)_ | `bin/omniroute.mjs` | Suprime a notificação de atualização da CLI à saída do processo quando definido com qualquer valor não vazio. O aviso permanece desativado independentemente em CI, modo quiet e modos de saída não textuais. |
| `OMNIROUTE_DOCTOR_LIVENESS_URL` | _(derivado)_ | `bin/cli/commands/doctor.mjs` | URL de liveness testado por `omniroute doctor`. Uma opção programática `livenessUrl` tem precedência; caso contrário, este valor é utilizado tal como está. Se não definido, a CLI deriva o endpoint `/api/health/degradation` do painel local. |
| `OMNIROUTE_PROVIDER_CATALOG_PATH` | `src/shared/constants/providers/` | `bin/cli/provider-catalog.mjs` | Caminho do catálogo de fornecedores utilizado pelos comandos de fornecedores da CLI. Uma opção programática `catalogPath` tem precedência. Caminhos absolutos são utilizados tal como estão; caminhos relativos são resolvidos a partir da raiz do projeto. Se não definido, a CLI utiliza o diretório de constantes de fornecedores, com o ficheiro legado `providers.ts` como fallback. |
| `OMNIROUTE_PROVIDER_TEST_MODEL` | _(predefinição do fornecedor)_ | `bin/cli/provider-test.mjs` | Modelo de fallback global para testes de ligação de fornecedores da CLI. A precedência é: modelo de ligação configurado, substituição de modelo específica do fornecedor, este valor e, por fim, o modelo de teste integrado do fornecedor. |
---
## 10. Integrações internas do Agent e MCP
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ----------------------------------------------- | --------------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_BASE_URL` | deteção automática | `open-sse/mcp-server/server.ts` | URL explícito para as ferramentas MCP/A2A alcançarem o OmniRoute. Substitui a deteção automática de localhost. |
| `OMNIROUTE_API_KEY` | _(não definida)_ | Módulos MCP/A2A | Chave de API para chamadas internas de ferramentas MCP e skills A2A. |
| `OMNIROUTE_API_KEY_ID` | _(não definida)_ | `open-sse/mcp-server/audit.ts` | ID da chave para atribuição no registo de auditoria MCP. |
| `ROUTER_API_KEY` | _(não definida)_ | Legado | Alias legado de `OMNIROUTE_API_KEY`. |
| `OMNIROUTE_A2A_HISTORY_RETENTION_DAYS` | `30` | `src/lib/a2a/taskManager.ts` | Dias de histórico de tarefas A2A mantidos na base de dados local antes de a limpeza diária eliminar uma linha. Se não estiver definida, for não numérica ou `<= 0`, recorre a `30`. |
| `OMNIROUTE_A2A_MEMORY_HITS` | `1` | `src/lib/a2a/taskExecution.ts` | Interruptor de desativação da funcionalidade de observabilidade de acertos de memória do A2A. Defina como `0` para ignorar totalmente a pesquisa de recuperação de memória de uma tarefa; qualquer outro valor (incluindo não definido) mantém a funcionalidade ativada. |
| `OMNIROUTE_ISSUE_AGENT_ENABLED` | `false` | `src/app/api/issue-agent/runs/route.ts` | Ativa o endpoint de triagem gravada do Issue Agent offline/local. Mantenha desativado, exceto se estiver explicitamente a executar fluxos de trabalho locais de triagem gravada. |
| `OMNIROUTE_ISSUE_AGENT_TIMEOUT_MS` | _(não definida)_ | `src/lib/issueAgent/execution.ts` | Tempo limite (ms) para uma única execução de triagem gravada do Issue Agent. Limitado a um máximo interno; recorre à predefinição incorporada quando não definido ou inválido. |
| `OMNIROUTE_CONTEXT` | _(contexto ativo)_ | `bin/cli/program.mjs`, `bin/cli/api.mjs` | Contexto/perfil de modo remoto da CLI para comandos `omniroute`; substitui o contexto ativo no armazenamento local de contextos. Equivalente a `--context `. |
| `OMNIROUTE_CONTEXT_KEYCHAIN_DISABLED` | `0` | `bin/cli/contexts.mjs` | Desativa o backend opcional `keytar` (keychain do SO) para as credenciais de contexto da CLI. Quando ativado, as credenciais permanecem em `config.json` com modo `0600` e a CLI emite um aviso único de fallback; destinado a operação deliberada em modo headless/contentor. |
| `OMNIROUTE_MCP_ENFORCE_SCOPES` | `false` | `open-sse/mcp-server/server.ts` | Aplica controlo de acesso baseado em scopes às chamadas de ferramentas MCP. |
| `OMNIROUTE_MCP_SCOPES` | _(todos)_ | `open-sse/mcp-server/server.ts` | Scopes separados por vírgulas: `admin`, `combos`, `health`, `models`, `routing`, `budget`, `metrics`, `pricing`, `memory`, `skills`. |
| `OMNIROUTE_MCP_COMPRESS_DESCRIPTIONS` | `false` | `open-sse/mcp-server/descriptionCompressor.ts` | Comprime as descrições das ferramentas MCP antes de serializar o manifesto. Valores de ativação: `1`, `true`, `on`. |
| `OMNIROUTE_MCP_DESCRIPTION_COMPRESSION` | `rtk` | `open-sse/mcp-server/descriptionCompressor.ts` | Algoritmo/perfil de compressão. Valores de desativação: `0`, `false`, `off`. |
| `OMNIROUTE_MCP_FETCH_TIMEOUT_MS` | `10000` | `open-sse/mcp-server/fetchTimeout.ts` | Limite de cancelamento (ms) para leituras internas de gestão do servidor MCP (estado, resiliência, combos, quota, utilização). |
| `OMNIROUTE_MCP_UPSTREAM_TIMEOUT_MS` | `60000` | `open-sse/mcp-server/fetchTimeout.ts` | Orçamento de cancelamento (ms) para saltos MCP que aguardam um fornecedor (`route_request`, `web_search`, `web_fetch`). |
| `OMNIROUTE_CORPUS_CACHE_SIZE` | `5` | `src/lib/localCorpus/configured.ts` | Número máximo de instâncias de índice do corpus local mantidas em cache na memória (LRU, uma por diretório raiz indexado). Limitado a um mínimo de `1`. |
| `MODEL_SYNC_INTERVAL_HOURS` | `6` | `src/shared/services/modelSyncScheduler.ts` | Intervalo de sincronização do catálogo de modelos em horas. |
| `PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES` | `70` | `src/lib/usage/providerLimits.ts` | Intervalo de sondagem dos limites de taxa e quotas do fornecedor. |
| `PROVIDER_LIMITS_SYNC_SPACING_MS` | `1500` | `src/lib/usage/providerLimits.ts` | Intervalo (ms) entre obtenções consecutivas de quota OAuth numa sincronização em massa; as ligações OAuth são obtidas uma de cada vez para evitar sobrecarregar o upstream. `0` desativa (concorrente). |
| `OMNIROUTE_QUOTA_FETCH_MIN_INTERVAL_MS` | `250` | `open-sse/services/quotaFetchThrottle.ts` | Intervalo mínimo (ms) entre obtenções consecutivas de quota upstream no caminho de pré-verificação/monitorização por pedido; espaça chamadas de rede concorrentes para que muitas contas num mesmo IP não sobrecarreguem o upstream. Ligado aos obtentores de quota do Codex (`/wham/usage`), DeepSeek, Bailian (ambos os locais de obtenção), OpenCode e Crof (#6009, #6911). O caminho genérico de despacho `usage.ts::getUsageForProvider` (github/glm/minimax/nanogpt/xai/etc.) ainda não está coberto — acompanhado separadamente. Acertos de cache não afetados. `0` desativa; limitado a `0..60000`. |
| `OMNIROUTE_QUOTA_FETCH_JITTER_MS` | `120` | `open-sse/services/quotaFetchThrottle.ts` | Espaçamento aleatório adicional por pedido (ms), amostrado em cada obtenção de quota upstream reservada. Predefinição de 120; limitado a `0..60000`; `0` remove apenas o jitter. Defina `OMNIROUTE_QUOTA_FETCH_MIN_INTERVAL_MS=0` para desativar todo o estrangulamento. O jitter não garante a prevenção de banimentos pelo upstream. |
| `PROVIDER_LIMITS_POST_USAGE_REFRESH_DELAY_MS` | `5000` | `src/lib/usage/providerLimits.ts` | Atraso (ms) antes de atualizar os limites do fornecedor após um evento real de utilização, dando à API de quota upstream tempo para registar o consumo. |
| `OMNIROUTE_LOGIN_BROWSER_PATH` | deteção automática | `open-sse/services/adobeFireflyBrowserLogin.ts` | Caminho absoluto para um executável Chrome ou Edge do sistema usado para o início de sessão interativo no Adobe Firefly e renovação fora do ecrã. |
| `ADOBE_FIREFLY_BROWSER_REFRESH` | ativado | `open-sse/services/adobeFireflySession.ts` | Mantém o estado do IMS e de risco do navegador atualizado com sessões Chrome CDP no âmbito da conta. Defina como `0` para desativar a renovação do navegador. |
| `ADOBE_FIREFLY_SESSION_DISK` | ativado | `open-sse/services/adobeFireflySession.ts` | Persiste sessões Adobe reparadas em `DATA_DIR` entre reinícios do processo. Defina como `0` para manter as sessões apenas em memória. |
| `ADOBE_FIREFLY_MIN_SUBMIT_GAP_MS` | `12000` | `open-sse/services/adobeFireflySession.ts` | Espaçamento mínimo em milissegundos entre submissões de geração do Adobe Firefly; `0` desativa o espaçamento. |
| `ADOBE_FIREFLY_BATCH_EXTRA_GAP_MS` | `15000` | `open-sse/services/adobeFireflySession.ts` | Período extra de silêncio em milissegundos após cada terceira submissão bem-sucedida ao Adobe. |
| `ADOBE_FIREFLY_SUBMIT_BASE_DELAY_MS` | `8000` | `open-sse/services/adobeFireflyClient.ts` | Backoff base em milissegundos após respostas transitórias Adobe 408; combinado com o espaçamento de submissão ao longo de no máximo cinco tentativas. |
| `OMNIROUTE_DISABLE_BACKGROUND_SERVICES` | `false` | `src/instrumentation-node.ts` | Desativa todos os serviços em segundo plano (sincronização, preços, atualização de modelos). Útil para CI/testes. |
| `OMNIROUTE_HEADLESS` | _(não definido)_ | `src/lib/system/headless.ts` | Arranque apenas do motor de proxy: ignora subsistemas opcionais, `/dashboard` → 404. Igual a `omniroute serve --headless`. Consulte [HEADLESS.md](../guides/HEADLESS.md). |
| `OMNIROUTE_ENABLE_RUNTIME_BACKGROUND_TASKS` | _(não definido)_ | `src/lib/config/runtimeSettings.ts` | Força a ativação das tarefas em segundo plano sob deteção de testes automatizados. Defina `1` para ignorar a heurística de teste. |
| `OMNIROUTE_BUDGET_RESET_JOB_INTERVAL_MS` | `600000` | `src/lib/jobs/budgetResetJob.ts` | Cadência de verificação da reposição de orçamento (ms). Mínimo `10000`. |
| `OMNIROUTE_CONNECTION_RECOVERY_INTERVAL_MS` | `60000` | `src/lib/quota/connectionRecovery.ts` | Cadência de recuperação proativa do arrefecimento de ligações (ms): revalida ligações cujo `rate_limited_until` transitório já decorreu, fora do caminho crítico dos pedidos. Mínimo `5000`. |
| `OMNIROUTE_DISABLE_CONNECTION_RECOVERY` | `false` | `src/lib/quota/connectionRecovery.ts` | Desativa o agendador de recuperação proativa do arrefecimento de ligações (a recuperação diferida em `getProviderCredentials` continua a aplicar-se). |
| `OMNIROUTE_REASONING_CACHE_CLEANUP_INTERVAL_MS` | `1800000` | `src/lib/jobs/reasoningCacheCleanupJob.ts` | Cadência de limpeza da cache de raciocínio (ms). Mínimo `60000`. |
| `OMNIROUTE_REASONING_MIN_BUDGET` | _não definido_ (desativado) | `open-sse/services/reasoningTokenBuffer.ts` | Limite inferior opcional (opt-in) para os orçamentos de saída de modelos de pensamento: um `max_tokens` do chamador em `[256, floor)` é elevado até ao limite inferior (limitado pelo teto de saída do modelo). Não definido = os orçamentos do cliente nunca são aumentados (#9507). |
| `OMNIROUTE_REASONING_EFFORT_PROBE_PROVIDERS` | _não definido_ (desativado) | `open-sse/services/learnedReasoningEffortCaps.ts` | Opcional (opt-in), ids de fornecedores separados por vírgulas (ou `*`): quando um 400/422 de `reasoning_effort` não indica nenhum conjunto aceite, tenta novamente uma vez um nível abaixo (nunca abaixo de `low`) e aprende esse nível apenas se a sondagem for respondida (#14895). |
| `OMNIROUTE_LOG_EXPORT_CRON` | `0 * * * *` | `src/lib/jobs/logExportJob.ts` | Expressão cron (UTC) para a tarefa de exportação de registos de chamadas que esvazia todos os destinos de exportação de registos ativados. Prefira `*/5 * * * *` ao exportar corpos. |
| `OMNIROUTE_LOG_EXPORT_RUN_TIMEOUT_MS` | `900000` | `src/lib/logExport/childRunner.ts` | Tempo limite de relógio (wall-clock) do processo filho por destino, em milissegundos. O tempo limite regista a falha e termina o processo sem avançar o lote não confirmado. Valores inválidos/não positivos/não inteiros usam a predefinição. |
| `OMNIROUTE_LOG_EXPORT_CHILD_MAX_OLD_SPACE_MB` | `1024` | `src/lib/logExport/childRunner.ts` | Limite de old-space do V8 (em MB) do processo filho de exportação Node (não o RSS total). A predefinição deixa margem para 500 linhas de artefactos truncados com corpos; lotes demasiado grandes podem mesmo assim esgotar a heap do filho. A falha aconselha a reduzir o tamanho do lote ou a aumentar este limite. Valores inválidos/não positivos/não inteiros usam a predefinição. As exportações Bun recorrem à execução no próprio processo, sem este limite. |
| `OMNIROUTE_CONFIG_HOT_RELOAD_MS` | `5000` | `src/lib/config/hotReload.ts` | Intervalo de sondagem (ms) para a recarga a quente da configuração. Valores inferiores a `1000` são rejeitados. |
| `OMNIROUTE_DISABLE_REDIS_AUTH_CACHE` | _(ativado)_ | `src/lib/db/apiKeys.ts` | Defina `1` para contornar a cache de autenticação de chaves API baseada em Redis (força leituras da base de dados). |
| `OMNIROUTE_RTK_TRUST_PROJECT_FILTERS` | `0` | `open-sse/services/compression/engines/rtk/filterLoader.ts` | Confia nas regras de filtro de projeto RTK geridas pelo utilizador sem verificações rigorosas de assinatura. |
| `OMNIROUTE_LITE_MAX_TOOL_LENGTH` | `2000` | `open-sse/services/compression/lite.ts` | Limite de caracteres para o truncamento proativo de resultados de ferramentas no Lite quando `lite.maxToolLength` não está definido. Intervalo 256–1000000. A definição do painel prevalece sobre esta variável de ambiente. |
| `OMNI_COMPRESSION_WORKERS` | `2` | `open-sse/services/compression/compressionWorkerPool.ts` | Número máximo de workers RTK/Caveman síncronos em simultâneo; as tarefas excedentes aguardam em FIFO. |
| `OMNI_COMPRESSION_WORKER_TIMEOUT_MS` | `120000` | `open-sse/services/compression/compressionWorkerPool.ts` | Tempo limite por tarefa em milissegundos. Os workers que excederem o tempo limite são terminados e o pedido falha em modo aberto (fail-open), sem alterações. |
| `OMNI_COMPRESSION_WORKER_IDLE_MS` | `60000` | `open-sse/services/compression/compressionWorkerPool.ts` | Tempo de vida inativo em milissegundos antes de um worker de compressão não utilizado ser terminado. |
| `OMNI_COMPRESSION_WORKER_MAX_OLD_MB` | `1024` | `open-sse/services/compression/compressionWorkerPool.ts` | Limite da heap old-generation do V8 em MB para cada worker de compressão, em todos os modos (mínimo `128`). Uma tarefa que o exceda falha em modo aberto (sem compressão) em vez de aumentar a heap do gateway. |
| `COMPRESSION_PIPELINE_BREAKER_ENABLED` | `false` | `open-sse/services/compression/pipelineEngineBreaker.ts` | Interruptor principal do circuit-breaker por motor do pipeline empilhado T02. **Ativação opcional (desativado por predefinição)** — quando ativado, um motor que lance erros repetidamente entre pedidos é ignorado (fail-open) durante um período de cooldown; desativado = comportamento legado byte a byte idêntico. |
| `COMPRESSION_PIPELINE_BREAKER_THRESHOLD` | `3` | `open-sse/services/compression/pipelineEngineBreaker.ts` | Falhas consecutivas entre pedidos antes de o breaker de um motor abrir. |
| `COMPRESSION_PIPELINE_BREAKER_COOLDOWN_MS` | `30000` | `open-sse/services/compression/pipelineEngineBreaker.ts` | Milissegundos durante os quais um motor aberto permanece ignorado antes de uma sonda half-open. |
| `COMPRESSION_CCR_RETRIEVAL_RAMP_FACTOR` | `2` | `open-sse/services/compression/engines/ccr/index.ts` | Rampa de feedback de recuperação CCR T08/H8: cada recuperação anterior de um bloco armazenado aumenta linearmente o seu `minChars` efetivo (conteúdo recuperado com frequência comprime menos; `>=3` recuperações = nunca comprimido). `1` desativa a rampa (ignorar de forma binária apenas no limiar). |
| `COMPRESSION_CCR_DURABLE_STORE` | `true` | `open-sse/services/compression/engines/ccr/index.ts` | Armazenamento durável de blocos CCR (#9061). Suporta o armazenamento em memória com SQLite, para que um bloco sobreviva à expulsão LRU, ao TTL, a um reinício ou a uma recuperação que chegue a outra instância. Defina como `false` para manter os blocos apenas em memória. Blocos acima de 512KB e runtimes cloud permanecem apenas em memória independentemente. |
| `COMPRESSION_PREFIX_FREEZE_ENABLED` | `false` | `open-sse/services/compression/prefixFreeze.ts` | Interruptor principal de congelamento de prefixos observados por utilização T08/H5. **Ativação opcional (desativado por predefinição)** — quando ativado, um system prompt observado `>=` o limiar é tratado como um prefixo estável colocável em cache e preservado da compressão, mesmo para fornecedores que a heurística estática de cache não deteta (o congelamento apenas _preserva_, nunca modifica). |
| `COMPRESSION_PREFIX_FREEZE_THRESHOLD` | `3` | `open-sse/services/compression/prefixFreeze.ts` | Observações de um system prompt antes de este ser tratado como um prefixo estável congelado. |
| `OMNIROUTE_BOOTSTRAPPED` | `false` | `src/app/(dashboard)/dashboard/page.tsx` | Definido como `true` pelo script de bootstrap após a configuração inicial. Controla a visibilidade do assistente de configuração. |
| `OMNIROUTE_ALLOW_BODY_PROJECT_OVERRIDE` | `0` | `open-sse/executors/antigravity.ts` | Válvula de escape: permite que o corpo do pedido substitua o campo de projeto do Antigravity. |
| `ANTIGRAVITY_CREDITS` | `off` | `open-sse/services/antigravityCredits.ts` | Política de créditos Google One AI: `off` nunca injeta créditos, `retry` injeta uma vez após um 429 de quota elegível, e `always` injeta no primeiro pedido. |
| `ANTIGRAVITY_ALLOW_SIGNATURE_BYPASS` | `0` | `open-sse/translator/request/openai-to-gemini.ts` | Permite que o tradutor de pedidos do Antigravity ignore a sua validação rigorosa de assinatura de pedidos CLI quando o upstream recusa assinaturas reais (modo de depuração/CLI antigo). Um valor diferente de zero ativa o bypass. |
| `AGY_TOKEN_FILE` | `~/.gemini/antigravity-cli/antigravity-oauth-token` | `src/app/api/providers/agy-auth/apply-local/route.ts` | Substitui o caminho do ficheiro de token do Antigravity CLI (agy) para a importação de login local com deteção automática. |
### Ponte OAuth CLI (Interna)
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ------------------- | ------------------ | ------------------------------- | ----------------------------------------------------------- |
| `OMNIROUTE_SERVER` | deteção automática | `src/lib/oauth/config/index.ts` | URL do servidor para a ponte de autenticação CLI↔OmniRoute. |
| `OMNIROUTE_TOKEN` | _(não definido)_ | `src/lib/oauth/config/index.ts` | Token de autenticação para a ponte CLI. |
| `OMNIROUTE_USER_ID` | `cli` | `src/lib/oauth/config/index.ts` | ID de utilizador para as sessões da ponte CLI. |
| `SERVER_URL` | _(não definido)_ | `src/lib/oauth/config/index.ts` | Alias legado de `OMNIROUTE_SERVER`. |
| `CLI_TOKEN` | _(não definido)_ | `src/lib/oauth/config/index.ts` | Alias legado de `OMNIROUTE_TOKEN`. |
| `CLI_USER_ID` | _(não definido)_ | `src/lib/oauth/config/index.ts` | Alias legado de `OMNIROUTE_USER_ID`. |
---
## 11. Credenciais de Fornecedores OAuth
Credenciais integradas para **desenvolvimento em localhost**. Para implementações remotas, registe as suas próprias credenciais na consola de programador de cada fornecedor.
| Variável | Fornecedor | Notas |
| ------------------------------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CLAUDE_OAUTH_CLIENT_ID` | Claude Code (Anthropic) | Cliente público — não requer segredo. |
| `CLAUDE_CODE_REDIRECT_URI` | Claude Code | Substitui o URI de redirecionamento. Predefinição: `https://platform.claude.com/oauth/code/callback` |
| `CODEX_OAUTH_CLIENT_ID` | Codex / OpenAI | Cliente público. |
| `GEMINI_OAUTH_CLIENT_ID` | Gemini (Google) | Requer o `_SECRET` correspondente. |
| `GEMINI_OAUTH_CLIENT_SECRET` | Gemini (Google) | — |
| `KIMI_CODING_OAUTH_CLIENT_ID` | Kimi Coding (Moonshot) | Cliente público. |
| `MUSE_CODE_OAUTH_CLIENT_ID` | Muse Code (Meta) | Substituição opcional do ID de cliente público de fluxo de dispositivo da CLI Muse. Deixe por definir para usar o cliente público incorporado. |
| `ANTIGRAVITY_OAUTH_CLIENT_ID` | Antigravity (Google) | Requer o `_SECRET` correspondente. |
| `ANTIGRAVITY_OAUTH_CLIENT_SECRET` | Antigravity (Google) | — |
| `GITHUB_OAUTH_CLIENT_ID` | GitHub Copilot | Cliente público. |
| `GHE_COPILOT_OAUTH_CLIENT_ID` | GHE Copilot | Substituição opcional do ID de cliente OAuth do GitHub Enterprise Copilot. Recorre à predefinição pública de `GITHUB_OAUTH_CLIENT_ID` quando não definido. |
| `COPILOT_INTEGRATION_ID` | GitHub Copilot | Substituição opcional do ID de integração do cliente GitHub Copilot enviado nos cabeçalhos `Copilot-Integration-Id` e `Editor-Plugin-Version`. Predefinição: `copilot-developer-cli`. |
| `WINDSURF_API_KEY` | Windsurf / Devin (v3.8) | Chave de API de recurso usada por `open-sse/executors/devin-cli.ts` quando não está disponível nenhuma credencial por ligação. Opcional. |
| `CLI_DEVIN_BIN` | Devin CLI (v3.8) | Caminho personalizado para o binário da CLI Devin (`devin`). Resolvido por `open-sse/executors/devin-cli.ts`. |
| `GITLAB_DUO_OAUTH_CLIENT_ID` | GitLab Duo (v3.8) | ID de cliente OAuth para o GitLab Duo. Registe uma aplicação em `https://gitlab.com/-/profile/applications` com o URI de redirecionamento `/callback` e os âmbitos `api, read_user, openid, profile, email`. Recorre a `GITLAB_OAUTH_CLIENT_ID`. |
| `GITLAB_DUO_OAUTH_CLIENT_SECRET` | GitLab Duo (v3.8) | Segredo de cliente OAuth para o GitLab Duo. Opcional — o fluxo PKCE não requer um segredo. Recorre a `GITLAB_OAUTH_CLIENT_SECRET`. |
| `GITLAB_DUO_BASE_URL` | GitLab Duo (v3.8) | Substitui o URL base do GitLab (GitLab autoalojado). Predefinição: `https://gitlab.com`. Recorre a `GITLAB_BASE_URL`. |
| `GITLAB_BASE_URL` | GitLab Duo (v3.8) | Fallback legado para `GITLAB_DUO_BASE_URL`. Utilizado quando a variante `_DUO_` não está definida. |
| `GITLAB_OAUTH_CLIENT_ID` | GitLab Duo (v3.8) | Fallback legado para `GITLAB_DUO_OAUTH_CLIENT_ID` consumido por `src/lib/oauth/constants/oauth.ts`. |
| `GITLAB_OAUTH_CLIENT_SECRET` | GitLab Duo (v3.8) | Fallback legado para `GITLAB_DUO_OAUTH_CLIENT_SECRET` consumido por `src/lib/oauth/constants/oauth.ts`. |
| `QODER_OAUTH_CLIENT_SECRET` | Qoder | — |
| `QODER_OAUTH_AUTHORIZE_URL` | Qoder | Definir para ativar o OAuth do Qoder. |
| `QODER_OAUTH_TOKEN_URL` | Qoder | — |
| `QODER_OAUTH_USERINFO_URL` | Qoder | — |
| `QODER_OAUTH_CLIENT_ID` | Qoder | — |
| `QODER_PERSONAL_ACCESS_TOKEN` | Qoder | Fallback direto de chave de API (contorna o OAuth). |
| `QODER_CLI_WORKSPACE` | Qoder | ID do espaço de trabalho para o Qoder CLI. |
| `OMNIROUTE_QODER_WORKSPACE` | Qoder | Alias de `QODER_CLI_WORKSPACE`. |
| `QODER_CLI_CONFIG_DIR` | Qoder | Substitui o diretório de configuração do Qoder CLI (sessão PAT isolada, evita sobrescrever um início de sessão no navegador). |
| `QODER_CLI_MAX_CONCURRENCY` | Qoder | Máximo de execuções simultâneas do qodercli (processos de print ou prompts ACP); os pedidos excedentes aguardam em fila FIFO. Não definido (predefinição) = sem limite. |
| `QODER_CLI_QUEUE_TIMEOUT_MS` | Qoder | Tempo que um pedido Qoder aguarda por um slot do qodercli (apenas com limite definido) antes de falhar com 429 `qodercli_busy` + `Retry-After`. Predefinição: `120000`. |
| `QODER_CLI_TRANSPORT` | Qoder | `print` (predefinição) cria um processo `qodercli --print` por pedido; `acp` mantém um processo persistente `qodercli --acp` por PAT. |
| `QODER_CLI_ACP_IDLE_TIMEOUT_MS` | Qoder | Transporte ACP: termina o processo persistente do qodercli após este tempo de inatividade. Predefinição: `600000`. |
| `QODER_CLI_ACP_STARTUP_TIMEOUT_MS` | Qoder | Transporte ACP: tempo limite para o qodercli responder ao `initialize` do ACP. Predefinição: `60000`. |
| `QODER_CLI_ACP_MAX_SESSIONS_PER_PROCESS` | Qoder | Transporte ACP: recicla o processo persistente do qodercli após este número de sessões. Predefinição: `500`. |
| `BLACKBOX_WEB_VALIDATED_TOKEN` | Blackbox Web | Token `tk` do frontend a enviar como `validated` em `/api/chat`. Obrigatório quando o Blackbox exige correspondência de tokens; caso contrário, o OmniRoute recorre a um UUID aleatório. Consulte a issue #2252. |
| `VISION_BRIDGE_BASE_URL` | Vision Bridge guardrail | URL base compatível com OpenAI para chamadas vision-bridge não-Anthropic. Por predefinição, utiliza a variável de ambiente de URL OpenAI legada ou api.openai.com. Aponte para o self-loop `/v1` do OmniRoute ou para qualquer endpoint compatível com OpenAI (Gemini OpenAI-compat, OpenRouter). Issue #2232. Quando o URL é o próprio `/v1` do OmniRoute, o sub-pedido describe envia `x-omniroute-admission-bypass: internal` e autentica-se com a credencial de self-loop resolvida (sentinela `sk_omniroute` em modo local, ou `OMNIROUTE_API_KEY` / `ROUTER_API_KEY` — #1350), para que as implementações com `REQUIRE_API_KEY=true` funcionem. |
| `VISION_BRIDGE_API_KEY` | Vision Bridge guardrail | Chave de API para o URL acima. Substitui as variáveis de ambiente OpenAI / Google por fornecedor nas chamadas vision-bridge não-Anthropic. Os modelos Anthropic mantêm o seu caminho de chave Anthropic dedicado. Issue #2232. |
| `OMNIROUTE_VISION_BRIDGE_NEGATIVE_CACHE_MS` | Vision Bridge guardrail | Durante quanto tempo um resultado de encaminhamento "sem candidato utilizável" fica em cache, em ms (predefinição `30000`). Valores inválidos ou negativos revertem para a predefinição; `0` desativa a cache negativa. Fonte: `src/lib/guardrails/visionBridgeRouter.ts`. |
> [!WARNING]
>
> 1. Aceda a [Google Cloud Console → Credentials](https://console.cloud.google.com/apis/credentials)
> 2. Crie um ID de Cliente OAuth 2.0 (tipo: "Aplicação Web")
> 3. Adicione o URL do seu servidor como URI de redirecionamento autorizado
> 4. Substitua os valores das credenciais em `.env`.
---
## 12. Substituições de User-Agent por Fornecedor
Substitua o cabeçalho `User-Agent` enviado a cada fornecedor upstream. Isto é resolvido dinamicamente em tempo de execução pela classe base do executor:
```
process.env[`${PROVIDER_ID}_USER_AGENT`]
```
> **Fonte:** `open-sse/executors/base.ts` → `buildHeaders()`
| Variável | Valor Predefinido | Quando Atualizar |
| -------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `CLAUDE_USER_AGENT` | `claude-cli/2.1.280 (external, cli)` | Quando a Anthropic lança uma nova versão da CLI |
| `CLAUDE_DISABLE_TOOL_NAME_CLOAK` | `false` | `executors/base.ts` + `executors/cliproxyapi.ts` | Defina como `1`/`true` para encaminhar os nomes de ferramentas de harnesses de terceiros, verbatim, para a Anthropic em ambos os caminhos destinados à Anthropic (OAuth nativo e CLIProxyAPI). Por predefinição, o executor cria aliases determinísticos para nomes de ferramentas que não são do Claude Code (mapeamento canónico do Claude Code quando existe, caso contrário PascalCase) e reverte-os na resposta através de `_toolNameMap`, para que harnesses com ferramentas snake_case não sejam recusados como clientes de terceiros identificados por fingerprint. Apenas para depuração. |
| `CODEX_USER_AGENT` | `codex-cli/0.155.0 (Windows 10.0.26200; x64)` | Quando a OpenAI atualiza o Codex CLI |
| `CODEX_CLIENT_VERSION` | `0.155.0` | Substituir a versão do cliente Codex independentemente da string UA completa |
| `GROK_CLI_CLIENT_VERSION` | `1.0.41` | Substituir `x-grok-client-version` para inferência, sincronização de modelos e OAuth com código de dispositivo, além do User-Agent predefinido do Grok CLI para inferência e sincronização de modelos. Aceita SemVer com metadados opcionais de pré-lançamento/build, até 128 caracteres após remover os espaços em branco circundantes. Valores não definidos, vazios, inválidos ou com quebras de linha usam o valor fixo distribuído. A substituição existente do User-Agent completo de inferência mantém precedência. |
| `CLAUDE_CODE_CLIENT_VERSION` | `2.1.280` | Substituir a versão anunciada do Claude Code independentemente de `CLAUDE_USER_AGENT`. A Anthropic condiciona alguns modelos com base neste valor (#12417). |
| `CLAUDE_CODE_CLIENT_BUILD_REVISION` | `1e2` | Substituir o sufixo de 3 caracteres que o OmniRoute anexa a `cc_version=` no bloco de faturação do Claude. Atualize em conjunto com `CLAUDE_CODE_CLIENT_VERSION` — fixar apenas a versão anuncia um par `version.revision` que nenhum binário real emite. |
| `GITHUB_COPILOT_CLI_VERSION` | `1.0.91` | Substituir a versão anunciada do Copilot CLI independentemente de `GITHUB_USER_AGENT` |
| `GITHUB_USER_AGENT` | `GitHubCopilotChat/0.54.0` | Quando o GitHub Copilot Chat é atualizado |
| `ANTIGRAVITY_USER_AGENT` | `antigravity/2.0.1 darwin/arm64` | Quando o Antigravity IDE é atualizado |
| `KIRO_USER_AGENT` | `AWS-SDK-JS/3.0.0 kiro-ide/1.0.0` | Quando o Kiro IDE é atualizado |
| `KIRO_OAUTH_CLIENT_ID` | `kiro-cli` | Substituir o `clientId` de código de dispositivo social do Kiro (id público) |
| `KIRO_VERIFY_FULL_CRC` | `false` | Opção ativável: validação CRC completa de mensagens por frame no fluxo de eventos do Kiro (depurar fluxos corrompidos) |
| `KIRO_CREDIT_PRICE_USD` | `0.02` | USD por crédito Kiro; converte os créditos de `meteringEvent` no custo exato por pedido |
| `KIRO_REQUIRE_CREDITS` | `false` | Falhar uma resposta Kiro que não reporte medição de créditos em vez de a registar como não faturada |
| `QODER_USER_AGENT` | `Qoder-Cli` | Quando o Qoder CLI é atualizado |
| `CURSOR_USER_AGENT` | `Cursor/3.3` | Quando o Cursor é atualizado |
> [!TIP]
> Pode adicionar substituições de User-Agent para **qualquer** fornecedor usando o padrão `{PROVIDER_ID}_USER_AGENT`. O executor constrói dinamicamente o nome da variável de ambiente.
---
## 13. Compatibilidade de impressão digital da CLI
Quando ativado, o OmniRoute reordena os cabeçalhos HTTP e os campos do corpo JSON para corresponder à assinatura exata das ferramentas CLI oficiais. Isto reduz o risco de sinalização da conta, preservando simultaneamente o seu IP de proxy.
**Origem:** `open-sse/config/cliFingerprints.ts`, `open-sse/executors/base.ts`
### Por fornecedor
| Variável | Ativação | Efeito |
| ------------------------ | -------- | ------------------------------------------------ |
| `CLI_COMPAT_CODEX` | `=1` | Imita a assinatura dos pedidos da CLI Codex |
| `CLI_COMPAT_CLAUDE` | `=1` | Imita a assinatura dos pedidos do Claude Code |
| `CLI_COMPAT_GITHUB` | `=1` | Imita a assinatura dos pedidos do GitHub Copilot |
| `CLI_COMPAT_ANTIGRAVITY` | `=1` | Imita a assinatura dos pedidos do Antigravity |
| `CLI_COMPAT_CURSOR` | `=1` | Imita a assinatura dos pedidos do Cursor |
| `CLI_COMPAT_KIMI_CODING` | `=1` | Imita a assinatura dos pedidos do Kimi Coding |
| `CLI_COMPAT_KILOCODE` | `=1` | Imita a assinatura dos pedidos do Kilo Code |
| `CLI_COMPAT_CLINE` | `=1` | Imita a assinatura dos pedidos do Cline |
### Global
| Variável | Ativação | Efeito |
| ---------------- | -------- | ------------------------------------------------------------------------------------------ |
| `CLI_COMPAT_ALL` | `=1` | Ativa a compatibilidade de impressão digital para **todos** os fornecedores de uma só vez. |
### Substituições da identidade da CLI Kimi Coding
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ----------------------- | ----------------------- | ---------------------------------------- | -------------------------------------------------------------------------------- |
| `KIMI_CLI_VERSION` | `1.36.0` | `src/lib/oauth/providers/kimi-coding.ts` | Substitui a versão da CLI Kimi enviada durante as chamadas OAuth/API. |
| `KIMI_CODING_DEVICE_ID` | _(predefinição obtida)_ | `src/lib/oauth/providers/kimi-coding.ts` | Substitui o ID de dispositivo Kimi obtido e utilizado nos cabeçalhos do cliente. |
> [!NOTE]
> Esta funcionalidade funciona em conjunto com as substituições de User-Agent (§12). O sistema de impressão digital gere a ordenação dos cabeçalhos e dos campos do corpo, enquanto as substituições de User-Agent gerem a cadeia UA específica. Ambos podem ser ativados de forma independente.
---
## 14. Fornecedores de chaves de API
Chaves de API para fornecedores que utilizam autenticação direta. **Configuração preferencial:** Painel → Fornecedores → Adicionar chave de API.
A configuração através de variáveis de ambiente é uma alternativa para implementações Docker ou sem interface gráfica.
Padrão reconhecido: `{PROVIDER_ID}_API_KEY`
| Variável | Fornecedor |
| ------------------ | ------------------------------------------------------ |
| `DEEPSEEK_API_KEY` | DeepSeek |
| `NVIDIA_API_KEY` | NVIDIA NIM |
| `JINA_AI_API_KEY` | Jina AI (API Foundation + recurso ao Reader) |
| `JINA_API_KEY` | Jina AI (alias de `JINA_AI_API_KEY`) |
| `GEMINI_API_KEY` | Gemini (Google AI Studio) embeddings + recurso ao chat |
| `GOOGLE_API_KEY` | Gemini (alias de `GEMINI_API_KEY`) |
> [!NOTE]
> As entradas estáticas `${PROVIDER}_API_KEY` para Groq, xAI, Mistral, Perplexity, Together AI, Fireworks, Cerebras, Cohere, Nebius e Qianfan foram removidas na v3.8.0 porque o runtime já não as lê — esses fornecedores dependem exclusivamente do Painel / `data/provider-credentials.json` / da base de dados encriptada. Consulte a secção _Auditoria: variáveis removidas/inativas_ no final deste documento para conhecer o procedimento de migração.
> [!TIP]
> As chaves configuradas através do Painel são armazenadas de forma encriptada no SQLite e têm precedência sobre as variáveis de ambiente.
>
> **Jina:** os embeddings `jina-ai/…`, bem como rerank, classify, segment e `jina-search`, **não** faturam uma chave de ambiente do cluster quando existe uma ligação `jina-ai` (ou `jina-reader` partilhada) no painel — `getProviderCredentials` utiliza preenchimento prioritário. `JINA_AI_API_KEY` / `JINA_API_KEY` são utilizadas apenas quando não existe uma chave utilizável no painel. Os registos de chamadas atribuem o recurso à variável de ambiente como `connection_id=env:JINA_AI_API_KEY`. O cartão Reader (`jina-reader`, `r.jina.ai`) nunca serve `/v1/embeddings` nem `/v1/rerank`.
>
> **Gemini:** `gemini/gemini-embedding-2` (alias `google/gemini-embedding-2`) utiliza primeiro a ligação `gemini` do painel. `GEMINI_API_KEY` / `GOOGLE_API_KEY` são utilizadas apenas quando não existe uma chave utilizável no painel. Os registos de chamadas atribuem o recurso à variável de ambiente como `connection_id=env:GEMINI_API_KEY`. O tráfego multimodal nativo utiliza `x-goog-api-key` com `:embedContent` / `:batchEmbedContents` — N itens OpenAI em `input` tornam-se N vetores.
---
## 15. Definições de Timeout
Todos os valores estão em **milissegundos**. Resolução centralizada em `src/shared/utils/runtimeTimeouts.ts`.
### Hierarquia de Timeouts
```
REQUEST_TIMEOUT_MS (substituição global)
├─→ FETCH_TIMEOUT_MS (chamadas a fornecedores upstream, predefinição: 600000)
│ ├─→ FETCH_HEADERS_TIMEOUT_MS (herda de FETCH_TIMEOUT_MS)
│ ├─→ FETCH_BODY_TIMEOUT_MS (herda de FETCH_TIMEOUT_MS)
│ ├─→ TLS_CLIENT_TIMEOUT_MS (herda de FETCH_TIMEOUT_MS)
│ │ └── TLS_FIRST_BYTE_WATCHDOG_MS (independente, predefinição: 10000)
│ ├── RESPONSES_FIRST_BYTE_TIMEOUT_MS (independente, predefinição: 15000)
│ ├── OPENCODE_RESPONSES_HEADERS_WAIT_MS (independente, predefinição: 0 = desativado, sugerido: 30000)
│ ├── OPENCODE_RESPONSES_HEADERS_WAIT_MAX_ROTATIONS (independente, predefinição: 2)
│ ├── FETCH_CONNECT_TIMEOUT_MS (independente, predefinição: 30000)
│ └── FETCH_KEEPALIVE_TIMEOUT_MS (independente, predefinição: 4000)
├─→ STREAM_IDLE_TIMEOUT_MS (herda de REQUEST_TIMEOUT_MS, predefinição: 600000)
├─→ STREAM_ACTIVE_TIMEOUT_MS (independente, predefinição: 1260000; 0 desativa)
├─→ STREAM_READINESS_TIMEOUT_MS (herda de REQUEST_TIMEOUT_MS, predefinição: 80000)
├─→ STREAM_READINESS_MAX_TIMEOUT_MS (limita as extensões adaptativas de prontidão, predefinição: 180000)
└─→ API_BRIDGE_PROXY_TIMEOUT_MS (herda de REQUEST_TIMEOUT_MS, predefinição: 30000)
├─→ API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS (derivado, predefinição: 300000)
├── API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS (predefinição: 60000)
├── API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS (predefinição: 5000)
└── API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS (predefinição: 0 = desativado)
```
| Variável | Predefinição | Descrição |
| ----------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `REQUEST_TIMEOUT_MS` | _(não definido)_ | Atalho global — substitui as predefinições de `FETCH_TIMEOUT_MS` e `STREAM_IDLE_TIMEOUT_MS`. |
| `FETCH_TIMEOUT_MS` | `600000` | Tempo limite total do pedido HTTP para chamadas ao fornecedor upstream. |
| `STREAM_IDLE_TIMEOUT_MS` | `600000` | Silêncio máximo entre bytes brutos do upstream antes de abortar. Modelos com pensamento estendido raramente pausam >90s. |
| `STREAM_ACTIVE_TIMEOUT_MS` | `1260000` | Tempo de vida máximo total de um stream SSE ativo; nunca é reiniciado com bytes do upstream e é independente de `REQUEST_TIMEOUT_MS`. Derivado do maior `timeoutMs` por modelo no registo (1200000, Codex) mais uma margem de 60000, para que um modelo autorizado a usar todo o seu orçamento nunca seja interrompido a meio de uma resposta. Defina como `0` para desativar. |
| `OMNIROUTE_SSE_COMMENTS` | _(desativado)_ | Se o OmniRoute pode emitir linhas de comentário SSE `:` (por ex. o heartbeat `: keepalive` e os trailers de metadados `x-omniroute-*`). Desativado por predefinição (#10524), uma vez que clientes estritamente compatíveis com OpenAI fazem JSON.parse a cada linha SSE e falham com comentários `:`; os heartbeats `data:` não são afetados. Defina `on`/`true`/`1`/`yes` para voltar a ativar. Utilizado por `open-sse/utils/sseHeartbeat.ts`. |
| `SSE_COALESCE_MS` | `0` (desativado) | Opção ativável: funde eventos consecutivos `content_block_delta` do Claude (mesmo índice de bloco e tipo de delta) enviados a clientes Claude, com flush pelo menos a cada N ms. Sem perdas; `signature_delta` e eventos de fronteira nunca são fundidos. Aplica-se a todos os tipos de delta, exceto se uma das variáveis por tipo abaixo estiver definida. Utilizado por `open-sse/utils/sseDeltaCoalesce.ts`. |
| `SSE_COALESCE_THINKING_MS` | `0` (desativado) | Substituição por tipo de `SSE_COALESCE_MS` para `thinking_delta`. |
| `SSE_COALESCE_TEXT_MS` | `0` (desativado) | Substituição por tipo de `SSE_COALESCE_MS` para `text_delta`. |
| `SSE_COALESCE_INPUT_JSON_MS` | `0` (desativado) | Substituição por tipo de `SSE_COALESCE_MS` para `input_json_delta`. |
| `SSE_FRAME_COALESCE_MS` | `0` (desativado) | Opção ativável: agrupa frames SSE reencaminhados dentro de N ms numa única escrita para o cliente. O primeiro frame e os frames terminais (`[DONE]`, `message_stop`, `error`, `response.completed`/`failed`/`incomplete`) nunca são atrasados; com o agrupamento ativo, o ITL mede os intervalos entre lotes. Utilizado por `open-sse/utils/sseOutputSink.ts`. |
| `SSE_STALL_WATCHDOG` | `timer` | Implementação de watchdog de estagnação de bytes para respostas em stream. `timer` rearma um temporizador por chunk do upstream (dispara exatamente no limite de estagnação); `interval` mantém uma verificação por stream com período `clamp(budget/4, 1s, 5s)`, pelo que uma estagnação dispara dentro de limite + período. Utilizado por `open-sse/utils/streamStallWatchdog.ts`. |
| `STREAM_READINESS_TIMEOUT_MS` | `80000` | Tempo para receber o primeiro evento SSE que não seja ping. Herda `REQUEST_TIMEOUT_MS` quando definido. |
| `STREAM_READINESS_MAX_TIMEOUT_MS` | `180000` | Janela máxima adaptativa de prontidão do primeiro evento para pedidos de streaming grandes, com uso intensivo de ferramentas ou de elevado raciocínio. |
| `OMNIROUTE_AGENT_GOAL_POLICY_ENABLED` | `true` | Kill-switch para a heurística `/goal`. Defina `false`/`0`/`off` para desativar totalmente a deteção — os tempos limite de prontidão e a recuperação de stream nunca são elevados pelo corpo/cabeçalhos do pedido, mitigando a amplificação de tempos limite controlada pelo cliente. |
| `OMNIROUTE_AGENT_GOAL_READINESS_MAX_TIMEOUT_MS` | `600000` | Janela máxima de prontidão do primeiro evento para execuções de agente `/goal` detetadas ou pedidos forçados com `x-omniroute-agent-goal`. |
| `OMNIROUTE_AGENT_GOAL_STREAM_RECOVERY` | `true` | Ativa automaticamente a recuperação antecipada de stream para execuções de agente `/goal` detetadas. Defina `false`/`0`/`off` para desativar esta opção específica de goal. Isto apenas pode ADICIONAR recuperação sobre a predefinição do operador — nunca substitui uma recusa explícita via `STREAM_RECOVERY_ENABLED`/definições da BD. |
| `OMNIROUTE_CODEX_DROP_NONSTANDARD_EVENTS` | `true` | Remove eventos SSE `codex.*` não padrão (por ex. `codex.rate_limits`) que quebram o `responses.stream()` do SDK OpenAI com um 502. Predefinição ATIVADO (#11014). Defina `0`/`false`/`no`/`off` para os reencaminhar. |
| `OMNIROUTE_CODEX_APPSERVER_WS` | _(não definido)_ | Transporte opcional do app-server Codex. Endpoint WebSocket (`ws://`/`wss://`) de um sidecar local `codex app-server`. Quando definido em conjunto com um token, os pedidos Codex são encaminhados via JSON-RPC para o sidecar em vez da API HTTP Responses. Também configurável por ligação via `providerSpecificData.codexAppServerUrl`. Utilizado por `open-sse/executors/codex/appServerConfig.ts`. |
| `OMNIROUTE_CODEX_APPSERVER_WS_TOKEN` | _(não definido)_ | Token de capability/bearer inline apresentado ao app-server. Substituição por ligação: `providerSpecificData.codexAppServerToken`. |
| `OMNIROUTE_CODEX_APPSERVER_WS_TOKEN_FILE` | _(não definida)_ | Caminho para um ficheiro que contém o token de capacidade do app-server (de `codex app-server --ws-token-file`). Utilizado quando `OMNIROUTE_CODEX_APPSERVER_WS_TOKEN` não está definida. Substituição por ligação: `providerSpecificData.codexAppServerTokenFile`. |
| `OMNIROUTE_CODEX_APPSERVER_CWD` | `/tmp` | Diretório de trabalho em que o turn do app-server é executado. Substituição por ligação: `providerSpecificData.codexAppServerCwd`. |
| `OMNIROUTE_CODEX_APPSERVER_APPROVAL` | _(não definida)_ | Política de aprovação passada ao turn do app-server (p. ex. `never`, `on-request`). Substituição por ligação: `providerSpecificData.codexAppServerApprovalPolicy`. |
| `OMNIROUTE_CODEX_APPSERVER_SANDBOX` | _(não definida)_ | Política de sandbox passada ao turn do app-server (p. ex. `read-only`, `workspace-write`, `danger-full-access`). Quando não definida, o executor usa `workspace-write` por predefinição (reforçado; anteriormente `danger-full-access`). Substituição por ligação: `providerSpecificData.codexAppServerSandbox`. |
| `OMNIROUTE_CODEX_APPSERVER_AUTO_APPROVE` | `false` | Aprovar automaticamente os próprios pedidos de aprovação do app-server (execução de comandos/ficheiros/permissões no anfitrião). Desativado por predefinição — os pedidos são negados automaticamente; as chamadas de ferramentas do harness não são afetadas (viajam pelo passthrough separado `item/tool/call`). Aceita `true`/`1`/`yes`. Substituição por ligação: `providerSpecificData.codexAppServerAutoApprove`. |
| `FETCH_HEADERS_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Tempo para receber os cabeçalhos da resposta. |
| `OMNIROUTE_FETCH_START_TIMEOUT_CAP_MS` | `110000` | Espera máxima pelos cabeçalhos da resposta em pedidos de streaming (ms). `0` desativa este limite; um `fetchStartTimeoutCapMs` explícito do provider tem precedência. |
| `OMNIROUTE_DIRECT_HEADERS_TIMEOUT_MS` | `30000` (30s) | Espera máxima pelo início da resposta (ms) em cada tentativa direta sem proxy. Um timeout tenta novamente uma vez num socket novo; defina `0` para desativar o limite e manter o comportamento anterior. |
| `OMNIROUTE_LOCAL_DIRECT_HEADERS_TIMEOUT_MS` | `300000` (5 min) | Limite mínimo de início da resposta (ms) para tentativas diretas sem proxy cujo anfitrião de destino é privado/LAN/loopback (por exemplo `localhost`, `host.docker.internal`, `192.168.x.x`), para que um arranque a frio do Ollama nativo não seja cortado pelo padrão de 30s acima. Atua como limite mínimo: a espera efetiva é o maior deste valor e de `OMNIROUTE_DIRECT_HEADERS_TIMEOUT_MS`; `0` ou um valor inválido remove o limite mínimo local. Anfitriões remotos não são afetados. |
| `OMNIROUTE_DIRECT_RESPONSE_RETRY_TIMEOUT_MS` | `600000` (10 min) | Teto (ms) para a tentativa de RETRY em socket novo após um timeout de início de resposta da tentativa em pool acima (#13703). Aplica-se apenas quando o chamador já anexou o seu próprio sinal de prazo (a cascata resolvida connection/model/provider/`FETCH_TIMEOUT_MS`); esse sinal é o limite real e dispara primeiro no caminho previsto, pelo que este é uma salvaguarda generosa e não um teto fixo — sem ele, a nova tentativa reutilizava a mesma janela curta de `OMNIROUTE_DIRECT_HEADERS_TIMEOUT_MS` da tentativa em pool e devolvia 504 em modelos de raciocínio saudáveis com TTFB lento. Nunca é permitido abaixo do limite mínimo fixo acima; quando o chamador não fornece qualquer sinal de prazo, a nova tentativa mantém o limite mínimo fixo inalterado. |
| `FETCH_BODY_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Tempo para receber o corpo completo da resposta. |
| `FETCH_CONNECT_TIMEOUT_MS` | `30000` | Timeout de estabelecimento da ligação TCP. |
| `FETCH_KEEPALIVE_TIMEOUT_MS` | `4000` | Timeout de inatividade do socket keep-alive. |
| `TLS_CLIENT_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Timeout do proxy de fingerprint TLS (wreq-js). |
| `TLS_FIRST_BYTE_WATCHDOG_MS` | `10000` | Limita o time-to-first-byte especificamente no corpo do transporte de fingerprint TLS do wreq-js; `TLS_CLIENT_TIMEOUT_MS` por si só não consegue detetar um corpo bloqueado, pois resolve assim que os cabeçalhos chegam (#12656). Um timeout cancela o leitor wreq e recorre ao dispatcher direto/proxy; `0` desativa o watchdog. |
| `RESPONSES_FIRST_BYTE_TIMEOUT_MS` | `15000` | Apenas no executor OpenCode, e apenas enquanto a feature flag `OPENCODE_RESPONSES_STALL_ROTATION` estiver ativa (desativada por predefinição): limita a espera pelo primeiro byte do corpo de uma resposta Responses em streaming após os seus cabeçalhos (#13484). Um stream Responses abre com `response.created`, pelo que silêncio além desta janela é um bloqueio: a conta entra em cooldown e o pedido roda uma vez para a conta seguinte; um segundo bloqueio falha de imediato. `0` desativa a proteção mesmo com a flag ativa. |
| `OPENCODE_RESPONSES_HEADERS_WAIT_MS` | `0` (= desativado) | Apenas no executor OpenCode: limita a espera pelos cabeçalhos da resposta upstream numa chamada Responses em streaming quando outra conta ainda está disponível — um pedido em fila deixa de esperar e avança em vez de reter a janela completa de cabeçalhos. Apenas as chamadas Responses em streaming são afetadas (o stream Responses abre com `response.created`, pelo que silêncio aí é uma fila, não geração); chat completions e chamadas sem streaming ficam intocados, e a janela apenas encurta o teto efetivo de início do fetch, nunca o prolonga. Valor sugerido ao ativar: `30000`. `0` desativa. |
| `OPENCODE_RESPONSES_HEADERS_WAIT_MAX_ROTATIONS` | `2` | Apenas executor OpenCode: quantas vezes por pedido o limite de espera de headers acima pode passar para a conta seguinte. A última conta restante mantém sempre a janela completa de headers. |
| `OPENCODE_PARK_AND_RESUME` | `false` | Apenas executor OpenCode: estaciona o pedido com um heartbeat após 429s transitórios repetidos (ou um marcador de pressão do pool recente) e depois repete uma etapa limitada de até 3 contas sequenciais em vez de distribuir por toda a frota (#13924). Desativado por predefinição: cada 429 roda para a conta seguinte exatamente como antes. |
| `OPENCODE_PARK_REPLAY_SERVE_SETASIDE` | `false` | Apenas executor OpenCode: quando todas as contas prontas após cooldown na etapa de repetição do park-and-resume são postas de lado pela memória de recusas do proxy, serve-as mesmo assim em vez de não repetir nada (#14851, seguimento de #14750). Desativado por predefinição: nesse caso a etapa de repetição fica vazia, como antes de #14750. |
| `STREAM_READINESS_STALL_RETRY` | `false` | Apenas chat em streaming: quando o primeiro body upstream bloqueia antes de produzir um evento utilizável, emite uma segunda tentativa limitada pelo mesmo caminho de encaminhamento, com o mesmo orçamento de prontidão e sem penalização da conta. Desativado por predefinição: um primeiro body bloqueado falha o pedido sem nova tentativa. |
| `OPENCODE_POOL_RESELECT` | `false` | Apenas executor OpenCode: após um 429 de um fornecedor com buckets de egress numa conta sem proxy sob um contexto de pool ambiente, pede ao connection pool outro membro para a tentativa seguinte em vez de repetir o mesmo endereço de egress. Ordena, nunca exclui: um pool esgotado mantém o comportamento atual. Desativado por predefinição: cada 429 roda para a conta seguinte exatamente como antes. |
| `OPENCODE_POOL_STRAIN_MARKER_PATH` | _(não definido)_ | Apenas executor OpenCode: caminho alternativo do marcador de pressão do pool lido antes de estacionar (`{since, reason, ttl_s}`, predefinição `/tmp/opencode-pool-strain.json`, #13924). Um marcador recente estaciona sem recontagem; ausente ou expirado, recorre ao contador de rajadas. |
| `API_BRIDGE_PROXY_TIMEOUT_MS` | `30000` | Timeout do salto de proxy para pedidos bridge `/v1`. |
| `FIRECRAWL_BASE_URL` | `https://api.firecrawl.dev` | Aponta o executor de web-fetch do Firecrawl para uma instância autoalojada (chave de API opcional fora da cloud). |
| `FIRECRAWL_TIMEOUT_MS` | `30000` | Timeout por pedido para o executor de web-fetch do Firecrawl. |
| `TAVILY_BASE_URL` | _(não definido)_ | URL base para o obtentor de quota `/usage` do Tavily (Provider Limits); ignorado quando aponta para `api.tavily.com`. Não definido, recorre ao URL base da ligação. |
| `API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS` | `300000` | Timeout geral de pedidos do servidor para o bridge. |
| `API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS` | `60000` | Tempo para enviar os headers de resposta através do bridge. |
| `API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS` | `5000` | Timeout de inatividade keep-alive do bridge. |
| `API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS` | `0` | Timeout do socket raw (0 = desativado). |
| `SHUTDOWN_TIMEOUT_MS` | `30000` | Período de tolerância em SIGTERM/SIGINT antes da saída forçada. |
| `OMNIROUTE_DEFAULT_FETCH_TIMEOUT_MS` | `120000` | Fallback usado por `src/shared/utils/fetchTimeout.ts` quando `FETCH_TIMEOUT_MS` não está definido. |
| `OMNIROUTE_PROVIDER_PROBE_TIMEOUT_MS` | `8000` | Timeout (ms) para os presets `validationRead` e `modelsProbe` em `src/shared/network/safeOutboundFetch.ts`. Aumentar para endpoints lentos (Cerebras, Cloudflare AI, Groq) para evitar oscilação entre ativo/erro no dashboard. Recorre a 8000ms para valores inválidos (<1000) ou não numéricos. |
| `OMNIROUTE_RELAY_FETCH_TIMEOUT_MS` | `25000` | Timeout de fetch específico do relay em `open-sse/utils/proxyFetch.ts` (#9158). Um relay bloqueado deve falhar antes do timeout do cliente/agente (~30s), para que os chamadores vejam uma falha específica do relay em vez de um timeout genérico de upstream. Limitado a `29000` para disparar sempre primeiro. |
| `OMNIROUTE_RETRY_BACKOFF_MS` | `10` | Backoff de nova tentativa partilhado para os caminhos de tentativa única direto/relay/proxy em `open-sse/utils/proxyFetch.ts` (#9158). `0` = tenta novamente de imediato. |
| `OMNIROUTE_CLAUDE_TLS_TIMEOUT_MS` | `60000` | Timeout de pedido nativo do wreq-js (`claudeTlsClient.ts`). |
| `OMNIROUTE_CLAUDE_TLS_GRACE_MS` | `10000` | Tolerância de prazo limite absoluto em JS adicionada ao timeout nativo. |
| `OMNIROUTE_PPLX_TLS_TIMEOUT_MS` | `30000` | Timeout de pedido nativo do wreq-js (`perplexityTlsClient.ts`). |
| `OMNIROUTE_PPLX_TLS_GRACE_MS` | `10000` | Margem de tolerância absoluta do hard-deadline em JS, adicionada ao tempo limite nativo. |
| `OMNIROUTE_PPLX_SEARCH_HINT` | `0` (off) | Acrescenta "You have built-in web search. Answer questions directly using search results." à mensagem de sistema do chamador (`perplexity-web/protocol.ts`). Desativado por predefinição — o Perplexity pesquisa na mesma, e a frase infiltra-se nas respostas como meta-comentário em clientes de programação. Defina `1`/`true`/`yes`/`on` para restaurar. |
| `OMNIROUTE_GROK_TLS_TIMEOUT_MS` | `60000` | Tempo limite nativo de pedidos do wreq-js (`grokTlsClient.ts`). |
| `OMNIROUTE_GROK_TLS_GRACE_MS` | `10000` | Margem de tolerância absoluta do hard-deadline em JS, adicionada ao tempo limite nativo. |
| `OMNIROUTE_NOTION_TLS_TIMEOUT_MS` | `30000` | Tempo limite nativo de pedidos do wreq-js (`notionTlsClient.ts`); o `notion-web` aumenta-o por pedido para `180000` em gerações longas. |
| `OMNIROUTE_NOTION_TLS_GRACE_MS` | `10000` | Margem de tolerância absoluta do hard-deadline em JS, adicionada ao tempo limite nativo. |
| `OMNIROUTE_BROWSER_POOL` | `on` | Pool partilhado de browsers Playwright para chat com cookies web suportado por browser (`browserPool.ts`); defina `off` para desativar. |
| `OBSCURA_BIN` | `auto-detect` | Caminho para o binário `obscura` usado como motor principal pelo pool de browsers e pelo executor do Cloudflare Playground (`open-sse/services/obscura.ts`); detetado automaticamente a partir do PATH do sistema quando não definido. |
| `OBSCURA_CDP_ENDPOINT` | _(não definido)_ | Aponta para um Obscura já em execução (`http://host:port`) em vez de iniciar um novo; o módulo não é proprietário desse processo (`open-sse/services/obscura.ts`). |
| `OBSCURA_PORT` | `random free port` | Porta explícita para o `obscura serve` iniciado; uma porta livre é escolhida automaticamente quando não definida (`open-sse/services/obscura.ts`). |
| `WEB_COOKIE_USE_BROWSER` | `0` | Ativa o caminho suportado por browser para um pedido de chat com cookies web (`browserBackedChat.ts`); `1` para ativar. |
| `KIMI_WEB_BASE_URL` | `https://www.kimi.ai` | URL base para o executor Kimi Web (Connect-RPC internacional kimi.ai) (`kimi-web.ts`); substitua apenas para endpoints mirror/proxy. |
| `KIMI_WEB_CHAT_URL` | `/apiv2/kimi.gateway.chat.v1.ChatService/Chat` | Endpoint de chat completo para o executor Kimi Web (`kimi-web.ts`). |
| `OMNIROUTE_LOGIN_BROWSER_PATH` | _(detetado automaticamente)_ | Caminho para um executável Chrome/Edge do sistema para o início de sessão interativo no browser do Adobe Firefly (`adobeFireflyBrowserLogin.ts`); substitui a deteção automática por SO. |
| `OMNIROUTE_STANDALONE_DIR` | _Saída standalone de .build/_ | Substituição em tempo de compilação para o diretório de saída standalone consumido pelo passo de colocalização pós-compilação (`scripts/build/colocate-standalone.mjs`); ferramenta de compilação, não de execução. |
As tentativas de destino do combo herdam o tempo limite de pedido upstream resolvido (`FETCH_TIMEOUT_MS`, ou
`REQUEST_TIMEOUT_MS` quando este fornece a predefinição do fetch). Defina `targetTimeoutMs` num combo,
nas predefinições do combo ou numa substituição de provider apenas para tornar o fallback do combo mais rápido; valores acima
do tempo limite upstream atual são limitados ao tempo limite upstream.
O `comboTimeoutMs` é um orçamento separado de tempo real (wall-clock) para todo o combo, abrangendo os destinos de failover.
Deixe-o por definir ou em `0` para manter a iteração ilimitada (continua a aplicar-se um limite fixo de 10 minutos contra bloqueios em
`comboPredicates.ts`). Um valor positivo substitui essa
rede de segurança para o combo. Mantenha o `comboTimeoutMs` superior ao `targetTimeoutMs` para que o failover
ainda tenha tempo após um primeiro destino lento.
### Limiares do Circuit Breaker
Ajuste do circuit breaker ao nível do provider. As predefinições refletem os valores escalados usados desde a v3.6 para mais de 500 ligações.
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ------------------------------------------------------------- | ------------ | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_CIRCUIT_BREAKER_OAUTH_THRESHOLD` | `8` | `open-sse/config/constants.ts` | Limite de falhas consecutivas para fornecedores OAuth antes de o disjuntor disparar. |
| `OMNIROUTE_CIRCUIT_BREAKER_OAUTH_RESET_MS` | `60000` | `open-sse/config/constants.ts` | Janela de reinício (ms) para o disjuntor do fornecedor OAuth. |
| `OMNIROUTE_CIRCUIT_BREAKER_API_KEY_THRESHOLD` | `12` | `open-sse/config/constants.ts` | Limite de falhas consecutivas para fornecedores com chave API. |
| `OMNIROUTE_CIRCUIT_BREAKER_API_KEY_RESET_MS` | `30000` | `open-sse/config/constants.ts` | Janela de reinício (ms) para o disjuntor do fornecedor com chave API. |
| `OMNIROUTE_CIRCUIT_BREAKER_LOCAL_THRESHOLD` | `2` | `open-sse/config/constants.ts` | Limite de falhas consecutivas para fornecedores locais (Ollama, LM Studio, ...). |
| `OMNIROUTE_CIRCUIT_BREAKER_LOCAL_RESET_MS` | `15000` | `open-sse/config/constants.ts` | Janela de reinício (ms) para o disjuntor do fornecedor local. |
| `OMNIROUTE_PROVIDER_BREAKER_OAUTH_FAILURE_THRESHOLD` | `10` | `open-sse/config/constants.ts` | Disjuntor ao nível do fornecedor: falhas dentro da janela antes de todo o fornecedor OAuth entrar em período de espera. |
| `OMNIROUTE_PROVIDER_BREAKER_OAUTH_FAILURE_WINDOW_MS` | `900000` | `open-sse/config/constants.ts` | Disjuntor ao nível do fornecedor: janela deslizante de contagem de falhas (ms) para fornecedores OAuth. |
| `OMNIROUTE_PROVIDER_BREAKER_OAUTH_COOLDOWN_MS` | `300000` | `open-sse/config/constants.ts` | Disjuntor ao nível do fornecedor: período de espera (ms) assim que o limite do fornecedor OAuth é atingido. |
| `OMNIROUTE_PROVIDER_BREAKER_OAUTH_DEGRADATION_THRESHOLD` | `5` | `open-sse/config/constants.ts` | O fornecedor OAuth entra no estado DEGRADED após este número de falhas. |
| `OMNIROUTE_PROVIDER_BREAKER_OAUTH_MAX_BACKOFF_MULTIPLIER` | `8` | `open-sse/config/constants.ts` | Multiplicador máximo de escalonamento de resetTimeout do fornecedor OAuth. |
| `OMNIROUTE_PROVIDER_BREAKER_OAUTH_BACKOFF_ESCALATION_COUNT` | `2` | `open-sse/config/constants.ts` | O fornecedor OAuth escala após este número de ciclos abertos. |
| `OMNIROUTE_PROVIDER_BREAKER_API_KEY_FAILURE_THRESHOLD` | `15` | `open-sse/config/constants.ts` | Disjuntor ao nível do fornecedor: falhas dentro da janela antes de todo o fornecedor com chave API entrar em período de espera. |
| `OMNIROUTE_PROVIDER_BREAKER_API_KEY_FAILURE_WINDOW_MS` | `1800000` | `open-sse/config/constants.ts` | Disjuntor ao nível do fornecedor: janela deslizante de contagem de falhas (ms) para fornecedores com chave API. |
| `OMNIROUTE_PROVIDER_BREAKER_API_KEY_COOLDOWN_MS` | `600000` | `open-sse/config/constants.ts` | Disjuntor ao nível do fornecedor: período de espera (ms) assim que o limite do fornecedor com chave API é atingido. |
| `OMNIROUTE_PROVIDER_BREAKER_API_KEY_DEGRADATION_THRESHOLD` | `7` | `open-sse/config/constants.ts` | O fornecedor com chave API entra no estado DEGRADED após este número de falhas. |
| `OMNIROUTE_PROVIDER_BREAKER_API_KEY_MAX_BACKOFF_MULTIPLIER` | `4` | `open-sse/config/constants.ts` | Multiplicador máximo de escalonamento de resetTimeout do fornecedor com chave API. |
| `OMNIROUTE_PROVIDER_BREAKER_API_KEY_BACKOFF_ESCALATION_COUNT` | `3` | `open-sse/config/constants.ts` | O fornecedor com chave API escala após este número de ciclos abertos. |
| `OMNIROUTE_PROVIDER_BREAKER_LOCAL_FAILURE_THRESHOLD` | `2` | `open-sse/config/constants.ts` | Disjuntor ao nível do fornecedor: falhas antes de todo o fornecedor local entrar em período de espera. |
| `OMNIROUTE_PROVIDER_BREAKER_LOCAL_FAILURE_WINDOW_MS` | `300000` | `open-sse/config/constants.ts` | Disjuntor ao nível do fornecedor: janela deslizante de contagem de falhas (ms) para fornecedores locais. |
| `OMNIROUTE_PROVIDER_BREAKER_LOCAL_COOLDOWN_MS` | `60000` | `open-sse/config/constants.ts` | Disjuntor ao nível do fornecedor: período de espera (ms) assim que o limite do fornecedor local é atingido. |
| `OMNIROUTE_API_KEY_COOLDOWN_MS` | `60000` | `open-sse/services/apiKeyRotator.ts` | Período de espera (ms) por chave aplicado pela rotação de múltiplas chaves API quando um 429 do upstream não inclui `Retry-After` (#14573). Valores não positivos ou não numéricos revertem para a predefinição. |
| `PIN_DROP_BACKOFF_LEVEL` | `2` | `open-sse/services/combo.ts` | Profundidade de backoff na qual o fornecedor de um pin de cache de contexto é considerado persistentemente indisponível e o pin é descartado para failover. |
| `PIN_DROP_GRACE_MS` | `20000` | `open-sse/services/combo.ts` | Janela anti-oscilação (ms) que tolera breves períodos de espera transitórios antes de descartar um pin de cache de contexto. |
### Cenários
| Cenário | Configuração |
| -------------------------------------- | ---------------------------------------------------- |
| **Geração de código de longa duração** | `REQUEST_TIMEOUT_MS=900000` (15 min) |
| **Limitar a duração total do stream** | `STREAM_ACTIVE_TIMEOUT_MS=1260000` (21 min) |
| **Falha rápida para API de produção** | `API_BRIDGE_PROXY_TIMEOUT_MS=10000` |
| **Modelos de pensamento prolongado** | `STREAM_IDLE_TIMEOUT_MS=300000` (5 min entre chunks) |
---
## 16. Registo de logs
O sistema de registo de logs escreve tanto em stdout como em ficheiros de log sujeitos a rotação. Toda a configuração é lida por `src/lib/logEnv.ts`.
| Variável | Predefinição | Descrição |
| ----------------------------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `APP_LOG_LEVEL` | `info` | Nível mínimo de log: `debug`, `info`, `warn`, `error`. |
| `APP_LOG_FORMAT` | `text` | Formato de saída: `text` (legível por humanos) ou `json` (estruturado). |
| `APP_LOG_TO_FILE` | `true` | Escreve os logs num ficheiro, além de stdout. |
| `APP_LOG_FILE_PATH` | `logs/application/app.log` | Caminho do ficheiro de log (relativo à raiz do projeto ou a `DATA_DIR`). |
| `APP_LOG_MAX_FILE_SIZE` | `50M` | Tamanho máximo do ficheiro antes da rotação. Aceita: `50M`, `1G`, `512K` ou bytes sem unidade. |
| `APP_LOG_RETENTION_DAYS` | `7` | Número de dias durante os quais são mantidos os ficheiros de log da aplicação sujeitos a rotação. |
| `APP_LOG_MAX_FILES` | `20` | Número máximo de cópias de segurança dos ficheiros de log sujeitos a rotação. |
| `CALL_LOG_RETENTION_DAYS` | `7` | Número de dias durante os quais são mantidas na base de dados as entradas de log de pedidos/chamadas. |
| `CALL_LOG_MAX_ENTRIES` | `10000` | Número máximo de entradas do log de chamadas na memória intermédia. |
| `CALL_LOGS_TABLE_MAX_ROWS` | `100000` | Número máximo de linhas na tabela SQLite `call_logs` antes da eliminação das mais antigas. |
| `ENABLE_REQUEST_LOGS` | _(não definido)_ | Força a ativação ou desativação do registo detalhado de pedidos, substituindo a definição do painel. |
| `MAX_PENDING_REQUEST_AGE_MS` | `3600000` (1 hora) | Idade máxima das entradas órfãs de log de pedidos ativos antes da limpeza em memória. |
| `CALL_LOG_PIPELINE_CAPTURE_STREAM_CHUNKS` | `false` | Armazena segmentos do fluxo nos artefactos do pipeline quando `call_log_pipeline_enabled=true`. Ativação opcional (`true`) — desativado por predefinição para poupar espaço em disco. |
| `CALL_LOG_PIPELINE_MAX_SIZE_KB` | `512` | Tamanho máximo, em KB, do artefacto de log de chamadas do pipeline quando `call_log_pipeline_enabled=true`. |
| `PROXY_LOGS_TABLE_MAX_ROWS` | `100000` | Número máximo de linhas na tabela SQLite `proxy_logs` antes da eliminação das mais antigas. |
| `PROXY_LOG_INCLUDE_IPS` | `false` | Inclui os IPs do cliente/de saída e os prefixos das contas nos logs da consola `[ProxyEgress]`. Os registos de log do proxy no painel/na base de dados mantêm todos os detalhes. |
| `PROXY_LOG_FIRST_CHUNK_TIMING` | `false` | Defina como `"true"` ou `"1"` para registar `first_chunk_ms` (desde o início do envio até ao primeiro byte útil do corpo) nas linhas de log do proxy. Encapsula cada corpo a montante num fluxo de passagem preguiçoso e atualiza a linha assim que o byte chega; está desativado por predefinição para que as respostas passem sem alterações. |
| `APP_LOG_ROTATION_CHECK_INTERVAL_MS` | `60000` (1 min) | Frequência com que `src/lib/logRotation.ts` volta a verificar o tamanho do ficheiro de log ativo. |
| `CHAT_LOG_TEXT_LIMIT` | `65536` | Comprimento máximo das cadeias de caracteres mantidas nos artefactos de log de conversação (predefinição: 64 KB). |
| `CHAT_LOG_ARRAY_TAIL_ITEMS` | `128` | Número de itens da matriz mantidos a partir do fim ao truncar os payloads do log de conversação. |
| `CHAT_LOG_MAX_DEPTH` | `6` | Profundidade máxima de aninhamento antes de os payloads do log de conversação serem truncados. |
| `CHAT_LOG_MAX_OBJECT_KEYS` | `80` | Número máximo de chaves de objeto mantidas nos payloads do log de conversação (0 = ilimitado). |
| `CHAT_LOG_MAX_BODY_KB` | `1024` | Tamanho total do corpo do pedido/resposta (KB) a partir do qual este é substituído por um resumo simples, em vez da cópia completa. Aumente este valor se as conversações agênticas longas apresentarem um marcador de posição no painel em vez das mensagens reais. |
| `CHAT_DEBUG_FILE` | `false` | Quando definido como true, `serializeArtifactForStorage` ignora o truncamento baseado no tamanho. Apenas para depuração. |
---
## 17. Otimização de Memória
| Variável | Predefinição | Descrição |
| ----------------------------- | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_MEMORY_MB` | _auto_ (bare metal); **`1024` na imagem Docker** | Limite de heap V8 (MB) **recomendado** para Docker/standalone. Quando não definido, é calibrado dinamicamente (~35% da RAM do sistema, limitado a `[512, 4096]`); `512` é apenas o limite mínimo quando a memória total não pode ser lida. Em `run-standalone.mjs` (Docker CMD), um valor **explícito** é anexado como `--max-old-space-size` e **prevalece** sobre uma flag de heap de NODE_OPTIONS em conflito (última flag do V8). O `omniroute serve` continua a preferir um heap de NODE_OPTIONS existente (#5238). Não defina ambos com valores diferentes — o processo regista um aviso indicando os dois valores e o vencedor. **A imagem oficial do Docker define sempre `1024`, pelo que a calibração nunca é executada aí.** O `/v1/responses` de agentes de codificação precisa de `8192`–`12288` mais margem de cgroup — consulte o [Guia Docker — RAM em runtime](../guides/DOCKER_GUIDE.md#runtime-ram-for-coding-agents). |
| `OMNIROUTE_RSS_PRESSURE_MB` | _auto_ (`max(3072, 2 × OMNIROUTE_MEMORY_MB)`; desativado quando `OMNIROUTE_MEMORY_MB` não está definido) | `open-sse/utils/resourcePressure.ts` | Limite absoluto de RSS do processo (MB) para memória nativa/externa que o `heapUsed` do V8 não consegue ver; acima dele, os novos pedidos recebem 503 `resource_pressure`. O RSS raramente desce após um pico, por isso combine-o com `OMNIROUTE_PRESSURE_SELF_RESTART`. |
| `PROMPT_CACHE_MAX_SIZE` | `50` | Número máximo de entradas de prompts de sistema em cache. |
| `PROMPT_CACHE_MAX_BYTES` | `2097152` (2 MB) | Tamanho máximo total da cache de prompts. |
| `PROMPT_CACHE_TTL_MS` | `300000` (5 min) | TTL das entradas da cache de prompts. |
| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Número máximo de respostas temperature=0 em cache. |
| `SEMANTIC_CACHE_MAX_BYTES` | `4194304` (4 MB) | Tamanho máximo total da cache semântica. |
| `SEMANTIC_CACHE_TTL_MS` | `1800000` (30 min) | TTL das entradas da cache semântica. |
| `OMNIROUTE_CORPUS_CACHE_SIZE` | `5` | Raízes de corpus local que mantêm um índice em memória ativo em simultâneo (`src/lib/localCorpus/configured.ts`). LRU: ao atingir o limite, o índice da raiz menos recentemente utilizada é removido e reconstruído na consulta seguinte. Limitado a um mínimo de `1`; um valor não numérico reverte para a predefinição. |
| `STREAM_HISTORY_MAX` | `50` | Número máximo de eventos de stream recentes no buffer da vista em direto do Dashboard. |
| `CONTEXT_LENGTH_DEFAULT` | _(não definido)_ | Substituição global do comprimento de contexto (tokens) para todos os fornecedores que não têm a variável `CONTEXT_LENGTH_`. Quando definida, **substitui** os valores do catálogo, da substituição do dashboard e do registo para esses fornecedores; quando não definida, o OmniRoute utiliza a sua cadeia incorporada, cujo último recurso é `128000`. Consulte [Comprimento de contexto por fornecedor](#per-provider-context-length-context_length_provider). |
| `USAGE_TOKEN_BUFFER` | `100` | Margem extra de tokens reservada ao monitorizar as quotas de utilização. |
### Comprimento de contexto por fornecedor (`CONTEXT_LENGTH_`)
O `open-sse/services/contextManager.ts` (`getEnvOverride()` / `resolveTokenLimit()`) também lê uma
forma **por fornecedor** cujo nome é construído a partir do ID do fornecedor em runtime, pelo que
não pode ser listada linha a linha na tabela acima nem no `.env.example`.
**Nome.** `CONTEXT_LENGTH_`, em que `` é o ID do fornecedor em maiúsculas, com todos os caracteres fora de `A-Z` / `0-9` substituídos por `_`. O ID do fornecedor é o canónico após resolução de alias (a parte `provider` de uma string `provider/model` depois de um alias curto ter sido resolvido). Os nós personalizados compatíveis com OpenAI ou Anthropic utilizam o respetivo ID de nó gerado, pelo que o UUID faz parte do nome da variável. O valor é um número inteiro positivo de tokens; qualquer outro valor (vazio, `0`, negativo, não numérico) é ignorado e a resolução passa para o passo seguinte.
| ID do fornecedor | Nome da variável |
| ----------------------------------------------------------- | -------------------------------------------------------------------------- |
| agentrouter | CONTEXT_LENGTH_AGENTROUTER |
| openrouter | CONTEXT_LENGTH_OPENROUTER |
| openai-compatible-chat-0f8e2c1a-5b7d-4e3f-9a6c-2d1b8e4f7a90 | CONTEXT_LENGTH_OPENAI_COMPATIBLE_CHAT_0F8E2C1A_5B7D_4E3F_9A6C_2D1B8E4F7A90 |
**Precedência.** Para um par `provider/model`, vence o primeiro passo que produza um valor:
1. `CONTEXT_LENGTH_` para esse fornecedor.
2. `CONTEXT_LENGTH_DEFAULT` (substituição global por variável de ambiente).
3. A janela por modelo: uma substituição de contexto persistida (definida no dashboard, ou fixada automaticamente pelo reconciliador de descoberta, ver `CONTEXT_WINDOW_RECONCILE_INTERVAL`), ou, caso contrário, o valor do catálogo sincronizado / models.dev.
4. O `defaultContextLength` do registo do fornecedor.
5. Heurísticas baseadas no nome do modelo (`claude` 200000, `gemini` 1000000, `gpt` / `o1` / `o3` / `o4` / `codex` 400000).
6. Predefinições incorporadas por fornecedor e, por fim, `128000`.
Ambos os passos de ambiente aplicam-se ao **fornecedor inteiro**: todos os modelos desse fornecedor ficam com o mesmo limite, e prevalecem sobre as substituições por modelo definidas no dashboard. Quando apenas um modelo de um fornecedor precisa de uma janela diferente, utilize antes uma substituição por modelo no dashboard.
**Âmbito.** Esta cadeia determina a verificação da janela de contexto em tempo de pedido (a rejeição `context_length_exceeded` / "Input exceeds context window" em `open-sse/handlers/chatCore.ts`), os orçamentos de compressão de prompts e os limites de contexto dos combos. O `context_length` anunciado por `GET /v1/models` pode ainda provir de metadados do catálogo ou do registo e não é garantido que reflita a substituição por variável de ambiente.
**Exemplo.** Um fornecedor cujo modelo aceita uma janela de 1 050 000 tokens, enquanto o catálogo indica 128 000:
```dotenv
CONTEXT_LENGTH_AGENTROUTER=1050000
```
Reinicie o servidor depois de a alterar: o valor é lido do ambiente do processo do servidor. Na **aplicação de ambiente de trabalho**, o servidor é executado como processo filho e não vê uma variável de sistema definida depois de a aplicação ter sido iniciada; coloque a linha no ficheiro `.env` que a aplicação carrega (ordem de procura em [Guia do Electron: procura do ficheiro de ambiente](../guides/ELECTRON_GUIDE.md#environment-file-lookup)) e, em seguida, encerre completamente a aplicação e volte a iniciá-la.
### Compressão
| Variável | Predefinição | Descrição |
| ------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_RTK_TRUST_PROJECT_FILTERS` | sem definição | Confia no `.rtk/filters.json` do projeto sem um hash `.rtk/trust.json`. Utilizar apenas em desenvolvimento local controlado. |
### Motor de memória (plano 21)
### Custo no event loop da memória, das skills e da atualização de tokens (#10349)
O OmniRoute é um **único processo Node**. A extração/obtenção de memória, a injeção de skills e a atualização de tokens dos fornecedores são executadas nesse **mesmo event loop** que o `GET /healthz` e o dashboard. Não são uma thread de trabalho.
| Trabalho | Código | Predefinição | Controlo do operador |
| ------------------------------ | ---------------------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Extração / obtenção de memória | `src/lib/memory/` | Dashboard **memoryEnabled** (ativo por predefinição) | Desative **Settings → Memory**. Não existe um interruptor de ambiente separado além de desativar a funcionalidade nas definições. |
| Injeção de skills | `src/lib/skills/injection.ts` | Dashboard **skillsEnabled** (ativo por predefinição) | Desative **Settings → Memory/Skills** (`skillsEnabled`). As opções de sandbox abaixo apenas limitam a execução depois de a injeção já estar ativa. |
| Atualização de tokens | `src/sse/services/tokenRefresh.ts` | Ativa para fornecedores OAuth/web ligados | Desligue o fornecedor ou deixe os tokens manterem-se válidos; hoje não existe uma variável de ambiente `TOKEN_REFRESH=0`. |
Se o `/healthz` estiver lento numa máquina sem carga, desative primeiro a memória e as skills e, em seguida, verifique a carga do catálogo/compressão (#10303, #9685). Estas funcionalidades cedem o controlo nos pontos `await`, mas continuam a competir pela única thread.
Opções da camada de embeddings, do armazenamento vetorial e do reranking para o subsistema de memória persistente (`src/lib/memory/`).
| Variável | Predefinição | Descrição |
| ------------------------------------ | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MEMORY_EMBEDDING_CACHE_TTL_MS` | `300000` (5 min) | TTL da cache de embeddings em memória (por assinatura de fonte/modelo/dim). |
| `MEMORY_EMBEDDING_CACHE_MAX` | `1000` | Número máximo de entradas LRU mantidas na cache de embeddings. |
| `MEMORY_TRANSFORMERS_MODEL` | `Xenova/all-MiniLM-L6-v2` | ID do repositório HF para o pipeline local MiniLM opt-in do `@huggingface/transformers` (~23 MB int8, ~400 MB RAM). |
| `MEMORY_STATIC_MODEL` | `minishlab/potion-base-8M` | ID do repositório HF para o embedder estático de tabela de pesquisa potion/Model2Vec. Descarregado de forma diferida (lazy) para o diretório de cache. |
| `MEMORY_STATIC_CACHE_DIR` | `/embeddings` | Diretório usado para armazenar em cache os ficheiros do modelo estático potion. Por predefinição fica dentro de `DATA_DIR` quando não definido. |
| `HF_HUB_ENDPOINT` | `https://huggingface.co` | Substitui o URL base do Hugging Face Hub usado por `staticPotion.ts` (ex.: endpoint mirror para ambientes air-gapped). |
| `MEMORY_VEC_TOP_K` | `20` | Top-K predefinido usado pela pesquisa vetorial brute-force do `sqlite-vec` dentro de `src/lib/memory/vectorStore.ts`. |
| `MEMORY_RRF_K` | `60` | Constante `k` do Reciprocal Rank Fusion para obtenção híbrida FTS5 + vetorial (receita sqlite-vec). |
| `VECTOR_STORE_DISABLE_VEC` | `false` | Seam de teste/diagnóstico em `getVectorStore()` (`src/lib/memory/vectorStore.ts`): quando `true`, força o vector store para `null` (simula um ambiente cloud/WASM sem `sqlite-vec`), degradando a obtenção de memória para pesquisa por palavras-chave FTS5. Deixar por definir em produção. |
| `NOTION_API_KEY` | _(por definir)_ | Chave de API para o backend Notion (usada pela predefinição de backend conhecido em `genericBackend.ts`). |
| `NOTION_API_URL` | `https://api.notion.com/v1` | URL base para a API do Notion (pode ser substituído para alternativas Notion autoalojadas). |
| `OBSIDIAN_API_KEY` | _(por definir)_ | Chave de API para o backend Obsidian Vault (usada pela predefinição de backend conhecido em `genericBackend.ts`). |
| `OBSIDIAN_API_URL` | `http://localhost:27123` | URL base para a API do Obsidian Vault (pode ser substituído para um vault remoto). |
| `MEMORY_TYPED_DECAY_ENABLED` | `false` | Interruptor principal do decaimento de memória tipada TV6. **Opt-in (desligado por predefinição)** — a varredura **elimina** memórias decaídas. Com ele desligado, `access_count`/`last_accessed_at` são pura telemetria e nada é alguma vez eliminado. |
| `MEMORY_TYPED_DECAY_EPISODIC_DAYS` | `30` | TTL (dias) após o qual uma memória `episodic` não utilizada decai. `0` também torna as episódicas imunes. Os tipos duráveis (`factual`/`procedural`/`semantic`) são sempre imunes. O relógio de decaimento é reajustado com base em `last_accessed_at`. |
| `MEMORY_TYPED_DECAY_ACCESS_IMMUNITY` | `3` | Uma memória injetada `>=` este número de vezes torna-se imune ao decaimento, independentemente do tipo. `0` desativa a imunidade por acesso. |
| `MEMORY_TYPED_DECAY_SWEEP_INTERVAL` | `0` (desativado) | Intervalo (segundos) para a varredura periódica opcional de decaimento em `src/lib/memory/typedDecay.ts`. `0`/por definir = sem varredura periódica. Duplamente opt-in: também requer `MEMORY_TYPED_DECAY_ENABLED=true`. |
| `OMNIROUTE_STRICT_SYSTEM_PROVIDERS` | _(por definir)_ | IDs de fornecedores separados por vírgulas (insensível a maiúsculas/minúsculas) que aceitam uma mensagem `system` **apenas no índice 0** (`src/lib/memory/injection.ts`). Para estes, o splice de memória a meio do array (seguro para cache) é inseguro em conversas multi-turn, pelo que a memória é fundida/anteposta como a mensagem system inicial. Por predefinição apenas `xiaomi-mimo`/`mimo`; alargue a endpoints autoalojados compatíveis com OpenAI (ex.: Qwen3.5+/3.6) cujo template de chat impõe a mesma restrição de mensagem system única no início. |
### Exemplo Docker com pouca RAM
`128` é apenas para o dashboard. Agentes de codificação com este heap dão `FATAL ERROR` durante `/v1/responses` longas. Não utilize este exemplo como gateway Claude/Codex/Grok.
```bash
OMNIROUTE_MEMORY_MB=128
PROMPT_CACHE_MAX_SIZE=20
PROMPT_CACHE_MAX_BYTES=524288 # 512 KB
SEMANTIC_CACHE_MAX_SIZE=25
SEMANTIC_CACHE_MAX_BYTES=1048576 # 1 MB
STREAM_HISTORY_MAX=10
```
---
## 18. Sincronização de preços
Sincronização automática dos dados de preços dos modelos a partir de fontes externas.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ----------------------- | ------------- | ------------------------ | ------------------------------------------- |
| `PRICING_SYNC_ENABLED` | `false` | `src/lib/pricingSync.ts` | Sincronização periódica de preços opcional. |
| `PRICING_SYNC_INTERVAL` | `86400` (24h) | `src/lib/pricingSync.ts` | Intervalo de sincronização, em segundos. |
| `PRICING_SYNC_SOURCES` | `litellm` | `src/lib/pricingSync.ts` | Fontes de dados separadas por vírgulas. |
---
## Sincronização do ELO da Arena
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ---------------------------- | ------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ARENA_ELO_SYNC_ENABLED` | `true` | `src/shared/constants/featureFlagDefinitions.ts` | Sincronização periódica do ELO da tabela classificativa da Arena AI, configurável nas funcionalidades experimentais do Painel ou com `false` para a desativar. |
| `MODELS_CATALOG_PREFIX_MODE` | `dual` | `src/shared/constants/featureFlagDefinitions.ts`, `src/app/api/v1/models/catalog.ts` | Forma do prefixo utilizada nos identificadores de modelos em `GET /v1/models`. `dual` anuncia tanto o prefixo curto do alias como o prefixo canónico do fornecedor para cada modelo (retrocompatibilidade — aproximadamente duplica o catálogo); `alias` emite um identificador por modelo; `canonical` emite apenas o prefixo completo do identificador do fornecedor (os fornecedores cujo alias já é o identificador canónico mantêm a sua única entrada). Os clientes podem substituir esta definição em cada pedido com `?prefix=alias`. Consulte [API_REFERENCE](API_REFERENCE.md#model-id-prefixes-prefix). |
| `ARENA_ELO_SYNC_INTERVAL` | `86400` (24h) | `src/lib/arenaEloSync.ts` | Intervalo de sincronização, em segundos. |
---
## Fornecedor do Playground do PromptQL (não oficial/experimental)
Ponte de sessão GraphQL obtida por engenharia inversa para prompt.ql.app (`src/shared/constants/providers/web-cookie.ts`). Todas as opções são facultativas — as predefinições apontam para os endpoints públicos do playground; substitua-as apenas para uma implementação do PromptQL autoalojada/alternativa.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ---------------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `PROMPTQL_GRAPHQL_ENDPOINT` | `https://data.prompt.ql.app/promptql/playground-v2-hge/v1/graphql` | `open-sse/executors/promptql.ts` | Endpoint GraphQL utilizado para operações de chat/sessão. |
| `PROMPTQL_CREDITS_ENDPOINT` | `https://data.pro.ql.app/v1/graphql` | `open-sse/executors/promptql.ts`, `open-sse/services/usage/promptql.ts` | Endpoint GraphQL utilizado para consultar o saldo/a utilização de créditos. |
| `PROMPTQL_TOKEN_REFRESH_URL` | `https://auth.pro.ql.app/ddn/project/token` | `open-sse/executors/promptql.ts` | Endpoint utilizado para tentar atualizar o token. |
| `PROMPTQL_POLL_TIMEOUT_MS` | `180000` | `open-sse/executors/promptql.ts` | Tempo máximo (ms) para consultar `thread_events` antes de expirar. |
---
## Fornecedor Web HyperAgent (Não oficial/Experimental)
Ponte de sessão obtida por engenharia inversa para hyperagent.com (`src/shared/constants/providers/web-cookie.ts`). Opcional — a predefinição aponta para o endpoint público de faturação/utilização; substitua-a apenas para uma implementação HyperAgent autoalojada/alternativa.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ---------------------- | --------------------------------------------------- | --------------------------------------- | ------------------------------------------------------------------------- |
| `HYPERAGENT_USAGE_URL` | `https://hyperagent.com/api/settings/billing/usage` | `open-sse/services/usage/hyperagent.ts` | Endpoint utilizado para obter blocos de créditos de faturação/utilização. |
---
## Quotas de utilização do Kilo Code
Consulta do saldo pessoal em USD e da utilização do Kilo Pass para o fornecedor Kilo Code. Opcional — a predefinição aponta para a API pública do Kilo; substitua-a apenas para um relay/fixture de teste. A autenticação utiliza o token de acesso OAuth existente da ligação.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| -------------- | --------------------- | ------------------------------------- | --------------------------------------------------------------------------------------- |
| `KILO_API_URL` | `https://api.kilo.ai` | `open-sse/services/usage/kilocode.ts` | URL base utilizado para obter o saldo pessoal do Kilo Code e a utilização do Kilo Pass. |
---
## Fornecedor Web Adobe Firefly (Não oficial/Experimental)
Atualização de sessão controlada pelo browser para o fornecedor Web Adobe Firefly
(`open-sse/services/adobeFireflyBrowserLogin.ts`, `open-sse/services/adobeFireflySession.ts`,
`open-sse/services/adobeFireflyClient.ts`). Opcional — todas as predefinições estão otimizadas para uma instalação
normal em computador.
> **Removido em #9255.** O antigo runtime do Chrome associado através de CDP (adobeFireflyChromeRuntime.ts) foi
> substituído por um serviço de início de sessão no browser com Playwright, e as respetivas opções deixaram de existir. As
> variáveis ADOBE_FIREFLY_CHROME_ CDP_PORT / VISIBLE / HEADED / PING / FORCE_RESTART, bem como
> ADOBE_FIREFLY_LOGIN_WAIT_MS e ADOBE_FIREFLY_FORTER_WAIT_MS, não são lidas em nenhum ponto da
> base de código — defini-las não produz qualquer efeito.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ------------------------------------ | ---------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ADOBE_FIREFLY_CHROME_HEADLESS` | `0` | `open-sse/services/adobeFireflyBrowserLogin.ts` | Defina como `1` para utilizar o Chrome verdadeiramente sem interface gráfica (não funciona para geração; apenas para depuração). |
| `ADOBE_FIREFLY_BROWSER_REFRESH` | `1` | `open-sse/services/adobeFireflySession.ts` | Adesão/desativação do aquecimento proativo do browser. `0` desativa o aquecimento proativo (a recuperação de erros 408 a meio de um lote continua a aplicar-se). |
| `ADOBE_FIREFLY_SESSION_DISK` | `1` | `open-sse/services/adobeFireflySession.ts` | Defina como `0` para desativar a persistência da sessão do Adobe Firefly no disco. |
| `ADOBE_FIREFLY_MIN_SUBMIT_GAP_MS` | _(não definido)_ | `open-sse/services/adobeFireflySession.ts` | Intervalo mínimo (ms) imposto entre envios sucessivos, substituindo a predefinição incorporada. |
| `ADOBE_FIREFLY_BATCH_EXTRA_GAP_MS` | _(não definido)_ | `open-sse/services/adobeFireflySession.ts` | Intervalo adicional (ms) acrescentado após um lote bem-sucedido, substituindo a predefinição incorporada. |
| `ADOBE_FIREFLY_SUBMIT_BASE_DELAY_MS` | _(não definido)_ | `open-sse/services/adobeFireflyClient.ts` | Atraso base (ms) antes do envio de um pedido de geração, substituindo a predefinição incorporada. |
---
## 19. Sincronização de modelos (Desenvolvimento)
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ----------------------------------- | ---------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MODELS_DEV_SYNC_ENABLED` | _(não definida)_ | `src/lib/modelsDevSync.ts` | Substituição rígida para a sincronização de preços do models.dev. Não definida = respeita Definições > IA (`modelsDevSyncEnabled`). `0`/`false`/`off`/`no` **prevalece sobre a BD** e ignora tanto a sincronização periódica como as análises SQL/JSON de `getModelsDevPricing()` (recuperação quando o painel está bloqueado no mesmo ciclo de eventos). `1`/`true`/`on`/`yes` força a ativação da sincronização. Guardar/limpar preços continua a chamar `backupDbFile("pre-write")`, que não efetua qualquer operação durante a limitação de 60 minutos ou com `DISABLE_SQLITE_AUTO_BACKUP`. |
| `MODELS_DEV_SYNC_INTERVAL` | `86400` (24 h) | `src/lib/modelsDevSync.ts` | Intervalo de sincronização do catálogo de modelos durante o desenvolvimento, em segundos. |
| `CONTEXT_WINDOW_RECONCILE_INTERVAL` | `86400` (24 h) | `src/lib/contextWindowResolver.ts` | Intervalo (segundos) para o reconciliador autocorretivo da janela de contexto (5004): fixa as janelas declaradas pelo fornecedor, obtidas através da deteção em `/models`, como substituições `auto:discovery` quando divergem do catálogo. Defina como `0` para desativar. Reutiliza dados já sincronizados (sem nova obtenção); nunca substitui substituições `manual`. |
---
## 20. Definições Específicas do Fornecedor
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ---------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OPENROUTER_CATALOG_TTL_MS` | `86400000` (24h) | `src/lib/catalog/openrouterCatalog.ts` | TTL da cache do catálogo de modelos OpenRouter. |
| `MODEL_CATALOG_INCLUDE_NAMES` | `true` | `src/shared/constants/featureFlagDefinitions.ts` | Inclui campos `name` legíveis nas respostas `/v1/models`. Desative para clientes que esperam apenas IDs. |
| `CATALOG_BUILD_TIMEOUT_MS` | `8000` (8s) | `src/app/api/v1/models/catalogCache.ts` | Limite de espera no caminho frio para uma reconstrução agregada do catálogo de `GET /v1/models` (#12627). Em caso de timeout, é servido um último 200 válido quando este existe. |
| `OMNIROUTE_SYNCED_CATALOG_STALE_AFTER_MS` | `2592000000` (30 dias) | `src/lib/db/models/activeSyncedCatalog.ts` | Idade após a qual a lista de modelos sincronizados de uma ligação deixa de ser autoritativa para o encaminhamento e falha de forma aberta para o registo (#12849). As linhas sem timestamp contam como desatualizadas. |
| `OMNIROUTE_ANALYTICS_CACHE_TTL_MS` | `60000` (60s) | `src/lib/usage/analyticsResponseCache.ts` | Durante quanto tempo uma resposta lenta de `GET /api/usage/analytics` é reutilizada para a mesma query string (#15629). `0` desativa a cache. |
| `OMNIROUTE_ANALYTICS_CACHE_MIN_COMPUTE_MS` | `1000` (1s) | `src/lib/usage/analyticsResponseCache.ts` | Apenas as respostas de análise que demoraram pelo menos este tempo a construir são colocadas em cache, pelo que as instâncias pequenas veem sempre dados atualizados. |
| `OMNIROUTE_CACHE_METRICS_MIN_COMPUTE_MS` | não definido (desativado) | `src/app/api/cache/route.ts` via `src/lib/usage/analyticsResponseCache.ts` | Ativação opcional (#16361). Quando definido como um inteiro não negativo N, a parte do histórico de utilização de `GET /api/cache` (totais da cache de prompts + tendência) é servida a partir da cache partilhada de respostas de análise quando esta demorou pelo menos N ms a construir, por janela de `trendHours` limitada, durante `OMNIROUTE_ANALYTICS_CACHE_TTL_MS` (o histórico pode estar desatualizado até esse TTL; `DELETE /api/cache` invalida-o). Não definido ou inválido = histórico lido em tempo real em cada pedido. |
| `NANOBANANA_POLL_TIMEOUT_MS` | `120000` | `open-sse/handlers/imageGeneration.ts` | Espera máxima pelos trabalhos de geração de imagens NanoBanana. |
| `NANOBANANA_POLL_INTERVAL_MS` | `2500` | `open-sse/handlers/imageGeneration.ts` | Frequência de polling dos trabalhos NanoBanana. |
| `ADOBE_FIREFLY_SUBMIT_BASE_DELAY_MS` | `8000` | `open-sse/services/adobeFireflyUpscale.ts` | Atraso base para o backoff exponencial de repetição de submissão de upscale do Adobe Firefly. |
| `AWS_REGION` | _(não definido)_ | `src/lib/providers/validation.ts`, `open-sse/handlers/audioSpeech.ts` | Região usada para construir os endpoints AWS Bedrock (Kiro, áudio). |
| `AWS_DEFAULT_REGION` | _(não definido)_ | `src/lib/providers/validation.ts`, `open-sse/handlers/audioSpeech.ts` | Alternativa quando `AWS_REGION` não está definida. |
| `CLOUDFLARE_ACCOUNT_ID` | _(não definido)_ | `open-sse/executors/cloudflare-ai.ts` | ID da conta para o Cloudflare Workers AI. |
| `CLOUDFLARE_PLAYGROUND_CHROME_PATH` | _(não definido)_ | `open-sse/executors/cloudflare-playground.ts` | Caminho completo do binário Chrome de desktop para o executor Cloudflare AI Playground, usado quando a verificação de fingerprint em modo headless bloqueia o Chromium incluído no Playwright. |
| `CODEBUDDY_SYSTEM_PROMPT_MAX_LEN` | ∅ (∞) — _(não definido = sem limite de comprimento)_ | `open-sse/executors/codebuddy/shared.ts` | Limite de comprimento opcional para os system prompts do chamador enviados ao CodeBuddy (CN e Internacional). Por predefinição, apenas um prompt que contenha um marcador de identidade de agente de codificação é substituído por um neutro (o filtro de conteúdo da Tencent rejeita-os); os prompts longos são mantidos. Um inteiro > 0 também substitui qualquer system prompt com mais do que esse número de caracteres; não definido, `0` ou um valor não inteiro desativa o limite. Cada substituição regista qual a regra acionada (marcador de identidade ou comprimento). |
| `CLOUDFLARE_API_BASE` | `https://api.cloudflare.com/client/v4` | `src/app/api/settings/proxy/cloudflare-deploy/route.ts` | Substitui a base da API REST da Cloudflare usada pelo implementador do relay Workers do proxy-pool (#4640 / 9router#1360). |
| `NEXT_PUBLIC_CLOUDFLARE_RELAY_DEFAULT_PROJECT` | `omniroute-relay` | `src/app/(dashboard)/dashboard/settings/components/proxy/CloudflareRelayModal.tsx` | Nome de projeto worker predefinido sugerido no modal "Deploy Relay" do proxy-pool. |
| `NEXT_PUBLIC_CLOUDFLARE_RELAY_ENABLED` | `true` | `src/app/(dashboard)/dashboard/settings/components/proxy/ProxyPoolTab.tsx` | Defina como `false` para ocultar a opção de relay do Cloudflare Workers no separador Proxy Pool. |
| `CLOUDFLARED_BIN` | deteção automática | `src/lib/cloudflaredTunnel.ts` | Caminho personalizado para o binário `cloudflared`. |
| `CLOUDFLARED_PROTOCOL` | `http2` | `src/lib/cloudflaredTunnel.ts` | Protocolo de transporte do túnel: `http2` (predefinição), `quic` ou `auto`. |
| `CLOUDFLARED_CONFIG` | _(não definido)_ | `src/lib/cloudflaredTunnel.ts` | Caminho para um `config.yml` do cloudflared gerido localmente (com `tunnel:`, `credentials-file:`, `ingress:`). Quando definido, o OmniRoute executa `tunnel --config run` (túnel nomeado) em vez de um túnel rápido efémero. |
| `CLOUDFLARED_HOSTNAME` | _(do ingress da configuração)_ | `src/lib/cloudflaredTunnel.ts` | Substituição do hostname público do túnel nomeado (p. ex. `ai.example.com`), reportado como `publicUrl`/`apiUrl`. Quando não definido, é lido a partir do primeiro hostname `ingress` da configuração. |
| `DENO_DEPLOY_API_BASE` | `https://api.deno.com/v2` | `src/app/api/settings/proxy/deno-deploy/route.ts` | Substitui a base da API REST do Deno Deploy usada pelo implementador de relay do proxy-pool (#4643 / 9router#1437). |
| `NEXT_PUBLIC_DENO_RELAY_DEFAULT_PROJECT` | `omniroute-deno-relay` | `src/app/(dashboard)/dashboard/settings/components/proxy/DenoRelayModal.tsx` | Nome de app Deno Deploy predefinido sugerido no modal "Deploy Relay" do proxy-pool. |
| `NEXT_PUBLIC_DENO_RELAY_ENABLED` | `true` | `src/app/(dashboard)/dashboard/settings/components/proxy/ProxyPoolTab.tsx` | Defina como `false` para ocultar a opção de relay do Deno Deploy no separador Proxy Pool. |
| `SEARCH_CACHE_TTL_MS` | `300000` (5 min) | `open-sse/services/searchCache.ts` | TTL para a colocação em cache das respostas da API de pesquisa (Perplexity, Brave, etc.). |
| `ENABLE_CC_COMPATIBLE_PROVIDER` | `false` | `src/shared/utils/featureFlags.ts` | Revela a IU experimental de fornecedor compatível com CC para relays exclusivos do Claude Code. |
| `NINEROUTER_HOST` | `127.0.0.1` | `open-sse/executors/ninerouter.ts` | Substitui o host onde a instância incorporada do 9router escuta. |
| `NINEROUTER_PORT` | `20130` | `open-sse/executors/ninerouter.ts` | Substitui a porta onde a instância incorporada do 9router escuta. |
| `EMBED_WS_PROXY_HOST` | `127.0.0.1` | `src/lib/services/embedWsProxy.ts` | Host de vinculação para o proxy WebSocket do serviço incorporado (apenas loopback por predefinição). |
| `EMBED_WS_PROXY_PORT` | `20131` | `src/lib/services/embedWsProxy.ts` | Porta para o servidor proxy WebSocket do serviço incorporado. |
| `CLIPROXYAPI_HOST` | `127.0.0.1` | `open-sse/executors/cliproxyapi.ts` | Host da ponte CLIProxyAPI (integração legada). |
| `CLIPROXYAPI_PORT` | `5544` | `open-sse/executors/cliproxyapi.ts` | Porta da ponte CLIProxyAPI. |
| `CLIPROXYAPI_API_KEY` | _(vazio)_ | `open-sse/handlers/chatCore/cliproxyapiCredentials.ts` | Chave de fallback do plano de dados quando a definição `cliproxyapi_api_key` está ausente. |
| `CLIPROXYAPI_MANAGEMENT_KEY` | _(vazio)_ | `src/lib/services/cliproxyAccountHealth.ts` | Chave de gestão para leituras de integridade da conta a partir de uma instância CLIProxyAPI gerida externamente. |
| `CLIPROXYAPI_CONFIG_DIR` | `~/.cli-proxy-api` | `src/lib/versionManager/processManager.ts` | Diretório de configuração do CLIProxyAPI. |
| `CLIPROXY_BIND_HOST` | `127.0.0.1` | `docker-compose.yml` | Interface de host onde o docker-compose publica o sidecar `cliproxyapi` (#12578). O seu volume de dados contém credenciais OAuth/API de fornecedores e a imagem fixada não tem nenhuma substituição por variável de ambiente para `api-keys` no plano de dados (apenas um `config.yaml` montado), pelo que `0.0.0.0` expõe um serviço portador de credenciais a toda a LAN. |
| `MUX_SERVICE_PORT` | `8322` | `src/lib/services/bootstrap.ts` | Substitui a porta onde o daemon incorporado de orquestração de agentes Mux (coder/mux) escuta (sempre 127.0.0.1). |
| `OPENWA_SERVICE_PORT` | `8323` | `src/lib/services/bootstrap.ts` | Substitui a porta onde o daemon incorporado open-wa (automação do WhatsApp Web) escuta (sempre 127.0.0.1). |
| `DARIO_HOST` | `127.0.0.1` | `open-sse/executors/dario.ts` | Host de associação/ligação do serviço incorporado Dario (apenas loopback por predefinição). |
| `DARIO_PORT` | `3456` | `open-sse/executors/dario.ts` | Porta do serviço incorporado Dario. |
| `DARIO_HOST` | `127.0.0.1` | `open-sse/executors/dario.ts` | Host de associação/ligação do serviço incorporado Dario (apenas loopback por predefinição). |
| `DARIO_PORT` | `3456` | `open-sse/executors/dario.ts` | Porta do serviço incorporado Dario. |
| `LOCAL_HOSTNAMES` | _(vazio)_ | `open-sse/config/providerRegistry.ts` | Nomes de host adicionais separados por vírgulas tratados como "local" (nomes de serviços Docker, etc.). |
`ENABLE_CC_COMPATIBLE_PROVIDER` destina-se apenas a retransmissores de terceiros que aceitam clientes Claude Code
exclusivamente. O OmniRoute reescreve os pedidos para que esses retransmissores os aceitem. Se pretender apenas utilizar
o Claude Code CLI, ou se não tiver a certeza do que são estes retransmissores, mantenha esta opção desativada e adicione
antes um fornecedor normal compatível com Anthropic.
---
## 21. Saúde do Proxy
| Variable | Default | Source File | Description |
| ------------------------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `PROXY_FAST_FAIL_TIMEOUT_MS` | `2000` | `src/lib/proxyHealth.ts` | Tempo limite da verificação de saúde fast-fail. |
| `PROXY_LATENCY_WINDOW_HOURS` | `3` | `src/lib/db/proxies.ts` | Janela temporal (horas) para calcular a latência média dos proxies candidatos na estratégia de pool otimizada para latência. |
| `PROXY_HEALTH_CACHE_TTL_MS` | `30000` | `src/lib/proxyHealth.ts` | TTL da cache dos resultados da verificação de saúde. |
| `PROXY_HEALTH_UNHEALTHY_CACHE_TTL_MS` | `2000` | `src/lib/proxyHealth.ts` | TTL da cache para sondas de saúde de proxies falhadas. Mantenha este valor inferior a `PROXY_HEALTH_CACHE_TTL_MS` para que timeouts transitórios de proxies sob elevada concorrência sejam rapidamente repetidos, sem desativar o fast-fail para proxies realmente inativos. |
| `PROXY_HEALTH_ENABLED` | `true` | `src/lib/proxyHealth/scheduler.ts` | Defina como `false` para desativar o agendador de saúde de proxies em segundo plano, que sonda periodicamente os proxies registados. |
| `PROXY_HEALTH_INTERVAL_MS` | `600000` | `src/lib/proxyHealth/scheduler.ts` | Intervalo de varrimento do agendador de saúde em segundo plano, em ms (mínimo `60000`). |
| `PROXY_HEALTH_RELAY_INTERVAL_MS` | `21600000` | `src/lib/proxyHealth/relayCadence.ts` | Intervalo de sondagem em ms para proxies edge-relay (`deno`/`vercel`/`cloudflare`), cujas sondagens ativam um isolado serverless faturado (mínimo `60000`). |
| `PROXY_HEALTH_RECOVERY_INTERVAL_MS` | `600000` | `src/lib/proxyHealth/scheduler.ts` | Intervalo em ms da passagem de recuperação em segundo plano: com que frequência os proxies anteriormente não saudáveis são novamente sondados, para que um proxy recuperado regresse à rotação sem reinício. Valores abaixo de `60000` revertem para a predefinição. |
| `PROXY_HEALTH_TEST_URL` | `https://httpbin.org/ip` | `src/lib/proxyHealth/probeTarget.ts` | Destino da sondagem de alcançabilidade usado pelo agendador e pelo endpoint `/api/settings/proxies/auto-test`. Aponte-o para um URL interno/autoalojado para evitar a predefinição pública. |
| `PROXY_HEALTH_TEST_CONCURRENCY` | `10` | `src/lib/proxyHealth/probeTarget.ts` | Sondagens iniciadas em simultâneo por lote, partilhado pelo agendador e pelo endpoint `/api/settings/proxies/auto-test`. Com mínimo de 1 e máximo de 50. |
| `PROXY_HEALTH_TEST_STAGGER_MS` | `100` | `src/lib/proxyHealth/probeTarget.ts` | Atraso em ms entre duas partidas de sondagem dentro de um lote. Sem ele, todo o lote parte no mesmo momento e um IP de saída partilhado pode despoletar um destino com limite de taxa. Defina como `0` para desativar o espaçamento; limitado a 5000. |
| `PROXY_HEALTH_USE_PROVIDER_TARGET` | `true` | `src/lib/proxyHealth/providerProbeTarget.ts` | Defina como "false" para deixar de sondar o anfitrião real do fornecedor atribuído a um proxy (`GET /models`, sem chave API) e usar sempre `PROXY_HEALTH_TEST_URL`. |
| `PROXY_HEALTH_AUTO_DEACTIVATE` | `false` | `src/lib/proxyHealth/statusPolicy.ts` | Quando `false` (predefinição), as sondagens de alcançabilidade automatizadas (o agendador + o botão "Test All" de `/api/settings/proxies/auto-test`) são **só de leitura** e nunca escrevem o estado de um proxy — apenas o operador define ativo/inativo, pelo que uma sondagem instável não pode deixar um proxy atribuído encalhado (#6246). Defina como `true` para restaurar o comportamento legado de testar-e-definir. |
| `FLUSH_EMPTY_RETRY_ENABLED` | `false` | `src/shared/utils/featureFlags.ts` | Flag de funcionalidade opt-in (ver [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); um override na BD do painel tem precedência). `true` (ou `1`, `yes`) tenta novamente os turnos de streaming traduzidos vazios através do caminho normal de credenciais (até `STREAM_RECOVERY.EMPTY_TURN_RETRY_MAX` tentativas) em vez de expor um 200 vazio ou um 502 de conteúdo vazio. |
| `EMPTY_STREAM_SIBLING_RECOVERY_ENABLED` | `false` | `src/shared/utils/featureFlags.ts` | Flag de funcionalidade opt-in (ver [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); um override na BD do painel tem precedência). `true` (ou `1`, `yes`) ativa a sondagem de conteúdo de stream vazio do Claude/Codex e utiliza a tentativa limitada existente noutra ligação elegível após um turno `empty_content`, sem cooldown nem bloqueio de modelo. |
| `STREAM_LATE_OUTPUT_PROBE_ENABLED` | `false` | `src/shared/utils/featureFlags.ts` | Flag de funcionalidade opt-in (ver [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); um override na BD do painel tem precedência). `true` (ou `1`, `yes`) continua a amostrar um chunk reencaminhado em cada 16 após os primeiros 64, para que uma saída visível tardia ainda marque o stream como tendo emitido saída (um 5xx isolado pós-saída permanece com âmbito de pedido em vez de um bloqueio apenas do modelo). |
| `PROXY_POOL_EGRESS_OBSERVATION` | `false` | `src/shared/utils/featureFlags.ts` | Feature flag de ativação explícita (ver [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); uma substituição na BD do dashboard prevalece). `true` (ou `1`, `yes`) mostra a observação de egress do pool, apenas de leitura, sob um pool de proxies no dashboard (IPs de egress distintos, ligações e o máximo observado atrás de um único IP nas últimas 24 h, a partir do registo do proxy). Nunca usada para encaminhamento. |
| `PROXY_OPERATOR_EGRESS_ENABLED` | `false` | `src/shared/utils/featureFlags.ts` | Feature flag de ativação explícita (ver [FEATURE_FLAGS.md](./FEATURE_FLAGS.md); uma substituição na BD do dashboard prevalece). `true` (ou `1`, `yes`) aceita endereços observados e datados, enviados pelo operador, por membro do pool e funde-os com a leitura do journal para apresentação e ordenação do pool. |
| `PROXY_OPERATOR_EGRESS_WINDOW_HOURS` | `24` | `src/lib/db/proxyOperatorEgress.ts` | Janela de observação em horas para as linhas de egress enviadas pelo operador (lida em cada leitura; não é necessário reiniciar). Limitada a 1..168; valores fora do intervalo, não numéricos ou vazios recorrem a 24 com um único aviso ao nível do processo, nunca lançando uma exceção. |
| `PROXY_AUTO_REMOVE` | `false` | `src/lib/proxyHealth/scheduler.ts` | Defina `true` para permitir que o agendador remova automaticamente proxies após falhas consecutivas repetidas. |
| `PROXY_AUTO_REMOVE_AFTER` | `3` | `src/lib/proxyHealth/scheduler.ts` | Falhas consecutivas antes de o agendador remover automaticamente um proxy (quando `PROXY_AUTO_REMOVE=true`). |
| `PROXY_AUTO_DISABLE` | `false` | `src/lib/proxyHealth/scheduler.ts` | Defina `true` para permitir que o agendador desative de forma reversível (status `dead`, nunca eliminado) um proxy após falhas consecutivas repetidas, em vez de o remover. Alternativa não destrutiva a `PROXY_AUTO_REMOVE`: o proxy sai imediatamente da resolução de pool/rotação (o filtro de status alive usado pela resolução de scope-pool já o exclui) e é automaticamente reativado assim que voltar a passar nas sondas. Partilha o limiar `PROXY_AUTO_REMOVE_AFTER`. Se ambas as flags forem `true`, `PROXY_AUTO_REMOVE` prevalece. |
| `PROXY_HEALTH_PASSIVE_SKIP` | `false` | `src/lib/proxyHealth/scheduler.ts` | Salto passivo de ativação explícita: quando `true`, o agendador salta a sonda em tempo real para um endpoint cujo tráfego de produção recente já o comprova (pelo menos um sucesso e nenhuma falha de proxy atribuída na janela, exatamente um provider observado). Desativado por predefinição: todos os proxies são sondados. |
| `PROXY_PASSIVE_WINDOW_MS` | `300000` | `src/lib/proxyHealth/passiveVerdict.ts` | Janela em ms do tráfego de produção que o salto passivo analisa (limitada a `60000..599999`). Mais curta do que o intervalo de varredura de 10 minutos, para que uma falha recente predomine em vez de ser diluída. |
| `OMNIROUTE_CONTROL_PLANE_PROXY_DIRECT_FALLBACK` | `false` | `src/shared/constants/featureFlagDefinitions.ts` | Permite que os fluxos de validação de OAuth e de providers contornem um proxy fixado e se liguem diretamente quando as verificações prévias de alcançabilidade do proxy falham. A precedência efetiva é: substituição na BD de Feature Flags > variável de ambiente > predefinição. |
| `RATE_LIMIT_MAX_WAIT_MS` | `30000` (30s) | `src/lib/resilience/settings.ts` | Orçamento predefinido de **espera em fila**: quanto tempo um pedido pode aguardar por uma vaga de fornecedor e permanecer em fila antes de ser rejeitado, sem nunca chegar ao upstream. O temporizador é limpo assim que a tarefa começa a executar — a execução é limitada separadamente por `RATE_LIMIT_EXECUTION_MAX_WAIT_MS`. A variável de ambiente define apenas a predefinição: um `resilienceSettings.requestQueue.maxWaitMs` persistido e, depois, um `rateLimitOverrides.maxWaitMs` por ligação, cada um prevalece sobre ela. |
| `RATE_LIMIT_EXECUTION_MAX_WAIT_MS` | `600000` (10 min) | `open-sse/services/rateLimitManager.ts` | Teto para quanto tempo um pedido admitido pode permanecer em execução antes de a sua reserva de rate limit expirar — desacoplado do orçamento de espera em fila, para que arranques lentos de fetch em gateways não incrementais não atinjam o tempo limite (#12027). |
| `RATE_LIMIT_MAX_QUEUE_DEPTH` | `0` (disabled) | `open-sse/services/rateLimitManager.ts` | Limite de admissão na fila: rejeita com um 429 `queue_full` quando este número de pedidos já estiver em fila. `0` = ilimitado (predefinição). |
| `RATE_LIMIT_AUTO_ENABLE` | _(não definida)_ | `open-sse/services/rateLimitManager.ts` | Força a ativação/desativação da rede de segurança de rate limit de ativação automática, independentemente da definição persistida no Dashboard (`resilienceSettings.requestQueue.autoEnableApiKeyProviders`). Aceita `true`/`1`/`on` para forçar a ativação, `false`/`0`/`off` para forçar a desativação. Quando ativa (predefinição), as ligações ativas com chave de API ficam automaticamente protegidas por rate limit. Definir `rateLimitProtection: false` por ligação desativa a proteção explícita, mas não a exclui desta rede de segurança; definir esta variável de ambiente como `false` é o mecanismo global para executar ligações com chave de API sem filas de rate limit. |
| `PROVIDER_COOLDOWN_ENABLED` | _(não definida → desativada)_ | `open-sse/services/providerCooldownTracker.ts` | Monitorização global opcional (opt-in), entre pedidos, de cooldown de fornecedor/ligação. DESATIVADA por predefinição (sobrepõe-se ao Connection Cooldown / Provider Circuit Breaker). Aceita `true`/`1`/`on` para ativar. |
| `PROVIDER_COOLDOWN_MIN_MS` | `5000` | `open-sse/services/providerCooldownTracker.ts` | Cooldown mínimo (ms) antes de um fornecedor/ligação com falha ser tentado novamente. Escalado exponencialmente com falhas consecutivas. Usado apenas quando `PROVIDER_COOLDOWN_ENABLED` está ativa. |
| `PROVIDER_COOLDOWN_MAX_MS` | `300000` (5 min) | `open-sse/services/providerCooldownTracker.ts` | Limite máximo de cooldown (ms) antes de um fornecedor/ligação com falha ser tentado novamente, independentemente. Usado apenas quando `PROVIDER_COOLDOWN_ENABLED` está ativa. |
| `STREAM_RECOVERY_ENABLED` | _(não definida → desativada)_ | `src/lib/resilience/settings.ts` (seed) → `open-sse/services/streamRecovery.ts` (logic) | **O que é:** recuperação transparente de streams upstream truncados (port de free-claude-code). Retém a janela inicial de SSE até `STREAM_RECOVERY.HOLDBACK_MS` (750 ms), para que um corte _pre-commit_ — um que ocorra antes de qualquer byte chegar ao cliente — seja reaberto e repetido de forma invisível. **Quando ativar:** upstreams instáveis que truncam frequentemente com 0 bytes no início do stream; deixe DESATIVADA se não puder suportar até 750 ms adicionais de time-to-first-token em cada stream. Aceita `true`/`1`/`on`. Inicializa a definição persistida de Resilience; a definição do Dashboard prevalece uma vez definida. |
| `STREAM_RECOVERY_MIDSTREAM_ENABLED` | _(não definido → desativado)_ | `src/lib/resilience/settings.ts` (inicialização) → `open-sse/services/streamRecovery.ts` (lógica) | **O quê:** continuação a meio do stream (Fase 4.4) — após um truncamento _post-commit_ (bytes que já chegaram ao cliente), volta a fazer o pedido com o texto parcial como prefill do assistente e emenda o sufixo em falta. Apenas streams de texto simples compatíveis com OpenAI; nunca dispara com uma chamada de ferramenta em curso. **Quando ativar:** gerações longas que são cortadas a meio da resposta e em que aceitas que a parte recuperada chegue num só burst em vez de token a token. Independente de `STREAM_RECOVERY_ENABLED` (perfil de risco diferente). Aceita `true`/`1`/`on`. |
| `STREAM_THROUGHPUT_WATCHDOG_ENABLED` | _(não definido → desativado)_ | `src/lib/resilience/settings.ts` → `open-sse/services/throughputWatchdog.ts` | Watchdog opcional de produção útil de streams ativos. Deteta streams que continuam a enviar chunks mas permanecem abaixo da taxa configurada de produção do assistente; heartbeats, eventos de utilização, deltas vazios e fases de ferramentas/raciocínio não se disfarçam de progresso. Separado dos timeouts de inatividade e de prazo limite rígido. |
| `STREAM_THROUGHPUT_WATCHDOG_WARMUP_MS` | `30000` | `src/lib/resilience/settings/normalize.ts` | Período de tolerância antes da avaliação de throughput, limitado a 0–600000 ms. |
| `STREAM_THROUGHPUT_WATCHDOG_WINDOW_MS` | `30000` | `src/lib/resilience/settings/normalize.ts` | Janela móvel de produção útil, limitada a 1000–600000 ms; é necessária uma janela completa antes de abortar. |
| `STREAM_THROUGHPUT_WATCHDOG_MIN_BYTES_PER_SECOND` | `4` | `src/lib/resilience/settings/normalize.ts` | Taxa mínima de bytes UTF-8 de produção do assistente (proxy conservador de tokens), limitada a 1–1000000. |
| `STREAM_THROUGHPUT_WATCHDOG_MIN_USEFUL_BYTES` | `1` | `src/lib/resilience/settings/normalize.ts` | Amostra mínima de produção útil não nula considerada mensurável, limitada a 1–1000000 bytes. |
| `HEALTHCHECK_STAGGER_MS` | `3000` | `src/lib/tokenHealthCheck.ts` | Intervalo de escalonamento (ms) entre healthchecks de tokens de fornecedores no arranque. |
| `HEALTHCHECK_JITTER_MIN_MS` | `500` | `src/lib/tokenHealthCheck.ts` | Jitter aleatório mínimo (ms) adicionado sobre `HEALTHCHECK_STAGGER_MS` entre healthchecks de tokens de fornecedores, para evitar rajadas (Issue #1220). |
| `HEALTHCHECK_JITTER_MAX_MS` | `5000` | `src/lib/tokenHealthCheck.ts` | Jitter aleatório máximo (ms) adicionado sobre `HEALTHCHECK_STAGGER_MS` entre healthchecks de tokens de fornecedores, para evitar rajadas (Issue #1220). |
| `HEALTHCHECK_BATCH_SIZE` | `20` | `src/lib/tokenHealthCheck.ts` | Tamanho do lote de verificações concorrentes para a varredura de healthchecks de tokens no arranque; valores maiores verificam mais ligações em paralelo, valores menores reduzem a carga de rajada (Issue #7875, regressão de #7719). |
| `REQUEST_RETRY` | `2` | `src/sse/services/cooldownAwareRetry.ts` | Número de tentativas automáticas em respostas de cooldown com âmbito de modelo antes de devolver o erro ao cliente. |
| `MAX_RETRY_INTERVAL_SEC` | `30` | `src/sse/services/cooldownAwareRetry.ts` | Intervalo máximo de backoff (segundos) entre tentativas de cooldown. Limitado por este valor independentemente do `Retry-After` do upstream. |
| `HEADROOM_URL` | `http://localhost:8787` | `src/lib/headroom/detect.ts` | URL do proxy de poupança de tokens Headroom. O ciclo de vida do dashboard (`api/headroom/*`) inicia por omissão uma CLI `headroom-ai` local em loopback; substitua apenas para apontar para um proxy sidecar Docker externo. |
### Constantes de ajuste da recuperação de stream
O comportamento de retenção (holdback) da recuperação é ajustado por constantes
fixas no código em `open-sse/config/constants.ts` (`STREAM_RECOVERY`), apresentadas
aqui para referência — alterá-las requer uma edição do código, não uma variável
de ambiente:
- `STREAM_RECOVERY.HOLDBACK_MS = 750` — durante quanto tempo a janela SSE inicial
é retida, para que um truncamento precoce possa ser repetido antes de qualquer
byte ser confirmado para o cliente.
- `STREAM_RECOVERY.BUFFER_MAX_BYTES = 65536` — limite rígido da janela retida;
confirma (flush + passthrough) assim que este número de bytes se acumula,
independentemente do temporizador.
- `STREAM_RECOVERY.EARLY_RETRY_MAX = 4` — número máximo de reaberturas transparentes
do stream upstream enquanto a retenção ainda não foi confirmada.
> **Limite de taxa por janela deslizante por fornecedor (sem variável de ambiente):**
> o _fallback_ do limite de taxa por janela deslizante por fornecedor, portado do FCC,
> existe no código (`open-sse/services/providerDefaultRateLimit.ts`, ligado através de
> `open-sse/services/rateLimitManager.ts`), mas é distribuído com um **mapa predefinido
> vazio** e atualmente **não tem variável de ambiente para o operador** — só é ativado
> através de um hook de teste / edição do código. Não está intencionalmente listado na
> tabela acima. O limitador de relay por `(token, IP)` que _de facto_ tem um controlo
> é `RELAY_IP_PER_MINUTE` (§3 Rede e Portas).
---
## 22. Depuração
> [!CAUTION]
> Estas variáveis produzem **resultados detalhados** e podem expor dados sensíveis. **Nunca as ative em produção.**
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ------------------------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CURSOR_DEBUG` | _(não definida)_ | `open-sse/executors/cursor.ts` | Defina como `1` para ativar registos detalhados do executor Cursor (blocos SSE descodificados, etc.). |
| `CURSOR_STREAM_DEBUG` | _(não definida)_ | `open-sse/executors/cursor.ts` | Alias retrocompatível de `CURSOR_DEBUG`. |
| `CURSOR_DUMP_FILE` | _(não definida)_ | `open-sse/executors/cursor.ts` | Caminho de ficheiro opcional que recebe blocos Cursor descodificados em bruto quando `CURSOR_DEBUG=1`. |
| `CURSOR_STREAM_TIMEOUT_MS` | `300000` | `open-sse/executors/cursor.ts` | Tempo limite de inatividade do fluxo (ms) para o executor Cursor. |
| `CURSOR_KV_GRACE_MS` | `2000` | `open-sse/executors/cursor.ts` | Período de tolerância (ms) após um terminador suave composer kv_after_text quando permanecem bytes em memória intermédia — permite que uma chamada de ferramenta exec_mcp subsequente tenha tempo para concluir a respetiva trama. |
| `CURSOR_TOOL_DIRECTIVE` | ativada (`!== "0"`) | `open-sse/executors/cursor.ts` | Diretiva de confirmação de ferramenta que faz com que composer-2.5 emita chamadas de ferramentas de forma fiável. Defina como `0` para desativar. |
| `OMNIROUTE_SYSTEM_INSTRUCTION_APPEND` | _(não definida)_ | `open-sse/translator/request/claude-to-openai.ts`, `open-sse/translator/response/openai-to-claude.ts` | Texto de instrução de sistema definido pelo operador, anexado à mensagem de sistema APÓS a tradução (injeção pós-tradução), chegando aos caminhos codex/Responses e `/v1/messages`. Também é utilizado como prefixo da diretiva removido dos blocos de preâmbulo de sistema repetidos. Deixe por definir para desativar. |
| `OMNIROUTE_STRIP_SYSTEM_PREAMBLE` | `0` (desativada) | `open-sse/translator/response/openai-to-claude.ts`, `open-sse/utils/directivePreambleStripper.ts` | Defina como `1` para remover blocos de preâmbulo da instrução de sistema do início de um fluxo openai→claude. Desativada por predefinição — as heurísticas foram concebidas para prosa em inglês e alteram o conteúdo da resposta, pelo que uma resposta que comece legitimamente com uma secção desse tipo iria perdê-la. |
| `CURSOR_IMAGE_FETCH_TIMEOUT_MS` | `15000` | `open-sse/utils/cursorImages.ts` | Tempo limite de obtenção por imagem (ms) para entrada visual remota `image_url`. |
| `CURSOR_STATE_DB_PATH` | _(detetada)_ | `open-sse/utils/cursorVersionDetector.ts` | Substitui a pesquisa da base de dados de estado do Cursor IDE utilizada para detetar a versão do IDE. |
| `CURSOR_AGENT_CLI_VERSION` | _(detetar / fixar)_ | `open-sse/utils/cursorAgentCliVersion.ts` | ID da compilação do Agent CLI (`YYYY.MM.DD-`) para `x-cursor-client-version: cli-…` no Agent Run. |
| `CURSOR_AGENT_BIN` | _(não definida)_ | `open-sse/handlers/imageGeneration/providers/cursorAgentImage.ts` | Caminho para o binário do Cursor Agent utilizado para geração de imagens. Se não estiver definida, o processador utiliza `providerSpecificData.agentBin` e, em seguida, PATH. |
| `CURSOR_IMG_TIMEOUT_MS` | `210000` | `open-sse/handlers/imageGeneration/providers/cursorAgentImage.ts` | Tempo real máximo por imagem (ms) para tarefas de imagem do Cursor Agent. |
| `CURSOR_IMG_MAX_CONCURRENT` | `2` | `open-sse/handlers/imageGeneration/providers/cursorAgentImage.ts` | Limite de simultaneidade do posto partilhado para tarefas de imagem do Cursor. |
| `CURSOR_IMG_MODEL` | pedido / `auto` | `open-sse/handlers/imageGeneration/providers/cursorAgentImage.ts` | Substitui `--model` da CLI do Cursor para tarefas de imagem. |
| `UC_IMAGE_POLL_INTERVAL_MS` | `2000` | `open-sse/handlers/imageGeneration/providers/ucImage.ts` | Cadência de consulta de resultados da geração de imagens da UC (uncensored.com) (ms). |
| `UC_IMAGE_POLL_TIMEOUT_MS` | `60000` | `open-sse/handlers/imageGeneration/providers/ucImage.ts` | Tempo real máximo (ms) para a consulta de resultados da geração de imagens da UC. |
| `UC_VIDEO_POLL_INTERVAL_MS` | `3000` | `open-sse/handlers/videoGeneration/providers/ucVideo.ts` | Cadência de consulta de resultados da geração de vídeos da UC (uncensored.com) (ms). |
| `UC_VIDEO_POLL_TIMEOUT_MS` | `300000` | `open-sse/handlers/videoGeneration/providers/ucVideo.ts` | Tempo real máximo (ms) para a consulta de resultados da geração de vídeos da UC. |
| `CURSOR_DATA_DIR` | _(detetado)_ | `open-sse/utils/cursorAgentCliVersion.ts` | Substitui o diretório de dados da CLI do Cursor Agent (`…/versions/`); é a mesma variável utilizada pelo agente oficial. |
| `CURSOR_TOKEN` | _(não definida)_ | `scripts/ad-hoc/cursor-tap.cjs` | Token de portador direto do Cursor utilizado pelas ferramentas de desenvolvimento. |
| `OMNIROUTE_LOG_REQUEST_SHAPE` | desativada (ativação explícita através de `"1"`) | `src/app/api/v1/chat/completions/route.ts` | Regista marcadores de tipo/comprimento de conteúdo para cargas úteis de conversação grandes quando `"1"` está definido. Desativada por predefinição para reduzir o ruído dos registos. |
| `DEBUG_RESPONSES_SSE_TO_JSON` | _(não definida)_ | `open-sse/handlers/responseTranslator.ts` | Defina como `true` para registar detalhes da tradução SSE→JSON da Responses API. |
| `DEBUG_CLAUDE_NONSTREAM` | _(não definida)_ | `open-sse/handlers/responseTranslator.ts` | Defina como `true` para apresentar blocos textContent vazios no caminho de tradução de respostas do Claude (apenas para depuração). |
| `NEXT_PUBLIC_OMNIROUTE_E2E_MODE` | _(não definida)_ | Infraestrutura de testes E2E | Defina como `true` para ativar o modo de teste E2E (autenticação menos restritiva, pontos de integração de teste). |
---
## 23. Integração com o GitHub
Permita que os utilizadores comuniquem problemas diretamente a partir do Dashboard.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| --------------------- | ---------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `GITHUB_ISSUES_REPO` | _(não definido)_ | `src/app/api/v1/issues/report/route.ts` | Repositório no formato `owner/repo`. |
| `GITHUB_ISSUES_TOKEN` | _(não definido)_ | `src/app/api/v1/issues/report/route.ts` | Token de acesso pessoal do GitHub com o âmbito `issues:write`. |
| `GITHUB_TOKEN` | _(não definido)_ | triagem de problemas/auxiliares do agente na cloud | Token genérico de acesso ao GitHub utilizado como alternativa a `GITHUB_ISSUES_TOKEN` e pelos auxiliares do agente na cloud em `src/lib/cloudAgent/*`. |
---
## Cenários de Implementação
Para obter orientações de SRE sobre o backend de retransmissão (comportamento de ts/bifrost/auto, posicionamento de 9router vs CLIProxyAPI e estratégia de contingência para débitos elevados), consulte [Estratégia do Backend de Retransmissão](/docs/reference/RELAY_BACKEND_STRATEGY.md).
### Desenvolvimento Local Mínimo
```bash
JWT_SECRET=$(openssl rand -base64 48)
API_KEY_SECRET=$(openssl rand -hex 32)
INITIAL_PASSWORD=dev123
PORT=20128
NODE_ENV=development
```
### Produção com Docker
```bash
JWT_SECRET=
API_KEY_SECRET=
INITIAL_PASSWORD=
STORAGE_ENCRYPTION_KEY=
DATA_DIR=/data
PORT=20128
API_PORT=20129
NODE_ENV=production
AUTH_COOKIE_SECURE=true
REQUIRE_API_KEY=true
NEXT_PUBLIC_BASE_URL=https://omniroute.example.com
BASE_URL=http://localhost:20128
OMNIROUTE_MEMORY_MB=8192
CORS_ORIGIN=https://your-frontend.example.com
```
### Ambiente Isolado / CI
```bash
JWT_SECRET=test-jwt-secret-for-ci
API_KEY_SECRET=test-api-key-secret-for-ci
INITIAL_PASSWORD=testpass
NODE_ENV=production
OMNIROUTE_DISABLE_BACKGROUND_SERVICES=true
APP_LOG_TO_FILE=false
```
### VPS com Proxy Inverso (nginx + Cloudflare)
```bash
JWT_SECRET=
API_KEY_SECRET=
STORAGE_ENCRYPTION_KEY=
PORT=20128
AUTH_COOKIE_SECURE=true
REQUIRE_API_KEY=true
NEXT_PUBLIC_BASE_URL=https://omniroute.example.com
BASE_URL=http://127.0.0.1:20128
CORS_ORIGIN=https://omniroute.example.com
ENABLE_TLS_FINGERPRINT=true
CLI_COMPAT_ALL=1
```
---
## 24. Sandbox de Skills (v3.8.0+)
Limites e controlos de segurança aplicados quando a framework Skills (`src/lib/skills/`) executa automatizações definidas pelo utilizador num ambiente isolado.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| --------------------------------- | ----------------------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `SKILLS_SANDBOX_TIMEOUT_MS` | `10000` (10 s) | `src/lib/skills/builtins.ts` | Limite de tempo real por execução para código de skills no sandbox. Limite rígido; qualquer execução mais longa é terminada. |
| `SKILLS_EXECUTION_TIMEOUT_MS` | _(recorre a `SKILLS_SANDBOX_TIMEOUT_MS`)_ | `src/lib/skills/` | Limite de tempo da orquestração de skills de alto nível. Defina-o acima de `SKILLS_SANDBOX_TIMEOUT_MS` para permitir fluxos com vários passos. |
| `SKILLS_MAX_FILE_BYTES` | `1048576` (1 MB) | `src/lib/skills/builtins.ts` | Número máximo de bytes que uma skill pode ler de um único ficheiro no sandbox. |
| `SKILLS_MAX_HTTP_RESPONSE_BYTES` | `256000` (250 KB) | `src/lib/skills/builtins.ts` | Número máximo de bytes capturados de uma única resposta HTTP numa skill. |
| `SKILLS_MAX_SANDBOX_OUTPUT_CHARS` | `100000` | `src/lib/skills/builtins.ts` | Limite rígido de carateres de stdout/stderr devolvidos por uma invocação do sandbox. |
| `SKILLS_SANDBOX_NETWORK_ENABLED` | `false` | `src/lib/skills/builtins.ts` | Defina como `1`/`true` para permitir ligações de saída a partir do sandbox. Por predefinição, é **isolado** por segurança. |
| `SKILLS_ALLOWED_SANDBOX_IMAGES` | _(vazio)_ | `src/lib/skills/builtins.ts` | Lista de imagens de contentor permitidas para execução no sandbox, separadas por vírgulas. Vazio significa apenas a predefinição integrada. |
| `SKILLS_SANDBOX_DOCKER_IMAGE` | _(predefinição integrada)_ | `src/lib/skills/` | Imagem de contentor utilizada ao iniciar um sandbox baseado em Docker. Substitua-a para fixar uma imagem base personalizada e reforçada. |
| `SKILLS_SANDBOX_RUNTIME` | `auto` | `src/lib/skills/sandbox.ts`, `src/lib/skills/containerProvider.ts` | Runtime de contentores para o isolamento de skills: `auto` \| `docker` \| `apple` \| `wsl` \| `orbstack` \| `podman`. `auto` seleciona o melhor runtime instalado para o SO anfitrião (Apple Container/OrbStack no macOS, WSL Container no Windows, Podman no Linux), recorrendo ao Docker como alternativa. |
> [!CAUTION]
> Ativar `SKILLS_SANDBOX_NETWORK_ENABLED=true` abre um caminho de saída para código arbitrário de skills. Combine esta opção com `OUTBOUND_SSRF_GUARD_ENABLED=true` e uma política rigorosa de `CORS_ORIGIN`/proxy em implementações partilhadas.
---
## 25. Quotas de Fornecedores, Túneis, Cópias de Segurança e Runtime Diverso
Endpoints de quotas de fornecedores, túneis de rede (Tailscale, Ngrok, proxy de depuração MITM), o pool de saída 1Proxy, cópias de segurança da base de dados e pequenas substituições por funcionalidade referenciadas pela camada do executor ou por scripts.
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ---------------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `REDIS_URL` | `redis://localhost:6379` | `src/shared/utils/rateLimiter.ts` | Cadeia de ligação Redis para o backend do limitador de taxa. |
| `ALIBABA_CODING_PLAN_HOST` | _(host de produção)_ | `open-sse/services/bailianQuotaFetcher.ts` | Substitui o host utilizado para obter as quotas do coding plan da Alibaba Bailian. |
| `ALIBABA_CODING_PLAN_QUOTA_URL` | derivado do host | `open-sse/services/bailianQuotaFetcher.ts` | Substituição completa do URL de quotas para a Alibaba Bailian. |
| `QWEN_CLOUD_COOKIE` | _(não definido)_ | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Cookie de sessão da consola para o gateway de quotas do Token Plan pessoal da Qwen Cloud / Model Studio (a chave da API de inferência não consegue lê-lo). Copie o cabeçalho de pedido `Cookie` completo — contém `login_qwencloud_ticket` — a partir de qualquer chamada `api.json` para `cs-data.qwencloud.com` em home.qwencloud.com › Faturação › Subscrição (F12 › Rede). Sensível e limitado à sessão; prefira o campo `qwenCloudCookie` do Dashboard, por ligação. |
| `QWEN_CLOUD_SEC_TOKEN` | _(não definido)_ | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Substituição manual do `sec_token` para o gateway da consola do Token Plan. Sensível; quando não definido, o módulo de obtenção resolve-o a partir do HTML do dashboard utilizando o cookie. |
| `QWEN_TOKEN_PLAN_HOST` | `https://cs-data.qwencloud.com` | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | Substituição do host do gateway para o módulo de obtenção de quotas do Token Plan pessoal (por exemplo, `bailian-singapore-cs.alibabacloud.com` para a consola do Model Studio). |
| `QWEN_TOKEN_PLAN_DASHBOARD_URL` | `https://home.qwencloud.com/` | `open-sse/services/qwenTokenPlanQuotaFetcher.ts` | URL do dashboard utilizado para resolver o `sec_token` a partir do HTML com sessão iniciada. |
| `XIAOMI_MIMO_CONSOLE_COOKIE` | _(não definido)_ | `open-sse/services/usage/xiaomi-mimo.ts` | Cookie de sessão da consola para a API de quotas do Token Plan da Xiaomi MiMo (`platform.xiaomimimo.com/api/v1/tokenPlan/usage` + `tokenPlan/detail` — a chave da API de inferência não consegue lê-lo). Copie o cabeçalho de pedido `Cookie` completo — contém `api-platform_serviceToken` e `userId` — a partir de qualquer pedido para `platform.xiaomimimo.com` na página do Token Plan (F12 › Rede). Sensível e limitado à sessão; prefira o campo `xiaomiMimoConsoleCookie` do Dashboard, por ligação. |
| `XIAOMI_MIMO_MONTHLY_TOKEN_LIMIT` | `4100000000` | `open-sse/services/usage/xiaomi-mimo.ts` | Orçamento mensal (Credits) para o fallback Xiaomi MiMo monitorizado pelo OmniRoute, utilizado quando não está configurado nenhum cookie de consola. A predefinição é 4,1B do nível Lite; defina-o para os Credits do plano (Standard 11B / Pro 38B / Max 82B). Uma substituição por ligação `providerSpecificData.monthlyTokenLimit` prevalece sobre esta variável de ambiente. |
| `ALIBABA_FREE_TIER_VISION_FE_PATH` | `/costing-balance/free-quota-image-video` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Substituição do caminho de front-end da consola para obter a quota de visão/multimédia do nível gratuito do Alibaba Model Studio. |
| `ALIBABA_FREE_TIER_MULTIMODAL_FE_PATH` | `/costing-balance/free-quota-multimodal` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Substituição do caminho de front-end da consola para obter a quota multimodal do nível gratuito do Alibaba Model Studio. |
| `ALIBABA_FREE_TIER_AUDIO_FE_PATH` | `/costing-balance/free-quota-audio` | `open-sse/services/alibabaFreeTierQuotaFetcher.ts` | Substituição do caminho de front-end da consola para obter a quota de áudio do nível gratuito do Alibaba Model Studio. |
| `ALIBABA_FREE_TIER_ALLOWLIST_PATH` | _(não definido)_ | `open-sse/services/alibabaFreeTierAllowlist.ts` | Caminho opcional para uma substituição JSON local da lista de permissões incorporada de modelos de texto do nível gratuito da Alibaba. Se não estiver definido, recorre a `$DATA_DIR/alibaba-free-tier-allowlist.json` e, em seguida, a `config/alibaba-free-tier-allowlist.json`. |
| `CONTEXT_RESERVE_TOKENS` | `1024` | `open-sse/services/contextManager.ts` | Tokens reservados para a saída de conclusão ao calcular os orçamentos do prompt. |
| `CONTEXT_KEEP_LATEST_IMAGES` | `2` | `open-sse/services/contextManager.ts` | Quantas das imagens inline mais recentes manter ao remover as mais antigas para caber na janela de contexto (#8560). |
| `MODEL_ALIAS_COMPAT_ENABLED` | ativado | `open-sse/services/model.ts` | Ativa/desativa a camada de compatibilidade de aliases de modelo legados utilizada por clientes mais antigos. |
| `OMNIROUTE_EMERGENCY_FALLBACK` | ativado | `open-sse/services/emergencyFallback.ts` | Defina como `false` (ou `0`) para desativar o fallback de emergência por esgotamento de orçamento, que redireciona os pedidos falhados para o modelo gratuito `nvidia`/`openai/gpt-oss-120b`. A precedência efetiva é: substituição na BD de Feature Flags > variável de ambiente > predefinição; se indisponível, o serviço recorre ao valor bruto da variável de ambiente. |
| `COMMAND_CODE_CALLBACK_PORT` | _(não definido)_ | `src/app/api/providers/command-code/auth/shared.ts` | Porta local utilizada para callbacks do tipo OAuth a partir do auxiliar CLI do Command Code. |
| `COMMAND_CODE_VERSION` | `0.33.2` | `open-sse/executors/commandCode.ts` | Valor enviado como cabeçalho `x-command-code-version` para o upstream do Command Code. Substitua para atualizar a versão da CLI. |
| `COMMANDCODE_API_URL` | `https://api.commandcode.ai` | `open-sse/services/usage/command-code.ts` | URL base para o upstream de utilização/quota do Command Code usado pela telemetria de recolha de quota do smartphone. Substitua por uma API Command Code autoalojada/alternativa. |
| `MITM_LOCAL_PORT` | `443` | `src/mitm/server.cjs` | Porta local de escuta do proxy de depuração MITM. |
| `MITM_DISABLE_TLS_VERIFY` | `0` | `src/mitm/server.cjs` | Defina `1` para desativar a verificação TLS do upstream (apenas em desenvolvimento). |
| `MITM_IDLE_TIMEOUT_MS` | `60000` | `src/mitm/socketTimeouts.ts`, `src/mitm/server.cjs` | Tempo limite de inatividade do socket (ms) para ligações via proxy; sockets inativos além deste limite são terminados para evitar fugas de túneis semiabertos. |
| `BRIDGE_PORT` | `20129` | `bin/antigravity-bridge.mjs` | Porta em que a bridge MITM do Antigravity escuta. |
| `ROUTER_URL` | `http://127.0.0.1:20128/v1/antigravity` | `bin/antigravity-bridge.mjs` | Endpoint do router para o qual a bridge reencaminha o tráfego do Antigravity. |
| `CERT_DIR` | `/mitm` | `bin/antigravity-bridge.mjs` | Substitui o diretório de onde a bridge lê o seu material TLS. O modelo de certificado é escolhido da mesma forma que o servidor AgentBridge: `server.crt`/`server.key` para uma instalação leaf legada, caso contrário `ca.crt`/`ca.key` (CA raiz, um leaf por anfitrião intercetado; forçado por `MITM_ROOT_CA_ENABLED=true`). A bridge termina no arranque se os ficheiros do modelo ativo estiverem em falta. |
| `MITM_VERBOSE` | `1` | `src/mitm/server.cjs`, `src/mitm/_internal/bypass.cjs` | Verbosidade do registo de decisões de encaminhamento: `0` silencia, valores superiores registam mais decisões de bypass/rota. |
| `MITM_ROOT_CA_ENABLED` | `false` | `src/mitm/manager.ts` | Defina `true` para optar pelo modelo de certificado CA raiz + leaf por anfitrião (#6684). Instalações novas recebem-no automaticamente; instalações com um leaf legado já confiável mantêm o certificado legado de SAN fixo, a menos que se opte pelo novo modelo. |
| `MITM_CERT_MODE` | `legacy` | `src/mitm/manager.ts`, `src/mitm/server.cjs` | Definida PELO gestor MITM para o processo proxy iniciado (`root-ca` \| `legacy`) — reflete a decisão de migração de certificados; não se destina a ser definida manualmente. |
| `OMNIROUTE_NO_SUDO` | `0` | `src/mitm/systemCommands.ts` | Defina `1` (truthy) para remover o `sudo` inicial dos comandos de confiança de certificados do MITM — para implementações sem root / com namespaces de utilizador em que o operador confia na CA manualmente (por exemplo, através do mecanismo extra-CA-certs do Node). |
| `SKIP_ANTIGRAVITY_DNS` | _(não definido)_ | `src/mitm/dns/provision.ts` | Defina `true` para ignorar completamente o aprovisionamento de entradas DNS em `/etc/hosts` para os hostnames do proxy Antigravity — para contentores sem sudo/root disponível. |
| `OMNIROUTE_SKIP_DNS_WRITE` | _(não definido)_ | `src/mitm/dns/dnsConfig.ts` | Defina `1` para ignorar a escrita no ficheiro hosts ao adicionar/remover entradas DNS — para ambientes de teste em sandbox ou apenas de leitura. |
| `OMNIROUTE_SKIP_SYSTEM_TRUST` | `0` | `src/mitm/cert/install.ts`, `src/mitm/tproxy/caTrust.ts` | Proteção apenas para testes/CI: defina `1` para tornar a instalação/desinstalação da confiança de certificados uma operação sem efeito (no-op), para que o conjunto de testes nunca altere o armazenamento de confiança do SO. Definido automaticamente pela configuração de testes e pelos workflows de CI. |
| `CHANGELOG_BASE_REF` | _(automático)_ | `scripts/check/check-changelog-integrity.mjs` | Ref base explícita para a verificação anti-"devoramento" do CHANGELOG (por predefinição, o branch base do PR em CI, ou o `release/v*` mais elevado). |
| `FREE_PROXY_AUTO_SYNC_ENABLED` | `false` | `src/lib/freeProxyProviders/scheduler.ts` | Defina `true` para ativar o agendador de sincronização automática em segundo plano do pool de proxies gratuitos. Opção ativável (opt-in), desativada por predefinição. |
| `FREE_PROXY_AUTO_SYNC_INTERVAL_MS` | `1800000` | `src/lib/freeProxyProviders/scheduler.ts` | Intervalo de sincronização automática em milissegundos (predefinição: 30 min). |
| `FREE_PROXY_1PROXY_ENABLED` | `true` | `src/lib/freeProxyProviders/oneproxy.ts` | Ativa a fonte de proxies gratuitos 1proxy. Defina como `false` para desativar. |
| `FREE_PROXY_1PROXY_API_URL` | _(ver oneproxy.ts)_ | `src/lib/freeProxyProviders/oneproxy.ts` | Substituição do URL da API do 1proxy. |
| `FREE_PROXY_1PROXY_MAX` | `500` | `src/lib/freeProxyProviders/oneproxy.ts` | Número máximo de proxies obtidos por sincronização a partir do 1proxy. |
| `FREE_PROXY_1PROXY_MIN_QUALITY` | `50` | `src/lib/freeProxyProviders/oneproxy.ts` | Limiar mínimo da pontuação de qualidade para as importações do 1proxy. |
| `FREE_PROXY_PROXIFLY_ENABLED` | `true` | `src/lib/freeProxyProviders/proxifly.ts` | Ativar a fonte de proxies gratuitos Proxifly. Defina como `false` para desativar. |
| `FREE_PROXY_PROXIFLY_QUANTITY` | `100` | `src/lib/freeProxyProviders/proxifly.ts` | Número de proxies a obter por sincronização do Proxifly. |
| `FREE_PROXY_PROXIFLY_ANONYMITY` | `elite` | `src/lib/freeProxyProviders/proxifly.ts` | Filtro de nível de anonimato para o Proxifly (`elite`, `anonymous`, `transparent`). |
| `FREE_PROXY_IPLOCATE_ENABLED` | `false` | `src/lib/freeProxyProviders/iplocate.ts` | Ativar a fonte de proxies gratuitos IPLocate. Apenas mediante ativação explícita (opt-in). |
| `FREE_PROXY_IPLOCATE_BASE_URL` | `https://raw.githubusercontent.com/iplocate/free-proxy-list/main/protocols` | `src/lib/freeProxyProviders/iplocate.ts` | Substituição do URL base da lista de proxies do IPLocate. |
| `FREE_PROXY_WEBSHARE_ENABLED` | `true` | `src/lib/freeProxyProviders/webshare.ts` | Ativar a fonte do pool de proxies Webshare. Defina como `false` para desativar; requer também que `FREE_PROXY_WEBSHARE_API_KEY` esteja definida. |
| `FREE_PROXY_WEBSHARE_API_KEY` | _(nenhuma)_ | `src/lib/freeProxyProviders/webshare.ts` | Token de API da conta Webshare (`Authorization: Token `). Obrigatório — o fornecedor permanece desativado sem ele. |
| `FREE_PROXY_WEBSHARE_API_URL` | `https://proxy.webshare.io/api/v2/proxy/list/` | `src/lib/freeProxyProviders/webshare.ts` | Substituição do URL da API da lista de proxies do Webshare. |
| `FREE_PROXY_WEBSHARE_MAX` | `500` | `src/lib/freeProxyProviders/webshare.ts` | Máximo de proxies importados por sincronização do Webshare. |
| `NEXT_PUBLIC_VERCEL_RELAY_ENABLED` | `true` | `src/app/(dashboard)/…/ProxyPoolTab.tsx` | Mostrar/ocultar o botão Deploy Vercel Relay no separador Proxy Pool. |
| `VERCEL_API_BASE` | `https://api.vercel.com` | `src/app/api/settings/proxy/vercel-deploy/route.ts` | Substituição do URL base da API Vercel (para testes). |
| `NEXT_PUBLIC_VERCEL_RELAY_DEFAULT_PROJECT` | `omniroute-relay` | `src/app/(dashboard)/…/VercelRelayModal.tsx` | Nome de projeto predefinido pré-preenchido na janela modal de implementação do Vercel Relay. |
| `TAILSCALE_BIN` | _(deteção automática)_ | `src/lib/tailscaleTunnel.ts` | Caminho explícito para o binário `tailscale`. |
| `TAILSCALED_BIN` | _(deteção automática)_ | `src/lib/tailscaleTunnel.ts` | Caminho explícito para o binário do daemon `tailscaled`. |
| `TAILSCALE_AUTHKEY` | _(não definido)_ | `src/lib/tailscaleTunnel.ts` | Chave de autenticação Tailscale pré-partilhada para `tailscale up` não interativo / headless (passada através de `--auth-key=`). Quando não definida, o início de sessão recorre ao URL de autenticação interativo no navegador. |
| `NGROK_AUTHTOKEN` | _(não definido)_ | `src/lib/ngrokTunnel.ts` | Autentica túneis ngrok de saída. |
| `DB_BACKUP_MAX_FILES` | `20` | `src/lib/db/backup.ts` | Número máximo de ficheiros de cópia de segurança SQLite retidos pela limpeza de cópias de segurança manual/agendada. Os snapshots de migração são endereçados por conteúdo e reutilizados para um estado de BD idêntico; não são eliminados dentro da janela de migração concorrente. Substitui o valor guardado em Definições → Retenção de cópias de segurança da base de dados. |
| `DB_BACKUP_RETENTION_DAYS` | `0` | `src/lib/db/backup.ts` | Idade máxima (dias) retida pela limpeza de cópias de segurança manual/agendada. `0` desativa a eliminação baseada na idade. Os snapshots de migração não são eliminados dentro da janela de migração concorrente. Substitui o valor guardado em Definições → Retenção de cópias de segurança da base de dados. |
| `OMNIROUTE_BACKUP_SCHEDULE_JOB_INTERVAL_MS` | `30000` | `src/lib/jobs/backupScheduleJob.ts` | Intervalo de execução (ms) da tarefa do lado do servidor que executa `backup-schedule.json`. Deve manter-se bem abaixo da granularidade de 1 minuto do cron; valores abaixo de `5000` ou inválidos revertem para `30000`. |
| `CONTAINER_HOST` | `docker` | `scripts/check-permissions.sh` | Indicação do runtime de contentores para a verificação de permissões do entrypoint. Defina como `podman` para qualquer topologia Podman. Uma vez que o contentor não consegue determinar se o motor é local ou acedido através do Podman Machine, o aviso mantém-se neutro quanto à topologia e aponta para `contrib/podman/README.md`. |
| `QUOTA_STORE_DRIVER` | `sqlite` | `src/lib/quota/storeFactory.ts` | Backend do repositório de consumo de partilha de quota: `sqlite` (predefinição) ou `redis`. |
| `QUOTA_STORE_REDIS_URL` | _(não definido)_ | `src/lib/quota/storeFactory.ts` | Cadeia de ligação Redis utilizada quando `QUOTA_STORE_DRIVER=redis` (p. ex. `redis://localhost:6379`). |
| `QUOTA_SATURATION_THRESHOLD` | `0.5` | `src/lib/quota/enforce.ts` | Rácio de saturação do pool (0..1); igual ou acima deste valor, o pool entra em modo estrito (sem empréstimos). |
| `QUOTA_SOFT_DEPRIORITIZE_FACTOR` | `0.7` | `open-sse/services/combo.ts` | Multiplicador de pontuação (0..1) aplicado a um destino quando a política de quota flexível o desprioriza. |
| `STATUS_SOFT_DEPRIORITIZE_FACTOR` | `0.5` | `open-sse/services/combo/autoStrategy.ts` | Multiplicador de pontuação (0..1) aplicado a um fornecedor esgotado (`credits_exhausted`/`rate_limited`) na pontuação auto-combo quando o corte de quota de pré-verificação está desativado (#4540). |
| `QUOTA_CONSUMPTION_RETENTION_DAYS` | `14` | `src/lib/db/quotaConsumption.ts` | Janela de retenção (dias) dos buckets `quota_consumption` antes da GC (`gcQuotaConsumption`). |
| `QUOTA_PREFLIGHT_CUTOFF_ENABLED` | `false` | `src/lib/resilience/settings.ts` | Ativação opcional (predefinição: desativado): ativa o corte rígido de quota do encaminhamento automático, que elimina candidatos com quota baixa antes da pontuação. |
| `OMNIROUTE_AUTO_FREE_FALLBACK_TO_FULL_POOL` | `false` | `open-sse/services/autoCombo/virtualFactory.ts` | Ativação opcional (predefinição: desativado): quando um filtro `auto/:` não corresponde a nenhum candidato ligado, restaura o comportamento legado de recorrer ao pool completo (não filtrado) em vez de devolver um pool vazio. Com a predefinição desativada, `:free` significa «apenas o nível gratuito». |
| `OMNIROUTE_CHAOS_MAX_PANEL` | `5` | `open-sse/services/autoCombo/virtualFactory.ts` | Limite do tamanho do painel (limitado entre 1–10) para a variante de difusão `auto/*:chaos` — um pedido é distribuído por, no máximo, este número de modelos de fornecedores distintos. |
| `OMNIROUTE_CHAOS_MIN_PANEL` | _(predefinição do motor)_ | `open-sse/services/autoCombo/virtualFactory.ts` | Ajuste mínimo do tamanho do painel reencaminhado para o gestor de difusão de caos; se não definido, mantém a predefinição do motor. |
| `OMNIROUTE_CHAOS_PANEL_TIMEOUT_MS` | _(predefinição do motor)_ | `open-sse/services/autoCombo/virtualFactory.ts` | Tempo limite rígido (ms) para todo o fan-out do painel de caos; se não definido, mantém a predefinição do motor. |
| `GROK_AUTH_PATH` | `~/.grok/auth.json` | `open-sse/services/grokQuotaFetcher.ts` | Caminho do `auth.json` do Grok CLI utilizado para obter a quota semanal do grok-web; substitua para testes ou para uma instalação não padrão do CLI. |
| `AGENTBRIDGE_UPSTREAM_CA_CERT` | _(não definido)_ | `src/mitm/manager.ts` | Certificado de CA adicional (PEM) considerado confiável para as ligações TLS upstream do AgentBridge. |
| `INSPECTOR_BUFFER_SIZE` | `1000` | `src/mitm/inspector/buffer.ts` | Número máximo de pedidos capturados mantidos no buffer circular do Traffic Inspector. |
| `INSPECTOR_MAX_BODY_KB` | `1024` | `src/mitm/inspector/buffer.ts` | Tamanho máximo (KB) do corpo do pedido/resposta capturado antes de ser truncado. |
| `INSPECTOR_HTTP_PROXY_PORT` | `8080` | `src/mitm/inspector/httpProxyServer.ts` | Porta local para o proxy HTTP do Traffic Inspector. |
| `INSPECTOR_HTTP_PROXY_AUTOSTART` | `false` | `src/mitm/inspector/httpProxyServer.ts` | Iniciar automaticamente o proxy HTTP do inspector no arranque. |
| `INSPECTOR_LLM_HOSTS_EXTRA` | _(não definido)_ | `src/lib/inspector/captureState.ts` | Nomes de anfitrião adicionais (separados por vírgulas) tratados como endpoints de LLM para captura. |
| `INSPECTOR_MASK_SECRETS` | `true` | `src/mitm/inspector/buffer.ts` | Ocultar segredos (cabeçalhos de autenticação / chaves de API) no tráfego capturado. |
| `INSPECTOR_SYSTEM_PROXY_GUARD_MINUTES` | `30` | `src/app/api/tools/traffic-inspector/capture-modes/system-proxy/route.ts` | Minutos antes de a proteção do proxy de sistema reverter automaticamente as definições de proxy do SO. |
| `INSPECTOR_INTERNAL_INGEST_TOKEN` | _(automático)_ | `src/app/api/tools/traffic-inspector/internal/ingest/route.ts` | Token que autentica a ingestão interna de capturas no inspector. |
| `PLAYGROUND_COMPARE_MAX_COLUMNS` | `4` | `src/app/(dashboard)/dashboard/playground/` | Número máximo de colunas lado a lado no modo de comparação do Playground. |
| `PLAYGROUND_IMPROVE_PROMPT_DEFAULT_MODEL` | _(não definido)_ | `src/app/(dashboard)/dashboard/playground/` | Modelo predefinido para a ação 'improve prompt' do Playground (recorre ao modelo ativo quando não definido). |
| `BIFROST_ENABLED` | `1` | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Interruptor geral (kill switch) para o proxy sidecar bifrost. Quando definido como `0`, a rota devolve 503 com o cabeçalho `X-Bifrost-Killswitch` e o operador é redirecionado para o caminho TS. Utilize para desativar o sidecar sem reimplementar (incidente no router de nível 1, rotação de chaves). |
| `BIFROST_BASE_URL` | _(não definido)_ | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Quando definido, a rota do proxy sidecar Bifrost encaminha o tráfego de `/v1/chat/completions` para este gateway Go em vez do handler de relay TS. Não definido → 503 com fallback. A barra final é removida. |
| `BIFROST_PORT` | `8080` | `src/lib/services/bootstrap.ts` | Porta à qual o serviço incorporado Bifrost supervisionado se vincula (`127.0.0.1:`) quando o OmniRoute gere o ciclo de vida do sidecar Bifrost. Predefinição: `8080`. |
| `LLMLINGUA_PORT` | `20135` | `src/lib/services/bootstrap.ts` | Porta à qual o serviço de compressão LLMLingua supervisionado se vincula (`127.0.0.1:`). Predefinição: `20135`. |
| `LLMLINGUA_BASE_URL` | `http://127.0.0.1:20135` | `open-sse/services/compression/engines/llmlingua/index.ts` | URL base para o daemon do microserviço local de compressão HTTP LLMLingua. Predefinição: `http://127.0.0.1:20135`. |
| `LLMLINGUA_MODEL` | `atjsh/llmlingua-2-js-tinybert-meetingbank` | `src/lib/services/installers/llmlingua.ts` | ID do modelo Hugging Face que o sidecar LLMLingua supervisionado carrega (passado ao ambiente do processo filho). |
| `BIFROST_API_KEY` | _(não definido)_ | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Chave de API para o gateway Bifrost (enviada como `Authorization: Bearer ...`). Se não estiver definida, a rota espera que o pedido transporte uma chave de API OmniRoute válida; esta chave destina-se apenas à autenticação do lado do gateway. |
| `BIFROST_STREAMING_ENABLED` | `true` | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Quando verdadeiro, a rota do sidecar Bifrost devolve as respostas em streaming via SSE através do gateway, em vez do executor de streaming TS. Defina como `0` para forçar respostas JSON sem streaming através do gateway. |
| `BIFROST_TIMEOUT_MS` | `30000` | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Timeout por pedido ao fazer proxy para o gateway Bifrost (ms). Em caso de timeout, a rota devolve o caminho de relay TS através do cabeçalho `X-Bifrost-Fallback`. |
| `OMNIROUTE_BIFROST_KEY` | _(não definido)_ | `src/app/api/v1/relay/chat/completions/bifrost/route.ts` | Alias de `BIFROST_API_KEY` (usado por scripts que leem o ambiente via `OMNIROUTE_*`). `BIFROST_API_KEY` tem precedência quando ambos estão definidos. |
| `OMNIROUTE_RELAY_BACKEND` | `ts` / `auto` | `src/app/api/v1/relay/chat/completions/routingBackend.ts` | Backend de relay para `/api/v1/relay/chat/completions`: `ts \| bifrost \| auto`. `ts` = relay TypeScript (predefinição quando o Bifrost não está configurado); `auto` seleciona o Bifrost quando `BIFROST_BASE_URL` está definido e `BIFROST_ENABLED` ≠ `0`, com fallback automático para TS se o sidecar estiver inacessível; `bifrost` força o Bifrost (estrito, sem fallback). A autenticação/rate-limit/injection-guard/allowlist são sempre executados primeiro na rota Next. As respostas transportam `X-Routing-Backend` / `X-Routing-Fallback` / `X-Routing-Fallback-Reason`. |
| `RELAY_ROUTING_BACKEND` | _(não definido)_ | `src/app/api/v1/relay/chat/completions/routingBackend.ts` | Alias aceite de `OMNIROUTE_RELAY_BACKEND` (mesmos valores `ts \| bifrost \| auto`). `OMNIROUTE_RELAY_BACKEND` tem precedência quando ambos estão definidos. |
| `OMNIROUTE_BIFROST_FAILURE_COOLDOWN_MS` | `5000` | `src/app/api/v1/relay/chat/completions/bifrostCooldown.ts` | Cooldown (ms) após a falha de um salto do sidecar Bifrost em modo `auto`, antes de o relay tentar novamente o sidecar; encaminha diretamente para o caminho TS enquanto o cooldown durar e depois volta a sondar. `0` desativa. Aplica-se apenas quando `OMNIROUTE_RELAY_BACKEND=auto`. |
| `OMNIROUTE_TLS_CERT` | _(não definido)_ | `bin/cli/commands/serve.mjs` | Caminho para um certificado TLS PEM para servir o `omniroute serve` por HTTPS (equivalente a `--tls-cert`). Tem de ser emparelhado com `OMNIROUTE_TLS_KEY`; o servidor standalone termina então o TLS no mesmo listener (`wss://` funciona sem alterações). Não definido → HTTP simples. Fornecer apenas um de cert/key, ou um caminho ilegível, regista um aviso e mantém HTTP. |
| `OMNIROUTE_TLS_KEY` | _(não definido)_ | `bin/cli/commands/serve.mjs` | Caminho para a chave privada TLS PEM para o HTTPS do `omniroute serve` (equivalente a `--tls-key`). Tem de ser emparelhada com `OMNIROUTE_TLS_CERT`. Ver `OMNIROUTE_TLS_CERT`. |
| `OMNIROUTE_LOCAL_ENDPOINTS_ENABLED` | `0` | `src/lib/security/localEndpoints.ts` | Interruptor principal das rotas `/api/local/*`. Quando não definido ou `0`, todas as rotas `/api/local/*` devolvem 503 em produção. Tem de ser `1` em implementações não-loopback para ativar o launcher do Redis e iniciadores de serviços locais semelhantes com 1 clique. Dupla camada de segurança com a classificação route-guard de `isLocalOnlyPath()` (`LOCAL_ONLY_API_PREFIXES` em `src/server/authz/routeGuard.ts`). |
| `OMNIROUTE_LOCAL_ENDPOINTS_TOKEN` | _(não definido)_ | `src/lib/security/localEndpoints.ts` | Token Bearer para os chamadores de `/api/local/*` que não estão em loopback (p. ex. a aplicação desktop). Quando definido, os pedidos provenientes de IPs não-loopback têm de incluir `Authorization: Bearer `. Obrigatório quando `OMNIROUTE_LOCAL_ENDPOINTS_ENABLED=1` em implementações não-loopback. |
| `OMNIROUTE_REDIS_CONTAINER_NAME` | `omniroute-redis` | `bin/cli/commands/redis.mjs` | Nome do contentor para o lançador Redis de 1 clique (`omniroute redis up`). Utilizado tanto pela CLI como pela GUI `RedisLauncherPanel`. |
| `OMNIROUTE_REDIS_HOST_PORT` | `6379` | `bin/cli/commands/redis.mjs` | Porta do anfitrião para o lançador Redis de 1 clique. Aumente se o anfitrião já tiver a porta 6379 vinculada. A porta interna do contentor permanece 6379. |
| `OMNIROUTE_REDIS_BIND_HOST` | `127.0.0.1` | `bin/cli/commands/redis.mjs` | Interface do anfitrião na qual o lançador Redis de 1 clique publica. O lançador inicia o Redis SEM palavra-passe, pelo que vincular a `0.0.0.0` entrega a todos os anfitriões da sua LAN um Redis sem autenticação — só alargue isto se também definir uma palavra-passe na instância por si próprio. |
| `REDIS_BIND_HOST` | `127.0.0.1` | `docker-compose.yml` | Interface do anfitrião na qual o docker-compose publica o sidecar Redis (#9286). O Redis do compose é executado sem `requirepass`; os contentores da aplicação alcançam-no através da rede do compose (`redis:6379`) — a porta publicada existe apenas para ferramentas do lado do anfitrião. `0.0.0.0` expõe um Redis sem autenticação a toda a LAN. |
| `REDIS_PORT` | `6379` | `docker-compose.yml` | Porta do anfitrião para o sidecar Redis do compose. |
| `APP_BIND_HOST` | `127.0.0.1` | `docker-compose.yml`, `docker-compose.prod.yml` | Interface do anfitrião na qual o docker-compose publica as portas do dashboard/API/live-WS da própria aplicação (#12568). Com `REQUIRE_API_KEY=false` fornecido como predefinição do `.env.example`, `0.0.0.0` expõe o proxy LLM anónimo em `/v1` a toda a LAN/WAN — só alargue quando `REQUIRE_API_KEY=true` ou um proxy reverso à frente impor a sua própria autenticação. |
| `QDRANT_BIND_HOST` | `127.0.0.1` | `docker-compose.yml` | Interface do anfitrião na qual o docker-compose publica o sidecar de memória Qdrant (#12578). O mesmo raciocínio de exposição à LAN que `REDIS_BIND_HOST`. |
| `BIFROST_BIND_HOST` | `127.0.0.1` | `docker-compose.yml` | Interface do anfitrião na qual o docker-compose publica o sidecar do router Bifrost (#12578). O mesmo raciocínio de exposição à LAN que `REDIS_BIND_HOST`. |
| `REDIS_KEY_PREFIX` | `omniroute:` | `src/shared/utils/rateLimiter.ts` | Prefixo de namespace aplicado a todas as chaves Redis do OmniRoute (limitador de taxa, cache de autenticação, armazenamento de quotas, circuit breaker de warmup). Evita colisões de chaves quando a instância Redis é partilhada com outras aplicações (#11042). |
| `OMNIROUTE_INTERNAL_SERVICE_TOKEN` | _(não definido — mecanismo desativado)_ | `src/lib/api/internalServiceAuth.ts` | Segredo partilhado para saltos REST internos com preservação de identidade (#9260): os componentes do OmniRoute que chamam outras rotas locais do OmniRoute enviam-no como `x-omniroute-internal-service-token` para que a identidade do chamador original seja preservada. Comparado com `timingSafeEqual`. |
| `OMNIROUTE_INTERNAL_SERVICE_TOKEN_FILE` | _(não definido)_ | `src/lib/api/internalServiceAuth.ts` | Variante em ficheiro secreto do token de serviço interno: caminho para um ficheiro cujo conteúdo, após remoção de espaços em branco às extremidades, é o token. Consultado apenas quando a variável inline não está definida. |
| `OPENROUTER_PROVIDER_STATS_ENABLED` | `true` | `src/lib/catalog/openrouterProviderStats.ts` | Enriquece a lista de fornecedores do dashboard com estatísticas semanais de classificação do OpenRouter (#9324). Ativado por predefinição; defina como `false` para ignorar totalmente a obtenção em segundo plano (não bloqueante, nunca fatal). |
| `OPENROUTER_PROVIDER_STATS_TTL_MS` | `86400000` (24h) | `src/lib/catalog/openrouterProviderStats.ts` | TTL da cache para o snapshot de estatísticas de fornecedores do OpenRouter, em milissegundos. |
| `OMNIROUTE_REDIS_IMAGE` | `redis:7-alpine` | `bin/cli/commands/redis.mjs` | Imagem Redis utilizada pelo lançador Redis de 1 clique. Substitua por `redis:8-alpine` ou por um mirror de registo privado, conforme necessário. |
| `QDRANT_HOST` | `qdrant` | _(perfil de cluster opcional)_ | Nome do host do sidecar Qdrant quando `--profile memory` está ativo. A predefinição aponta para o nome do serviço qdrant na rede interna; substitua para uma implementação externa. Consumido apenas quando `qdrantEnabled` é `true` no código (`src/lib/memory/vectorStore.ts:108`). |
| `QDRANT_PORT` | `6333` | _(perfil de cluster opcional)_ | Porta REST do sidecar Qdrant. |
| `QDRANT_GRPC_PORT` | `6334` | _(perfil de cluster opcional)_ | Porta gRPC do sidecar Qdrant. Utilizada por bibliotecas de cliente que preferem gRPC em vez de REST para operações de streaming. |
| `QDRANT_API_KEY` | _(não definido)_ | _(perfil de cluster opcional)_ | Chave de API opcional para o Qdrant Cloud ou uma instância on-prem autenticada. Vazio → nenhum cabeçalho `api-key` é enviado. |
| `QDRANT_COLLECTION` | `omniroute-memory` | _(perfil de cluster opcional)_ | Nome da coleção para os embeddings de memória de conversação do OmniRoute. Criada na primeira execução com `QDRANT_VECTOR_SIZE` dimensões. |
| `QDRANT_EMBEDDING_MODEL` | `text-embedding-3-small` | _(perfil de cluster opcional)_ | Nome do modelo de embedding predefinido, registado nos metadados da coleção Qdrant. Os embeddings reais são gerados pelo fornecedor para o qual o campo `embeddingModel` nas definições do OmniRoute aponta. |
| `QDRANT_VECTOR_SIZE` | `1536` | _(perfil de cluster opt-in)_ | Dimensão do vetor de embedding. Tem de corresponder ao modelo com que faz o embedding (text-embedding-3-small → 1536; ada-002 → 1536; nomic-embed-text → 768). |
| `QDRANT_HNSW_EF_CONSTRUCT` | `128` | _(perfil de cluster opt-in)_ | Precisão em tempo de construção do índice HNSW. Valor mais alto = construção mais lenta, pesquisa mais rápida. |
| `OMNIROUTE_ROTATION_ENABLED` | `true` | `open-sse/services/rotationConfig.ts` | Interruptor principal para a rotação de contas configurável pelo operador. Quando `false`, nenhuma das classes `OMNIROUTE_ROTATE_*` abaixo aciona a alternância de conta (o estado principal desligado também bloqueia as classes 429/500/502 ativadas por predefinição). Permite que um front-end supervisor (p. ex. a aplicação de desktop VibeProxy) replique as suas próprias regras de rotação no motor de alternância de contas do backend. |
| `OMNIROUTE_ROTATION_RATE_LIMIT_RESET_SECONDS` | `0` | `open-sse/services/rotationConfig.ts` | Cooldown (segundos) aplicado a uma conta limitada por taxa quando o upstream não fornece uma indicação explícita de reposição. `0` = usar o cooldown predefinido do motor em vez de uma substituição fixa. |
| `OMNIROUTE_ROTATION_DISABLE_TAG_WITHOUT_RESET` | `true` | `open-sse/services/rotationConfig.ts` | Espelho da preferência do front-end "não marcar como limitada por taxa sem um tempo de reposição". |
| `OMNIROUTE_ROTATE_ON_429` | `true` | `open-sse/services/rotationConfig.ts` | Ativação da alternância por código de estado para erros `429`. Quando `false` (e `OMNIROUTE_ROTATION_ENABLED=true`), um `429` deixa de acionar a rotação de conta e é devolvido ao cliente. |
| `OMNIROUTE_ROTATE_429_THRESHOLD` | `1` | `open-sse/services/rotationConfig.ts` | Número de erros `429` dentro de `OMNIROUTE_ROTATE_429_WINDOW_SECONDS` necessários antes de a conta ser rodada. `1` (predefinição) roda imediatamente, preservando o comportamento histórico. |
| `OMNIROUTE_ROTATE_429_WINDOW_SECONDS` | `120` | `open-sse/services/rotationConfig.ts` | Janela deslizante (segundos) durante a qual os erros `429` são contabilizados para `OMNIROUTE_ROTATE_429_THRESHOLD`. |
| `OMNIROUTE_ROTATE_ON_500` | `true` | `open-sse/services/rotationConfig.ts` | Ativação da alternância por código de estado para erros de servidor `5xx` (excluindo `502`, que tem a sua própria classe). Quando `false`, estes erros deixam de acionar a rotação de conta. |
| `OMNIROUTE_ROTATE_500_THRESHOLD` | `1` | `open-sse/services/rotationConfig.ts` | Número de erros `5xx` dentro de `OMNIROUTE_ROTATE_500_WINDOW_SECONDS` necessários antes de a conta ser rodada. `1` (predefinição) roda imediatamente. |
| `OMNIROUTE_ROTATE_500_WINDOW_SECONDS` | `120` | `open-sse/services/rotationConfig.ts` | Janela deslizante (segundos) durante a qual os erros `5xx` são contabilizados para `OMNIROUTE_ROTATE_500_THRESHOLD`. |
| `OMNIROUTE_ROTATE_ON_502` | `true` | `open-sse/services/rotationConfig.ts` | Ativação de fallback por código de estado para erros `502` (bad gateway). Quando `false`, os erros `502` deixam de acionar a rotação de contas. |
| `OMNIROUTE_ROTATE_502_THRESHOLD` | `1` | `open-sse/services/rotationConfig.ts` | Número de erros `502` dentro de `OMNIROUTE_ROTATE_502_WINDOW_SECONDS` necessário antes de a conta ser rodada. `1` (predefinição) roda imediatamente. |
| `OMNIROUTE_ROTATE_502_WINDOW_SECONDS` | `120` | `open-sse/services/rotationConfig.ts` | Janela deslizante (segundos) durante a qual os erros `502` são contabilizados para `OMNIROUTE_ROTATE_502_THRESHOLD`. |
| `OMNIROUTE_ROTATE_ON_400` | `false` | `open-sse/services/rotationConfig.ts` | Opt-in (predefinição: DESLIGADO): quando `true`, um `400` simples (bad request) também aciona a rotação de contas. Isto é apenas aditivo — nunca bloqueia o comportamento existente do motor, em que um `400` com texto de rate limit/quota continua a fazer failover independentemente desta flag. |
| `OMNIROUTE_ROTATE_400_THRESHOLD` | `1` | `open-sse/services/rotationConfig.ts` | Número de erros `400` dentro de `OMNIROUTE_ROTATE_400_WINDOW_SECONDS` necessário antes de a conta ser rodada (consultado apenas quando `OMNIROUTE_ROTATE_ON_400=true`). |
| `OMNIROUTE_ROTATE_400_WINDOW_SECONDS` | `120` | `open-sse/services/rotationConfig.ts` | Janela deslizante (segundos) durante a qual os erros `400` são contabilizados para `OMNIROUTE_ROTATE_400_THRESHOLD`. |
### Agendador de Aquecimento do Claude
Aquecimento controlado por cron para ligações Anthropic OAuth com opt-in, para que a janela de rate limit de 5 horas seja aberta por um simples pedido agendado em vez de o ser pelo primeiro pedido real (#8848). O agendador está desligado, a menos que `OMNIROUTE_WARMUP_ENABLED` seja truthy **e** a ligação esteja assinalada em `settings.claudeWarmup.connections`; uma lista de ligações vazia significa que nada é aquecido, mesmo com a variável de ambiente ativa.
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ------------------------------ | ---------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_WARMUP_ENABLED` | _(não definido → desligado)_ | `src/lib/warmupScheduler.ts` | Interruptor principal do agendador de warmup. Aceita `1`/`true`/`yes`/`on` (insensível a maiúsculas/minúsculas, com espaços removidos). Qualquer outro valor, ou não definido, deixa o agendador desligado. |
| `OMNIROUTE_WARMUP_CRON` | `0 7 * * *` | `src/lib/warmupScheduler.ts` | Expressão cron de cinco campos para o tick de warmup, avaliada em `America/Los_Angeles` (o fuso horário de reposição da Anthropic), independentemente do relógio do anfitrião. |
| `OMNIROUTE_WARMUP_CONCURRENCY` | `3` | `src/lib/warmupScheduler.ts` | Quantas ligações são aquecidas em paralelo por tick. Limitado a `1`-`10`; um valor não numérico recorre a `3`. |
| `OMNIROUTE_WARMUP_MODEL` | `claude-3-5-haiku-20241022` | `src/lib/warmupScheduler.ts` | Modelo usado para o pedido de warmup. Substitua apenas se a predefinição não estiver disponível no seu plano; escolha o modelo mais barato que ainda abra a janela. |
### Sessões VNC de Início de Sessão no Navegador e Alias de Data-Dir
Chromium+VNC em contentor usado para a captura interativa de credenciais de início de sessão no navegador (`/api/vnc-session`), mais um alias legado de `DATA_DIR`. Todas opcionais — as predefinições de VNC destinam-se à imagem incluída `omniroute-vnc-chromium:local` e só são substituídas para uma imagem de contentor personalizada, portas ou afinação do ciclo de vida.
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_VNC_IMAGE` | `omniroute-vnc-chromium:local` | `src/lib/vncSession/manifest.ts` | Tag da imagem Docker para o contentor de login Chromium+VNC. Compile `docker/vnc-browser/chromium` ou aponte esta variável para uma imagem personalizada. |
| `OMNIROUTE_DOCKER_BIN` | `docker` | `src/lib/vncSession/manifest.ts` | Binário do runtime de contentores usado para iniciar o contentor VNC (por exemplo, defina como `podman`). |
| `OMNIROUTE_VNC_CONTAINER_VNC_PORT` | `3000` | `src/lib/vncSession/manifest.ts` | Porta VNC/noVNC exposta dentro do contentor. |
| `OMNIROUTE_VNC_CONTAINER_CDP_PORT` | `9223` | `src/lib/vncSession/manifest.ts` | Porta do Chrome DevTools Protocol dentro do contentor. |
| `OMNIROUTE_VNC_CONTAINER_PROFILE_DIR` | `/config` | `src/lib/vncSession/manifest.ts` | Caminho do diretório de perfil do Chromium dentro do contentor. |
| `OMNIROUTE_VNC_PROFILE_DIR` | `$HOME/.omniroute/browser-login-profiles` | `src/lib/vncSession/manifest.ts` | Diretório do anfitrião que contém os perfis persistentes de início de sessão no navegador. |
| `OMNIROUTE_VNC_IDLE_MS` | `600000` (10 min) | `src/lib/vncSession/manifest.ts` | Tempo limite de inatividade (ms) antes de uma sessão VNC inativa ser terminada. |
| `OMNIROUTE_VNC_MAX_MS` | `1800000` (30 min) | `src/lib/vncSession/manifest.ts` | Limite máximo absoluto (ms) da duração de uma única sessão VNC. |
| `OMNIROUTE_VNC_MAX_SESSIONS` | `4` | `src/lib/vncSession/manifest.ts` | Número máximo de sessões VNC simultâneas. |
| `OMNIROUTE_VNC_READY_MS` | `45000` | `src/lib/vncSession/manifest.ts` | Tempo limite (ms) à espera de que o navegador em contentor fique pronto para CDP. |
| `OMNIROUTE_VNC_HARVEST_MS` | `20000` | `src/lib/vncSession/manifest.ts` | Tempo limite (ms) para a recolha da sessão/cookies capturados após a conclusão do início de sessão. |
| `OMNIROUTE_VNC_CHROMIUM_ARGS` | `--remote-debugging-port=9222 --no-first-run --no-default-browser-check` | `src/lib/vncSession/manifest.ts` | Flags adicionais de linha de comandos passadas ao Chromium em contentor. |
| `OMNIROUTE_VNC_NETWORK` | `omniroute-vnc-browser-login` | `src/lib/vncSession/manifest.ts` | Rede Docker dedicada a que o contentor de login VNC se junta (#12571) em vez da bridge predefinida, para que contentores irmãos não consigam alcançar a sua porta bridge CDP. |
| `VIBEPROXY_DATA_DIR` | _(não definido)_ | `open-sse/services/notionThreadSessions.ts` | **Alias legado** de `DATA_DIR`, verificado apenas quando `DATA_DIR` e `OMNIROUTE_DATA_DIR` não estão definidos. Localiza a cache de sessões de threads web do Notion (`/notion-web-thread-sessions.json`). |
---
## 26. Arnês de Testes & E2E
Utilizado por `scripts/dev/run-next-playwright.mjs`, `scripts/dev/smoke-electron-packaged.mjs`,
`scripts/dev/run-ecosystem-tests.mjs` e `scripts/build/uninstall.mjs`. Deixe todos os
valores abaixo indefinidos em implementações de produção.
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| -------------------------------------- | ------------------------------ | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `OMNIROUTE_E2E_BOOTSTRAP_MODE` | `auth` | `scripts/dev/run-next-playwright.mjs` | Modo de arranque E2E (`auth`, `fresh`, `reuse`) para o executor Playwright. |
| `OMNIROUTE_E2E_PASSWORD` | recorre a `INITIAL_PASSWORD` | `scripts/dev/run-next-playwright.mjs` | Palavra-passe de administrador injetada no ambiente Playwright. |
| `OMNIROUTE_DISABLE_LOCAL_HEALTHCHECK` | `true` | `scripts/dev/run-next-playwright.mjs` | Desativar a verificação de saúde local (healthcheck) durante as execuções do Playwright. |
| `OMNIROUTE_DISABLE_TOKEN_HEALTHCHECK` | `true` | `scripts/dev/run-next-playwright.mjs` | Desativar o ciclo de verificação de saúde dos tokens OAuth durante os testes. |
| `OMNIROUTE_HEALTHCHECK_SKIP_PROVIDERS` | _(indefinido)_ | `src/lib/tokenHealthCheck.ts` | Fornecedores separados por vírgulas excluídos da varredura proativa de renovação de tokens (ex.: `codex,openai`). Alternativa direcionada à desativação total do healthcheck — os fornecedores com TTL curto continuam a renovar enquanto os fornecedores em cascata permanecem apenas reativos. |
| `OMNIROUTE_HIDE_HEALTHCHECK_LOGS` | `true` | `scripts/dev/run-next-playwright.mjs` | Silenciar o ruído do healthcheck no stdout do Playwright. |
| `OMNIROUTE_PLAYWRIGHT_SKIP_BUILD` | `0` | `scripts/dev/run-next-playwright.mjs` | Ignorar a compilação de produção do Next.js antes do arranque do Playwright (otimização de CI). |
| `OMNIROUTE_SKIP_UNINSTALL_HOOK` | `0` | `scripts/build/uninstall.mjs` | Ignorar o hook de desinstalação do OmniRoute (usado pelo CI para manter `node_modules` intacto). |
| `ECOSYSTEM_SERVER_WAIT_MS` | `180000` | `scripts/dev/run-ecosystem-tests.mjs` | Tempo de espera (ms) para o servidor ficar saudável antes de executar os testes de ecossistema/protocolo. |
| `ELECTRON_SMOKE_URL` | `http://127.0.0.1:20128/login` | `scripts/dev/smoke-electron-packaged.mjs` | URL que o arnês de smoke do Electron espera que a aplicação empacotada sirva. |
| `ELECTRON_SMOKE_TIMEOUT_MS` | `45000` | `scripts/dev/smoke-electron-packaged.mjs` | Tempo limite total (ms) antes de o arnês de smoke desistir. |
| `ELECTRON_SMOKE_SETTLE_MS` | `2000` | `scripts/dev/smoke-electron-packaged.mjs` | Janela de estabilização (ms) após o carregamento da página. |
| `ELECTRON_SMOKE_APP_EXECUTABLE` | _(auto)_ | `scripts/dev/smoke-electron-packaged.mjs` | Caminho explícito para o executável Electron empacotado. |
| `ELECTRON_SMOKE_DATA_DIR` | _(tmpdir)_ | `scripts/dev/smoke-electron-packaged.mjs` | Diretório de dados para a execução de smoke do Electron. |
| `ELECTRON_SMOKE_KEEP_DATA` | `0` | `scripts/dev/smoke-electron-packaged.mjs` | Defina `1` para preservar o diretório de dados do smoke após a execução. |
| `ELECTRON_SMOKE_STREAM_LOGS` | `0` | `scripts/dev/smoke-electron-packaged.mjs` | Defina `1` para transmitir os logs do Electron para o stdout durante a execução. |
| `ELECTRON_SMOKE_COLD_RESTART` | `0` | `scripts/dev/smoke-electron-packaged.mjs` | #7592: reinicia com o mesmo diretório de dados e verifica que o segundo arranque seleciona o driver SQLite nativo. |
| `CLI_DEVIN_BIN` | _(pesquisa no PATH)_ | `open-sse/executors/devin-cli.ts` | Substitui o caminho do binário da Devin CLI. |
### Pipeline de tradução da documentação
Utilizado por `scripts/i18n/run-translation.mjs` (o comando `npm run i18n:run`).
As seis variáveis estão indefinidas por predefinição — defina-as no `.env` apenas
em máquinas que devam poder executar o tradutor da documentação.
| Variável | Predefinição | Ficheiro de Origem | Descrição |
| ---------------------------------------- | -------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `OMNIROUTE_TRANSLATION_API_URL` | _(indefinido)_ | `scripts/i18n/run-translation.mjs` | URL base compatível com OpenAI para o backend de tradução. |
| `OMNIROUTE_TRANSLATION_API_KEY` | _(indefinido)_ | `scripts/i18n/run-translation.mjs` | Token Bearer para o backend de tradução (nunca registado em logs). |
| `OMNIROUTE_TRANSLATION_MODEL` | _(indefinido)_ | `scripts/i18n/run-translation.mjs` | ID do modelo, p. ex. `gpt-4o-mini` ou `cx/gpt-5.4-mini`. |
| `OMNIROUTE_TRANSLATION_FALLBACK_MODELS` | _(indefinido)_ | `scripts/i18n/lib/translate-backend.mjs` | Cadeia opcional de modelos separados por vírgulas, tentada por ordem quando o modelo principal falha (quota 429, 401/402, 5xx, timeout, rede); um pedido malformado (400/413/422) não é tentado novamente noutro modelo. |
| `OMNIROUTE_TRANSLATION_TIMEOUT_MS` | `60000` | `scripts/i18n/run-translation.mjs` | Timeout por pedido em milissegundos. |
| `OMNIROUTE_TRANSLATION_REASONING_EFFORT` | _(indefinido)_ | `scripts/i18n/lib/translate-backend.mjs` | Controlo opcional de raciocínio, enviado tal como está para o backend quando definido. |
| `OMNIROUTE_TRANSLATION_CONCURRENCY` | `4` | `scripts/i18n/run-translation.mjs` | Pedidos de tradução paralelos ao executar sobre múltiplos ficheiros / locales. |
---
## 27. Feed do Radar (Alojamento Próprio)
Extensão opcional controlada pela flag de funcionalidade RADAR_ENABLED (desativada por predefinição — uma flag de
funcionalidade ativada através das Definições/BD, e não uma variável de ambiente; consulte
[docs/frameworks/RADAR.md](../frameworks/RADAR.md#flag-radar_enabled-default-off)).
As primeiras quatro variáveis abaixo são substituições opcionais para um feed autoalojado ou derivado e
para os fluxos de chaves de apoiantes. A quinta, `RADAR_ADMIN_URL`, é uma ligação separada, sem valor predefinido, para o
painel de operações privado do proprietário. Consulte [docs/frameworks/RADAR.md](../frameworks/RADAR.md) para obter a documentação
completa do módulo e a respetiva
[sequência integral de ativação e configuração guiada](../frameworks/RADAR.md#end-to-end-activation-and-guided-setup).
O leitor genérico de anúncios da página inicial/registo de alterações não é configurado através de uma variável
de ambiente e não depende da flag de funcionalidade RADAR_ENABLED. Este lê apenas através de
GET o URL público de `news.json` do repositório, declarado em `src/shared/utils/releaseNotes.ts`;
os IDs de dispensa permanecem no armazenamento local do navegador.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ----------------------------- | -------------------------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `RADAR_FEED_URL` | `https://radar.omniroute.online` | `src/lib/radar/{sync,referralsSync,offersSync,intelSync}.ts` | URL base partilhado pelos feeds, assinados separadamente, de catálogo, referências, ofertas para apoiantes e Intel. Substitua-o para apontar para um serviço autoalojado ou derivado. |
| `RADAR_FEED_PUBKEY` | _(chave predefinida fixada)_ | `src/lib/radar/pinnedKeys.ts` | Chave pública Ed25519 (SPKI DER em base64 ou PEM) utilizada para verificar as assinaturas de um feed personalizado. |
| `RADAR_CONTRIBUTOR_CLAIM_URL` | `https://radar.omniroute.online/auth/github` | `src/lib/radar/links.ts` | URL aberto pelo botão "Sou colaborador" do painel (fluxo de reivindicação de chave de apoiante através do GitHub OAuth). |
| `RADAR_SUPPORTER_PLANS_URL` | `https://radar.omniroute.online/planos` | `src/lib/radar/links.ts` | URL aberto pelo botão "Apoiar o projeto" do painel (página de pagamentos/planos). |
| `RADAR_ADMIN_URL` | _(não definido)_ | `src/lib/radar/links.ts` | Ligação ao painel de operações privado, exclusiva do proprietário. HTTPS é obrigatório, exceto para um reencaminhamento SSH de loopback HTTP; valores não definidos ou inválidos não criam qualquer item de navegação. |
---
## Auditoria: Variáveis Removidas / Obsoletas
As seguintes variáveis apareciam em versões anteriores de `.env.example`, mas **não têm referências em tempo de execução** na base de código atual. Foram removidas:
| Variável | Motivo |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `STORAGE_DRIVER=sqlite` | Nunca é lida por qualquer ficheiro de código-fonte. SQLite é o único driver suportado — não é necessária qualquer seleção. |
| `INSTANCE_NAME=omniroute` | Presente em documentação/modelos de ambiente antigos, mas não utilizada em tempo de execução. Poderá regressar numa futura funcionalidade de múltiplas instâncias. |
| `SQLITE_MAX_SIZE_MB=2048` | Não é referenciada no código-fonte. O tamanho da base de dados não é limitado artificialmente. |
| `SQLITE_CLEAN_LEGACY_FILES=true` | Não é referenciada no código-fonte. A limpeza de ficheiros legados foi provavelmente removida. |
| `CLI_ROO_BIN` | Não está registada em `src/shared/services/cliRuntime.ts`. |
| `CLI_KIMI_CODING_BIN` | Não está registada em `src/shared/services/cliRuntime.ts` (o Kimi Coding utiliza OAuth, não um binário da CLI). |
| `IFLOW_OAUTH_CLIENT_ID` / `IFLOW_OAUTH_CLIENT_SECRET` | Não são referenciadas em nenhuma parte do código-fonte. |
| `CEREBRAS_API_KEY` / `COHERE_API_KEY` / `FIREWORKS_API_KEY` / `GROQ_API_KEY` / `MISTRAL_API_KEY` / `NEBIUS_API_KEY` / `PERPLEXITY_API_KEY` / `TOGETHER_API_KEY` / `XAI_API_KEY` | Removidas na v3.8.0. O runtime deixou de ler estas variáveis de ambiente — as credenciais provêm do Dashboard / `data/provider-credentials.json` / base de dados encriptada. |
| `CURSOR_PROTOBUF_DEBUG` | Removida na v3.8.0. O executor do Cursor utiliza `CURSOR_DEBUG` / `CURSOR_STREAM_DEBUG` (consulte a secção §22). |
| `CLI_COMPAT_KIRO` | Removida na v3.8.0. O Kiro está em `CLI_COMPAT_OMITTED_PROVIDER_IDS` — a respetiva opção não tem efeito. |
| `QIANFAN_API_KEY` | Removida juntamente com outros stubs de chaves de API de fornecedores não utilizados na v3.8.0. |
### Correções dos valores predefinidos
| Variável | Valor antigo em `.env.example` | Valor predefinido real no código | Correção |
| ------------------------- | ------------------------------ | -------------------------------- | -------------------------------------------------------------- |
| `APP_LOG_RETENTION_DAYS` | `90` | `7` | ✅ Valor enganador removido; `7` documentado como predefinição |
| `CALL_LOG_RETENTION_DAYS` | `90` | `7` | ✅ Valor enganador removido; `7` documentado como predefinição |
### Regeneração da configuração do OpenCode (ferramenta ad hoc)
Utilizada por `scripts/ad-hoc/regen-opencode-config.ts` para regenerar um `opencode.json`
com valores exatos de `limit.context` e `limit.output` obtidos da instância do
OmniRoute em execução. Nenhuma destas variáveis é necessária para o funcionamento normal — o script
é apenas uma ferramenta para programadores.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ------------------ | ------------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_URL` | `http://localhost:20128` | `scripts/ad-hoc/regen-opencode-config.ts` | URL base da instância do OmniRoute a consultar para `/v1/models`. |
| `OMNIROUTE_KEY` | _(não definida)_ | `scripts/ad-hoc/regen-opencode-config.ts` | Chave de API para autenticação no endpoint `/v1/models` do OmniRoute. Se não estiver definida, utiliza `OPENCODE_API_KEY`. |
| `OPENCODE_API_KEY` | _(não definida)_ | `scripts/ad-hoc/regen-opencode-config.ts` | Chave de API ao estilo do OpenCode (`sk-...`) escrita no `opencode.json` regenerado. Se não estiver definida, utiliza `OMNIROUTE_KEY`. |
### Ferramenta ad hoc de avaliação offline da compressão
Utilizada por `scripts/compression-eval/index.ts`, a CLI de avaliação offline da compressão.
Não é necessária para o funcionamento normal — destina-se apenas a ferramentas de desenvolvimento.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ---------------------------- | ------------ | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_EVAL_CREDENTIALS` | `{}` (vazio) | `scripts/compression-eval/index.ts` | Credenciais JSON fornecidas pelo operador para o fornecedor utilizado pela CLI de avaliação offline da compressão (analisadas com `JSON.parse`). Deixe por definir para uma execução de teste. |
### Sessões de navegador VNC
Utilizadas por `src/lib/vncSession/manifest.ts` para configurar sessões do Chromium sem interface gráfica baseadas em Docker para fornecedores de automatização de navegadores. Todas são opcionais — as predefinições são apresentadas abaixo.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ------------------------------------- | ------------------------------ | ------------------------------------------- | --------------------------------------------------------------------------------------- |
| `OMNIROUTE_DOCKER_BIN` | `docker` | `src/lib/vncSession/manifest.ts` | Caminho para o binário do Docker utilizado para iniciar contentores VNC. |
| `OMNIROUTE_VNC_IMAGE` | `omniroute-vnc-chromium:local` | `src/lib/vncSession/manifest.ts` | Imagem Docker para o contentor VNC do Chromium. |
| `OMNIROUTE_VNC_CHROMIUM_ARGS` | _(opções incorporadas)_ | `src/lib/vncSession/manifest.ts` | Argumentos adicionais da CLI do Chromium transmitidos ao navegador dentro do contentor. |
| `OMNIROUTE_VNC_CONTAINER_VNC_PORT` | `3000` | `src/lib/vncSession/manifest.ts` | Porta VNC dentro do contentor. |
| `OMNIROUTE_VNC_CONTAINER_CDP_PORT` | `9223` | `src/lib/vncSession/manifest.ts` | Porta do Chrome DevTools Protocol dentro do contentor. |
| `OMNIROUTE_VNC_CONTAINER_PROFILE_DIR` | `/config` | `src/lib/vncSession/manifest.ts` | Diretório do perfil dentro do contentor. |
| `OMNIROUTE_VNC_PROFILE_DIR` | _(não definida)_ | `src/lib/vncSession/manifest.ts` | Diretório no anfitrião para perfis persistentes do navegador. |
| `OMNIROUTE_VNC_IDLE_MS` | `600000` | `src/lib/vncSession/manifest.ts` | Tempo limite de inatividade (ms) antes de uma sessão VNC ser recolhida. |
| `OMNIROUTE_VNC_MAX_MS` | `1800000` | `src/lib/vncSession/manifest.ts` | Duração máxima da sessão (ms). |
| `OMNIROUTE_VNC_MAX_SESSIONS` | `4` | `src/lib/vncSession/manifest.ts` | Número máximo de sessões VNC simultâneas. |
| `OMNIROUTE_VNC_READY_MS` | `45000` | `src/lib/vncSession/manifest.ts` | Tempo limite para o navegador ficar pronto (ms). |
| `OMNIROUTE_VNC_HARVEST_MS` | `20000` | `src/lib/vncSession/manifest.ts` | Tempo limite para recolha/limpeza (ms). |
| `OMNIROUTE_VNC_NETWORK` | `omniroute-vnc-browser-login` | `src/lib/vncSession/manifest.ts` | Rede Docker dedicada à qual o contentor se liga (#12571), fora da ponte predefinida. |
| `VIBEPROXY_DATA_DIR` | _(não definida)_ | `open-sse/services/notionThreadSessions.ts` | Diretório para persistência das sessões de conversação do Notion. |
### Autenticação de serviços internos
| Variável | Predefinição | Descrição |
| --------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
| `OMNIROUTE_INTERNAL_SERVICE_TOKEN` | – | Token inline para autenticação serviço a serviço do plano de gestão. |
| `OMNIROUTE_INTERNAL_SERVICE_TOKEN_FILE` | – | Caminho para um ficheiro que contém o token de serviço interno (preferível em contentores; substitui a variável inline). |
### Estatísticas de fornecedores do OpenRouter
| Variável | Predefinição | Descrição |
| ----------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------- |
| `OPENROUTER_PROVIDER_STATS_ENABLED` | `true` | Defina como `false` para não obter estatísticas por fornecedor do OpenRouter para enriquecimento do catálogo. |
| `OPENROUTER_PROVIDER_STATS_TTL_MS` | `3600000` | TTL da cache (ms) para as estatísticas obtidas dos fornecedores do OpenRouter. |
### Associação do Redis incorporado
| Variável | Predefinição | Descrição |
| --------------------------- | ------------ | ------------------------------------------------------------------------------------ |
| `REDIS_BIND_HOST` | `127.0.0.1` | Endereço de escuta do serviço Redis incorporado. |
| `REDIS_PORT` | `6379` | Porta do serviço Redis incorporado. |
| `OMNIROUTE_REDIS_BIND_HOST` | – | Substituição específica do OmniRoute para o endereço de escuta do Redis incorporado. |
---
## 24. Adições da versão v3.8.50
Estas definições foram introduzidas após o snapshot anterior do contrato de ambiente.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ------------------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_CHAT_ADMISSION_QUEUE_MS` | `2000` | `src/shared/middleware/chatBodyAdmission.ts` | Espera máxima por uma vaga de admissão de chat pesado antes de um `503` passível de nova tentativa; uma espera curta e limitada serializa as rajadas de agentes em vez de um `503` instantâneo. `0` restaura a rejeição imediata. |
| `OMNIROUTE_CHAT_ADMISSION_MAX_QUEUED_BYTES` | `4194304` (4 MB) | `src/shared/middleware/chatBodyAdmission.ts` | Orçamento de bytes em fila para a espera de admissão: limita o total de bytes de corpo em buffer retidos em todo o processo, para que a espera não possa amplificar a heap (#4380). As esperas acima do orçamento recebem imediatamente um `503` passível de nova tentativa. |
| `OMNIROUTE_CHAT_VIRTUAL_TTL_MS` | `60000` (60 s) | `src/shared/middleware/chatBodyAdmission.ts` | No-op obsoleto desde #10110: as lanes de admissão por sessão foram removidas em favor de um único orçamento ao nível do processo. Aceite para compatibilidade de configuração; ignorado. |
| `OMNIROUTE_CHAT_VIRTUAL_MAX_SESSIONS` | `64` | `src/shared/middleware/chatBodyAdmission.ts` | No-op obsoleto desde #10110: as lanes de admissão por sessão foram removidas em favor de um único orçamento ao nível do processo. Aceite para compatibilidade de configuração; ignorado. |
| `OMNIROUTE_CHAT_VIRTUAL_LANES` | `0` (desativado) | `open-sse/services/admission/runtime.ts` | Lanes de admissão virtuais adaptativas em runtime (#9654): interruptor principal do gate adaptativo por tenant (sistema 2). Distinta das variáveis de lane por ligação obsoletas acima (TTL_MS / MAX_SESSIONS, no-ops desde #10110). Feature flag do dashboard com o mesmo nome; a variável de ambiente prevalece sobre a substituição do dashboard; requer reinício. |
| `OMNIROUTE_RUNNOW_TIMEOUT_MS` | `30000` | `src/app/api/jobs/[id]/run-now/route.ts` | Limita quanto tempo uma chamada run-now espera por um job em curso antes de iniciar a execução em fila. |
| `ADOBE_FIREFLY_BROWSER_REFRESH` | ativado | `open-sse/services/adobeFireflySession.ts` | Mantém o estado de risco do IMS e do browser atualizado através de sessões Chrome CDP com âmbito de conta; defina `0` para desativar. |
| `ADOBE_FIREFLY_SESSION_DISK` | ativado | `open-sse/services/adobeFireflySession.ts` | Persiste as sessões Adobe reparadas em `DATA_DIR`; defina `0` para estado apenas em memória. |
| `ADOBE_FIREFLY_MIN_SUBMIT_GAP_MS` | `12000` | `open-sse/services/adobeFireflySession.ts` | Espaçamento mínimo entre submissões de geração do Adobe Firefly. |
| `ADOBE_FIREFLY_BATCH_EXTRA_GAP_MS` | `15000` | `open-sse/services/adobeFireflySession.ts` | Período de pausa extra após cada terceira submissão Adobe bem-sucedida. |
| `ADOBE_FIREFLY_CHROME_HEADLESS` | `0` | `open-sse/services/adobeFireflyBrowserLogin.ts` | Modo true-headless apenas para depuração; o colligo da Adobe rejeita normalmente a sessão de risco resultante. |
| `CHROME_PATH` | deteção automática | `open-sse/executors/cloudflare-playground.ts`, `open-sse/executors/chatgpt-web-codex.ts` | Executável Chrome absoluto opcional utilizado pelos executores baseados em browser quando a deteção automática da plataforma é insuficiente. |
| `TELEGRAM_BOT_TOKEN` | _(não definido)_ | `src/lib/telegram/config.ts` | Token do BotFather que ativa o webhook de entrada e assina o `initData` do Mini App. |
| `TELEGRAM_WEBHOOK_SECRET` | _(não definido)_ | `src/lib/telegram/config.ts` | Segredo partilhado registado via `setWebhook` e verificado em relação ao cabeçalho `X-Telegram-Bot-Api-Secret-Token` em cada entrega de webhook. Necessário para o caminho do webhook; se não estiver definido, as entregas de webhook são recusadas com 503. |
| `TELEGRAM_DEFAULT_MODEL` | `auto/chat` | `src/lib/telegram/chatProxy.ts` | Modelo utilizado para as respostas de chat do Telegram. |
| `TELEGRAM_BOT_API_BASE` | `https://api.telegram.org` | `src/lib/telegram/config.ts` | Substituição do URL base da Bot API para proxies ou servidores Bot API autoalojados. |
| `TELEGRAM_WEBHOOK_TIMEOUT_MS` | `60000` | `src/lib/telegram/config.ts` | Tempo limite, em milissegundos, para as chamadas de saída da Bot API. |
| `OMNIROUTE_OPTIONAL_PACK_TAR` | `1` (ativado) | `scripts/build/optionalPackStaging.mjs` | Defina `0` para não emitir os tarballs `.tar.gz` durante a preparação dos pacotes opcionais de ML/browser para a árvore standalone do Electron (os diretórios dos pacotes e o `optional-packs.index.json` continuam a ser produzidos). Utilizado pelo workflow de lançamento para desktop para reduzir o tamanho de upload dos artefactos. |
| `GROK_SUBSCRIPTION_IMAGES_ENABLED` | `false` | `open-sse/config/imageRegistry.ts` | Ativa o registo das rotas de imagem da subscrição xAI; desativado por predefinição para que o caminho de imagem por chave de API permaneça inalterado. |
| `OMNIROUTE_API_KEY_COOLDOWN_MS` | `60000` | `open-sse/services/apiKeyRotator.ts` | Cooldown por chave, em milissegundos, quando uma resposta `429` não tem uma indicação `Retry-After` utilizável. |
| `OMNIROUTE_ESTIMATOR_CALIBRATION` | ativado | `open-sse/services/estimatorCalibration.ts` | Defina como `off`, `0` ou `false` para desativar o registo e a aplicação da calibração do estimador em memória. |
| `NEXT_MANUAL_SIG_HANDLE` | _(interno)_ | `scripts/dev/standalone-server-ws.mjs` | Substituição interna do gestor de sinais do servidor standalone; normalmente definida e limpa pelo launcher em vez de configurada pelos operadores. |
### ChatGPT Web (Codex)
Predefinições globais para o browser headless e para o túnel de ferramentas de saída. Os valores de ligação definidos no dashboard têm precedência.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| --------------------------------------- | ------------------------------ | -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CHATGPT_WEB_CODEX_CHROME_PATH` | _(deteção automática)_ | `open-sse/executors/chatgpt-web-codex.ts` | Caminho explícito do Chrome/Chromium para operação com npm, systemd e PM2. |
| `CHROME_PATH` | _(deteção automática)_ | `open-sse/executors/chatgpt-web-codex.ts` | Fallback partilhado para um caminho explícito do Chrome/Chromium. |
| `CHATGPT_WEB_CODEX_CDP_URL` | _(não definido)_ | `open-sse/executors/chatgpt-web-codex.ts` | Endpoint CDP interno; o Docker utiliza o sidecar na porta `9223`. |
| `CHATGPT_WEB_CODEX_USE_CDP_PROFILE` | _(não definido — desativado)_ | `open-sse/vendor/codex-chatgpt-web/persistent-cdp-context.ts` | Defina como `1` (com um endpoint CDP configurado) para reutilizar a página ChatGPT existente do perfil de navegador com sessão iniciada e gerido externamente, em vez de um contexto isolado por turno; também limita os separadores ChatGPT simultâneos a 1. Desativado por predefinição. Consulte [perfil CDP persistente](../guides/CHATGPT-WEB-PERSISTENT-CDP.md). |
| `CDP_PROXY_TOKEN` | _(não definido)_ | `docker/chatgpt-web-codex-browser/cdp-proxy.mjs` | Quando definido, cada pedido ao sidecar do proxy CDP tem de enviar este valor no cabeçalho `X-Omni-Cdp-Token` (#13679). Sem valor, o proxy reencaminha sem autenticação — nesse caso, apenas o isolamento de rede da rede Compose `chatgpt-web-codex-net` protege. Gerar com `openssl rand -hex 32`. |
| `CHATGPT_WEB_CODEX_TUNNEL_ID` | _(não definido)_ | `open-sse/executors/chatgpt-web-codex.ts` | ID de túnel OpenAI global para rondas locais de ferramentas Codex. |
| `CHATGPT_WEB_CODEX_RUNTIME_KEY` | _(não definido)_ | `open-sse/executors/chatgpt-web-codex.ts` | Chave de runtime do túnel global; nunca registar em logs. |
| `CHATGPT_WEB_CODEX_CONNECTOR_NAME` | `OmniRoute Codex v2` | `open-sse/executors/chatgpt-web-codex.ts` | Nome exato do conector personalizado ChatGPT recém-criado para a ponte MCP. |
| `CODEX_CHATGPT_WEB_HOME` | `/chatgpt-web-codex` | `open-sse/vendor/codex-chatgpt-web/config.ts` | Diretório dedicado para o estado do navegador, do broker e do túnel. |
| `CODEX_CHATGPT_WEB_BROWSER_DIAGNOSTICS` | `0` | `open-sse/vendor/codex-chatgpt-web/adapters/chatgpt-web/browser-worker.ts` | Com `1`, são capturadas imagens de diagnóstico do navegador em cada checkpoint. |
| `CODEX_CHATGPT_WEB_LAUNCHER` | _(não definido)_ | `open-sse/vendor/codex-chatgpt-web/config.ts` | Caminho absoluto opcional para um binário de launcher permanente. |
| `CODEX_CHATGPT_WEB_BUN` | _(deteção automática)_ | `open-sse/vendor/codex-chatgpt-web/config.ts` | Caminho absoluto opcional para o binário do runtime Bun. |
| `CODEX_WEB_GPT_BUN` | _(não definido)_ | `open-sse/vendor/codex-chatgpt-web/config.ts` | Fallback legado para `CODEX_CHATGPT_WEB_BUN`; as novas configurações utilizam o nome canónico. |
---
## OmniConductor Bridge
Consumidor SSE de longa duração que espelha as tarefas do hub OmniConductor para o TaskManager A2A local (`src/lib/conductor/`). Opt-in — a bridge só inicia quando `CONDUCTOR_HUB_URL` está definida. Apenas no lado do servidor: o token do hub nunca deve chegar ao browser.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ------------------------------ | ----------------------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `CONDUCTOR_HUB_URL` | _(vazio)_ | `src/lib/conductor/boot.ts` | URL base do hub OmniConductor (ex.: `http://127.0.0.1:7910`). Não definido = bridge desativada. |
| `CONDUCTOR_HUB_TOKEN` | _(vazio)_ | `src/lib/conductor/boot.ts` | Credencial do hub para o feed SSE — emite um peer do tipo `spokesperson` no hub (`POST /v1/peers`, admin). |
| `CONDUCTOR_ORCHESTRATOR_TOKEN` | _(vazio)_ | `src/lib/conductor/hubProxy.ts` | Credencial para a delegação de tarefas A2A→hub recebidas (`POST /v1/tasks`); recorre a `CONDUCTOR_HUB_TOKEN` quando não definida. |
| `CONDUCTOR_SPOKESPERSON_URL` | `http://127.0.0.1:7920` | `src/lib/conductor/faroProxy.ts` | URL base do serviço spokesperson (Faro) por trás do proxy de chat do dashboard (`/api/conductor/ask`). |
### Agendamento sensível a quotas
Utilizado por `open-sse/services/combo.ts` e `src/lib/quota/quotaScheduler.ts` para verificações do orçamento de tokens antes do pedido. Opt-in — o comportamento de encaminhamento predefinido permanece inalterado quando não definido.
| Variável | Predefinição | Ficheiro de origem | Descrição |
| ---------------------------------- | ------------ | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_QUOTA_AWARE_ROUTING` | `0` | `open-sse/services/combo.ts` | Quando `1`, ignora as ligações cujo orçamento de tokens por janela (`rateLimitOverrides.tpm`, tabela `provider_quota_state`) não consegue cobrir o custo estimado do pedido antes do envio. Fail-open quando não está configurado nenhum orçamento. |
| `OMNIROUTE_ESTIMATOR_CALIBRATION` | _(ligado)_ | `open-sse/services/estimatorCalibration.ts` | Calibração por feedback do estimador de tokens do context-guard (#14931): EMA por (fornecedor, modelo, ferramentas presentes) de `usage.prompt_tokens` / estimativa, limitada a 0.15–2.0, apenas em memória. `off`, `0` ou `false` desativa o registo e a aplicação. |
| `GROK_SUBSCRIPTION_IMAGES_ENABLED` | `false` | `open-sse/config/imageRegistry.ts` | Regista as rotas de imagem `xai-oauth` (`xao`) e `grok-cli`. Feature flag do dashboard com o mesmo nome; um override na base de dados tem precedência sobre este valor. |