diff --git a/.i18n-state.json b/.i18n-state.json new file mode 100644 index 0000000000..de42539510 --- /dev/null +++ b/.i18n-state.json @@ -0,0 +1,24 @@ +{ + "sources": { + "CLAUDE.md": { + "source_hash": "ee7af1716a6e22feb93bb160f8b2810fa7dce8f56075b218ced51b04863f1786", + "locales": { + "pt-BR": { + "source_hash": "ee7af1716a6e22feb93bb160f8b2810fa7dce8f56075b218ced51b04863f1786", + "target_hash": "7a85c5795d376e8572598f9d963e32ec62f925b952b61b60c78fa42785836014", + "updated_at": "2026-05-13T20:02:23.088Z" + } + } + }, + "docs/architecture/ARCHITECTURE.md": { + "source_hash": "573ccfe1a49d74999101460a3ee055bd07109c832d15dc9a4c6ef61ee8433302", + "locales": { + "pt-BR": { + "source_hash": "573ccfe1a49d74999101460a3ee055bd07109c832d15dc9a4c6ef61ee8433302", + "target_hash": "6daa8b7db866dd2781efd9ae02a576cf9f2cce2a8597b02a808c341e1d1335c3", + "updated_at": "2026-05-13T20:09:25.192Z" + } + } + } + } +} diff --git a/docs/guides/I18N.md b/docs/guides/I18N.md index db85d72746..96fe1902ae 100644 --- a/docs/guides/I18N.md +++ b/docs/guides/I18N.md @@ -4,16 +4,74 @@ OmniRoute supports **30 languages** with full dashboard UI translation, translat 🌐 **Languages:** 🇺🇸 [English](./I18N.md) | 🇧🇷 [Português (Brasil)](./pt-BR/I18N.md) | 🇪🇸 [Español](./es/I18N.md) | 🇫🇷 [Français](./fr/I18N.md) | 🇩🇪 [Deutsch](./de/I18N.md) | 🇮🇹 [Italiano](./it/I18N.md) | 🇷🇺 [Русский](./ru/I18N.md) | 🇨🇳 [中文 (简体)](./zh-CN/I18N.md) | 🇯🇵 [日本語](./ja/I18N.md) | 🇰🇷 [한국어](./ko/I18N.md) | 🇸🇦 [العربية](./ar/I18N.md) | 🇮🇳 [हिन्दी](./hi/I18N.md) | 🇹🇭 [ไทย](./th/I18N.md) | 🇹🇷 [Türkçe](./tr/I18N.md) | 🇺🇦 [Українська](./uk-UA/I18N.md) | 🇻🇳 [Tiếng Việt](./vi/I18N.md) | 🇧🇬 [Български](./bg/I18N.md) | 🇩🇰 [Dansk](./da/I18N.md) | 🇫🇮 [Suomi](./fi/I18N.md) | 🇮🇱 [עברית](./he/I18N.md) | 🇭🇺 [Magyar](./hu/I18N.md) | 🇮🇩 [Bahasa Indonesia](./id/I18N.md) | 🇲🇾 [Bahasa Melayu](./ms/I18N.md) | 🇳🇱 [Nederlands](./nl/I18N.md) | 🇳🇴 [Norsk](./no/I18N.md) | 🇵🇹 [Português (Portugal)](./pt/I18N.md) | 🇷🇴 [Română](./ro/I18N.md) | 🇵🇱 [Polski](./pl/I18N.md) | 🇸🇰 [Slovenčina](./sk/I18N.md) | 🇸🇪 [Svenska](./sv/I18N.md) | 🇵🇭 [Filipino](./phi/I18N.md) | 🇨🇿 [Čeština](./cs/I18N.md) +## Translation pipeline (recommended — v3.8.0) + +OmniRoute uses a hash-based incremental translator for docs, backed by an +OpenAI-compatible LLM endpoint (typically `cx/gpt-5.4-mini` through OmniRoute +Cloud): + +```bash +# Run translations (incremental — only touches changed sources) +npm run i18n:run + +# Limit to one locale +npm run i18n:run -- --locale=pt-BR + +# Specific files (comma-separated, repo-relative paths) +npm run i18n:run -- --files=CLAUDE.md,docs/architecture/ARCHITECTURE.md + +# Force retranslate everything (expensive) +npm run i18n:run -- --force + +# Preview what would happen (no API calls, no writes) +npm run i18n:run:dry + +# CI gate — exits non-zero if state is drifting +npm run i18n:check +``` + +**Source of truth.** `config/i18n.json` lists every locale (UI + docs) plus +the RTL set and the `docsExcluded` codes. The runtime config in +`src/i18n/config.ts` is a thin adapter over that JSON. + +**Backend.** Configured via env (set in `.env`, never committed): + +| Variable | Purpose | +| ----------------------------------- | --------------------------------------- | +| `OMNIROUTE_TRANSLATION_API_URL` | OpenAI-compatible base URL, e.g. `…/v1` | +| `OMNIROUTE_TRANSLATION_API_KEY` | bearer token (kept out of logs) | +| `OMNIROUTE_TRANSLATION_MODEL` | model id, e.g. `cx/gpt-5.4-mini` | +| `OMNIROUTE_TRANSLATION_TIMEOUT_MS` | optional, default `60000` | +| `OMNIROUTE_TRANSLATION_CONCURRENCY` | optional, default `4` | + +**State tracking.** `.i18n-state.json` (committed) keeps SHA-256 hashes per +source + per locale. Drift detection is automatic and deterministic — no API +calls in `i18n:check`. + +**Output shape.** Each translated file gets a top-level `# +()` line, a `🌐 Languages: …` bar, an `---` separator, and the +translated body. That layout matches what `scripts/check/check-docs-sync.mjs` +already enforces for `llm.txt` and `CHANGELOG.md` mirrors. + +### Legacy scripts (deprecated) + +The older Python script (`scripts/i18n/i18n_autotranslate.py`) and the +Google-Translate-backed generator (`scripts/i18n/generate-multilang.mjs`) +still exist with a deprecation banner. They will be removed in v3.10. The +`messages` and `readme` modes of `generate-multilang.mjs` (UI strings + root +README variants) are not yet handled by the new pipeline and are still used. + ## Quick Reference -| Task | Command | -| ---------------------- | -------------------------------------------------------------------------------------------- | -| Generate translations | `node scripts/i18n/generate-multilang.mjs messages` | -| Translate docs (LLM) | `python3 scripts/i18n/i18n_autotranslate.py --api-url --api-key --model ` | -| Validate a locale | `python3 scripts/i18n/validate_translation.py quick -l cs` | -| Check code keys | `python3 scripts/i18n/check_translations.py` | -| Generate QA report | `node scripts/i18n/generate-qa-checklist.mjs` | -| Visual QA (Playwright) | `node scripts/i18n/run-visual-qa.mjs` | +| Task | Command | +| ----------------------- | ---------------------------------------------------------- | +| Translate docs (LLM) | `npm run i18n:run` (preferred — incremental, hash-based) | +| Translate UI strings | `node scripts/i18n/generate-multilang.mjs messages` | +| Check translation drift | `npm run i18n:check` | +| Validate a locale | `python3 scripts/i18n/validate_translation.py quick -l cs` | +| Check code keys | `python3 scripts/i18n/check_translations.py` | +| Generate QA report | `node scripts/i18n/generate-qa-checklist.mjs` | +| Visual QA (Playwright) | `node scripts/i18n/run-visual-qa.mjs` | ## Architecture diff --git a/docs/i18n/pt-BR/CLAUDE.md b/docs/i18n/pt-BR/CLAUDE.md index 0d33427f74..be71772ef1 100644 --- a/docs/i18n/pt-BR/CLAUDE.md +++ b/docs/i18n/pt-BR/CLAUDE.md @@ -1,233 +1,401 @@ -# CLAUDE.md — AI Agent Session Bootstrap (Português (Brasil)) +# CLAUDE.md (Português (Brasil)) -🌐 **Languages:** 🇺🇸 [English](../../../CLAUDE.md) · 🇸🇦 [ar](../ar/CLAUDE.md) · 🇧🇬 [bg](../bg/CLAUDE.md) · 🇧🇩 [bn](../bn/CLAUDE.md) · 🇨🇿 [cs](../cs/CLAUDE.md) · 🇩🇰 [da](../da/CLAUDE.md) · 🇩🇪 [de](../de/CLAUDE.md) · 🇪🇸 [es](../es/CLAUDE.md) · 🇮🇷 [fa](../fa/CLAUDE.md) · 🇫🇮 [fi](../fi/CLAUDE.md) · 🇫🇷 [fr](../fr/CLAUDE.md) · 🇮🇳 [gu](../gu/CLAUDE.md) · 🇮🇱 [he](../he/CLAUDE.md) · 🇮🇳 [hi](../hi/CLAUDE.md) · 🇭🇺 [hu](../hu/CLAUDE.md) · 🇮🇩 [id](../id/CLAUDE.md) · 🇮🇹 [it](../it/CLAUDE.md) · 🇯🇵 [ja](../ja/CLAUDE.md) · 🇰🇷 [ko](../ko/CLAUDE.md) · 🇮🇳 [mr](../mr/CLAUDE.md) · 🇲🇾 [ms](../ms/CLAUDE.md) · 🇳🇱 [nl](../nl/CLAUDE.md) · 🇳🇴 [no](../no/CLAUDE.md) · 🇵🇭 [phi](../phi/CLAUDE.md) · 🇵🇱 [pl](../pl/CLAUDE.md) · 🇵🇹 [pt](../pt/CLAUDE.md) · 🇧🇷 [pt-BR](../pt-BR/CLAUDE.md) · 🇷🇴 [ro](../ro/CLAUDE.md) · 🇷🇺 [ru](../ru/CLAUDE.md) · 🇸🇰 [sk](../sk/CLAUDE.md) · 🇸🇪 [sv](../sv/CLAUDE.md) · 🇰🇪 [sw](../sw/CLAUDE.md) · 🇮🇳 [ta](../ta/CLAUDE.md) · 🇮🇳 [te](../te/CLAUDE.md) · 🇹🇭 [th](../th/CLAUDE.md) · 🇹🇷 [tr](../tr/CLAUDE.md) · 🇺🇦 [uk-UA](../uk-UA/CLAUDE.md) · 🇵🇰 [ur](../ur/CLAUDE.md) · 🇻🇳 [vi](../vi/CLAUDE.md) · 🇨🇳 [zh-CN](../zh-CN/CLAUDE.md) +🌐 **Languages:** 🇺🇸 [English](../../../CLAUDE.md) · 🇸🇦 [ar](../ar/CLAUDE.md) · 🇧🇬 [bg](../bg/CLAUDE.md) · 🇧🇩 [bn](../bn/CLAUDE.md) · 🇨🇿 [cs](../cs/CLAUDE.md) · 🇩🇰 [da](../da/CLAUDE.md) · 🇩🇪 [de](../de/CLAUDE.md) · 🇪🇸 [es](../es/CLAUDE.md) · 🇮🇷 [fa](../fa/CLAUDE.md) · 🇫🇮 [fi](../fi/CLAUDE.md) · 🇫🇷 [fr](../fr/CLAUDE.md) · 🇮🇳 [gu](../gu/CLAUDE.md) · 🇮🇱 [he](../he/CLAUDE.md) · 🇮🇳 [hi](../hi/CLAUDE.md) · 🇭🇺 [hu](../hu/CLAUDE.md) · 🇮🇩 [id](../id/CLAUDE.md) · 🇮🇩 [in](../in/CLAUDE.md) · 🇮🇹 [it](../it/CLAUDE.md) · 🇯🇵 [ja](../ja/CLAUDE.md) · 🇰🇷 [ko](../ko/CLAUDE.md) · 🇮🇳 [mr](../mr/CLAUDE.md) · 🇲🇾 [ms](../ms/CLAUDE.md) · 🇳🇱 [nl](../nl/CLAUDE.md) · 🇳🇴 [no](../no/CLAUDE.md) · 🇵🇭 [phi](../phi/CLAUDE.md) · 🇵🇱 [pl](../pl/CLAUDE.md) · 🇵🇹 [pt](../pt/CLAUDE.md) · 🇷🇴 [ro](../ro/CLAUDE.md) · 🇷🇺 [ru](../ru/CLAUDE.md) · 🇸🇰 [sk](../sk/CLAUDE.md) · 🇸🇪 [sv](../sv/CLAUDE.md) · 🇰🇪 [sw](../sw/CLAUDE.md) · 🇮🇳 [ta](../ta/CLAUDE.md) · 🇮🇳 [te](../te/CLAUDE.md) · 🇹🇭 [th](../th/CLAUDE.md) · 🇹🇷 [tr](../tr/CLAUDE.md) · 🇺🇦 [uk-UA](../uk-UA/CLAUDE.md) · 🇵🇰 [ur](../ur/CLAUDE.md) · 🇻🇳 [vi](../vi/CLAUDE.md) · 🇨🇳 [zh-CN](../zh-CN/CLAUDE.md) --- -> Quick-start context for AI coding agents. For deep architecture details, see `AGENTS.md`. -> For contribution workflow, see `CONTRIBUTING.md`. +Este arquivo fornece orientações para Claude Code (claude.ai/code) ao trabalhar com código neste repositório. ## Início Rápido ```bash -npm install # Install deps (auto-generates .env from .env.example) -npm run dev # Dev server at http://localhost:20128 -npm run build # Production build (Next.js 16 standalone) -npm run lint # ESLint (0 errors expected; warnings are pre-existing) -npm run typecheck:core # TypeScript check (should be clean) -npm run typecheck:noimplicit:core # Strict check (no implicit any) -npm run test:coverage # Unit tests + coverage gate (60% min) -npm run check # lint + test combined -npm run check:cycles # Detect circular dependencies +npm install # Instalar dependências (gera automaticamente .env a partir de .env.example) +npm run dev # Servidor de desenvolvimento em http://localhost:20128 +npm run build # Build de produção (Next.js 16 standalone) +npm run lint # ESLint (0 erros esperados; avisos são pré-existentes) +npm run typecheck:core # Verificação TypeScript (deve estar limpo) +npm run typecheck:noimplicit:core # Verificação rigorosa (sem any implícito) +npm run test:coverage # Testes unitários + gate de cobertura (75/75/75/70 — declarações/líneas/funções/branches) +npm run check # lint + teste combinados +npm run check:cycles # Detectar dependências circulares ``` -### Running a Single Test +### Executando Testes ```bash -# Node.js native test runner (most tests) -node --import tsx/esm --test tests/unit/your-file.test.mjs +# Arquivo de teste único (executador de teste nativo do Node.js — a maioria dos testes) +node --import tsx/esm --test tests/unit/your-file.test.ts -# Vitest (MCP server, autoCombo, cache) +# Vitest (servidor MCP, autoCombo, cache) npm run test:vitest + +# Todas as suítes +npm run test:all ``` +Para a matriz completa de testes, veja `CONTRIBUTING.md` → "Executando Testes". Para arquitetura profunda, veja `AGENTS.md`. + --- -## Visão Geral +## Projeto em Resumo -**OmniRoute** — unified AI proxy/router. One endpoint, 100+ LLM providers, auto-fallback. +**OmniRoute** — proxy/router de IA unificado. Um endpoint, 160+ provedores de LLM, fallback automático. -| Layer | Location | Purpose | -| --------------- | ------------------------ | ------------------------------------------ | -| API Routes | `src/app/api/v1/` | Next.js App Router — entry points | -| Handlers | `open-sse/handlers/` | Request processing (chat, embeddings, etc) | -| Executors | `open-sse/executors/` | Provider-specific HTTP dispatch | -| Translators | `open-sse/translator/` | Format conversion (OpenAI↔Claude↔Gemini) | -| Services | `open-sse/services/` | Combo routing, rate limits, caching, etc | -| Database | `src/lib/db/` | SQLite domain modules (22 files) | -| Domain/Policy | `src/domain/` | Policy engine, cost rules, fallback logic | -| MCP Server | `open-sse/mcp-server/` | 25 tools, 3 transports, 10 scopes | -| A2A Server | `src/lib/a2a/` | JSON-RPC 2.0 agent protocol | -| Skills | `src/lib/skills/` | Extensible skill framework | -| Memory | `src/lib/memory/` | Persistent conversational memory | -| UI Components | `src/shared/components/` | React components (Tailwind CSS v4) | -| Provider Consts | `src/shared/constants/` | Provider registry (Zod-validated) | -| Validation | `src/shared/validation/` | Zod v4 schemas | -| Tests | `tests/` | Unit, integration, e2e, security, load | +| Camada | Localização | Propósito | +| ---------------- | ----------------------- | -------------------------------------------------------------------------------- | +| Rotas da API | `src/app/api/v1/` | Next.js App Router — pontos de entrada | +| Manipuladores | `open-sse/handlers/` | Processamento de requisições (chat, embeddings, etc) | +| Executores | `open-sse/executors/` | Dispatch HTTP específico do provedor | +| Tradutores | `open-sse/translator/` | Conversão de formato (OpenAI↔Claude↔Gemini) | +| Transformador | `open-sse/transformer/` | API de Respostas ↔ Completações de Chat | +| Serviços | `open-sse/services/` | Roteamento combinado, limites de taxa, cache, etc | +| Banco de Dados | `src/lib/db/` | Módulos de domínio SQLite (45+ arquivos, 55 migrações) | +| Domínio/Política | `src/domain/` | Motor de políticas, regras de custo, lógica de fallback | +| Servidor MCP | `open-sse/mcp-server/` | 37 ferramentas (30 base + 3 memória + 4 habilidades), 3 transportes, ~13 escopos | +| Servidor A2A | `src/lib/a2a/` | Protocolo de agente JSON-RPC 2.0 | +| Habilidades | `src/lib/skills/` | Estrutura de habilidades extensível | +| Memória | `src/lib/memory/` | Memória conversacional persistente | -### Monorepo Layout - -``` -OmniRoute/ # Root package -├── src/ # Next.js 16 app (TypeScript) -├── open-sse/ # @omniroute/open-sse workspace (streaming engine) -├── electron/ # Desktop app (Electron) -├── tests/ # All test suites -├── docs/ # Documentation -└── bin/ # CLI entry point -``` +Monorepo: `src/` (aplicativo Next.js 16), `open-sse/` (workspace do motor de streaming), `electron/` (aplicativo desktop), `tests/`, `bin/` (ponto de entrada CLI). --- -## Request Pipeline (Abbreviated) +## Pipeline de Requisições ``` -Client → /v1/chat/completions (Next.js route) - → CORS → Zod validation → auth? → policy check → prompt injection guard +Cliente → /v1/chat/completions (rota Next.js) + → CORS → validação Zod → auth? → verificação de política → proteção contra injeção de prompt → handleChatCore() [open-sse/handlers/chatCore.ts] - → cache check → rate limit → combo routing? - → resolveComboTargets() → handleSingleModel() per target + → verificação de cache → limite de taxa → roteamento combinado? + → resolveComboTargets() → handleSingleModel() por alvo → translateRequest() → getExecutor() → executor.execute() → fetch() upstream → retry w/ backoff - → response translation → SSE stream or JSON + → tradução da resposta → stream SSE ou JSON + → Se Responses API: responsesTransformer.ts TransformStream ``` +As rotas da API seguem um padrão consistente: `Rota → pré-vôo CORS → validação de corpo Zod → Autenticação opcional (extractApiKey/isValidApiKey) → aplicação de política de chave da API → delegação de manipulador (open-sse)`. Sem middleware global do Next.js — a interceptação é específica da rota. + +**Roteamento combinado** (`open-sse/services/combo.ts`): 14 estratégias (prioridade, ponderada, preenchimento-primeiro, round-robin, P2C, aleatório, menos-usado, otimizado por custo, ciente de reset, estritamente-aleatório, automático, lkgp, otimizado por contexto, retransmissão de contexto). Cada alvo chama `handleSingleModel()`, que envolve `handleChatCore()` com tratamento de erro por alvo e verificações de disjuntor. Veja `docs/routing/AUTO-COMBO.md` para a pontuação Auto-Combo de 9 fatores e `docs/architecture/RESILIENCE_GUIDE.md` para as 3 camadas de resiliência. + --- -## Key Conventions +## Estado de Execução de Resiliência -### Code Style +OmniRoute possui três mecanismos de falha temporária relacionados, mas distintos. Mantenha seu +escopo separado ao depurar o comportamento de roteamento. Veja o +[diagrama de resiliência de 3 camadas](./docs/diagrams/exported/resilience-3layers.svg) +(fonte: [docs/diagrams/resilience-3layers.mmd](./docs/diagrams/resilience-3layers.mmd)) +para um mapa rápido. -- **2 spaces**, semicolons, double quotes, 100 char width, es5 trailing commas -- **Imports**: external → internal (`@/`, `@omniroute/open-sse`) → relative -- **Naming**: files=camelCase/kebab, components=PascalCase, constants=UPPER_SNAKE +### Disjuntor de Provedor -### Database Access +**Escopo**: provedor inteiro, por exemplo, `glm`, `openai`, `anthropic`. -- **Always** go through `src/lib/db/` domain modules -- **Never** write raw SQL in routes or handlers -- **Never** add logic to `src/lib/localDb.ts` (re-export layer only) -- **Never** barrel-import from `localDb.ts` — import specific `db/` modules -- DB singleton: `getDbInstance()` from `src/lib/db/core.ts` (WAL journaling) -- Migrations: `src/lib/db/migrations/` — 21 versioned SQL files +**Propósito**: parar de enviar tráfego para um provedor que está falhando repetidamente no +nível upstream/serviço, para que um provedor não saudável não atrase cada requisição. -### Error Handling +**Implementação**: -- try/catch with specific error types, log with pino context -- Never swallow errors in SSE streams — use abort signals -- Return proper HTTP status codes (4xx/5xx) +- Classe principal: `src/shared/utils/circuitBreaker.ts` +- Fiação de gate/executação de chat: `src/sse/handlers/chatHelpers.ts`, `src/sse/handlers/chat.ts` +- API de status em tempo de execução: `src/app/api/monitoring/health/route.ts` +- Wrappers compartilhados: `open-sse/services/accountFallback.ts` +- Tabela de estado persistido: `domain_circuit_breakers` + +**Estados**: + +- `CLOSED`: tráfego normal é permitido. +- `OPEN`: provedor está temporariamente bloqueado; chamadores recebem uma resposta de circuito-aberto do provedor + ou o roteamento combinado pula para outro alvo. +- `HALF_OPEN`: o tempo limite de reset expirou; permite uma requisição de teste. Sucesso fecha o + disjuntor, falha o abre novamente. + +**Padrões** (`open-sse/config/constants.ts`): + +- Provedores OAuth: limite `3`, tempo limite de reset `60s`. +- Provedores de chave da API: limite `5`, tempo limite de reset `30s`. +- Provedores locais: limite `2`, tempo limite de reset `15s`. + +Somente estados de falha em nível de provedor devem acionar o disjuntor do provedor: + +```ts +(408, 500, 502, 503, 504); +``` + +Não acione o disjuntor do provedor inteiro para erros normais de conta/chave/modelo como a maioria +dos casos `401`, `403` ou `429`. Esses geralmente pertencem ao cooldown de conexão ou bloqueio de modelo. Um erro genérico de provedor de chave da API `403` deve ser recuperável, a menos que seja classificado +como um erro terminal de provedor/conta. + +O disjuntor usa recuperação preguiçosa, não um temporizador em segundo plano. Quando `OPEN` expira, leituras como `getStatus()`, `canExecute()`, e `getRetryAfterMs()` atualizam o estado para +`HALF_OPEN`, para que painéis e construtores de candidatos de combinação não continuem excluindo um +provedor expirado para sempre. + +### Cooldown de Conexão + +**Escopo**: uma conexão de provedor/conta/chave. + +**Propósito**: pular temporariamente uma chave/conta ruim enquanto permite que outras conexões para +o mesmo provedor continuem atendendo requisições. + +**Implementação**: + +- Caminho de escrita/atualização: `src/sse/services/auth.ts::markAccountUnavailable()` +- Seleção/filtragem de conta: `src/sse/services/auth.ts::getProviderCredentials...` +- Cálculo de cooldown: `open-sse/services/accountFallback.ts::checkFallbackError()` +- Configurações: `src/lib/resilience/settings.ts` + +Campos importantes nas conexões de provedor: + +```ts +rateLimitedUntil; +testStatus: "unavailable"; +lastError; +lastErrorType; +errorCode; +backoffLevel; +``` + +Durante a seleção de conta, uma conexão é pulada enquanto: + +```ts +new Date(rateLimitedUntil).getTime() > Date.now(); +``` + +Cooldowns também são preguiçosos: quando `rateLimitedUntil` está no passado, a conexão se torna +elegível novamente. Ao usar com sucesso, `clearAccountError()` limpa `testStatus`, +`rateLimitedUntil`, campos de erro e `backoffLevel`. + +Comportamento padrão de cooldown de conexão: + +- Cooldown base de OAuth: `5s`. +- Cooldown base de chave da API: `3s`. +- Chave da API `429` deve preferir dicas de retry upstream (`Retry-After`, cabeçalhos de reset, ou + texto de reset analisável) quando disponíveis. +- Falhas recuperáveis repetidas usam backoff exponencial: + +```ts +baseCooldownMs * 2 ** failureIndex; +``` + +O guardião anti-thundering-herd impede que falhas concorrentes na mesma conexão +estendam repetidamente o cooldown ou dobrem o incremento de `backoffLevel`. + +Estados terminais não são cooldowns. `banned`, `expired`, e `credits_exhausted` são +destinados a permanecer indisponíveis até que credenciais/configurações mudem ou um operador os redefina. +Não sobrescreva estados terminais com estado de cooldown transitório. + +### Bloqueio de Modelo + +**Escopo**: provedor + conexão + modelo. + +**Propósito**: evitar desabilitar uma conexão inteira quando apenas um modelo está indisponível ou +com limite de cota para essa conexão. + +Exemplos: + +- Provedores de cota por modelo retornando `429`. +- Provedores locais retornando `404` para um modelo ausente. +- Falhas de permissão de modo/modelo específicas do provedor, como modos Grok selecionados. + +O bloqueio de modelo vive em `open-sse/services/accountFallback.ts` e permite que a mesma +conexão continue atendendo outros modelos. + +### Orientações para Depuração + +- Se todas as chaves para um provedor forem puladas, inspecione tanto o estado do disjuntor do provedor quanto o `rateLimitedUntil`/`testStatus` de cada conexão. +- Se um provedor parecer permanentemente excluído após a janela de reset, verifique se o código + está lendo o `state` bruto em vez de usar `getStatus()`/`canExecute()`. +- Se uma chave de provedor falhar, mas outras devem funcionar, prefira o cooldown de conexão em vez + do disjuntor do provedor. +- Se apenas um modelo falhar, prefira o bloqueio de modelo em vez do cooldown de conexão. +- Se um estado deve se recuperar automaticamente, ele deve ter um timestamp futuro/tempo limite de reset e um + caminho de leitura que atualiza o estado expirado. Status permanentes requerem mudanças manuais de credenciais + ou configuração. + +## Convenções Chave + +### Estilo de Código + +- **2 espaços**, ponto e vírgula, aspas duplas, largura de 100 caracteres, vírgulas finais ES5 (aplicadas pelo lint-staged via Prettier) +- **Imports**: externo → interno (`@/`, `@omniroute/open-sse`) → relativo +- **Nomeação**: arquivos=camelCase/kebab, componentes=PascalCase, constantes=UPPER_SNAKE +- **ESLint**: `no-eval`, `no-implied-eval`, `no-new-func` = erro em todo lugar; `no-explicit-any` = aviso em `open-sse/` e `tests/` +- **TypeScript**: `strict: false`, alvo ES2022, módulo esnext, resolução bundler. Preferir tipos explícitos. + +### Banco de Dados + +- **Sempre** passe pelos módulos de domínio em `src/lib/db/` — **nunca** escreva SQL bruto em rotas ou manipuladores +- **Nunca** adicione lógica em `src/lib/localDb.ts` (apenas camada de re-exportação) +- **Nunca** faça importação em lote de `localDb.ts` — importe módulos específicos de `db/` em vez disso +- Singleton de DB: `getDbInstance()` de `src/lib/db/core.ts` (journaling WAL) +- Migrações: `src/lib/db/migrations/` — arquivos SQL versionados, idempotentes, executados em transações + +### Tratamento de Erros + +- try/catch com tipos de erro específicos, registre com contexto pino +- Nunca oculte erros em streams SSE — use sinais de abortar para limpeza +- Retorne códigos de status HTTP apropriados (4xx/5xx) ### Segurança -- **Never** commit secrets/credentials -- **Never** use `eval()`, `new Function()`, or implied eval -- Validate all inputs with Zod schemas -- Encrypt credentials at rest (AES-256-GCM) +- **Nunca** use `eval()`, `new Function()`, ou eval implícito +- Valide todas as entradas com esquemas Zod +- Criptografe credenciais em repouso (AES-256-GCM) +- Lista de negação de cabeçalhos upstream: `src/shared/constants/upstreamHeaders.ts` — mantenha a sanitização, esquemas Zod e testes unitários alinhados ao editar --- -## Common Modification Scenarios +## Cenários Comuns de Modificação -### Adding a New Provider +### Adicionando um Novo Provedor -1. Register in `src/shared/constants/providers.ts` (Zod-validated at load) -2. Add executor in `open-sse/executors/` if custom logic needed -3. Add translator in `open-sse/translator/` if non-OpenAI format -4. Add OAuth config in `src/lib/oauth/constants/oauth.ts` if OAuth-based -5. Register models in `open-sse/config/providerRegistry.ts` -6. Write tests in `tests/unit/` (registration, translation, error handling) +1. Registre em `src/shared/constants/providers.ts` (validado por Zod ao carregar) +2. Adicione executor em `open-sse/executors/` se lógica personalizada for necessária (estenda `BaseExecutor`) +3. Adicione tradutor em `open-sse/translator/` se formato não for OpenAI +4. Adicione configuração OAuth em `src/lib/oauth/constants/oauth.ts` se baseado em OAuth +5. Registre modelos em `open-sse/config/providerRegistry.ts` +6. Escreva testes em `tests/unit/` -### Adding a New API Route +### Adicionando uma Nova Rota de API -1. Create directory under `src/app/api/v1/your-route/` -2. Create `route.ts` with `GET`/`POST` handlers -3. Follow pattern: CORS → Zod body validation → optional auth → handler delegation -4. Handler goes in `open-sse/handlers/` (import from there, not inline) -5. Add tests +1. Crie diretório em `src/app/api/v1/sua-rota/` +2. Crie `route.ts` com manipuladores `GET`/`POST` +3. Siga o padrão: CORS → validação do corpo Zod → autenticação opcional → delegação de manipulador +4. O manipulador vai em `open-sse/handlers/` (importe de lá, não inline) +5. Adicione testes -### Adding a New DB Module +### Adicionando um Novo Módulo de DB -1. Create `src/lib/db/yourModule.ts` -2. Import `getDbInstance` from `./core.ts` -3. Export CRUD functions for your domain table(s) -4. Add migration in `src/lib/db/migrations/` if new tables needed -5. Re-export from `src/lib/localDb.ts` (add to the re-export list only) -6. Write tests +1. Crie `src/lib/db/seuModulo.ts` — importe `getDbInstance` de `./core.ts` +2. Exporte funções CRUD para sua(s) tabela(s) de domínio +3. Adicione migração em `src/lib/db/migrations/` se novas tabelas forem necessárias +4. Re-exporte de `src/lib/localDb.ts` (adicione apenas à lista de re-exportação) +5. Escreva testes -### Adding a New MCP Tool +### Adicionando uma Nova Ferramenta MCP -1. Add tool definition in `open-sse/mcp-server/tools/` -2. Define Zod input schema + async handler -3. Register in tool set (wired by `createMcpServer()`) -4. Assign to appropriate scope(s) -5. Write tests (tool invocation logged to `mcp_audit` table) +1. Adicione definição da ferramenta em `open-sse/mcp-server/tools/` com esquema de entrada Zod + manipulador assíncrono +2. Registre no conjunto de ferramentas (conectado por `createMcpServer()`) +3. Atribua aos escopos apropriados +4. Escreva testes (invocação da ferramenta registrada na tabela `mcp_audit`) -### Adding a New A2A Skill +### Adicionando uma Nova Habilidade A2A -1. Create skill in `src/lib/a2a/skills/` -2. Skill receives task context (messages, metadata) → returns structured result -3. Register in the DB-backed skill registry -4. Write tests +1. Crie habilidade em `src/lib/a2a/skills/` (5 já existem: smart-routing, quota-management, provider-discovery, cost-analysis, health-report) +2. A habilidade recebe contexto de tarefa (mensagens, metadados) → retorna resultado estruturado +3. Registre em `A2A_SKILL_HANDLERS` em `src/lib/a2a/taskExecution.ts` +4. Exponha em `src/app/.well-known/agent.json/route.ts` (Cartão do Agente) +5. Escreva testes em `tests/unit/` +6. Documente na tabela de habilidades em `docs/frameworks/A2A-SERVER.md` + +### Adicionando um Novo Agente de Nuvem + +1. Crie classe de agente em `src/lib/cloudAgent/agents/` estendendo `CloudAgentBase` (3 já existem: codex-cloud, devin, jules) +2. Implemente `createTask`, `getStatus`, `approvePlan`, `sendMessage`, `listSources` +3. Registre em `src/lib/cloudAgent/registry.ts` +4. Adicione tratamento de OAuth/credenciais se necessário (`src/lib/oauth/providers/`) +5. Testes + documente em `docs/frameworks/CLOUD_AGENT.md` + +### Adicionando um Novo Guardrail / Eval / Habilidade / Evento de Webhook + +- Guardrail: `src/lib/guardrails/` → docs: `docs/security/GUARDRAILS.md` +- Conjunto de Eval: `src/lib/evals/` → docs: `docs/frameworks/EVALS.md` +- Habilidade (sandbox): `src/lib/skills/` → docs: `docs/frameworks/SKILLS.md` +- Evento de Webhook: `src/lib/webhookDispatcher.ts` → docs: `docs/frameworks/WEBHOOKS.md` + +## Documentação de Referência + +Para qualquer alteração não trivial, leia primeiro a análise correspondente: + +| Área | Documento | +| --------------------------------------------------- | ----------------------------------------------------------------- | +| Navegação no repositório | `docs/architecture/REPOSITORY_MAP.md` | +| Arquitetura | `docs/architecture/ARCHITECTURE.md` | +| Referência de engenharia | `docs/architecture/CODEBASE_DOCUMENTATION.md` | +| Auto-Combo (pontuação de 9 fatores, 14 estratégias) | `docs/routing/AUTO-COMBO.md` | +| Resiliência (3 mecanismos) | `docs/architecture/RESILIENCE_GUIDE.md` | +| Repetição de raciocínio | `docs/routing/REASONING_REPLAY.md` | +| Estrutura de habilidades | `docs/frameworks/SKILLS.md` | +| Sistema de memória (FTS5 + Qdrant) | `docs/frameworks/MEMORY.md` | +| Agentes de nuvem | `docs/frameworks/CLOUD_AGENT.md` | +| Guardrails (PII / injeção / visão) | `docs/security/GUARDRAILS.md` | +| Avaliações | `docs/frameworks/EVALS.md` | +| Conformidade / auditoria | `docs/security/COMPLIANCE.md` | +| Webhooks | `docs/frameworks/WEBHOOKS.md` | +| Pipeline de autorização | `docs/architecture/AUTHZ_GUIDE.md` | +| Stealth (TLS / impressão digital) | `docs/security/STEALTH_GUIDE.md` | +| Protocolos de agente (A2A / ACP / Nuvem) | `docs/frameworks/AGENT_PROTOCOLS_GUIDE.md` | +| Servidor MCP | `docs/frameworks/MCP-SERVER.md` | +| Servidor A2A | `docs/frameworks/A2A-SERVER.md` | +| Referência de API + OpenAPI | `docs/reference/API_REFERENCE.md` + `docs/reference/openapi.yaml` | +| Catálogo de provedores (gerado automaticamente) | `docs/reference/PROVIDER_REFERENCE.md` | +| Fluxo de lançamento | `docs/ops/RELEASE_CHECKLIST.md` | --- -## Testing Cheat Sheet +## Testes -| What | Command | -| ----------------------- | ------------------------------------------------------- | -| All tests | `npm run test:all` | -| Unit tests | `npm run test:unit` | -| Single file | `node --import tsx/esm --test tests/unit/file.test.mjs` | -| Vitest (MCP, autoCombo) | `npm run test:vitest` | -| E2E (Playwright) | `npm run test:e2e` | -| Protocol E2E (MCP+A2A) | `npm run test:protocols:e2e` | -| Ecosystem | `npm run test:ecosystem` | -| Coverage gate | `npm run test:coverage` (60% min all metrics) | -| Coverage report | `npm run coverage:report` | +| O que | Comando | +| ----------------------- | ------------------------------------------------------------------------------- | +| Testes unitários | `npm run test:unit` | +| Arquivo único | `node --import tsx/esm --test tests/unit/file.test.ts` | +| Vitest (MCP, autoCombo) | `npm run test:vitest` | +| E2E (Playwright) | `npm run test:e2e` | +| Protocolo E2E (MCP+A2A) | `npm run test:protocols:e2e` | +| Ecossistema | `npm run test:ecosystem` | +| Portão de cobertura | `npm run test:coverage` (75/75/75/70 — declarações/líneas/funções/ramificações) | +| Relatório de cobertura | `npm run coverage:report` | -**PR rule**: If you change production code in `src/`, `open-sse/`, `electron/`, or `bin/`, -you must include or update tests in the same PR. +**Regra de PR**: Se você alterar o código de produção em `src/`, `open-sse/`, `electron/` ou `bin/`, você deve incluir ou atualizar testes no mesmo PR. -**Test layer preference**: unit first → integration (multi-module or DB state) → e2e (UI/workflow only). Encode bug reproductions as automated tests before or alongside the fix. +**Preferência de camada de teste**: unitário primeiro → integração (multi-módulo ou estado do DB) → e2e (somente UI/workflow). Codifique reproduções de bugs como testes automatizados antes ou junto com a correção. + +**Política de cobertura do Copilot**: Quando um PR altera o código de produção e a cobertura está abaixo de 75% (declarações/líneas/funções) ou 70% (ramificações), não apenas relate — adicione ou atualize testes, reexecute o portão de cobertura e, em seguida, peça confirmação. Inclua comandos executados, arquivos de teste alterados e o resultado final da cobertura no relatório do PR. --- -## Git Workflow +## Fluxo de Trabalho do Git ```bash -# Never commit directly to main -git checkout -b feat/your-feature -# ... make changes ... -git commit -m "feat: describe your change" -git push -u origin feat/your-feature +# Nunca faça commit diretamente no main +git checkout -b feat/sua-funcionalidade +git commit -m "feat: descreva sua alteração" +git push -u origin feat/sua-funcionalidade ``` -**Branch prefixes**: `feat/`, `fix/`, `refactor/`, `docs/`, `test/`, `chore/` +**Prefixos de branch**: `feat/`, `fix/`, `refactor/`, `docs/`, `test/`, `chore/` -**Commit format** ([Conventional Commits](https://www.conventionalcommits.org/)): +**Formato de commit** (Commits Convencionais): `feat(db): adicionar circuito de interrupção` — escopos: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills` -``` -feat: add circuit breaker for provider calls -fix: resolve JWT secret validation edge case -docs: update AGENTS.md with pipeline internals -test: add MCP tool unit tests -refactor(db): consolidate rate limit tables -``` +**Ganchos do Husky**: -**Scopes**: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, -`memory`, `skills`. +- **pre-commit**: lint-staged + `check-docs-sync` + `check:any-budget:t11` +- **pre-push**: `npm run test:unit` --- -## Environment +## Ambiente -- **Runtime**: Node.js ≥18 <24, ES Modules -- **TypeScript**: 5.9, target ES2022, module esnext, resolution bundler -- **Path aliases**: `@/*` → `src/`, `@omniroute/open-sse` → `open-sse/` -- **Default port**: 20128 (API + dashboard on same port) -- **Data directory**: `DATA_DIR` env var, defaults to `~/.omniroute/` -- **Key env vars**: `PORT`, `JWT_SECRET`, `INITIAL_PASSWORD`, `REQUIRE_API_KEY`, `APP_LOG_LEVEL` +- **Tempo de Execução**: Node.js ≥20.20.2 <21 || ≥22.22.2 <23 || ≥24 <25, Módulos ES +- **TypeScript**: 5.9+, alvo ES2022, módulo esnext, resolução bundler +- **Aliases de caminho**: `@/*` → `src/`, `@omniroute/open-sse` → `open-sse/`, `@omniroute/open-sse/*` → `open-sse/*` +- **Porta padrão**: 20128 (API + dashboard na mesma porta) +- **Diretório de dados**: variável de ambiente `DATA_DIR`, padrão para `~/.omniroute/` +- **Principais variáveis de ambiente**: `PORT`, `JWT_SECRET`, `API_KEY_SECRET`, `INITIAL_PASSWORD`, `REQUIRE_API_KEY`, `APP_LOG_LEVEL` +- Configuração: `cp .env.example .env` e então gere `JWT_SECRET` (`openssl rand -base64 48`) e `API_KEY_SECRET` (`openssl rand -hex 32`) --- -## Hard Rules (Never Violate) +## Regras Estritas -1. Never commit secrets or credentials -2. Never add logic to `localDb.ts` -3. Never use `eval()` / `new Function()` / implied eval -4. Never commit directly to `main` -5. Never write raw SQL in routes — use `src/lib/db/` modules -6. Never silently swallow errors in SSE streams -7. Always validate inputs with Zod schemas -8. Always include tests when changing production code -9. Coverage must stay ≥60% (statements, lines, functions, branches) +1. Nunca faça commit de segredos ou credenciais +2. Nunca adicione lógica ao `localDb.ts` +3. Nunca use `eval()` / `new Function()` / eval implícito +4. Nunca faça commit diretamente no `main` +5. Nunca escreva SQL bruto em rotas — use módulos `src/lib/db/` +6. Nunca silenciosamente ignore erros em streams SSE +7. Sempre valide entradas com esquemas Zod +8. Sempre inclua testes ao alterar código de produção +9. A cobertura deve permanecer ≥75% (declarações, linhas, funções) / ≥70% (ramificações). Medido atualmente: ~82%. +10. Nunca contorne ganchos do Husky (`--no-verify`, `--no-gpg-sign`) sem aprovação explícita do operador. diff --git a/docs/i18n/pt-BR/docs/architecture/ARCHITECTURE.md b/docs/i18n/pt-BR/docs/architecture/ARCHITECTURE.md index 25f8bca167..fca0451441 100644 --- a/docs/i18n/pt-BR/docs/architecture/ARCHITECTURE.md +++ b/docs/i18n/pt-BR/docs/architecture/ARCHITECTURE.md @@ -1,149 +1,185 @@ # OmniRoute Architecture (Português (Brasil)) -🌐 **Languages:** 🇺🇸 [English](../../../../docs/ARCHITECTURE.md) · 🇸🇦 [ar](../../ar/docs/ARCHITECTURE.md) · 🇧🇬 [bg](../../bg/docs/ARCHITECTURE.md) · 🇧🇩 [bn](../../bn/docs/ARCHITECTURE.md) · 🇨🇿 [cs](../../cs/docs/ARCHITECTURE.md) · 🇩🇰 [da](../../da/docs/ARCHITECTURE.md) · 🇩🇪 [de](../../de/docs/ARCHITECTURE.md) · 🇪🇸 [es](../../es/docs/ARCHITECTURE.md) · 🇮🇷 [fa](../../fa/docs/ARCHITECTURE.md) · 🇫🇮 [fi](../../fi/docs/ARCHITECTURE.md) · 🇫🇷 [fr](../../fr/docs/ARCHITECTURE.md) · 🇮🇳 [gu](../../gu/docs/ARCHITECTURE.md) · 🇮🇱 [he](../../he/docs/ARCHITECTURE.md) · 🇮🇳 [hi](../../hi/docs/ARCHITECTURE.md) · 🇭🇺 [hu](../../hu/docs/ARCHITECTURE.md) · 🇮🇩 [id](../../id/docs/ARCHITECTURE.md) · 🇮🇹 [it](../../it/docs/ARCHITECTURE.md) · 🇯🇵 [ja](../../ja/docs/ARCHITECTURE.md) · 🇰🇷 [ko](../../ko/docs/ARCHITECTURE.md) · 🇮🇳 [mr](../../mr/docs/ARCHITECTURE.md) · 🇲🇾 [ms](../../ms/docs/ARCHITECTURE.md) · 🇳🇱 [nl](../../nl/docs/ARCHITECTURE.md) · 🇳🇴 [no](../../no/docs/ARCHITECTURE.md) · 🇵🇭 [phi](../../phi/docs/ARCHITECTURE.md) · 🇵🇱 [pl](../../pl/docs/ARCHITECTURE.md) · 🇵🇹 [pt](../../pt/docs/ARCHITECTURE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/ARCHITECTURE.md) · 🇷🇴 [ro](../../ro/docs/ARCHITECTURE.md) · 🇷🇺 [ru](../../ru/docs/ARCHITECTURE.md) · 🇸🇰 [sk](../../sk/docs/ARCHITECTURE.md) · 🇸🇪 [sv](../../sv/docs/ARCHITECTURE.md) · 🇰🇪 [sw](../../sw/docs/ARCHITECTURE.md) · 🇮🇳 [ta](../../ta/docs/ARCHITECTURE.md) · 🇮🇳 [te](../../te/docs/ARCHITECTURE.md) · 🇹🇭 [th](../../th/docs/ARCHITECTURE.md) · 🇹🇷 [tr](../../tr/docs/ARCHITECTURE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/ARCHITECTURE.md) · 🇵🇰 [ur](../../ur/docs/ARCHITECTURE.md) · 🇻🇳 [vi](../../vi/docs/ARCHITECTURE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/ARCHITECTURE.md) +🌐 **Languages:** 🇺🇸 [English](../../../../architecture/ARCHITECTURE.md) · 🇸🇦 [ar](../../../ar/docs/architecture/ARCHITECTURE.md) · 🇧🇬 [bg](../../../bg/docs/architecture/ARCHITECTURE.md) · 🇧🇩 [bn](../../../bn/docs/architecture/ARCHITECTURE.md) · 🇨🇿 [cs](../../../cs/docs/architecture/ARCHITECTURE.md) · 🇩🇰 [da](../../../da/docs/architecture/ARCHITECTURE.md) · 🇩🇪 [de](../../../de/docs/architecture/ARCHITECTURE.md) · 🇪🇸 [es](../../../es/docs/architecture/ARCHITECTURE.md) · 🇮🇷 [fa](../../../fa/docs/architecture/ARCHITECTURE.md) · 🇫🇮 [fi](../../../fi/docs/architecture/ARCHITECTURE.md) · 🇫🇷 [fr](../../../fr/docs/architecture/ARCHITECTURE.md) · 🇮🇳 [gu](../../../gu/docs/architecture/ARCHITECTURE.md) · 🇮🇱 [he](../../../he/docs/architecture/ARCHITECTURE.md) · 🇮🇳 [hi](../../../hi/docs/architecture/ARCHITECTURE.md) · 🇭🇺 [hu](../../../hu/docs/architecture/ARCHITECTURE.md) · 🇮🇩 [id](../../../id/docs/architecture/ARCHITECTURE.md) · 🇮🇩 [in](../../../in/docs/architecture/ARCHITECTURE.md) · 🇮🇹 [it](../../../it/docs/architecture/ARCHITECTURE.md) · 🇯🇵 [ja](../../../ja/docs/architecture/ARCHITECTURE.md) · 🇰🇷 [ko](../../../ko/docs/architecture/ARCHITECTURE.md) · 🇮🇳 [mr](../../../mr/docs/architecture/ARCHITECTURE.md) · 🇲🇾 [ms](../../../ms/docs/architecture/ARCHITECTURE.md) · 🇳🇱 [nl](../../../nl/docs/architecture/ARCHITECTURE.md) · 🇳🇴 [no](../../../no/docs/architecture/ARCHITECTURE.md) · 🇵🇭 [phi](../../../phi/docs/architecture/ARCHITECTURE.md) · 🇵🇱 [pl](../../../pl/docs/architecture/ARCHITECTURE.md) · 🇵🇹 [pt](../../../pt/docs/architecture/ARCHITECTURE.md) · 🇷🇴 [ro](../../../ro/docs/architecture/ARCHITECTURE.md) · 🇷🇺 [ru](../../../ru/docs/architecture/ARCHITECTURE.md) · 🇸🇰 [sk](../../../sk/docs/architecture/ARCHITECTURE.md) · 🇸🇪 [sv](../../../sv/docs/architecture/ARCHITECTURE.md) · 🇰🇪 [sw](../../../sw/docs/architecture/ARCHITECTURE.md) · 🇮🇳 [ta](../../../ta/docs/architecture/ARCHITECTURE.md) · 🇮🇳 [te](../../../te/docs/architecture/ARCHITECTURE.md) · 🇹🇭 [th](../../../th/docs/architecture/ARCHITECTURE.md) · 🇹🇷 [tr](../../../tr/docs/architecture/ARCHITECTURE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/architecture/ARCHITECTURE.md) · 🇵🇰 [ur](../../../ur/docs/architecture/ARCHITECTURE.md) · 🇻🇳 [vi](../../../vi/docs/architecture/ARCHITECTURE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/architecture/ARCHITECTURE.md) --- -_Last updated: 2026-04-15_ +🌐 **Idiomas:** 🇺🇸 [English](./ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](i18n/es/ARCHITECTURE.md) | 🇫🇷 [Français](i18n/fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](i18n/it/ARCHITECTURE.md) | 🇷🇺 [Русский](i18n/ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](i18n/de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](i18n/in/ARCHITECTURE.md) | 🇹🇭 [ไทย](i18n/th/ARCHITECTURE.md) | 🇺🇦 [Українська](i18n/uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](i18n/ar/ARCHITECTURE.md) | 🇯🇵 [日本語](i18n/ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/ARCHITECTURE.md) | 🇧🇬 [Български](i18n/bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](i18n/da/ARCHITECTURE.md) | 🇫🇮 [Suomi](i18n/fi/ARCHITECTURE.md) | 🇮🇱 [עברית](i18n/he/ARCHITECTURE.md) | 🇭🇺 [Magyar](i18n/hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/ARCHITECTURE.md) | 🇰🇷 [한국어](i18n/ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](i18n/nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](i18n/no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/ARCHITECTURE.md) | 🇷🇴 [Română](i18n/ro/ARCHITECTURE.md) | 🇵🇱 [Polski](i18n/pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](i18n/sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](i18n/sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](i18n/phi/ARCHITECTURE.md) | 🇨🇿 [Čeština](i18n/cs/ARCHITECTURE.md) -## Executive Summary +_Última atualização: 2026-05-13_ -OmniRoute is a local AI routing gateway and dashboard built on Next.js. -It provides a single OpenAI-compatible endpoint (`/v1/*`) and routes traffic across multiple upstream providers with translation, fallback, token refresh, and usage tracking. +## Resumo Executivo -Core capabilities: +OmniRoute é um gateway de roteamento de IA local e um painel construído em Next.js. +Ele fornece um único endpoint compatível com OpenAI (`/v1/*`) e roteia o tráfego entre vários provedores upstream com tradução, fallback, atualização de token e rastreamento de uso. -- OpenAI-compatible API surface for CLI/tools (100+ providers, 16 executors) -- Request/response translation across provider formats -- Model combo fallback (multi-model sequence) -- Structured combo steps (`provider + model + connection`) with runtime ordering by `compositeTiers` -- Account-level fallback (multi-account per provider) -- Quota preflight and quota-aware P2C account selection in the main chat path -- OAuth + API-key provider connection management (13 OAuth modules) -- Embedding generation via `/v1/embeddings` (6 providers, 9 models) -- Image generation via `/v1/images/generations` (10+ providers, 20+ models) -- Audio transcription via `/v1/audio/transcriptions` (7 providers) -- Text-to-speech via `/v1/audio/speech` (10 providers) -- Video generation via `/v1/videos/generations` (ComfyUI + SD WebUI) -- Music generation via `/v1/music/generations` (ComfyUI) -- Web search via `/v1/search` (5 providers) -- Moderations via `/v1/moderations` -- Reranking via `/v1/rerank` -- Think tag parsing (`...`) for reasoning models -- Response sanitization for strict OpenAI SDK compatibility -- Role normalization (developer→system, system→user) for cross-provider compatibility -- Structured output conversion (json_schema → Gemini responseSchema) -- Local persistence for providers, keys, aliases, combos, settings, pricing (26 DB modules) -- Usage/cost tracking and request logging -- Optional cloud sync for multi-device/state sync -- IP allowlist/blocklist for API access control -- Thinking budget management (passthrough/auto/custom/adaptive) -- Global system prompt injection -- Session tracking and fingerprinting -- Per-account enhanced rate limiting with provider-specific profiles -- Circuit breaker pattern for provider resilience -- Anti-thundering herd protection with mutex locking -- Signature-based request deduplication cache -- Domain layer: cost rules, fallback policy, lockout policy -- Context Relay: session handoff summaries for account rotation continuity -- Domain state persistence (SQLite write-through cache for fallbacks, budgets, lockouts, circuit breakers) -- Policy engine for centralized request evaluation (lockout → budget → fallback) -- Request telemetry with p50/p95/p99 latency aggregation -- Combo target telemetry and historical combo target health via `combo_execution_key` / `combo_step_id` -- Correlation ID (X-Request-Id) for end-to-end tracing -- Compliance audit logging with opt-out per API key -- Eval framework for LLM quality assurance -- Health dashboard with real-time provider circuit breaker status -- MCP Server (25 tools) with 3 transports (stdio/SSE/Streamable HTTP) -- A2A Server (JSON-RPC 2.0 + SSE) with skills and task lifecycle -- Memory system (extraction, injection, retrieval, summarization) -- Skills system (registry, executor, sandbox, built-in skills) -- MITM proxy with certificate management and DNS handling -- Prompt injection guard middleware -- ACP (Agent Communication Protocol) registry -- Modular OAuth providers (13 individual modules under `src/lib/oauth/providers/`) -- Uninstall/full-uninstall scripts -- OAuth environment repair action -- WebSocket bridge for OpenAI-compatible WS clients (`/v1/ws`) -- Sync token management (issue/revoke, ETag-versioned config bundle download) -- GLM Thinking (`glmt`) first-class provider preset -- Hybrid token counting (provider-side `/messages/count_tokens` with estimation fallback) -- Model alias auto-seeding (30+ cross-proxy dialect normalizations at startup) -- Safe outbound fetch with SSRF guard, private URL blocking, and configurable retry -- Cooldown-aware chat retries with configurable `requestRetry` and `maxRetryIntervalSec` -- Runtime environment validation with Zod at startup -- Compliance audit v2 with pagination, provider CRUD events, and SSRF-blocked validation logging +Capacidades principais: -Primary runtime model: +- Superfície de API compatível com OpenAI para CLI/ferramentas (179 provedores, 31 executores) +- Tradução de solicitação/resposta entre formatos de provedores +- Fallback de combinação de modelos (sequência de múltiplos modelos) +- Etapas de combinação estruturadas (`provedor + modelo + conexão`) com ordenação em tempo de execução por `compositeTiers` +- Fallback em nível de conta (múltiplas contas por provedor) +- Pré-verificação de cota e seleção de conta P2C ciente da cota no caminho principal de chat +- Gerenciamento de conexão de provedor OAuth + chave de API (14 módulos OAuth) +- Geração de embeddings via `/v1/embeddings` (6 provedores, 9 modelos) +- Geração de imagens via `/v1/images/generations` (10+ provedores, 20+ modelos) +- Transcrição de áudio via `/v1/audio/transcriptions` (7 provedores) +- Texto para fala via `/v1/audio/speech` (10 provedores) +- Geração de vídeo via `/v1/videos/generations` (ComfyUI + SD WebUI) +- Geração de música via `/v1/music/generations` (ComfyUI) +- Pesquisa na web via `/v1/search` (5 provedores) +- Moderações via `/v1/moderations` +- Reclassificação via `/v1/rerank` +- Análise de tags de pensamento (``) para modelos de raciocínio +- Sanitização de resposta para compatibilidade estrita com o SDK da OpenAI +- Normalização de papéis (desenvolvedor→sistema, sistema→usuário) para compatibilidade entre provedores +- Conversão de saída estruturada (json_schema → Gemini responseSchema) +- Persistência local para provedores, chaves, aliases, combos, configurações, preços (26 módulos de DB) +- Rastreamento de uso/custo e registro de solicitações +- Sincronização em nuvem opcional para sincronização de múltiplos dispositivos/estados +- Lista de permissão/bloqueio de IP para controle de acesso à API +- Gerenciamento de orçamento de pensamento (passagem/automático/customizado/adaptativo) +- Injeção de prompt global +- Rastreamento de sessão e identificação +- Limitação de taxa aprimorada por conta com perfis específicos de provedores +- Padrão de disjuntor para resiliência do provedor +- Proteção contra rebanho de trovão com bloqueio de mutex +- Cache de deduplicação de solicitação baseado em assinatura +- Camada de domínio: regras de custo, política de fallback, política de bloqueio +- Context Relay: resumos de transferência de sessão para continuidade de rotação de conta +- Persistência de estado de domínio (cache de gravação SQLite para fallbacks, orçamentos, bloqueios, disjuntores) +- Motor de políticas para avaliação centralizada de solicitações (bloqueio → orçamento → fallback) +- Telemetria de solicitação com agregação de latência p50/p95/p99 +- Telemetria de alvo de combo e saúde histórica do alvo de combo via `combo_execution_key` / `combo_step_id` +- ID de correlação (X-Request-Id) para rastreamento de ponta a ponta +- Registro de auditoria de conformidade com opção de exclusão por chave de API +- Framework de avaliação para garantia de qualidade de LLM +- Painel de saúde com status de disjuntor de provedor em tempo real +- Servidor MCP (37 ferramentas) com 3 transportes (stdio/SSE/Streamable HTTP) +- Servidor A2A (JSON-RPC 2.0 + SSE) com habilidades e ciclo de vida de tarefas +- Sistema de memória (extração, injeção, recuperação, sumarização) +- Sistema de habilidades (registro, executor, sandbox, habilidades integradas) +- Proxy MITM com gerenciamento de certificados e manipulação de DNS +- Middleware de proteção contra injeção de prompt +- Pipeline de compressão de prompt com Caveman, RTK, pipelines empilhados, combos de compressão, pacotes de idiomas e análises +- Registro de ACP (Agent Communication Protocol) +- Provedores OAuth modulares (14 módulos individuais sob `src/lib/oauth/providers/`) +- Scripts de desinstalação/desinstalação completa +- Ação de reparo de ambiente OAuth +- Ponte WebSocket para clientes WS compatíveis com OpenAI (`/v1/ws`) +- Gerenciamento de token de sincronização (emissão/revogação, download de pacote de configuração versionado por ETag) +- Pensamento GLM (`glmt`) como preset de provedor de primeira classe +- Contagem de tokens híbrida (contagem de tokens do lado do provedor `/messages/count_tokens` com fallback de estimativa) +- Auto-semeadura de alias de modelo (30+ normalizações de dialeto cross-proxy na inicialização) +- Busca segura de saída com proteção SSRF, bloqueio de URL privada e retry configurável +- Repetições de chat cientes de cooldown com `requestRetry` e `maxRetryIntervalSec` configuráveis +- Validação do ambiente de execução com Zod na inicialização +- Auditoria de conformidade v2 com paginação, eventos CRUD de provedores e registro de validação bloqueada por SSRF -- Next.js app routes under `src/app/api/*` implement both dashboard APIs and compatibility APIs -- A shared SSE/routing core in `src/sse/*` + `open-sse/*` handles provider execution, translation, streaming, fallback, and usage +Modelo de execução principal: -## Scope and Boundaries +- Rotas de aplicativo Next.js sob `src/app/api/*` implementam tanto APIs de painel quanto APIs de compatibilidade +- Um núcleo compartilhado de SSE/roteamento em `src/sse/*` + `open-sse/*` lida com execução de provedores, tradução, streaming, fallback e uso -### In Scope +## Diagramas de Referência -- Local gateway runtime -- Dashboard management APIs -- Provider authentication and token refresh -- Request translation and SSE streaming -- Local state + usage persistence -- Optional cloud sync orchestration +Fontes canônicas e controladas por versão do Mermaid para a plataforma v3.8.0 estão disponíveis em +[`docs/diagrams/`](../diagrams/README.md). Dois são reproduzidos abaixo para orientação; +os demais estão vinculados a seus guias específicos de domínio. -### Out of Scope +![Pipeline de requisição (/v1/chat/completions)](../diagrams/exported/request-pipeline.svg) -- Cloud service implementation behind `NEXT_PUBLIC_CLOUD_URL` -- Provider SLA/control plane outside local process -- External CLI binaries themselves (Claude CLI, Codex CLI, etc.) +> Fonte: [diagrams/request-pipeline.mmd](../diagrams/request-pipeline.mmd) -## Dashboard Surface (Current) +![Modelo de resiliência em 3 camadas](../diagrams/exported/resilience-3layers.svg) -Main pages under `src/app/(dashboard)/dashboard/`: +> Fonte: [diagrams/resilience-3layers.mmd](../diagrams/resilience-3layers.mmd) — também vinculado a +> [RESILIENCE_GUIDE.md](./RESILIENCE_GUIDE.md) e à referência de resiliência `CLAUDE.md`. -- `/dashboard` — quick start + provider overview -- `/dashboard/endpoint` — endpoint proxy + MCP + A2A + API endpoint tabs -- `/dashboard/providers` — provider connections and credentials -- `/dashboard/combos` — combo strategies, templates, step-based builder, model routing rules, manual persisted ordering -- `/dashboard/costs` — cost aggregation and pricing visibility -- `/dashboard/analytics` — usage analytics, evaluations, combo target health -- `/dashboard/limits` — quota/rate controls -- `/dashboard/cli-tools` — CLI onboarding, runtime detection, config generation -- `/dashboard/agents` — detected ACP agents + custom agent registration -- `/dashboard/media` — image/video/music playground -- `/dashboard/search-tools` — search provider testing and history -- `/dashboard/health` — uptime, circuit breakers, rate limits, quota-monitored sessions -- `/dashboard/logs` — request/proxy/audit/console logs -- `/dashboard/settings` — system settings tabs (general, routing, combo defaults, etc.) -- `/dashboard/api-manager` — API key lifecycle and model permissions +## Escopo e Limites -## High-Level System Context +### Dentro do Escopo + +- Tempo de execução do gateway local +- APIs de gerenciamento do painel +- Autenticação de provedor e atualização de token +- Tradução de requisições e streaming SSE +- Persistência de estado local + uso +- Orquestração opcional de sincronização em nuvem + +### Fora do Escopo + +- Implementação de serviço em nuvem por trás de `NEXT_PUBLIC_CLOUD_URL` +- SLA do provedor/plano de controle fora do processo local +- Binaries de CLI externas (Claude CLI, Codex CLI, etc.) + +## Superfície do Painel (Atual) + +Páginas principais em `src/app/(dashboard)/dashboard/`: + +- `/dashboard` — início rápido + visão geral do provedor +- `/dashboard/endpoint` — proxy de endpoint + MCP + A2A + abas de endpoint API +- `/dashboard/providers` — conexões e credenciais do provedor +- `/dashboard/combos` — estratégias de combo, templates, construtor baseado em etapas, regras de roteamento de modelo, ordenação persistida manual +- `/dashboard/auto-combo` — Motor de Auto Combo: pesos de pontuação, pacotes de modo, predefinições de fábrica virtual, telemetria +- `/dashboard/costs` — agregação de custos e visibilidade de preços +- `/dashboard/analytics` — análises de uso, avaliações, saúde do alvo do combo +- `/dashboard/limits` — controles de cota/taxa +- `/dashboard/cli-tools` — integração de CLI, detecção de tempo de execução, geração de configuração +- `/dashboard/agents` — agentes ACP detectados + registro de agente personalizado +- `/dashboard/cloud-agents` — tarefas de agente hospedadas na nuvem (Codex Cloud, Devin, Jules) e ciclo de vida da tarefa +- `/dashboard/skills` — registro de habilidades A2A, execução em sandbox, catálogo de habilidades embutido +- `/dashboard/memory` — inspeção e recuperação de memória conversacional persistente +- `/dashboard/webhooks` — assinaturas de webhook de saída, rotação de segredos, estatísticas de tentativas +- `/dashboard/batch` — submissão de trabalhos em lote e progresso +- `/dashboard/cache` — estatísticas de cache de leitura e raciocínio, controles de expulsão +- `/dashboard/playground` — playground de chat interativo contra qualquer combo/modelo configurado +- `/dashboard/changelog` — visualizador de changelog no aplicativo (renderiza `CHANGELOG.md`) +- `/dashboard/system` — diagnósticos de tempo de execução, informações de versão, superfície de validação de ambiente +- `/dashboard/onboarding` — assistente de configuração de primeira execução para novas instalações +- `/dashboard/media` — playground de imagem/vídeo/música +- `/dashboard/search-tools` — teste de provedor de busca e histórico +- `/dashboard/health` — tempo de atividade, disjuntores, limites de taxa, sessões monitoradas por cota +- `/dashboard/logs` — logs de requisição/proxy/auditoria/console +- `/dashboard/settings` — abas de configurações do sistema (geral, roteamento, padrões de combo, etc.) +- `/dashboard/context/caveman` — regras de compressão Caveman, pacotes de idioma, visualização e modo de saída +- `/dashboard/context/rtk` — filtros de saída de comando RTK, visualização e configurações de segurança em tempo de execução +- `/dashboard/context/combos` — pipelines de compressão nomeados atribuídos a combos de roteamento +- `/dashboard/translator` — inspeção de tradutor e visualização de conversão de formato de requisição +- `/dashboard/audit` — navegador de log de auditoria de conformidade com paginação e metadados estruturados +- `/dashboard/usage` — navegador de uso por requisição vinculado a `usage_history` +- `/dashboard/compression` — análises de compressão, estatísticas e atribuição de pipeline +- `/dashboard/api-manager` — ciclo de vida da chave API e permissões de modelo + +## Contexto do Sistema em Alto Nível ```mermaid flowchart LR - subgraph Clients[Developer Clients] + subgraph Clients[Clientes Desenvolvedores] C1[Claude Code] C2[Codex CLI] C3[OpenClaw / Droid / Cline / Continue / Roo] - C4[Custom OpenAI-compatible clients] - BROWSER[Browser Dashboard] + C4[Clientes personalizados compatíveis com OpenAI] + BROWSER[Dashboard do Navegador] end - subgraph Router[OmniRoute Local Process] - API[V1 Compatibility API\n/v1/*] - DASH[Dashboard + Management API\n/api/*] - CORE[SSE + Translation Core\nopen-sse + src/sse] + subgraph Router[Processo Local OmniRoute] + API[V1 API de Compatibilidade\n/v1/*] + DASH[Dashboard + API de Gerenciamento\n/api/*] + CORE[Núcleo SSE + Tradução\nopen-sse + src/sse] DB[(storage.sqlite)] - UDB[(usage tables + log artifacts)] + UDB[(tabelas de uso + artefatos de log)] end - subgraph Upstreams[Upstream Providers] - P1[OAuth Providers\nClaude/Codex/Gemini/Qwen/Qoder/GitHub/Kiro/Cursor/Antigravity] - P2[API Key Providers\nOpenAI/Anthropic/OpenRouter/GLM/Kimi/MiniMax\nDeepSeek/Groq/xAI/Mistral/Perplexity\nTogether/Fireworks/Cerebras/Cohere/NVIDIA] - P3[Compatible Nodes\nOpenAI-compatible / Anthropic-compatible] + subgraph Upstreams[Provedores Upstream] + P1[Provedores OAuth\nClaude/Codex/Gemini/Qwen/Qoder/GitHub/Kiro/Cursor/Antigravity] + P2[Provedores de Chave de API\nOpenAI/Anthropic/OpenRouter/GLM/Kimi/MiniMax\nDeepSeek/Groq/xAI/Mistral/Perplexity\nTogether/Fireworks/Cerebras/Cohere/NVIDIA] + P3[Nós Compatíveis\ncompatíveis com OpenAI / compatíveis com Anthropic] end - subgraph Cloud[Optional Cloud Sync] - CLOUD[Cloud Sync Endpoint\nNEXT_PUBLIC_CLOUD_URL] + subgraph Cloud[Sincronização em Nuvem Opcional] + CLOUD[Ponto de Sincronização em Nuvem\nNEXT_PUBLIC_CLOUD_URL] end C1 --> API @@ -164,168 +200,331 @@ flowchart LR DASH --> CLOUD ``` -## Core Runtime Components +## Componentes Centrais de Execução -## 1) API and Routing Layer (Next.js App Routes) +## 1) Camada de API e Roteamento (Rotas do App Next.js) -Main directories: +Diretórios principais: -- `src/app/api/v1/*` and `src/app/api/v1beta/*` for compatibility APIs -- `src/app/api/*` for management/configuration APIs -- Next rewrites in `next.config.mjs` map `/v1/*` to `/api/v1/*` +- `src/app/api/v1/*` e `src/app/api/v1beta/*` para APIs de compatibilidade +- `src/app/api/*` para APIs de gerenciamento/configuração +- Reescritas do Next em `next.config.mjs` mapeiam `/v1/*` para `/api/v1/*` -Important compatibility routes: +Rotas de compatibilidade importantes: - `src/app/api/v1/chat/completions/route.ts` - `src/app/api/v1/messages/route.ts` - `src/app/api/v1/responses/route.ts` -- `src/app/api/v1/models/route.ts` — includes custom models with `custom: true` -- `src/app/api/v1/embeddings/route.ts` — embedding generation (6 providers) -- `src/app/api/v1/images/generations/route.ts` — image generation (4+ providers incl. Antigravity/Nebius) +- `src/app/api/v1/models/route.ts` — inclui modelos personalizados com `custom: true` +- `src/app/api/v1/embeddings/route.ts` — geração de embeddings (6 provedores) +- `src/app/api/v1/images/generations/route.ts` — geração de imagens (4+ provedores, incluindo Antigravity/Nebius) - `src/app/api/v1/messages/count_tokens/route.ts` -- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — dedicated per-provider chat -- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — dedicated per-provider embeddings -- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — dedicated per-provider images +- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — chat dedicado por provedor +- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — embeddings dedicados por provedor +- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — imagens dedicadas por provedor - `src/app/api/v1beta/models/route.ts` - `src/app/api/v1beta/models/[...path]/route.ts` -Management domains: +Domínios de gerenciamento: -- Auth/settings: `src/app/api/auth/*`, `src/app/api/settings/*` -- Providers/connections: `src/app/api/providers*` -- Provider nodes: `src/app/api/provider-nodes*` -- Custom models: `src/app/api/provider-models` (GET/POST/DELETE) -- Model catalog: `src/app/api/models/route.ts` (GET) -- Proxy config: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST) +- Auth/configurações: `src/app/api/auth/*`, `src/app/api/settings/*` +- Provedores/conexões: `src/app/api/providers*` +- Nós de provedores: `src/app/api/provider-nodes*` +- Modelos personalizados: `src/app/api/provider-models` (GET/POST/DELETE) +- Catálogo de modelos: `src/app/api/models/route.ts` (GET) +- Configuração de proxy: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST) - OAuth: `src/app/api/oauth/*` -- Keys/aliases/combos/pricing: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing` -- Usage: `src/app/api/usage/*` -- Sync/cloud: `src/app/api/sync/*`, `src/app/api/cloud/*` -- CLI tooling helpers: `src/app/api/cli-tools/*` -- IP filter: `src/app/api/settings/ip-filter` (GET/PUT) -- Thinking budget: `src/app/api/settings/thinking-budget` (GET/PUT) -- System prompt: `src/app/api/settings/system-prompt` (GET/PUT) -- Sessions: `src/app/api/sessions` (GET) -- Rate limits: `src/app/api/rate-limits` (GET) -- Resilience: `src/app/api/resilience` (GET/PATCH) — request queue, connection cooldown, provider breaker, wait-for-cooldown config -- Resilience reset: `src/app/api/resilience/reset` (POST) — reset provider breakers -- Cache stats: `src/app/api/cache/stats` (GET/DELETE) -- Telemetry: `src/app/api/telemetry/summary` (GET) -- Budget: `src/app/api/usage/budget` (GET/POST) -- Fallback chains: `src/app/api/fallback/chains` (GET/POST/DELETE) -- Compliance audit: `src/app/api/compliance/audit-log` (GET, with pagination + structured metadata) +- Chaves/aliases/combos/preços: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing` +- Uso: `src/app/api/usage/*` +- Sincronização/nuvem: `src/app/api/sync/*`, `src/app/api/cloud/*` +- Ferramentas auxiliares de CLI: `src/app/api/cli-tools/*` +- Filtro de IP: `src/app/api/settings/ip-filter` (GET/PUT) +- Orçamento de pensamento: `src/app/api/settings/thinking-budget` (GET/PUT) +- Prompt do sistema: `src/app/api/settings/system-prompt` (GET/PUT) +- Compressão: `src/app/api/settings/compression`, `src/app/api/compression/*`, e + `src/app/api/context/*` +- Sessões: `src/app/api/sessions` (GET) +- Limites de taxa: `src/app/api/rate-limits` (GET) +- Resiliência: `src/app/api/resilience` (GET/PATCH) — fila de requisições, cooldown de conexão, breaker de provedor, configuração de espera por cooldown +- Reset de resiliência: `src/app/api/resilience/reset` (POST) — resetar breakers de provedores +- Estatísticas de cache: `src/app/api/cache/stats` (GET/DELETE) +- Telemetria: `src/app/api/telemetry/summary` (GET) +- Orçamento: `src/app/api/usage/budget` (GET/POST) +- Cadeias de fallback: `src/app/api/fallback/chains` (GET/POST/DELETE) +- Auditoria de conformidade: `src/app/api/compliance/audit-log` (GET, com paginação + metadados estruturados) - Evals: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET) -- Policies: `src/app/api/policies` (GET/POST) -- Sync tokens: `src/app/api/sync/tokens` (GET/POST), `src/app/api/sync/tokens/[id]` (GET/DELETE) -- Config bundle: `src/app/api/sync/bundle` (GET, ETag-versioned snapshot of settings/providers/combos/keys) -- WebSocket: `src/app/api/v1/ws/route.ts` — Upgrade handler for OpenAI-compatible WS clients +- Políticas: `src/app/api/policies` (GET/POST) +- Tokens de sincronização: `src/app/api/sync/tokens` (GET/POST), `src/app/api/sync/tokens/[id]` (GET/DELETE) +- Pacote de configuração: `src/app/api/sync/bundle` (GET, snapshot versionado por ETag de configurações/provedores/combos/chaves) +- WebSocket: `src/app/api/v1/ws/route.ts` — manipulador de upgrade para clientes WS compatíveis com OpenAI -## 2) SSE + Translation Core +## 2) SSE + Núcleo de Tradução -Main flow modules: +Módulos do fluxo principal: -- Entry: `src/sse/handlers/chat.ts` -- Core orchestration: `open-sse/handlers/chatCore.ts` -- Provider execution adapters: `open-sse/executors/*` -- Format detection/provider config: `open-sse/services/provider.ts` -- Model parse/resolve: `src/sse/services/model.ts`, `open-sse/services/model.ts` -- Account fallback logic: `open-sse/services/accountFallback.ts` -- Translation registry: `open-sse/translator/index.ts` -- Stream transformations: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts` -- Usage extraction/normalization: `open-sse/utils/usageTracking.ts` -- Think tag parser: `open-sse/utils/thinkTagParser.ts` -- Embedding handler: `open-sse/handlers/embeddings.ts` -- Embedding provider registry: `open-sse/config/embeddingRegistry.ts` -- Image generation handler: `open-sse/handlers/imageGeneration.ts` -- Image provider registry: `open-sse/config/imageRegistry.ts` -- Response sanitization: `open-sse/handlers/responseSanitizer.ts` -- Role normalization: `open-sse/services/roleNormalizer.ts` +- Entrada: `src/sse/handlers/chat.ts` +- Orquestração central: `open-sse/handlers/chatCore.ts` +- Adaptadores de execução do provedor: `open-sse/executors/*` +- Detecção de formato/configuração do provedor: `open-sse/services/provider.ts` +- Análise/resolução de modelo: `src/sse/services/model.ts`, `open-sse/services/model.ts` +- Lógica de fallback de conta: `open-sse/services/accountFallback.ts` +- Registro de tradução: `open-sse/translator/index.ts` +- Transformações de stream: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts` +- Extração/normalização de uso: `open-sse/utils/usageTracking.ts` +- Analisador de tags de pensamento: `open-sse/utils/thinkTagParser.ts` +- Manipulador de embeddings: `open-sse/handlers/embeddings.ts` +- Registro de provedores de embeddings: `open-sse/config/embeddingRegistry.ts` +- Manipulador de geração de imagem: `open-sse/handlers/imageGeneration.ts` +- Registro de provedores de imagem: `open-sse/config/imageRegistry.ts` +- Sanitização de resposta: `open-sse/handlers/responseSanitizer.ts` +- Normalização de papel: `open-sse/services/roleNormalizer.ts` -Services (business logic): +Serviços (lógica de negócios): -- Account selection/scoring: `open-sse/services/accountSelector.ts` -- Context lifecycle management: `open-sse/services/contextManager.ts` -- IP filter enforcement: `open-sse/services/ipFilter.ts` -- Session tracking: `open-sse/services/sessionManager.ts` -- Request deduplication: `open-sse/services/signatureCache.ts` -- System prompt injection: `open-sse/services/systemPrompt.ts` -- Thinking budget management: `open-sse/services/thinkingBudget.ts` -- Wildcard model routing: `open-sse/services/wildcardRouter.ts` -- Rate limit management: `open-sse/services/rateLimitManager.ts` -- Circuit breaker: `open-sse/services/circuitBreaker.ts` -- Context handoff: `open-sse/services/contextHandoff.ts` — handoff summary generation and injection for context-relay strategy -- Codex quota fetcher: `open-sse/services/codexQuotaFetcher.ts` — fetches Codex quota for context-relay handoff decisions -- Cooldown-aware retry: `src/sse/services/cooldownAwareRetry.ts` — per-model cooldown retries with configurable `requestRetry` / `maxRetryIntervalSec` -- Safe outbound fetch: `src/shared/network/safeOutboundFetch.ts` — guarded provider/model fetch with SSRF guard, private-URL blocking, retry, and timeout -- Outbound URL guard: `src/shared/network/outboundUrlGuard.ts` — validates provider URLs against private/localhost CIDR ranges -- Provider request defaults: `open-sse/services/providerRequestDefaults.ts` — provider-level `maxTokens`, `temperature`, `thinkingBudgetTokens` defaults -- GLM provider constants: `open-sse/config/glmProvider.ts` — shared GLM models, quota URLs, GLMT timeout/defaults -- Antigravity upstream: `open-sse/config/antigravityUpstream.ts` — base URL and discovery path constants -- Codex client constants: `open-sse/config/codexClient.ts` — versioned user-agent and client-version values -- Model alias seed: `src/lib/modelAliasSeed.ts` — seeds 30+ cross-proxy dialect aliases at startup +- Seleção/classificação de conta: `open-sse/services/accountSelector.ts` +- Gerenciamento do ciclo de vida do contexto: `open-sse/services/contextManager.ts` +- Aplicação de filtro de IP: `open-sse/services/ipFilter.ts` +- Rastreamento de sessão: `open-sse/services/sessionManager.ts` +- Deduplicação de requisições: `open-sse/services/signatureCache.ts` +- Injeção de prompt do sistema: `open-sse/services/systemPrompt.ts` +- Gerenciamento de orçamento de pensamento: `open-sse/services/thinkingBudget.ts` +- Roteamento de modelo curinga: `open-sse/services/wildcardRouter.ts` +- Gerenciamento de limite de taxa: `open-sse/services/rateLimitManager.ts` +- Disjuntor: `open-sse/services/circuitBreaker.ts` +- Transferência de contexto: `open-sse/services/contextHandoff.ts` — geração e injeção de resumo de transferência para estratégia de retransmissão de contexto +- Compressão: `open-sse/services/compression/*` — compressão proativa antes da tradução do provedor; + inclui regras de Caveman, filtros RTK, pipelines empilhados, combos de compressão, estatísticas e validação +- Recuperador de cota Codex: `open-sse/services/codexQuotaFetcher.ts` — recupera a cota Codex para decisões de transferência de contexto +- Retry ciente de cooldown: `src/sse/services/cooldownAwareRetry.ts` — retries de cooldown por modelo com `requestRetry` / `maxRetryIntervalSec` configuráveis +- Fetch seguro de saída: `src/shared/network/safeOutboundFetch.ts` — fetch protegido de provedor/modelo com proteção SSRF, bloqueio de URL privada, retry e timeout +- Guarda de URL de saída: `src/shared/network/outboundUrlGuard.ts` — valida URLs de provedores contra intervalos CIDR privados/localhost +- Padrões de requisição do provedor: `open-sse/services/providerRequestDefaults.ts` — padrões de `maxTokens`, `temperature`, `thinkingBudgetTokens` a nível de provedor +- Constantes do provedor GLM: `open-sse/config/glmProvider.ts` — modelos GLM compartilhados, URLs de cota, timeout/padrões GLMT +- Upstream de antigravidade: `open-sse/config/antigravityUpstream.ts` — constantes de URL base e caminho de descoberta +- Constantes do cliente Codex: `open-sse/config/codexClient.ts` — valores de user-agent e versão do cliente versionados +- Semente de alias de modelo: `src/lib/modelAliasSeed.ts` — semeia 30+ aliases de dialetos cross-proxy na inicialização -Domain layer modules: +Módulos da camada de domínio: -- Cost rules/budgets: `src/lib/domain/costRules.ts` -- Fallback policy: `src/lib/domain/fallbackPolicy.ts` -- Combo resolver: `src/lib/domain/comboResolver.ts` -- Lockout policy: `src/lib/domain/lockoutPolicy.ts` -- Policy engine: `src/domain/policyEngine.ts` — centralized lockout → budget → fallback evaluation -- Error codes catalog: `src/lib/domain/errorCodes.ts` -- Request ID: `src/lib/domain/requestId.ts` -- Fetch timeout: `src/lib/domain/fetchTimeout.ts` -- Request telemetry: `src/lib/domain/requestTelemetry.ts` -- Compliance/audit: `src/lib/domain/compliance/index.ts` -- Eval runner: `src/lib/domain/evalRunner.ts` -- Domain state persistence: `src/lib/db/domainState.ts` — SQLite CRUD for fallback chains, budgets, cost history, lockout state, circuit breakers +- Regras/orçamentos de custo: `src/lib/domain/costRules.ts` +- Política de fallback: `src/lib/domain/fallbackPolicy.ts` +- Resolvedor de combo: `src/lib/domain/comboResolver.ts` +- Política de bloqueio: `src/lib/domain/lockoutPolicy.ts` +- Motor de políticas: `src/domain/policyEngine.ts` — avaliação centralizada de bloqueio → orçamento → fallback +- Catálogo de códigos de erro: `src/lib/domain/errorCodes.ts` +- ID da requisição: `src/lib/domain/requestId.ts` +- Timeout de fetch: `src/lib/domain/fetchTimeout.ts` +- Telemetria de requisição: `src/lib/domain/requestTelemetry.ts` +- Conformidade/auditoria: `src/lib/domain/compliance/index.ts` +- Executor de avaliação: `src/lib/domain/evalRunner.ts` +- Persistência do estado do domínio: `src/lib/db/domainState.ts` — CRUD SQLite para cadeias de fallback, orçamentos, histórico de custos, estado de bloqueio, disjuntores -OAuth provider modules (13 individual files under `src/lib/oauth/providers/`): +Módulos do provedor OAuth (14 arquivos individuais sob `src/lib/oauth/providers/`): -- Registry index: `src/lib/oauth/providers/index.ts` -- Individual providers: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `qoder.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts` -- Thin wrapper: `src/lib/oauth/providers.ts` — re-exports from individual modules +- Índice do registro: `src/lib/oauth/providers/index.ts` +- Provedores individuais: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `qoder.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts`, `windsurf.ts`, `gitlab-duo.ts` +- Wrapper fino: `src/lib/oauth/providers.ts` — re-exporta de módulos individuais -## 3) Persistence Layer +## Subsistemas Principais (v3.8.0) -Primary state DB (SQLite): +### A. Motor de Combinação Automática -- Core infra: `src/lib/db/core.ts` (better-sqlite3, migrations, WAL) -- Re-export facade: `src/lib/localDb.ts` (thin compatibility layer for callers) -- file: `${DATA_DIR}/storage.sqlite` (or `$XDG_CONFIG_HOME/omniroute/storage.sqlite` when set, else `~/.omniroute/storage.sqlite`) -- entities (tables + KV namespaces): providerConnections, providerNodes, modelAliases, combos, apiKeys, settings, pricing, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt** +O Motor de Combinação Automática pontua e escolhe dinamicamente os alvos de roteamento no momento da solicitação, em vez de depender de uma definição de combinação estática. Ele alimenta a família de prefixos de modelo `auto/*`. -Usage persistence: +- Entrada do motor: `open-sse/services/autoCombo/` (`autoComboEngine.ts`, + `scoringEngine.ts`, `virtualFactory.ts`, `modePacks.ts`) +- Resolvedor: `src/domain/comboResolver.ts` (detecção automática do prefixo `auto/`) +- Painel: `/dashboard/auto-combo` +- Telemetria: tabela SQLite `auto_combo_decisions` -- facade: `src/lib/usageDb.ts` (decomposed modules in `src/lib/usage/*`) -- SQLite tables in `storage.sqlite`: `usage_history`, `call_logs`, `proxy_logs` -- optional file artifacts remain for compatibility/debug (`${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`, `/logs/...`) -- legacy JSON files are migrated to SQLite by startup migrations when present +Principais capacidades: -Domain State DB (SQLite): +- **14 estratégias de roteamento** (prioridade, ponderada, preenchimento primeiro, round-robin, P2C, aleatório, + menos utilizado, otimizado por custo, estritamente aleatório, **auto**, lkgp, otimizado por contexto, + retransmissão de contexto, além de um caminho de fallback) — auto é a adição principal na v3.8.0. +- **Pontuação de 9 fatores**: custo, latência p95, taxa de sucesso, margem de cota, proximidade de bloqueio, + estado do disjuntor, falhas recentes, disponibilidade do modelo e afinidade de tags. +- **Fábrica virtual** materializa combinações efêmeras quando nenhuma combinação nomeada correspondente + existe, obtendo candidatos de conexões de provedores ativos e saudáveis. +- **Prefixos automáticos**: `auto/coding`, `auto/cheap`, `auto/fast`, `auto/offline`, + `auto/smart`, `auto/lkgp` — cada um apoiado por um perfil de peso ajustado. +- **4 pacotes de modo**: coding, fast, cheap, smart — enviados como configurações de peso pré-definidas + chamáveis a partir do painel. -- `src/lib/db/domainState.ts` — CRUD operations for domain state -- Tables (created in `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers` -- Write-through cache pattern: in-memory Maps are authoritative at runtime; mutations are written synchronously to SQLite; state is restored from DB on cold start +Para detalhes algorítmicos completos (fórmulas de fatores, ajuste de peso), consulte +[`docs/routing/AUTO-COMBO.md`](../routing/AUTO-COMBO.md). -## 4) Auth + Security Surfaces +### B. Agentes de Nuvem -- Dashboard cookie auth: `src/proxy.ts`, `src/app/api/auth/login/route.ts` -- API key generation/verification: `src/shared/utils/apiKey.ts` -- Provider secrets persisted in `providerConnections` entries -- Outbound proxy support via `open-sse/utils/proxyFetch.ts` (env vars) and `open-sse/utils/networkProxy.ts` (configurable per-provider or global) -- SSRF / outbound URL guard: `src/shared/network/outboundUrlGuard.ts` — blocks private/loopback/link-local ranges for all provider calls -- Runtime env validation: `src/lib/env/runtimeEnv.ts` — Zod schema for all environment variables, surfaced as startup errors/warnings -- Sync tokens: `src/lib/db/syncTokens.ts` — scoped tokens for config bundle download endpoints; backed by `sync_tokens` SQLite table (migration `024_create_sync_tokens.sql`) -- WebSocket handshake auth: `src/lib/ws/handshake.ts` — validates WS upgrade requests via API key or session cookie +Agentes de Nuvem envolvem plataformas de código-agente hospedadas de terceiros (Codex Cloud, Devin, +Jules) por trás de um ciclo de vida de tarefa uniforme baseado em DB. Todos os pontos de criação/inspeção +de tarefas requerem autenticação de gerenciamento. -## 5) Cloud Sync +- Raiz do módulo: `src/lib/cloudAgent/` (`baseAgent.ts`, `registry.ts`, `api.ts`, + `types.ts`, `db.ts`, além de subdiretórios por agente em `agents/`) +- Implementações por agente: `agents/codex/`, `agents/devin/`, `agents/jules/` +- Pontos finais públicos: `/api/v1/agents/tasks/*` (listar/criar/obter/cancelar) +- Pontos finais de gerenciamento: `/api/cloud/*` (provisionamento, status, lote) +- Painel: `/dashboard/cloud-agents` +- Armazenamento: tabela `cloud_agent_tasks` -- Scheduler init: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`, `src/shared/services/modelSyncScheduler.ts` -- Periodic task: `src/shared/services/cloudSyncScheduler.ts` -- Periodic task: `src/shared/services/modelSyncScheduler.ts` -- Control route: `src/app/api/sync/cloud/route.ts` +Para detalhes de provisionamento por agente e especificidades de OAuth, consulte +[`docs/frameworks/CLOUD_AGENT.md`](../frameworks/CLOUD_AGENT.md). -## Request Lifecycle (`/v1/chat/completions`) +### C. Guardrails + +O módulo de guardrails é uma camada de middleware recarregável que inspeciona solicitações +e respostas em busca de PII, injeção de prompt e conteúdo de visão inseguro. Violações +interrompem a solicitação com HTTP **503** mais um código de erro estruturado, permitindo +que chamadores subsequentes tentem novamente ou ramifiquem. + +- Raiz do módulo: `src/lib/guardrails/` (`base.ts`, `registry.ts`, `piiMasker.ts`, + `promptInjection.ts`, `visionBridge.ts`, `visionBridgeHelpers.ts`) +- Recarregamento a quente: o registro observa mudanças de configuração e reconstrói a cadeia no local +- Pontos de conexão: entrada do manipulador de chat, manipulador de geração de imagem, sanitizador de resposta +- Contrato HTTP: violações aparecem como `503` com `error.code = "GUARDRAIL_VIOLATION"` + +Para autoria de regras e ajuste de limites, consulte +[`docs/security/GUARDRAILS.md`](../security/GUARDRAILS.md). + +### D. Camada de Domínio + +O namespace `src/domain/` centraliza decisões de política para que os manipuladores de rota não +precisem montar a lógica de bloqueio/orçamento/fallback por conta própria. + +- Motor de políticas: `src/domain/policyEngine.ts` — ponto de entrada único para + avaliação pré-execução (bloqueio → orçamento → ordem de fallback) +- Regras de custo: `src/domain/costRules.ts` +- Política de fallback: `src/domain/fallbackPolicy.ts` +- Política de bloqueio: `src/domain/lockoutPolicy.ts` +- Roteamento baseado em tags: `src/domain/tagRouter.ts` +- Resolvedor de combinação: `src/domain/comboResolver.ts` — resolve nomes de combinação, prefixos auto/\* + e alvos de modelo curinga para planos de execução concretos +- Conector de regras de conexão/modelo: `src/domain/connectionModelRules.ts` +- Capturas de disponibilidade do modelo: `src/domain/modelAvailability.ts` +- Rastreamento de expiração do provedor: `src/domain/providerExpiration.ts` +- Cache de cota: `src/domain/quotaCache.ts` +- Estado de degradação: `src/domain/degradation.ts` +- Auditoria de configuração: `src/domain/configAudit.ts` +- Construtor de metadados de resposta OmniRoute: `src/domain/omnirouteResponseMeta.ts` +- Subsistema de avaliação: `src/domain/assessment/` — trabalhos de avaliação periódicos + +### E. Pipeline de Autorização + +O pipeline de autorização classifica cada solicitação recebida e aplica a +cadeia de políticas apropriada antes do despacho. + +- Entrada do pipeline: `src/server/authz/pipeline.ts` +- Classificador de solicitações: `src/server/authz/classify.ts` — distingue rotas de compatibilidade públicas + de rotas de gerenciamento +- Inventário de rotas públicas: `src/shared/constants/publicApiRoutes.ts` +- Políticas: `src/server/authz/policies/` — predicados compostáveis + (`requireApiKey`, `requireManagement`, `requireFreshAuth`, etc.) +- Utilitários de cabeçalho: `src/server/authz/headers.ts` +- Helper de asserção: `src/server/authz/assertAuth.ts` +- Contexto da solicitação: `src/server/authz/context.ts` + +Rotas públicas vs rotas de gerenciamento são uma fronteira rígida: APIs de agente/cooldown e +mutações de provedores requerem autenticação de gerenciamento (HTTP 401 se ausente). + +Para as regras completas de classificação de rotas, consulte +[`docs/architecture/AUTHZ_GUIDE.md`](./AUTHZ_GUIDE.md). + +### F. FSM de Workflow e Roteador Consciente de Tarefas + +Um roteador acionado por máquina de estados finitos, posicionado acima da seleção de combinações para direcionar +o tráfego com base na fase de workflow detectada (planejamento, execução, +revisão) e afinidade de tarefas em segundo plano. + +- FSM de Workflow: `open-sse/services/workflowFSM.ts` +- Roteador consciente de tarefas: `open-sse/services/taskAwareRouter.ts` +- Detector de tarefas em segundo plano: `open-sse/services/backgroundTaskDetector.ts` +- Classificador de intenção: `open-sse/services/intentClassifier.ts` + +As transições da FSM alimentam a pontuação do Auto Combo, tendendo a modelos mais baratos +para tarefas de automação/fundo e a modelos mais robustos para turnos interativos de +planejamento/revisão. + +### G. Resiliência Específica do Provedor + +Vários provedores enviam módulos dedicados de resiliência e furtividade que se aproveitam das +camadas globais de disjuntor / cooldown de conexão / bloqueio de modelo: + +- Motor Antigravidade 429: `open-sse/services/antigravity429Engine.ts` (rotaciona + identidade, limpa cabeçalhos de resposta, controla créditos/rastreamento de versão via + `antigravityCredits.ts`, `antigravityHeaderScrub.ts`, `antigravityHeaders.ts`, + `antigravityIdentity.ts`, `antigravityObfuscation.ts`, `antigravityVersion.ts`) +- Política de cota ModelScope: `open-sse/services/modelscopePolicy.ts` +- Claude Code CCH (Handshake de Canal de Compatibilidade): `open-sse/services/claudeCodeCCH.ts`, + além de `claudeCodeCompatible.ts`, `claudeCodeConstraints.ts`, `claudeCodeExtraRemap.ts`, + `claudeCodeToolRemapper.ts` +- Modelagem de impressão digital do Claude Code: `open-sse/services/claudeCodeFingerprint.ts` +- Ofuscação do Claude Code: `open-sse/services/claudeCodeObfuscation.ts` +- Cliente TLS do ChatGPT: `open-sse/services/chatgptTlsClient.ts` (estilo curl-impersonate + para sessões do ChatGPT-Web) +- Cache de imagem do ChatGPT: `open-sse/services/chatgptImageCache.ts` + +Para o guia completo de furtividade e orientações operacionais, consulte +[`docs/security/STEALTH_GUIDE.md`](../security/STEALTH_GUIDE.md). + +### H. Webhooks, Cache de Raciocínio, Cache de Leitura + +- **Webhooks** — despacho de saída para eventos de provedor/conta/tarefa. + - Dispatcher: `src/lib/webhookDispatcher.ts` + - Armazenamento: tabela SQLite `webhooks` (via `src/lib/db/webhooks.ts`) + - Painel: `/dashboard/webhooks` (assinaturas, segredos, histórico de tentativas) + - Para taxonomia de eventos e semântica de tentativas, consulte [`docs/frameworks/WEBHOOKS.md`](../frameworks/WEBHOOKS.md). +- **Cache de Raciocínio** — blocos de raciocínio replays para provedores que emitem + tokens de pensamento (Claude, GLMT, etc.) para que turnos consecutivos possam pular o re-pensar. + - Camada de DB: `src/lib/db/reasoningCache.ts` + - Camada de serviço: `open-sse/services/reasoningCache.ts` + - Para semântica de replay, consulte [`docs/routing/REASONING_REPLAY.md`](../routing/REASONING_REPLAY.md). +- **Cache de Leitura** — cache de resposta de curta duração indexado por assinatura e usado para + colapsar tentativas idênticas de SDKs upstream quebrados. + - Camada de DB: `src/lib/db/readCache.ts` + - Endpoint de estatísticas: `GET /api/cache/stats`, painel em `/dashboard/cache` + +## 3) Camada de Persistência + +Banco de dados de estado primário (SQLite): + +- Infraestrutura principal: `src/lib/db/core.ts` (better-sqlite3, migrações, WAL) +- Fachada de re-exportação: `src/lib/localDb.ts` (camada de compatibilidade fina para chamadores) +- arquivo: `${DATA_DIR}/storage.sqlite` (ou `$XDG_CONFIG_HOME/omniroute/storage.sqlite` quando definido, caso contrário `~/.omniroute/storage.sqlite`) +- entidades (tabelas + namespaces KV): providerConnections, providerNodes, modelAliases, combos, apiKeys, settings, pricing, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt** + +Persistência de uso: + +- fachada: `src/lib/usageDb.ts` (módulos decompostos em `src/lib/usage/*`) +- tabelas SQLite em `storage.sqlite`: `usage_history`, `call_logs`, `proxy_logs` +- artefatos de arquivo opcionais permanecem para compatibilidade/debug (`${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`, `/logs/...`) +- arquivos JSON legados são migrados para SQLite por migrações de inicialização quando presentes + +Banco de dados de estado de domínio (SQLite): + +- `src/lib/db/domainState.ts` — operações CRUD para estado de domínio +- Tabelas (criadas em `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers` +- Padrão de cache write-through: Maps em memória são autoritativos em tempo de execução; mutações são escritas de forma síncrona no SQLite; estado é restaurado do DB na inicialização a frio + +## 4) Superfícies de Autenticação + Segurança + +- Autenticação de cookie do painel: `src/proxy.ts`, `src/app/api/auth/login/route.ts` +- Geração/verificação de chave de API: `src/shared/utils/apiKey.ts` +- Segredos do provedor persistidos nas entradas de `providerConnections` +- Suporte a proxy de saída via `open-sse/utils/proxyFetch.ts` (variáveis de ambiente) e `open-sse/utils/networkProxy.ts` (configurável por provedor ou global) +- Proteção SSRF / URL de saída: `src/shared/network/outboundUrlGuard.ts` — bloqueia intervalos privados/loopback/link-local para todas as chamadas de provedor +- Validação do ambiente em tempo de execução: `src/lib/env/runtimeEnv.ts` — esquema Zod para todas as variáveis de ambiente, apresentado como erros/avisos de inicialização +- Tokens de sincronização: `src/lib/db/syncTokens.ts` — tokens escopados para endpoints de download de pacotes de configuração; respaldados pela tabela SQLite `sync_tokens` (migração `024_create_sync_tokens.sql`) +- Autenticação de handshake WebSocket: `src/lib/ws/handshake.ts` — valida solicitações de upgrade WS via chave de API ou cookie de sessão + +## 5) Sincronização na Nuvem + +- Inicialização do agendador: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`, `src/shared/services/modelSyncScheduler.ts` +- Tarefa periódica: `src/shared/services/cloudSyncScheduler.ts` +- Tarefa periódica: `src/shared/services/modelSyncScheduler.ts` +- Rota de controle: `src/app/api/sync/cloud/route.ts` + +## Ciclo de Vida da Solicitação (`/v1/chat/completions`) ```mermaid sequenceDiagram @@ -372,111 +571,111 @@ sequenceDiagram Stream->>Usage: extract usage + persist history/log ``` -## Combo + Account Fallback Flow +## Fluxo de Fallback de Combo + Conta ```mermaid flowchart TD - A[Incoming model string] --> B{Is combo name?} - B -- Yes --> C[Load combo models sequence] - B -- No --> D[Single model path] + A[Modelo de string de entrada] --> B{É nome de combo?} + B -- Sim --> C[Carregar sequência de modelos de combo] + B -- Não --> D[Caminho de modelo único] - C --> E[Try model N] - E --> F[Resolve provider/model] + C --> E[Tentar modelo N] + E --> F[Resolver provedor/modelo] D --> F - F --> G[Select account credentials] - G --> H{Credentials available?} - H -- No --> I[Return provider unavailable] - H -- Yes --> J[Execute request] + F --> G[Selecionar credenciais da conta] + G --> H{Credenciais disponíveis?} + H -- Não --> I[Retornar provedor indisponível] + H -- Sim --> J[Executar solicitação] - J --> K{Success?} - K -- Yes --> L[Return response] - K -- No --> M{Fallback-eligible error?} + J --> K{Sucesso?} + K -- Sim --> L[Retornar resposta] + K -- Não --> M{Erro elegível para fallback?} - M -- No --> N[Return error] - M -- Yes --> O[Mark account unavailable cooldown] - O --> P{Another account for provider?} - P -- Yes --> G - P -- No --> Q{In combo with next model?} - Q -- Yes --> E - Q -- No --> R[Return all unavailable] + M -- Não --> N[Retornar erro] + M -- Sim --> O[Marcar cooldown de conta indisponível] + O --> P{Outra conta para o provedor?} + P -- Sim --> G + P -- Não --> Q{Em combo com o próximo modelo?} + Q -- Sim --> E + Q -- Não --> R[Retornar todas indisponíveis] ``` -Fallback decisions are driven by `open-sse/services/accountFallback.ts` using status codes and error-message heuristics. Combo routing adds one extra guard: provider-scoped 400s such as upstream content-block and role-validation failures are treated as model-local failures so later combo targets can still run. +As decisões de fallback são impulsionadas por `open-sse/services/accountFallback.ts` usando códigos de status e heurísticas de mensagens de erro. O roteamento de combo adiciona uma proteção extra: 400s específicos do provedor, como bloqueio de conteúdo upstream e falhas de validação de função, são tratados como falhas locais do modelo para que os alvos de combo posteriores ainda possam ser executados. -## OAuth Onboarding and Token Refresh Lifecycle +## Ciclo de Vida de Onboarding OAuth e Atualização de Token ```mermaid sequenceDiagram autonumber - participant UI as Dashboard UI - participant OAuth as /api/oauth/[provider]/[action] - participant ProvAuth as Provider Auth Server + participant UI as UI do Dashboard + participant OAuth as /api/oauth/[provedor]/[ação] + participant ProvAuth as Servidor de Autenticação do Provedor participant DB as localDb participant Test as /api/providers/[id]/test - participant Exec as Provider Executor + participant Exec as Executor do Provedor - UI->>OAuth: GET authorize or device-code - OAuth->>ProvAuth: create auth/device flow - ProvAuth-->>OAuth: auth URL or device code payload - OAuth-->>UI: flow data + UI->>OAuth: GET autorizar ou código de dispositivo + OAuth->>ProvAuth: criar fluxo de auth/dispositivo + ProvAuth-->>OAuth: URL de auth ou payload de código de dispositivo + OAuth-->>UI: dados do fluxo - UI->>OAuth: POST exchange or poll - OAuth->>ProvAuth: token exchange/poll - ProvAuth-->>OAuth: access/refresh tokens - OAuth->>DB: createProviderConnection(oauth data) - OAuth-->>UI: success + connection id + UI->>OAuth: POST trocar ou poll + OAuth->>ProvAuth: troca/poll de token + ProvAuth-->>OAuth: tokens de acesso/atualização + OAuth->>DB: createProviderConnection(dados oauth) + OAuth-->>UI: sucesso + id da conexão UI->>Test: POST /api/providers/[id]/test - Test->>Exec: validate credentials / optional refresh - Exec-->>Test: valid or refreshed token info - Test->>DB: update status/tokens/errors - Test-->>UI: validation result + Test->>Exec: validar credenciais / atualização opcional + Exec-->>Test: informações de token válidas ou atualizadas + Test->>DB: atualizar status/tokens/erros + Test-->>UI: resultado da validação ``` -Refresh during live traffic is executed inside `open-sse/handlers/chatCore.ts` via executor `refreshCredentials()`. +A atualização durante o tráfego ao vivo é executada dentro de `open-sse/handlers/chatCore.ts` via executor `refreshCredentials()`. -## Cloud Sync Lifecycle (Enable / Sync / Disable) +## Ciclo de Vida de Sincronização na Nuvem (Habilitar / Sincronizar / Desabilitar) ```mermaid sequenceDiagram autonumber - participant UI as Endpoint Page UI + participant UI as UI da Página de Endpoint participant Sync as /api/sync/cloud participant DB as localDb - participant Cloud as External Cloud Sync + participant Cloud as Sincronização Externa na Nuvem participant Claude as ~/.claude/settings.json - UI->>Sync: POST action=enable - Sync->>DB: set cloudEnabled=true - Sync->>DB: ensure API key exists - Sync->>Cloud: POST /sync/{machineId} (providers/aliases/combos/keys) - Cloud-->>Sync: sync result + UI->>Sync: POST ação=habilitar + Sync->>DB: definir cloudEnabled=true + Sync->>DB: garantir que a chave da API exista + Sync->>Cloud: POST /sync/{machineId} (provedores/aliases/combos/chaves) + Cloud-->>Sync: resultado da sincronização Sync->>Cloud: GET /{machineId}/v1/verify - Sync-->>UI: enabled + verification status + Sync-->>UI: habilitado + status de verificação - UI->>Sync: POST action=sync + UI->>Sync: POST ação=sincronizar Sync->>Cloud: POST /sync/{machineId} - Cloud-->>Sync: remote data - Sync->>DB: update newer local tokens/status - Sync-->>UI: synced + Cloud-->>Sync: dados remotos + Sync->>DB: atualizar tokens/status locais mais novos + Sync-->>UI: sincronizado - UI->>Sync: POST action=disable - Sync->>DB: set cloudEnabled=false + UI->>Sync: POST ação=desabilitar + Sync->>DB: definir cloudEnabled=false Sync->>Cloud: DELETE /sync/{machineId} - Sync->>Claude: switch ANTHROPIC_BASE_URL back to local (if needed) - Sync-->>UI: disabled + Sync->>Claude: mudar ANTHROPIC_BASE_URL de volta para local (se necessário) + Sync-->>UI: desabilitado ``` -Periodic sync is triggered by `CloudSyncScheduler` when cloud is enabled. +A sincronização periódica é acionada por `CloudSyncScheduler` quando a nuvem está habilitada. -## Data Model and Storage Map +## Modelo de Dados e Mapa de Armazenamento ```mermaid erDiagram - SETTINGS ||--o{ PROVIDER_CONNECTION : controls - PROVIDER_NODE ||--o{ PROVIDER_CONNECTION : backs_compatible_provider - PROVIDER_CONNECTION ||--o{ USAGE_ENTRY : emits_usage + SETTINGS ||--o{ PROVIDER_CONNECTION : controla + PROVIDER_NODE ||--o{ PROVIDER_CONNECTION : provedor_compatível + PROVIDER_CONNECTION ||--o{ USAGE_ENTRY : emite_uso SETTINGS { boolean cloudEnabled @@ -571,32 +770,32 @@ erDiagram } ``` -Physical storage files: +Arquivos de armazenamento físico: -- primary runtime DB: `${DATA_DIR}/storage.sqlite` -- request log lines: `${DATA_DIR}/log.txt` (compat/debug artifact) -- structured call payload archives: `${DATA_DIR}/call_logs/` -- optional translator/request debug sessions: `/logs/...` +- banco de dados de execução primário: `${DATA_DIR}/storage.sqlite` +- linhas de log de requisição: `${DATA_DIR}/log.txt` (artefato de compatibilidade/debug) +- arquivos de carga útil de chamadas estruturadas: `${DATA_DIR}/call_logs/` +- sessões de depuração de tradutor/requisição opcionais: `/logs/...` -## Deployment Topology +## Topologia de Implantação ```mermaid flowchart LR - subgraph LocalHost[Developer Host] + subgraph LocalHost[Host do Desenvolvedor] CLI[CLI Tools] - Browser[Dashboard Browser] + Browser[Navegador do Dashboard] end - subgraph ContainerOrProcess[OmniRoute Runtime] - Next[Next.js Server\nPORT=20128] - Core[SSE Core + Executors] + subgraph ContainerOrProcess[Execução do OmniRoute] + Next[Servidor Next.js\nPORT=20128] + Core[Núcleo SSE + Executores] MainDB[(storage.sqlite)] - UsageDB[(usage tables + log artifacts)] + UsageDB[(tabelas de uso + artefatos de log)] end - subgraph External[External Services] - Providers[AI Providers] - SyncCloud[Cloud Sync Service] + subgraph External[Serviços Externos] + Providers[Provedores de IA] + SyncCloud[Serviço de Sincronização em Nuvem] end CLI --> Next @@ -609,283 +808,333 @@ flowchart LR Next --> SyncCloud ``` -## Module Mapping (Decision-Critical) +## Mapeamento de Módulos (Crítico para Decisão) -### Route and API Modules +### Módulos de Rota e API -- `src/app/api/v1/*`, `src/app/api/v1beta/*`: compatibility APIs -- `src/app/api/v1/providers/[provider]/*`: dedicated per-provider routes (chat, embeddings, images) -- `src/app/api/providers*`: provider CRUD, validation, testing -- `src/app/api/provider-nodes*`: custom compatible node management -- `src/app/api/provider-models`: custom model management (CRUD) -- `src/app/api/models/route.ts`: model catalog API (aliases + custom models) -- `src/app/api/oauth/*`: OAuth/device-code flows -- `src/app/api/keys*`: local API key lifecycle -- `src/app/api/models/alias`: alias management -- `src/app/api/combos*`: fallback combo management -- `src/app/api/pricing`: pricing overrides for cost calculation -- `src/app/api/settings/proxy`: proxy configuration (GET/PUT/DELETE) -- `src/app/api/settings/proxy/test`: outbound proxy connectivity test (POST) -- `src/app/api/usage/*`: usage and logs APIs -- `src/app/api/sync/*` + `src/app/api/cloud/*`: cloud sync and cloud-facing helpers -- `src/app/api/cli-tools/*`: local CLI config writers/checkers -- `src/app/api/settings/ip-filter`: IP allowlist/blocklist (GET/PUT) -- `src/app/api/settings/thinking-budget`: thinking token budget config (GET/PUT) -- `src/app/api/settings/system-prompt`: global system prompt (GET/PUT) -- `src/app/api/sessions`: active session listing (GET) -- `src/app/api/rate-limits`: per-account rate limit status (GET) -- `src/app/api/sync/tokens`: sync token CRUD (GET/POST) -- `src/app/api/sync/tokens/[id]`: sync token get/delete (GET/DELETE) -- `src/app/api/sync/bundle`: config bundle download (GET, ETag versioning) -- `src/app/api/v1/ws`: WebSocket upgrade handler for OpenAI-compatible WS clients +- `src/app/api/v1/*`, `src/app/api/v1beta/*`: APIs de compatibilidade +- `src/app/api/v1/providers/[provider]/*`: rotas dedicadas por provedor (chat, embeddings, imagens) +- `src/app/api/providers*`: CRUD de provedores, validação, teste +- `src/app/api/provider-nodes*`: gerenciamento de nós compatíveis personalizados +- `src/app/api/provider-models`: gerenciamento de modelos personalizados (CRUD) +- `src/app/api/models/route.ts`: API de catálogo de modelos (aliases + modelos personalizados) +- `src/app/api/oauth/*`: fluxos de OAuth/código de dispositivo +- `src/app/api/keys*`: ciclo de vida da chave API local +- `src/app/api/models/alias`: gerenciamento de alias +- `src/app/api/combos*`: gerenciamento de combos de fallback +- `src/app/api/pricing`: substituições de preços para cálculo de custos +- `src/app/api/settings/proxy`: configuração de proxy (GET/PUT/DELETE) +- `src/app/api/settings/proxy/test`: teste de conectividade de proxy de saída (POST) +- `src/app/api/usage/*`: APIs de uso e logs +- `src/app/api/sync/*` + `src/app/api/cloud/*`: sincronização em nuvem e helpers voltados para a nuvem +- `src/app/api/cli-tools/*`: escritores/verificadores de configuração CLI local +- `src/app/api/settings/ip-filter`: lista de permissão/bloqueio de IP (GET/PUT) +- `src/app/api/settings/thinking-budget`: configuração do orçamento de tokens de pensamento (GET/PUT) +- `src/app/api/settings/system-prompt`: prompt do sistema global (GET/PUT) +- `src/app/api/settings/compression`: configurações de compressão global (GET/PUT) +- `src/app/api/compression/*`: visualização de compressão, metadados de regras e pacotes de idiomas +- `src/app/api/context/caveman/config`: alias de configurações do Caveman (GET/PUT) +- `src/app/api/context/rtk/*`: configuração RTK, catálogo de filtros, endpoint de teste e recuperação de saída bruta +- `src/app/api/context/combos*`: CRUD de combos de compressão e atribuições de combos de roteamento +- `src/app/api/context/analytics`: alias de análises de compressão +- `src/app/api/sessions`: listagem de sessões ativas (GET) +- `src/app/api/rate-limits`: status de limite de taxa por conta (GET) +- `src/app/api/sync/tokens`: CRUD de tokens de sincronização (GET/POST) +- `src/app/api/sync/tokens/[id]`: obter/excluir token de sincronização (GET/DELETE) +- `src/app/api/sync/bundle`: download de pacote de configuração (GET, versionamento ETag) +- `src/app/api/v1/ws`: manipulador de atualização WebSocket para clientes WS compatíveis com OpenAI -### Routing and Execution Core +### Núcleo de Roteamento e Execução -- `src/sse/handlers/chat.ts`: request parse, combo handling, account selection loop -- `open-sse/handlers/chatCore.ts`: translation, executor dispatch, retry/refresh handling, stream setup -- `open-sse/executors/*`: provider-specific network and format behavior +- `src/sse/handlers/chat.ts`: análise de requisição, manipulação de combo, loop de seleção de conta +- `open-sse/handlers/chatCore.ts`: tradução, despacho de executores, manipulação de retry/refresh, configuração de stream +- `open-sse/executors/*`: comportamento de rede e formato específico do provedor -### Translation Registry and Format Converters +### Registro de Tradução e Conversores de Formato -- `open-sse/translator/index.ts`: translator registry and orchestration -- Request translators: `open-sse/translator/request/*` -- Response translators: `open-sse/translator/response/*` -- Format constants: `open-sse/translator/formats.ts` +- `open-sse/translator/index.ts`: registro e orquestração de tradutores +- Tradutores de requisição: `open-sse/translator/request/*` (9 módulos — `antigravity-to-openai`, `claude-to-gemini`, `claude-to-openai`, `gemini-to-openai`, `openai-responses`, `openai-to-claude`, `openai-to-cursor`, `openai-to-gemini`, `openai-to-kiro`) +- Tradutores de resposta: `open-sse/translator/response/*` (8 módulos — `claude-to-openai`, `cursor-to-openai`, `gemini-to-claude`, `gemini-to-openai`, `kiro-to-openai`, `openai-responses`, `openai-to-antigravity`, `openai-to-claude`) +- Helpers: `open-sse/translator/helpers/*` (8 módulos — `claudeHelper`, `geminiHelper`, `geminiToolsSanitizer`, `maxTokensHelper`, `openaiHelper`, `responsesApiHelper`, `schemaCoercion`, `toolCallHelper`) +- Constantes de formato: `open-sse/translator/formats.ts` +- Bootstrap e registro: `open-sse/translator/bootstrap.ts`, `open-sse/translator/registry.ts` +- Helpers de formato de imagem: `open-sse/translator/image/` -### Persistence +### Persistência -- `src/lib/db/*`: persistent config/state and domain persistence on SQLite -- `src/lib/localDb.ts`: compatibility re-export for DB modules -- `src/lib/usageDb.ts`: usage history/call logs facade on top of SQLite tables +- `src/lib/db/*`: configuração/persistência de estado e domínio persistente no SQLite +- `src/lib/localDb.ts`: re-exportação de compatibilidade para módulos de DB +- `src/lib/usageDb.ts`: fachada de histórico de uso/logs de chamadas sobre tabelas SQLite -## Provider Executor Coverage (Strategy Pattern) +## Cobertura do Executor do Provedor (Padrão de Estratégia) -Each provider has a specialized executor extending `BaseExecutor` (in `open-sse/executors/base.ts`), which provides URL building, header construction, retry with exponential backoff, credential refresh hooks, and the `execute()` orchestration method. +Cada provedor possui um executor especializado que estende `BaseExecutor` (em `open-sse/executors/base.ts`), que fornece construção de URL, construção de cabeçalhos, tentativas com retrocesso exponencial, ganchos de atualização de credenciais e o método de orquestração `execute()`. -| Executor | Provider(s) | Special Handling | -| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA, etc. | Dynamic URL/header config per provider | -| `AntigravityExecutor` | Google Antigravity | Custom project/session IDs, Retry-After parsing | -| `CliProxyApiExecutor` | CLIProxyAPI-compatible providers | Custom auth and protocol handling | -| `CloudflareAiExecutor` | Cloudflare Workers AI | Account ID injection, Neurons-based usage tracking | -| `CodexExecutor` | OpenAI Codex | Injects system instructions, forces reasoning effort | -| `CursorExecutor` | Cursor IDE | ConnectRPC protocol, Protobuf encoding, request signing via checksum | -| `GithubExecutor` | GitHub Copilot | Copilot token refresh, VSCode-mimicking headers | -| `GeminiCLIExecutor` | Gemini CLI | Google OAuth token refresh cycle | -| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream binary format → SSE conversion | -| `OpenCodeExecutor` | OpenCode | AI SDK compatible provider setup | -| `PollinationsExecutor` | Pollinations AI | No API key required, rate-limited requests | -| `PuterExecutor` | Puter | Browser-based provider integration | -| `QoderExecutor` | Qoder AI | PAT and OAuth support, multi-model free tier | -| `VertexExecutor` | Google Vertex AI | Service account auth, region-based endpoints | +| Executor | Provedor(es) | Tratamento Especial | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | +| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA, etc. | Configuração dinâmica de URL/cabeçalho por provedor | +| `AntigravityExecutor` | Google Antigravity | IDs de projeto/sessão personalizados, análise de Retry-After, ofuscação de 429 | +| `AzureOpenAIExecutor` | Azure OpenAI | Roteamento baseado em implantação, aplicação de consulta de api-version | +| `BlackboxWebExecutor` | Blackbox AI (modo web) | Reversão de sessão web com emulação de impressão digital TLS | +| `ChatGPTWebExecutor` | ChatGPT web | Gerenciamento de cliente TLS + cookie de sessão (`chatgptTlsClient.ts`) | +| `ClaudeIdentityExecutor` | Claude.ai (caminho CCH) | Pipelines de restrição + remapeamento de ferramentas, modelagem de impressão digital | +| `CliProxyApiExecutor` | Provedores compatíveis com CLIProxyAPI | Tratamento personalizado de autenticação e protocolo | +| `CloudflareAiExecutor` | Cloudflare Workers AI | Injeção de ID de conta, rastreamento de uso baseado em Neurons | +| `CodexExecutor` | OpenAI Codex | Injeções de instruções do sistema, força de esforço de raciocínio | +| `CommandCodeExecutor` | Código de Comando | Rotação de cabeçalho por sessão + OAuth | +| `CursorExecutor` | Cursor IDE | Protocolo ConnectRPC, codificação Protobuf, assinatura de requisições via checksum | +| `DevinCliExecutor` | Devin CLI | Conexão do ciclo de vida da tarefa Devin via módulo de agente em nuvem | +| `GeminiCLIExecutor` | Gemini CLI | Ciclo de atualização de token OAuth do Google | +| `GithubExecutor` | GitHub Copilot | Atualização de token do Copilot, cabeçalhos imitando VSCode | +| `GitlabExecutor` | GitLab Duo | Roteamento baseado em projeto + OAuth do GitLab | +| `GlmExecutor` | Z.AI GLM (incl. preset `glmt`) | Consciente do orçamento de pensamento, constantes do preset GLMT | +| `GrokWebExecutor` | xAI Grok web | Reversão de sessão web, seleção de modo (pensar/padrão) | +| `KieExecutor` | KIE | Emissão de token personalizada com âncoras de sessão rotativas | +| `KiroExecutor` | AWS CodeWhisperer/Kiro | Formato binário do AWS EventStream → conversão para SSE | +| `MuseSparkWebExecutor` | Muse Spark (web) | Reversão de sessão web com integração de mensagem de imagem | +| `NlpCloudExecutor` | NLP Cloud | Formato de corpo de requisição específico do provedor | +| `OpenCodeExecutor` | OpenCode | Configuração de provedor compatível com AI SDK | +| `PerplexityWebExecutor` | Perplexity web | Reversão de sessão web para continuidade de chat | +| `PetalsExecutor` | Inferência distribuída Petals | Roteamento de enxame descentralizado | +| `PollinationsExecutor` | Pollinations AI | Nenhuma chave de API necessária, requisições limitadas por taxa | +| `PuterExecutor` | Puter | Integração de provedor baseada em navegador | +| `QoderExecutor` | Qoder AI | Suporte a PAT e OAuth, nível gratuito de múltiplos modelos | +| `VertexExecutor` | Google Vertex AI | Autenticação de conta de serviço, endpoints baseados em região | +| `WindsurfExecutor` | Windsurf (Codeium) | Atualização de token de sessão + OAuth do Codeium | -All other providers (including custom compatible nodes) use the `DefaultExecutor`. +Todos os outros provedores (incluindo nós compatíveis personalizados) usam o `DefaultExecutor`. -## Provider Compatibility Matrix +## Matriz de Compatibilidade de Provedores -| Provider | Format | Auth | Stream | Non-Stream | Token Refresh | Usage API | -| ---------------- | ---------------- | --------------------- | ---------------- | ---------- | ------------- | ------------------ | -| Claude | claude | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Admin only | -| Gemini | gemini | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console | -| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console | -| Antigravity | antigravity | OAuth | ✅ | ✅ | ✅ | ✅ Full quota API | -| OpenAI | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Codex | openai-responses | OAuth | ✅ forced | ❌ | ✅ | ✅ Rate limits | -| GitHub Copilot | openai | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Quota snapshots | -| Cursor | cursor | Custom checksum | ✅ | ✅ | ❌ | ❌ | -| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Usage limits | -| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ Per request | -| Qoder | openai | OAuth / PAT | ✅ | ✅ | ✅ | ⚠️ Per request | -| Kilo Code | openai | OAuth | ✅ | ✅ | ✅ | ❌ | -| Cline | openai | OAuth | ✅ | ✅ | ✅ | ❌ | -| Kimi Coding | openai | OAuth | ✅ | ✅ | ✅ | ❌ | -| OpenRouter | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| GLM/Kimi/MiniMax | claude | API Key | ✅ | ✅ | ❌ | ❌ | -| DeepSeek | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Groq | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| xAI (Grok) | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Mistral | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Perplexity | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Together AI | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Fireworks AI | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Cerebras | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Cohere | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| NVIDIA NIM | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Cloudflare AI | openai | API Token + Acct ID | ✅ | ✅ | ❌ | ❌ | -| Pollinations | openai | None (no key) | ✅ | ✅ | ❌ | ❌ | -| Scaleway AI | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| LongCat | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Ollama Cloud | openai | API Key (optional) | ✅ | ✅ | ❌ | ❌ | -| HuggingFace | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Nebius | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| SiliconFlow | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Hyperbolic | openai | API Key | ✅ | ✅ | ❌ | ❌ | -| Vertex AI | gemini | Service Account | ✅ | ✅ | ✅ | ⚠️ Cloud Console | -| Puter | openai | API Key | ✅ | ✅ | ❌ | ❌ | +> **Nota:** A matriz abaixo é uma amostra representativa dos 179 provedores registrados no +> OmniRoute v3.8.0. Para a lista canônica e continuamente atualizada, consulte +> [`docs/reference/PROVIDER_REFERENCE.md`](../reference/PROVIDER_REFERENCE.md) (gerada automaticamente) ou a fonte +> de verdade em `src/shared/constants/providers.ts` (validada pelo Zod no carregamento). -## Format Translation Coverage +| Provedor | Formato | Autenticação | Stream | Não-Stream | Atualização de Token | API de Uso | +| ----------------- | ---------------- | -------------------------- | ---------------- | ---------- | -------------------- | -------------------- | +| Claude | claude | Chave de API / OAuth | ✅ | ✅ | ✅ | ⚠️ Somente Admin | +| Gemini | gemini | Chave de API / OAuth | ✅ | ✅ | ✅ | ⚠️ Console da Nuvem | +| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Console da Nuvem | +| Antigravity | antigravity | OAuth | ✅ | ✅ | ✅ | ✅ API de cota total | +| OpenAI | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Codex | openai-responses | OAuth | ✅ forçado | ❌ | ✅ | ✅ Limites de taxa | +| GitHub Copilot | openai | OAuth + Token Copilot | ✅ | ✅ | ✅ | ✅ Capturas de cota | +| Cursor | cursor | Checksum personalizado | ✅ | ✅ | ❌ | ❌ | +| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Limites de uso | +| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ Por solicitação | +| Qoder | openai | OAuth / PAT | ✅ | ✅ | ✅ | ⚠️ Por solicitação | +| Kilo Code | openai | OAuth | ✅ | ✅ | ✅ | ❌ | +| Cline | openai | OAuth | ✅ | ✅ | ✅ | ❌ | +| Kimi Coding | openai | OAuth | ✅ | ✅ | ✅ | ❌ | +| OpenRouter | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| GLM/Kimi/MiniMax | claude | Chave de API | ✅ | ✅ | ❌ | ❌ | +| DeepSeek | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Groq | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| xAI (Grok) | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Mistral | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Perplexity | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Together AI | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Fireworks AI | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Cerebras | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Cohere | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| NVIDIA NIM | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Cloudflare AI | openai | Token de API + ID da Conta | ✅ | ✅ | ❌ | ❌ | +| Pollinations | openai | Nenhum (sem chave) | ✅ | ✅ | ❌ | ❌ | +| Scaleway AI | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| LongCat | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Ollama Cloud | openai | Chave de API (opcional) | ✅ | ✅ | ❌ | ❌ | +| HuggingFace | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Nebius | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| SiliconFlow | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Hyperbolic | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Vertex AI | gemini | Conta de Serviço | ✅ | ✅ | ✅ | ⚠️ Console da Nuvem | +| Puter | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Command Code | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ Por solicitação | +| Z.AI / GLM | openai | Chave de API / OAuth | ✅ | ✅ | ❌ | ❌ | +| GLMT (preset) | claude | Chave de API | ✅ | ✅ | ❌ | ⚠️ Por solicitação | +| Kimi Coding | openai | OAuth / Chave de API | ✅ | ✅ | ✅ | ❌ | +| KIE | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Windsurf | openai | OAuth (Codeium) | ✅ | ✅ | ✅ | ⚠️ Por solicitação | +| GitLab Duo | openai | OAuth (GitLab) | ✅ | ✅ | ✅ | ❌ | +| Devin CLI | openai | OAuth | ✅ | ✅ | ✅ | ✅ API de Tarefas | +| Codex Cloud | openai-responses | OAuth | ✅ | ❌ | ✅ | ✅ Limites de taxa | +| Jules | openai | OAuth | ✅ | ✅ | ✅ | ✅ API de Tarefas | +| AgentRouter | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| ChatGPT-Web | openai | Cookie de sessão + TLS | ✅ | ✅ | ❌ | ❌ | +| Grok-Web | openai | Cookie de sessão | ✅ | ✅ | ❌ | ❌ | +| Perplexity-Web | openai | Cookie de sessão | ✅ | ✅ | ❌ | ❌ | +| BlackBox-Web | openai | Cookie de sessão + TLS | ✅ | ✅ | ❌ | ❌ | +| Muse-Spark-Web | openai | Cookie de sessão | ✅ | ✅ | ❌ | ❌ | +| ModelScope | openai | Chave de API | ✅ | ✅ | ❌ | ⚠️ Política de cota | +| BazaarLink | openai | Chave de API | ✅ | ✅ | ❌ | ❌ | +| Petals | openai | Nenhum | ✅ | ✅ | ❌ | ❌ | +| Qoder | openai | OAuth / PAT | ✅ | ✅ | ✅ | ⚠️ Por solicitação | +| OpenCode (Go/Zen) | openai | OAuth | ✅ | ✅ | ✅ | ❌ | +| CLIProxyAPI | openai | Personalizado | ✅ | ✅ | ❌ | ❌ | -Detected source formats include: +## Cobertura de Tradução de Formato + +Os formatos de origem detectados incluem: - `openai` - `openai-responses` - `claude` - `gemini` -Target formats include: +Os formatos de destino incluem: -- OpenAI chat/Responses +- OpenAI chat/Respostas - Claude -- Gemini/Gemini-CLI/Antigravity envelope +- Gemini/Gemini-CLI/envelope Antigravity - Kiro - Cursor -Translations use **OpenAI as the hub format** — all conversions go through OpenAI as intermediate: +As traduções usam **OpenAI como o formato central** — todas as conversões passam pelo OpenAI como intermediário: ``` -Source Format → OpenAI (hub) → Target Format +Formato de Origem → OpenAI (central) → Formato de Destino ``` -Translations are selected dynamically based on source payload shape and provider target format. +As traduções são selecionadas dinamicamente com base na forma do payload de origem e no formato de destino do provedor. -Additional processing layers in the translation pipeline: +Camadas de processamento adicionais no pipeline de tradução: -- **Response sanitization** — Strips non-standard fields from OpenAI-format responses (both streaming and non-streaming) to ensure strict SDK compliance -- **Role normalization** — Converts `developer` → `system` for non-OpenAI targets; merges `system` → `user` for models that reject the system role (GLM, ERNIE) -- **Think tag extraction** — Parses `...` blocks from content into `reasoning_content` field -- **Structured output** — Converts OpenAI `response_format.json_schema` to Gemini's `responseMimeType` + `responseSchema` +- **Sanitização de resposta** — Remove campos não padrão das respostas no formato OpenAI (tanto streaming quanto não streaming) para garantir conformidade estrita com o SDK +- **Normalização de função** — Converte `developer` → `system` para alvos que não são OpenAI; mescla `system` → `user` para modelos que rejeitam a função de sistema (GLM, ERNIE) +- **Extração de tag de pensamento** — Analisa blocos ``do conteúdo para o campo`reasoning_content` +- **Saída estruturada** — Converte `response_format.json_schema` do OpenAI para `responseMimeType` + `responseSchema` do Gemini -## Supported API Endpoints +## Endpoints da API Suportados -| Endpoint | Format | Handler | -| -------------------------------------------------- | ------------------ | ------------------------------------------------------------------- | -| `POST /v1/chat/completions` | OpenAI Chat | `src/sse/handlers/chat.ts` | -| `POST /v1/messages` | Claude Messages | Same handler (auto-detected) | -| `POST /v1/responses` | OpenAI Responses | `open-sse/handlers/responsesHandler.ts` | -| `POST /v1/embeddings` | OpenAI Embeddings | `open-sse/handlers/embeddings.ts` | -| `GET /v1/embeddings` | Model listing | API route | -| `POST /v1/images/generations` | OpenAI Images | `open-sse/handlers/imageGeneration.ts` | -| `GET /v1/images/generations` | Model listing | API route | -| `POST /v1/providers/{provider}/chat/completions` | OpenAI Chat | Dedicated per-provider with model validation | -| `POST /v1/providers/{provider}/embeddings` | OpenAI Embeddings | Dedicated per-provider with model validation | -| `POST /v1/providers/{provider}/images/generations` | OpenAI Images | Dedicated per-provider with model validation | -| `POST /v1/messages/count_tokens` | Claude Token Count | API route | -| `GET /v1/models` | OpenAI Models list | API route (chat + embedding + image + custom models) | -| `GET /api/models/catalog` | Catalog | All models grouped by provider + type | -| `POST /v1beta/models/*:streamGenerateContent` | Gemini native | API route | -| `GET/PUT/DELETE /api/settings/proxy` | Proxy Config | Network proxy configuration | -| `POST /api/settings/proxy/test` | Proxy Connectivity | Proxy health/connectivity test endpoint | -| `GET/POST/DELETE /api/provider-models` | Provider Models | Provider model metadata backing custom and managed available models | +| Endpoint | Formato | Manipulador | +| -------------------------------------------------- | ------------------------- | --------------------------------------------------------------------------------------------- | +| `POST /v1/chat/completions` | OpenAI Chat | `src/sse/handlers/chat.ts` | +| `POST /v1/messages` | Claude Messages | Mesmo manipulador (detecção automática) | +| `POST /v1/responses` | OpenAI Respostas | `open-sse/handlers/responsesHandler.ts` | +| `POST /v1/embeddings` | OpenAI Embeddings | `open-sse/handlers/embeddings.ts` | +| `GET /v1/embeddings` | Listagem de Modelos | Rota da API | +| `POST /v1/images/generations` | OpenAI Imagens | `open-sse/handlers/imageGeneration.ts` | +| `GET /v1/images/generations` | Listagem de Modelos | Rota da API | +| `POST /v1/providers/{provider}/chat/completions` | OpenAI Chat | Dedicado por provedor com validação de modelo | +| `POST /v1/providers/{provider}/embeddings` | OpenAI Embeddings | Dedicado por provedor com validação de modelo | +| `POST /v1/providers/{provider}/images/generations` | OpenAI Imagens | Dedicado por provedor com validação de modelo | +| `POST /v1/messages/count_tokens` | Contagem de Tokens Claude | Rota da API | +| `GET /v1/models` | Lista de Modelos OpenAI | Rota da API (chat + embedding + imagem + modelos personalizados) | +| `GET /api/models/catalog` | Catálogo | Todos os modelos agrupados por provedor + tipo | +| `POST /v1beta/models/*:streamGenerateContent` | Nativo do Gemini | Rota da API | +| `GET/PUT/DELETE /api/settings/proxy` | Configuração de Proxy | Configuração de proxy de rede | +| `POST /api/settings/proxy/test` | Conectividade de Proxy | Endpoint de teste de saúde/conectividade do proxy | +| `GET/POST/DELETE /api/provider-models` | Modelos de Provedor | Metadados do modelo do provedor que suportam modelos disponíveis personalizados e gerenciados | -## Bypass Handler +## Manipulador de Bypass -The bypass handler (`open-sse/utils/bypassHandler.ts`) intercepts known "throwaway" requests from Claude CLI — warmup pings, title extractions, and token counts — and returns a **fake response** without consuming upstream provider tokens. This is triggered only when `User-Agent` contains `claude-cli`. +O manipulador de bypass (`open-sse/utils/bypassHandler.ts`) intercepta solicitações conhecidas como "descartáveis" do Claude CLI — pings de aquecimento, extrações de título e contagens de tokens — e retorna uma **resposta falsa** sem consumir tokens do provedor upstream. Isso é acionado apenas quando o `User-Agent` contém `claude-cli`. -## Request Logging and Artifacts +## Registro de Solicitações e Artefatos -The older file-based request logger (`open-sse/utils/requestLogger.ts`) is retained only for -legacy compatibility. The current runtime contract uses: +O antigo registrador de solicitações baseado em arquivo (`open-sse/utils/requestLogger.ts`) é mantido apenas para compatibilidade com versões anteriores. O contrato de tempo de execução atual utiliza: -- `APP_LOG_TO_FILE=true` for application and audit logs written under `/logs/` -- SQLite-backed call log records in `call_logs` -- `${DATA_DIR}/call_logs/YYYY-MM-DD/...` artifacts when the call log pipeline is enabled +- `APP_LOG_TO_FILE=true` para logs de aplicação e auditoria gravados em `/logs/` +- Registros de log de chamadas com suporte a SQLite em `call_logs` +- Artefatos em `${DATA_DIR}/call_logs/YYYY-MM-DD/...` quando o pipeline de log de chamadas está habilitado -## Failure Modes and Resilience +## Modos de Falha e Resiliência -## 1) Account/Provider Availability +## 1) Disponibilidade de Conta/Provedor -- connection cooldown on retryable upstream failures -- account fallback before failing request -- combo model fallback when current model/provider path is exhausted +- cooldown de conexão em falhas upstream recuperáveis +- fallback de conta antes de falhar a solicitação +- fallback de modelo combinado quando o caminho atual de modelo/provedor é esgotado -## 2) Token Expiry +## 2) Expiração de Token -- pre-check and refresh with retry for refreshable providers -- 401/403 retry after refresh attempt in core path +- pré-verificação e atualização com tentativa de repetição para provedores atualizáveis +- tentativa de repetição 401/403 após tentativa de atualização no caminho principal -## 3) Stream Safety +## 3) Segurança do Stream -- disconnect-aware stream controller -- translation stream with end-of-stream flush and `[DONE]` handling -- usage estimation fallback when provider usage metadata is missing +- controlador de stream ciente de desconexões +- stream de tradução com descarte de fim de stream e tratamento de `[DONE]` +- fallback de estimativa de uso quando os metadados de uso do provedor estão ausentes -## 4) Cloud Sync Degradation +## 4) Degradação da Sincronização na Nuvem -- sync errors are surfaced but local runtime continues -- scheduler has retry-capable logic, but periodic execution currently calls single-attempt sync by default +- erros de sincronização são exibidos, mas o tempo de execução local continua +- o agendador possui lógica capaz de repetição, mas a execução periódica atualmente chama a sincronização de tentativa única por padrão -## 5) Data Integrity +## 5) Integridade dos Dados -- SQLite schema migrations and auto-upgrade hooks at startup -- legacy JSON → SQLite migration compatibility path +- migrações de esquema SQLite e ganchos de autoatualização na inicialização +- caminho de compatibilidade de migração legado JSON → SQLite -## 6) SSRF / Outbound URL Guard +## 6) SSRF / Proteção de URL de Saída -- `src/shared/network/outboundUrlGuard.ts` blocks all private/loopback/link-local target URLs before they reach provider executors -- Provider model discovery and validation routes use `src/shared/network/safeOutboundFetch.ts` which applies the guard before every outbound request -- Guard errors surface as `URL_GUARD_BLOCKED` with HTTP 422 and are logged to the compliance audit trail via `providerAudit.ts` +- `src/shared/network/outboundUrlGuard.ts` bloqueia todas as URLs de destino privadas/loopback/link-local antes que elas cheguem aos executores do provedor +- As rotas de descoberta e validação do modelo do provedor usam `src/shared/network/safeOutboundFetch.ts`, que aplica a proteção antes de cada solicitação de saída +- Erros de proteção aparecem como `URL_GUARD_BLOCKED` com HTTP 422 e são registrados na trilha de auditoria de conformidade via `providerAudit.ts` -## Observability and Operational Signals +## Observabilidade e Sinais Operacionais -Runtime visibility sources: +Fontes de visibilidade em tempo de execução: -- console logs from `src/sse/utils/logger.ts` -- per-request usage aggregates in SQLite (`usage_history`, `call_logs`, `proxy_logs`) -- four-stage detailed payload captures in SQLite (`request_detail_logs`) when `settings.detailed_logs_enabled=true` -- textual request status log in `log.txt` (optional/compat) -- optional application log files under `logs/` when `APP_LOG_TO_FILE=true` -- optional request artifacts under `${DATA_DIR}/call_logs/` when the call log pipeline is enabled -- dashboard usage endpoints (`/api/usage/*`) for UI consumption +- logs do console de `src/sse/utils/logger.ts` +- agregados de uso por solicitação em SQLite (`usage_history`, `call_logs`, `proxy_logs`) +- capturas detalhadas de payload em quatro estágios em SQLite (`request_detail_logs`) quando `settings.detailed_logs_enabled=true` +- log de status de solicitação textual em `log.txt` (opcional/compat) +- arquivos de log de aplicação opcionais em `logs/` quando `APP_LOG_TO_FILE=true` +- artefatos de solicitação opcionais em `${DATA_DIR}/call_logs/` quando o pipeline de log de chamadas está habilitado +- endpoints de uso do dashboard (`/api/usage/*`) para consumo da UI -Detailed request payload capture stores up to four JSON payload stages per routed call: +A captura detalhada do payload da solicitação armazena até quatro estágios de payload JSON por chamada roteada: -- raw request received from the client -- translated request actually sent upstream -- provider response reconstructed as JSON; streamed responses are compacted to the final summary plus stream metadata -- final client response returned by OmniRoute; streamed responses are stored in the same compact summary form +- solicitação bruta recebida do cliente +- solicitação traduzida realmente enviada para upstream +- resposta do provedor reconstruída como JSON; respostas transmitidas são compactadas para o resumo final mais metadados do stream +- resposta final do cliente retornada pelo OmniRoute; respostas transmitidas são armazenadas na mesma forma de resumo compacto -## Security-Sensitive Boundaries +## Limites Sensíveis à Segurança -- JWT secret (`JWT_SECRET`) secures dashboard session cookie verification/signing -- Initial password bootstrap (`INITIAL_PASSWORD`) should be explicitly configured for first-run provisioning -- API key HMAC secret (`API_KEY_SECRET`) secures generated local API key format -- Provider secrets (API keys/tokens) are persisted in local DB and should be protected at filesystem level -- Cloud sync endpoints rely on API key auth + machine id semantics +- O segredo do JWT (`JWT_SECRET`) protege a verificação/assinatura do cookie de sessão do painel +- A senha inicial de bootstrap (`INITIAL_PASSWORD`) deve ser configurada explicitamente para o provisionamento na primeira execução +- O segredo HMAC da chave da API (`API_KEY_SECRET`) protege o formato da chave da API local gerada +- Segredos do provedor (chaves/tokens da API) são persistidos no banco de dados local e devem ser protegidos a nível de sistema de arquivos +- Os endpoints de sincronização em nuvem dependem da autenticação da chave da API + semântica do id da máquina -## Environment and Runtime Matrix +## Matriz de Ambiente e Tempo de Execução -Environment variables actively used by code: +Variáveis de ambiente ativamente usadas pelo código: - App/auth: `JWT_SECRET`, `INITIAL_PASSWORD` -- Storage: `DATA_DIR` -- Compatible node behavior: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE` -- Optional storage base override (Linux/macOS when `DATA_DIR` unset): `XDG_CONFIG_HOME` -- Security hashing: `API_KEY_SECRET`, `MACHINE_ID_SALT` -- Logging: `APP_LOG_TO_FILE`, `APP_LOG_RETENTION_DAYS`, `CALL_LOG_RETENTION_DAYS` -- Sync/cloud URLing: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL` -- Outbound proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` and lowercase variants -- SOCKS5 feature flags: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` -- Platform/runtime helpers (not app-specific config): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME` +- Armazenamento: `DATA_DIR` +- Comportamento compatível do node: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE` +- Sobrescrita opcional da base de armazenamento (Linux/macOS quando `DATA_DIR` não estiver definido): `XDG_CONFIG_HOME` +- Hashing de segurança: `API_KEY_SECRET`, `MACHINE_ID_SALT` +- Registro: `APP_LOG_TO_FILE`, `APP_LOG_RETENTION_DAYS`, `CALL_LOG_RETENTION_DAYS` +- URL de sincronização/nuvem: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL` +- Proxy de saída: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` e variantes em minúsculas +- Flags de recurso SOCKS5: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` +- Auxiliares de plataforma/tempo de execução (não configuração específica do app): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME` -## Known Architectural Notes +## Notas Arquitetônicas Conhecidas -1. `usageDb` and `localDb` share the same base directory policy (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) with legacy file migration. -2. `/api/v1/route.ts` delegates to the same unified catalog builder used by `/api/v1/models` (`src/app/api/v1/models/catalog.ts`) to avoid semantic drift. -3. Request logger writes full headers/body when enabled; treat log directory as sensitive. -4. Cloud behavior depends on correct `NEXT_PUBLIC_BASE_URL` and cloud endpoint reachability. -5. The `open-sse/` directory is published as the `@omniroute/open-sse` **npm workspace package**. Source code imports it via `@omniroute/open-sse/...` (resolved by Next.js `transpilePackages`). File paths in this document still use the directory name `open-sse/` for consistency. -6. Charts in the dashboard use **Recharts** (SVG-based) for accessible, interactive analytics visualizations (model usage bar charts, provider breakdown tables with success rates). -7. E2E tests use **Playwright** (`tests/e2e/`), run via `npm run test:e2e`. Unit tests use **Node.js test runner** (`tests/unit/`), run via `npm run test:unit`. Source code under `src/` is **TypeScript** (`.ts`/`.tsx`); the `open-sse/` workspace remains JavaScript (`.js`). -8. Settings page is organized into 7 tabs: General, Appearance, AI, Security, Routing, Resilience, Advanced. The Resilience page only configures request queue, connection cooldown, provider breaker, and wait-for-cooldown behavior; live breaker runtime state is shown on the Health page. -9. **Context Relay** strategy (`context-relay`) is split across two layers: `combo.ts` decides if a handoff should be generated, `chat.ts` injects the handoff after account resolution. Handoff data lives in `context_handoffs` SQLite table. This split is intentional because only `chat.ts` knows whether the actual account changed. -10. **Proxy enforcement** is now comprehensive: `tokenHealthCheck.ts` resolves proxy per connection, `/api/providers/validate` uses `runWithProxyContext`, and `proxyFetch.ts` uses `undici.fetch()` to maintain dispatcher compatibility on Node 22. -11. **Node.js runtime policy detection**: `/api/settings/require-login` returns `nodeVersion` and `nodeCompatible` fields. The login page renders a warning banner when the runtime falls outside the supported secure Node.js lines. +1. `usageDb` e `localDb` compartilham a mesma política de diretório base (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) com migração de arquivos legados. +2. `/api/v1/route.ts` delega para o mesmo construtor de catálogo unificado usado por `/api/v1/models` (`src/app/api/v1/models/catalog.ts`) para evitar desvios semânticos. +3. O registrador de solicitações escreve cabeçalhos/corpo completos quando habilitado; trate o diretório de logs como sensível. +4. O comportamento em nuvem depende do correto `NEXT_PUBLIC_BASE_URL` e da acessibilidade do endpoint em nuvem. +5. O diretório `open-sse/` é publicado como o pacote de **workspace npm** `@omniroute/open-sse`. O código-fonte o importa via `@omniroute/open-sse/...` (resolvido pelo Next.js `transpilePackages`). Os caminhos de arquivos neste documento ainda usam o nome do diretório `open-sse/` para consistência. +6. Gráficos no painel usam **Recharts** (baseado em SVG) para visualizações analíticas interativas e acessíveis (gráficos de barras de uso de modelo, tabelas de divisão de provedores com taxas de sucesso). +7. Testes E2E usam **Playwright** (`tests/e2e/`), executados via `npm run test:e2e`. Testes unitários usam **Node.js test runner** (`tests/unit/`), executados via `npm run test:unit`. O código-fonte sob `src/` é **TypeScript** (`.ts`/`.tsx`); o workspace `open-sse/` permanece em JavaScript (`.js`). +8. A página de configurações é organizada em 7 abas: Geral, Aparência, IA, Segurança, Roteamento, Resiliência, Avançado. A página de Resiliência configura apenas a fila de solicitações, o tempo de espera de conexão, o disjuntor do provedor e o comportamento de espera pelo tempo de espera; o estado de tempo de execução do disjuntor ao vivo é mostrado na página de Saúde. +9. A estratégia de **Context Relay** (`context-relay`) é dividida em duas camadas: `combo.ts` decide se uma transferência deve ser gerada, `chat.ts` injeta a transferência após a resolução da conta. Os dados da transferência vivem na tabela SQLite `context_handoffs`. Essa divisão é intencional porque apenas `chat.ts` sabe se a conta real mudou. +10. A **aplicação de proxy** agora é abrangente: `tokenHealthCheck.ts` resolve o proxy por conexão, `/api/providers/validate` usa `runWithProxyContext`, e `proxyFetch.ts` usa `undici.fetch()` para manter a compatibilidade do despachante no Node 22. +11. **Detecção de política de tempo de execução do Node.js**: `/api/settings/require-login` retorna os campos `nodeVersion` e `nodeCompatible`. A página de login renderiza um banner de aviso quando o tempo de execução está fora das linhas seguras suportadas do Node.js. -## Operational Verification Checklist +## Lista de Verificação de Verificação Operacional -- Build from source: `npm run build` -- Build Docker image: `docker build -t omniroute .` -- Start service and verify: +- Compilar a partir do código-fonte: `npm run build` +- Construir a imagem Docker: `docker build -t omniroute .` +- Iniciar o serviço e verificar: - `GET /api/settings` - `GET /api/v1/models` -- CLI target base URL should be `http://:20128/v1` when `PORT=20128` +- A URL base do alvo da CLI deve ser `http://:20128/v1` quando `PORT=20128`