From b49d5f6a9836fa00aa53b671880f41e4f089c8ec Mon Sep 17 00:00:00 2001 From: backryun Date: Wed, 12 Aug 2026 12:30:40 -0300 Subject: [PATCH] docs: merge duplicate guides (troubleshooting, chatgpt-web codex, docker channels, memory backend) --- docs/architecture/QUALITY_GATES.md | 4 +- docs/frameworks/MEMORY.md | 226 ++++++++ docs/frameworks/MEMORY_BACKEND.md | 228 -------- docs/getting-started/AUTO-COMBO-GUIDE.md | 2 +- docs/getting-started/FREE-TIERS-GUIDE.md | 2 +- docs/getting-started/PROVIDERS-GUIDE.md | 2 +- docs/getting-started/QUICK-START.md | 4 +- docs/getting-started/TROUBLESHOOTING.md | 498 ------------------ docs/guides/DOCKER_GUIDE.md | 51 ++ docs/guides/DOCKER_RELEASE_CHANNELS.md | 58 -- docs/guides/TROUBLESHOOTING.md | 13 + .../docs/getting-started/TROUBLESHOOTING.md | 498 ------------------ docs/ops/QUALITY_GATE_PLAYBOOK.md | 4 + docs/providers/CHATGPT_WEB.md | 96 ++++ docs/providers/CHATGPT_WEB_CODEX.md | 94 ---- 15 files changed, 398 insertions(+), 1382 deletions(-) delete mode 100644 docs/frameworks/MEMORY_BACKEND.md delete mode 100644 docs/getting-started/TROUBLESHOOTING.md delete mode 100644 docs/guides/DOCKER_RELEASE_CHANNELS.md delete mode 100644 docs/i18n/pl/docs/getting-started/TROUBLESHOOTING.md delete mode 100644 docs/providers/CHATGPT_WEB_CODEX.md diff --git a/docs/architecture/QUALITY_GATES.md b/docs/architecture/QUALITY_GATES.md index 34c05d0699..a7a3421cd7 100644 --- a/docs/architecture/QUALITY_GATES.md +++ b/docs/architecture/QUALITY_GATES.md @@ -9,7 +9,9 @@ It describes each gate, what it validates, which CI job it runs in, whether it u a ratchet baseline or a pass/fail policy, and whether it blocks the build or is advisory. For a short summary and the allowlist policy, see the "Quality Gates & Ratchets" section -in `CLAUDE.md`. +in `CLAUDE.md`. For the critical assessment, maturity classification, and tool-agnostic +replication plan of the same system, see the +[Quality Gate Playbook](../ops/QUALITY_GATE_PLAYBOOK.md). --- diff --git a/docs/frameworks/MEMORY.md b/docs/frameworks/MEMORY.md index 3f41c8a210..7f14a707a8 100644 --- a/docs/frameworks/MEMORY.md +++ b/docs/frameworks/MEMORY.md @@ -888,3 +888,229 @@ To leave it off, simply keep `autoSummarize` at its default (`false`). 0 3 * * * curl -X POST http://localhost:20128/api/memory/summarize \ -H "Authorization: Bearer $OMNIROUTE_KEY" ``` + +--- + + +## MemoryBackend Provider Pattern + +> **Source of truth:** `src/lib/memory/backend.ts`, `src/lib/memory/genericBackend.ts`, `src/lib/memory/manager.ts` +> **Tests:** `src/lib/memory/__tests__/generic-backend.test.ts` + +The MemoryBackend provider pattern introduces a **pluggable backend abstraction layer** over the existing memory engine. Instead of being tied to a single storage implementation, the memory system now supports multiple backends (SQLite, Obsidian, Notion, custom HTTP backends) with configurable primary/fallback routing. + +### Architecture + +``` +┌──────────────────────────────────────────────────────────┐ +│ API Routes │ +│ (src/app/api/memory/route.ts) │ +└──────────────────────┬───────────────────────────────────┘ + │ +┌──────────────────────▼───────────────────────────────────┐ +│ MemoryManager │ +│ Singleton orchestrator (manager.ts) │ +│ │ +│ Primary ──► Backend A (e.g. SQLite) │ +│ Fallback ─► Backend B (e.g. Obsidian) │ +│ Backend C (e.g. Notion via GenericBackend) │ +└──────────────────────┬───────────────────────────────────┘ + │ + ┌──────────────┼──────────────┐ + ▼ ▼ ▼ +┌────────────┐ ┌────────────┐ ┌──────────────────┐ +│ SQLite │ │ Obsidian │ │ GenericMemory │ +│ Backend │ │ Backend │ │ Backend (HTTP) │ +└────────────┘ └────────────┘ └──────────────────┘ +``` + +#### Core Interface (`backend.ts`) + +Every backend must implement the `MemoryBackend` interface: + +```typescript +interface MemoryBackend { + readonly id: string; + readonly displayName: string; + + // CRUD + create(input: CreateMemoryInput): Promise; + get(id: string): Promise; + update(id: string, updates: Partial<...>): Promise; + delete(id: string): Promise; + list(filter: MemoryFilter): Promise<{ data: Memory[]; total: number; byType: Record }>; + + // Search + search(config: SearchConfig): Promise; + + // Health + health(): Promise; + + // Lifecycle (optional) + initialize?(): Promise; + shutdown?(): Promise; +} +``` + +#### MemoryManager (`manager.ts`) + +Singleton orchestrator that: + +- **Registers** backends via `register(backend)` — called at boot from `index.ts` +- **Configures** primary + fallback via `configure(primary, fallbacks)` +- **Routes** CRUD/search to the primary, with fallback chain on failure +- **Health checks** all backends periodically + +**Fallback behavior:** + +| Operation | Primary | Fallbacks | +| --------- | -------------------- | ----------------------- | +| `create` | ✅ Primary only | ❌ | +| `get` | ✅ Try primary first | ✅ Fallback if null | +| `update` | ✅ Primary only | ✅ Fire-and-forget sync | +| `delete` | ✅ Primary only | ✅ Fire-and-forget sync | +| `list` | ✅ Primary only | ❌ | +| `search` | ✅ Primary first | ✅ Fallback on error | + +#### GenericMemoryBackend (`genericBackend.ts`) + +A generic HTTP connector that adapts any REST API into a MemoryBackend. Useful for: + +- **Notion** — connect via Notion API +- **Obsidian** — connect via Obsidian Local REST API +- **Custom backends** — any service that exposes a RESTful memory API + +**Configuration:** + +```typescript +interface GenericBackendConfig { + baseUrl: string; // Base URL of the backend API + apiKey?: string; // Bearer token for auth + headers?: Record; // Custom HTTP headers + timeout?: number; // Request timeout (default: 30000ms) + backendType?: string; // For logging + + // Endpoint overrides (defaults use REST conventions) + endpoints?: { + search?: string; // default: "/memories/search" + create?: string; // default: "/memories" + list?: string; // default: "/memories" + get?: string; // default: "/memories/{id}" + update?: string; // default: "/memories/{id}" + delete?: string; // default: "/memories/{id}" + health?: string; // default: "/health" + }; + + // Query parameter name mappings + queryParams?: { + query?/apiKeyId?/limit?/offset?/strategy?/maxTokens?/type?/sessionId?/orderBy?/orderDir?/options? + }; + + // Path parameter name mappings + pathParams?: { + id?/memoryId? + }; +} +``` + +**Known backends** are pre-configured in `KNOWN_BACKENDS`: + +```typescript +createKnownBackend("obsidian"); // → GenericMemoryBackend pointed at localhost:27123 +createKnownBackend("notion"); // → GenericMemoryBackend pointed at api.notion.com/v1 +``` + +#### Built-in Backends + +##### SQLiteBackend (`sqliteBackend.ts`) + +The default primary backend. Wraps the existing SQLite-based memory store using `src/lib/memory/store.ts`. Automatically registered at boot. + +```typescript +import { sqliteBackend } from "./sqliteBackend"; +memoryManager.register(sqliteBackend); +``` + +##### ObsidianBackend (`obsidianBackend.ts`) + +Wraps the existing Obsidian integration (`src/lib/memory/obsidianBackend.ts`). Connects to an Obsidian vault via the Obsidian Local REST API. + +### Settings + +Memory backend settings are stored in the app settings table and managed via `src/lib/memory/settings.ts`: + +| Setting | Env/Config Key | Default | Description | +| ----------------- | ------------------------ | ---------- | ---------------------------- | +| Primary backend | `memoryPrimaryBackend` | `"sqlite"` | ID of the primary backend | +| Fallback backends | `memoryFallbackBackends` | `[]` | Ordered fallback backend IDs | +| Backend configs | `memoryBackendConfigs` | `{}` | Per-backend config overrides | + +Settings are normalized via `normalizeMemorySettings()` and cached at `getMemorySettings()`. + +### Initialization Flow + +``` +App bootstrap + → index.ts imports (side-effect): registers SQLiteBackend + → initMemoryBackends() called from app lifecycle: + 1. Load settings (getMemorySettings) + 2. Configure primary + fallback + 3. Initialize all backends (health check) + 4. Ready for requests +``` + +### Adding a New Backend + +1. **Implement `MemoryBackend`** interface in `src/lib/memory/Backend.ts` +2. **Export** from `src/lib/memory/index.ts` +3. **Register** with `memoryManager.register(yourBackend)` at boot +4. **Configure** via settings: set `memoryPrimaryBackend` to your backend ID +5. **Test** with `src/lib/memory/__tests__/generic-backend.test.ts` as reference + +#### Example: Brain Backend + +```typescript +import { createGenericMemoryBackend } from "./genericBackend"; + +const brainBackend = createGenericMemoryBackend("brain", "BK-Brain", { + baseUrl: process.env.BRAIN_API_URL || "http://localhost:9099", + apiKey: process.env.BRAIN_API_KEY, + endpoints: { + search: "/api/memory/search", + create: "/api/memory", + health: "/api/health", + }, +}); + +memoryManager.register(brainBackend); +``` + +### Verification + +#### Unit tests + +```bash +npx vitest run src/lib/memory/__tests__/generic-backend.test.ts --reporter=verbose +``` + +Expected output: **26 tests, all passing** covering: + +- Constructor (2) +- Health check (4) — success, failure 500, network error, latency +- Initialize (2) — success, failure +- Create (2) — default endpoint, custom endpoint +- Get (4) — success, 404 → null, non-404 throw, custom path params +- Update (2) — success, 404 → false +- Delete (2) — success, 404 → false +- List (2) — query params, custom param names +- Search (3) — query params, custom endpoint, options serialization +- Auth headers (2) — Bearer token, custom headers +- Factory (1) + +#### Type check + +```bash +npm run typecheck:core +``` + +Expected: **0 errors**. diff --git a/docs/frameworks/MEMORY_BACKEND.md b/docs/frameworks/MEMORY_BACKEND.md deleted file mode 100644 index e76a5e476f..0000000000 --- a/docs/frameworks/MEMORY_BACKEND.md +++ /dev/null @@ -1,228 +0,0 @@ ---- -title: "MemoryBackend Provider Pattern" -version: 3.8.49 -lastUpdated: 2026-07-28 ---- - -# MemoryBackend Provider Pattern - -> **Source of truth:** `src/lib/memory/backend.ts`, `src/lib/memory/genericBackend.ts`, `src/lib/memory/manager.ts` -> **Tests:** `src/lib/memory/__tests__/generic-backend.test.ts` - -The MemoryBackend provider pattern introduces a **pluggable backend abstraction layer** over the existing memory engine. Instead of being tied to a single storage implementation, the memory system now supports multiple backends (SQLite, Obsidian, Notion, custom HTTP backends) with configurable primary/fallback routing. - -## Architecture - -``` -┌──────────────────────────────────────────────────────────┐ -│ API Routes │ -│ (src/app/api/memory/route.ts) │ -└──────────────────────┬───────────────────────────────────┘ - │ -┌──────────────────────▼───────────────────────────────────┐ -│ MemoryManager │ -│ Singleton orchestrator (manager.ts) │ -│ │ -│ Primary ──► Backend A (e.g. SQLite) │ -│ Fallback ─► Backend B (e.g. Obsidian) │ -│ Backend C (e.g. Notion via GenericBackend) │ -└──────────────────────┬───────────────────────────────────┘ - │ - ┌──────────────┼──────────────┐ - ▼ ▼ ▼ -┌────────────┐ ┌────────────┐ ┌──────────────────┐ -│ SQLite │ │ Obsidian │ │ GenericMemory │ -│ Backend │ │ Backend │ │ Backend (HTTP) │ -└────────────┘ └────────────┘ └──────────────────┘ -``` - -### Core Interface (`backend.ts`) - -Every backend must implement the `MemoryBackend` interface: - -```typescript -interface MemoryBackend { - readonly id: string; - readonly displayName: string; - - // CRUD - create(input: CreateMemoryInput): Promise; - get(id: string): Promise; - update(id: string, updates: Partial<...>): Promise; - delete(id: string): Promise; - list(filter: MemoryFilter): Promise<{ data: Memory[]; total: number; byType: Record }>; - - // Search - search(config: SearchConfig): Promise; - - // Health - health(): Promise; - - // Lifecycle (optional) - initialize?(): Promise; - shutdown?(): Promise; -} -``` - -### MemoryManager (`manager.ts`) - -Singleton orchestrator that: - -- **Registers** backends via `register(backend)` — called at boot from `index.ts` -- **Configures** primary + fallback via `configure(primary, fallbacks)` -- **Routes** CRUD/search to the primary, with fallback chain on failure -- **Health checks** all backends periodically - -**Fallback behavior:** - -| Operation | Primary | Fallbacks | -| --------- | -------------------- | ----------------------- | -| `create` | ✅ Primary only | ❌ | -| `get` | ✅ Try primary first | ✅ Fallback if null | -| `update` | ✅ Primary only | ✅ Fire-and-forget sync | -| `delete` | ✅ Primary only | ✅ Fire-and-forget sync | -| `list` | ✅ Primary only | ❌ | -| `search` | ✅ Primary first | ✅ Fallback on error | - -### GenericMemoryBackend (`genericBackend.ts`) - -A generic HTTP connector that adapts any REST API into a MemoryBackend. Useful for: - -- **Notion** — connect via Notion API -- **Obsidian** — connect via Obsidian Local REST API -- **Custom backends** — any service that exposes a RESTful memory API - -**Configuration:** - -```typescript -interface GenericBackendConfig { - baseUrl: string; // Base URL of the backend API - apiKey?: string; // Bearer token for auth - headers?: Record; // Custom HTTP headers - timeout?: number; // Request timeout (default: 30000ms) - backendType?: string; // For logging - - // Endpoint overrides (defaults use REST conventions) - endpoints?: { - search?: string; // default: "/memories/search" - create?: string; // default: "/memories" - list?: string; // default: "/memories" - get?: string; // default: "/memories/{id}" - update?: string; // default: "/memories/{id}" - delete?: string; // default: "/memories/{id}" - health?: string; // default: "/health" - }; - - // Query parameter name mappings - queryParams?: { - query?/apiKeyId?/limit?/offset?/strategy?/maxTokens?/type?/sessionId?/orderBy?/orderDir?/options? - }; - - // Path parameter name mappings - pathParams?: { - id?/memoryId? - }; -} -``` - -**Known backends** are pre-configured in `KNOWN_BACKENDS`: - -```typescript -createKnownBackend("obsidian"); // → GenericMemoryBackend pointed at localhost:27123 -createKnownBackend("notion"); // → GenericMemoryBackend pointed at api.notion.com/v1 -``` - -### Built-in Backends - -#### SQLiteBackend (`sqliteBackend.ts`) - -The default primary backend. Wraps the existing SQLite-based memory store using `src/lib/memory/store.ts`. Automatically registered at boot. - -```typescript -import { sqliteBackend } from "./sqliteBackend"; -memoryManager.register(sqliteBackend); -``` - -#### ObsidianBackend (`obsidianBackend.ts`) - -Wraps the existing Obsidian integration (`src/lib/memory/obsidianBackend.ts`). Connects to an Obsidian vault via the Obsidian Local REST API. - -## Settings - -Memory backend settings are stored in the app settings table and managed via `src/lib/memory/settings.ts`: - -| Setting | Env/Config Key | Default | Description | -| ----------------- | ------------------------ | ---------- | ---------------------------- | -| Primary backend | `memoryPrimaryBackend` | `"sqlite"` | ID of the primary backend | -| Fallback backends | `memoryFallbackBackends` | `[]` | Ordered fallback backend IDs | -| Backend configs | `memoryBackendConfigs` | `{}` | Per-backend config overrides | - -Settings are normalized via `normalizeMemorySettings()` and cached at `getMemorySettings()`. - -## Initialization Flow - -``` -App bootstrap - → index.ts imports (side-effect): registers SQLiteBackend - → initMemoryBackends() called from app lifecycle: - 1. Load settings (getMemorySettings) - 2. Configure primary + fallback - 3. Initialize all backends (health check) - 4. Ready for requests -``` - -## Adding a New Backend - -1. **Implement `MemoryBackend`** interface in `src/lib/memory/Backend.ts` -2. **Export** from `src/lib/memory/index.ts` -3. **Register** with `memoryManager.register(yourBackend)` at boot -4. **Configure** via settings: set `memoryPrimaryBackend` to your backend ID -5. **Test** with `src/lib/memory/__tests__/generic-backend.test.ts` as reference - -### Example: Brain Backend - -```typescript -import { createGenericMemoryBackend } from "./genericBackend"; - -const brainBackend = createGenericMemoryBackend("brain", "BK-Brain", { - baseUrl: process.env.BRAIN_API_URL || "http://localhost:9099", - apiKey: process.env.BRAIN_API_KEY, - endpoints: { - search: "/api/memory/search", - create: "/api/memory", - health: "/api/health", - }, -}); - -memoryManager.register(brainBackend); -``` - -## Verification - -### Unit tests - -```bash -npx vitest run src/lib/memory/__tests__/generic-backend.test.ts --reporter=verbose -``` - -Expected output: **26 tests, all passing** covering: - -- Constructor (2) -- Health check (4) — success, failure 500, network error, latency -- Initialize (2) — success, failure -- Create (2) — default endpoint, custom endpoint -- Get (4) — success, 404 → null, non-404 throw, custom path params -- Update (2) — success, 404 → false -- Delete (2) — success, 404 → false -- List (2) — query params, custom param names -- Search (3) — query params, custom endpoint, options serialization -- Auth headers (2) — Bearer token, custom headers -- Factory (1) - -### Type check - -```bash -npm run typecheck:core -``` - -Expected: **0 errors**. diff --git a/docs/getting-started/AUTO-COMBO-GUIDE.md b/docs/getting-started/AUTO-COMBO-GUIDE.md index 503e73b807..4d6abad9a6 100644 --- a/docs/getting-started/AUTO-COMBO-GUIDE.md +++ b/docs/getting-started/AUTO-COMBO-GUIDE.md @@ -201,7 +201,7 @@ Round-robin cycles through providers in order. Auto-combo **scores each provider - **[Connect a Provider](./PROVIDERS-GUIDE.md)** — Add your first AI provider - **[Free Tiers Guide](./FREE-TIERS-GUIDE.md)** — Get free AI with no credit card -- **[Troubleshooting](./TROUBLESHOOTING.md)** — Fix common issues +- **[Troubleshooting](../guides/TROUBLESHOOTING.md)** — Fix common issues - **[Technical Reference](../routing/AUTO-COMBO.md)** — Deep dive into the scoring algorithm --- diff --git a/docs/getting-started/FREE-TIERS-GUIDE.md b/docs/getting-started/FREE-TIERS-GUIDE.md index da8ddd3589..5b32825cc5 100644 --- a/docs/getting-started/FREE-TIERS-GUIDE.md +++ b/docs/getting-started/FREE-TIERS-GUIDE.md @@ -272,5 +272,5 @@ No catch! Providers offer free tiers to attract users. OmniRoute just makes it e - **[Auto-Combo Guide](./AUTO-COMBO-GUIDE.md)** — Let OmniRoute pick the best AI for you - **[Providers Guide](./PROVIDERS-GUIDE.md)** — Connect more providers -- **[Troubleshooting](./TROUBLESHOOTING.md)** — Fix common issues +- **[Troubleshooting](../guides/TROUBLESHOOTING.md)** — Fix common issues - **[Free Tiers Reference](../reference/FREE_TIERS.md)** — Full list of free tiers diff --git a/docs/getting-started/PROVIDERS-GUIDE.md b/docs/getting-started/PROVIDERS-GUIDE.md index f725baa6df..d54b656a8a 100644 --- a/docs/getting-started/PROVIDERS-GUIDE.md +++ b/docs/getting-started/PROVIDERS-GUIDE.md @@ -237,5 +237,5 @@ Go to Providers → click on the provider → click **Disconnect**. - **[Auto-Combo Guide](./AUTO-COMBO-GUIDE.md)** — Let OmniRoute pick the best AI for you - **[Free Tiers Guide](./FREE-TIERS-GUIDE.md)** — Get free AI with no credit card -- **[Troubleshooting](./TROUBLESHOOTING.md)** — Fix common issues +- **[Troubleshooting](../guides/TROUBLESHOOTING.md)** — Fix common issues - **[Provider Reference](../reference/PROVIDER_REFERENCE.md)** — Full list of 226 providers diff --git a/docs/getting-started/QUICK-START.md b/docs/getting-started/QUICK-START.md index a451327602..c4b34316c7 100644 --- a/docs/getting-started/QUICK-START.md +++ b/docs/getting-started/QUICK-START.md @@ -153,7 +153,7 @@ You can see the details of the request by clicking [Monitoring/Logs](http://loca - **[Auto-Combo Guide](./AUTO-COMBO-GUIDE.md)** — Let OmniRoute pick the best AI for you - **[Providers Guide](./PROVIDERS-GUIDE.md)** — Connect more providers (free and paid) - **[Free Tiers Guide](./FREE-TIERS-GUIDE.md)** — Get free AI with no credit card -- **[Troubleshooting](./TROUBLESHOOTING.md)** — Fix common issues +- **[Troubleshooting](../guides/TROUBLESHOOTING.md)** — Fix common issues --- @@ -183,6 +183,6 @@ OmniRoute automatically skips failed providers and tries the next one. You don't ## Need Help? -- **[Troubleshooting](./TROUBLESHOOTING.md)** — Common issues and fixes +- **[Troubleshooting](../guides/TROUBLESHOOTING.md)** — Common issues and fixes - **[Discord](https://discord.gg/U47eFqAXCn)** — Community support - **[GitHub Issues](https://github.com/diegosouzapw/OmniRoute/issues)** — Report bugs diff --git a/docs/getting-started/TROUBLESHOOTING.md b/docs/getting-started/TROUBLESHOOTING.md deleted file mode 100644 index 28486dc5cb..0000000000 --- a/docs/getting-started/TROUBLESHOOTING.md +++ /dev/null @@ -1,498 +0,0 @@ ---- -title: "Troubleshooting" -version: 3.8.40 -lastUpdated: 2026-06-28 ---- - -# Troubleshooting - -> **For Users**: Looking for quick fixes? See the [Quick Reference](#quick-reference) below. - -🌐 **Languages:** 🇺🇸 [English](./TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../i18n/pt-BR/docs/guides/TROUBLESHOOTING.md) | 🇪🇸 [Español](../i18n/es/docs/guides/TROUBLESHOOTING.md) | 🇫🇷 [Français](../i18n/fr/docs/guides/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../i18n/it/docs/guides/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../i18n/ru/docs/guides/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../i18n/zh-CN/docs/guides/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../i18n/de/docs/guides/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../i18n/in/docs/guides/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../i18n/th/docs/guides/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../i18n/uk-UA/docs/guides/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../i18n/ar/docs/guides/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../i18n/ja/docs/guides/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../i18n/vi/docs/guides/TROUBLESHOOTING.md) | 🇧🇬 [Български](../i18n/bg/docs/guides/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../i18n/da/docs/guides/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../i18n/fi/docs/guides/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../i18n/he/docs/guides/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../i18n/hu/docs/guides/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../i18n/id/docs/guides/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../i18n/ko/docs/guides/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../i18n/ms/docs/guides/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../i18n/nl/docs/guides/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../i18n/no/docs/guides/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../i18n/pt/docs/guides/TROUBLESHOOTING.md) | 🇷🇴 [Română](../i18n/ro/docs/guides/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../i18n/pl/docs/guides/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../i18n/sk/docs/guides/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../i18n/sv/docs/guides/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../i18n/phi/docs/guides/TROUBLESHOOTING.md) | 🇨🇿 [Čeština](../i18n/cs/docs/guides/TROUBLESHOOTING.md) - -Common problems and solutions for OmniRoute. - ---- - -## Quick Reference - -**New to OmniRoute?** Start here — these solve 90% of problems: - -| I see this | What it means | What to do | -| ----------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------- | -| "Can't connect" | OmniRoute isn't running | Run `omniroute` or `docker restart omniroute` | -| "Invalid API key" | Your key is wrong or expired | Re-copy the key from the provider's website | -| "Rate limit exceeded" | You're sending too many requests | Wait 1 minute, or use `model: "auto"` for automatic fallback | -| "Quota exceeded" | You've used up your free/paid quota | Connect more providers, or use free providers (Kiro, Pollinations) | -| "Slow responses" | Provider is busy or far away | Use `model: "auto/fast"` or connect a faster provider (Groq, Cerebras) | -| "Wrong provider used" | `auto` picked a different provider | That's normal! `auto` picks the best one. Force a specific provider with `model: "openai/gpt-4o"` | -| "502 Bad Gateway" | Provider is down | Wait and retry, or use `model: "auto"` to switch providers | -| "401 Unauthorized" | Your credentials are wrong | Check your API key or re-authenticate with OAuth | -| "429 Too Many Requests" | Rate limited | Wait 1 minute, or connect more providers | - -**Still stuck?** See the [Quick Fixes](#quick-fixes) below, or ask on [Discord](https://discord.gg/U47eFqAXCn). - ---- - -## npm install Warnings (ERESOLVE / peer / deprecated) - -When you run `npm install -g omniroute`, you may see a wall of warnings like `npm warn ERESOLVE`, peer-dependency notices, and `deprecated` messages. **These are expected and harmless.** Your install succeeded if you see `added packages` in the output. - -The warnings come from stale peer-dependency ranges in third-party packages OmniRoute doesn't control: - -1. **`marked-terminal` wants `marked >=1 <16`, found `marked@18`** — works fine in practice; the upstream peer range is just stale. -2. **`deprecated prebuild-install@7.1.3`** — the native-binary fetch helper. Only relevant later if a web-cookie provider reports a missing `tls-client-node` native binary (a separate issue, not caused by this warning). - -**No action needed** — the warnings cannot be fully silenced without forking upstream packages. - ---- - -## Quick Fixes - -| Problem | Solution | -| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -| First login not working | Set `INITIAL_PASSWORD` in `.env` (no hardcoded default) | -| Dashboard opens on wrong port | Set `PORT=20128` and `NEXT_PUBLIC_BASE_URL=http://localhost:20128` | -| No logs written to disk | Set `APP_LOG_TO_FILE=true` and verify call log capture is enabled | -| EACCES: permission denied | Set `DATA_DIR=/path/to/writable/dir` to override `~/.omniroute` | -| Routing strategy not saving | Update to the latest v3.x release (Zod schema fix for settings persistence shipped in earlier versions) | -| Login crash / blank page | Check Node.js version — see [Node.js Compatibility](#nodejs-compatibility) below | -| `dlopen` / `slice is not valid mach-o file` (macOS) | Run `cd $(npm root -g)/omniroute/app && npm rebuild better-sqlite3 && omniroute` — see [macOS native module rebuild](#macos-native-module-rebuild) below | -| Proxy "fetch failed" | Ensure proxy config is set at the correct level — see [Proxy Issues](#proxy-issues) below | - ---- - -## Node.js Compatibility - - - -### Login page crashes or shows "Module self-registration" error - -**Cause:** You are running a Node.js version outside OmniRoute's approved secure runtime floor. The most common case is running an older Node 22 or 24 patch level that falls below the patched security floor OmniRoute requires. - -**Symptoms:** - -- Login page shows a blank screen or a server error -- Console shows `Error: Module did not self-register` or similar native binding errors -- The login page shows an **orange warning banner** with your Node version if the runtime is outside the supported secure policy - -**Fix:** - -1. Install a supported Node.js LTS release (recommended: Node.js 24.x): - ```bash - nvm install 24 - nvm use 24 - ``` -2. Verify your version: `node --version` should show `v24.0.0` or newer on the 24.x LTS line -3. Reinstall OmniRoute: `npm install -g omniroute` -4. Restart: `omniroute` - -> **Supported secure versions:** `>=22.22.2 <23` or `>=24.0.0 <27`. Node.js 24.x LTS (Krypton) and Node.js 26 are fully supported. - -### macOS: `dlopen` / "slice is not valid mach-o file" - - - -**Cause:** After a global `npm install -g omniroute`, the `better-sqlite3` native binary inside the package may have been compiled for a different architecture or Node.js ABI than what is running locally. This is common on macOS (both Apple Silicon and Intel) when the pre-built binary does not match your environment. - -**Symptoms:** - -- Server fails immediately on startup with a `dlopen` error -- Error contains `slice is not valid mach-o file` -- Full example: - -``` -dlopen(/Users//.nvm/versions/node/v24.14.1/lib/node_modules/omniroute/app/node_modules/better-sqlite3/build/Release/better_sqlite3.node, 0x0001): tried: '...' (slice is not valid mach-o file) -``` - -**Fix — rebuild for your local environment (no Node.js downgrade required):** - -```bash -cd $(npm root -g)/omniroute/app -npm rebuild better-sqlite3 -omniroute -``` - -> **Note:** This recompiles the native binding against your local Node.js version and CPU architecture, resolving the binary mismatch. The officially supported runtime range is **`>=22.22.2 <23` or `>=24.0.0 <27`** (`SUPPORTED_NODE_RANGE` in `src/shared/utils/nodeRuntimeSupport.ts`, aligned with the `package.json` `engines` field). Node.js 24.x LTS (Krypton) and Node.js 26 are fully supported with `better-sqlite3` v12.x. - ---- - -## Proxy Issues - - - -### Provider validation shows "fetch failed" - -**Cause:** The API key validation endpoint (`POST /api/providers/validate`) was previously bypassing proxy configuration, causing failures in environments that require proxy routing. - -**Fix (v3.5.5+):** This is now fixed. Provider validation routes through `runWithProxyContext`, honoring provider-level and global proxy settings automatically. - -### Token health check fails with "fetch failed" - -**Cause:** Background OAuth token refresh was not resolving proxy configuration per connection. - -**Fix (v3.5.5+):** The token health check scheduler now resolves proxy config per connection before attempting refresh. Update to v3.5.5+. - -### SOCKS5 proxy returns "invalid onRequestStart method" - -**Cause:** On Node.js 22, the undici@8 dispatcher is incompatible with Node's built-in `fetch()` implementation. - -**Fix (v3.5.5+):** OmniRoute now uses undici's own `fetch()` function when a proxy dispatcher is active, ensuring consistent behavior. Update to v3.5.5+. - ---- - -## Provider Issues - -### "Language model did not provide messages" - -**Cause:** Provider quota exhausted. - -**Fix:** - -1. Check dashboard quota tracker -2. Use a combo with fallback tiers -3. Switch to cheaper/free tier - -### Rate Limiting - -**Cause:** Subscription quota exhausted. - -**Fix:** - -- Add fallback: `cc/claude-opus-4-6 → glm/glm-4.7 → if/qwen3.8-max-preview` -- Use GLM/MiniMax as cheap backup - -### OAuth Token Expired - -OmniRoute auto-refreshes tokens. If issues persist: - -1. Dashboard → Provider → Reconnect -2. Delete and re-add the provider connection - -### Kiro multi-account: second account invalidates the first - -**Cause:** Kiro's backend enforces a single active session per OIDC client registration. -When two accounts share the same registered client (connections imported before v3.8.0), -refreshing one account's token invalidates the other's refresh token. - -**Fix (v3.8.0+):** Re-import affected connections. -Starting with v3.8.0, every new Kiro connection created via **Import Token**, -**Google/GitHub social login**, or **Auto-Import** automatically registers its own -dedicated OIDC client. The connection is therefore fully isolated and refreshing one -account has no effect on any other account. - -Connections that were imported _before_ v3.8.0 do not carry a per-connection client -registration. Those connections continue to use the shared social-auth refresh endpoint. -To gain isolation, delete the old connection from Dashboard → Providers and re-add it -via any of the three import flows. - -For full details and step-by-step instructions for adding two Kiro accounts side by side, -see [`docs/guides/KIRO_SETUP.md`](../guides/KIRO_SETUP.md). - ---- - -## Cloud Issues - -### Cloud Sync Errors - -1. Verify `BASE_URL` points to your running instance (e.g., `http://localhost:20128`) -2. Verify `CLOUD_URL` points to your cloud endpoint (e.g., `https://omniroute.dev`) -3. Keep `NEXT_PUBLIC_*` values aligned with server-side values - -### Cloud `stream=false` Returns 500 - -**Symptom:** `Unexpected token 'd'...` on cloud endpoint for non-streaming calls. - -**Cause:** Upstream returns SSE payload while client expects JSON. - -**Workaround:** Use `stream=true` for cloud direct calls. Local runtime includes SSE→JSON fallback. - -### Cloud Says Connected but "Invalid API key" - -1. Create a fresh key from local dashboard (`/api/keys`) -2. Run cloud sync: Enable Cloud → Sync Now -3. Old/non-synced keys can still return `401` on cloud - ---- - -## Docker Issues - -### CLI Tool Shows Not Installed - -1. Check runtime fields: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq` -2. For portable mode: use image target `runner-cli` (bundled CLIs) -3. For host mount mode: set `CLI_EXTRA_PATHS` and mount host bin directory as read-only -4. If `installed=true` and `runnable=false`: binary was found but failed healthcheck - -### Quick Runtime Validation - -```bash -curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' -curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' -curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' -``` - ---- - -## Cost Issues - -### High Costs - -1. Check usage stats in Dashboard → Usage -2. Switch primary model to GLM/MiniMax -3. Use free tier (Qoder, Kiro) for non-critical tasks -4. Set cost budgets per API key: Dashboard → API Keys → Budget - ---- - -## Debugging - -### Enable Log Files - -Set `APP_LOG_TO_FILE=true` in your `.env` file. Application logs are written under `logs/`. -Request artifacts are stored under `${DATA_DIR}/call_logs/` when the call log pipeline is -enabled in settings. -When pipeline capture is enabled, set `CALL_LOG_PIPELINE_CAPTURE_STREAM_CHUNKS=false` to omit -stream chunk payloads, or tune `CALL_LOG_PIPELINE_MAX_SIZE_KB` to change the artifact cap in KB. - -### Check Provider Health - -```bash -# Health dashboard -http://localhost:20128/dashboard/health - -# API health check -curl http://localhost:20128/api/monitoring/health -``` - -### Runtime Storage - -- Main state: `${DATA_DIR}/storage.sqlite` (providers, combos, aliases, keys, settings) -- Usage: SQLite tables in `storage.sqlite` (`usage_history`, `call_logs`, `proxy_logs`) + optional `${DATA_DIR}/call_logs/` -- Application logs: `/logs/...` (when `APP_LOG_TO_FILE=true`) -- Call log artifacts: `${DATA_DIR}/call_logs/YYYY-MM-DD/...` when the call log pipeline is enabled - -The Request Logs page's **Clean history** action clears `call_logs`, legacy -`request_detail_logs`, and the local `${DATA_DIR}/call_logs/` artifact directory. - ---- - -## Circuit Breaker Issues - -### Provider stuck in OPEN state - -When a provider's circuit breaker is OPEN, requests are blocked until the cooldown expires. - -**Fix:** - -1. Go to **Dashboard → Settings → Resilience** -2. Check the circuit breaker card for the affected provider -3. Click **Reset All** to clear all breakers, or wait for the cooldown to expire -4. Verify the provider is actually available before resetting - -### Provider keeps tripping the circuit breaker - -If a provider repeatedly enters OPEN state: - -1. Check **Dashboard → Health → Provider Health** for the failure pattern -2. Go to **Settings → Resilience → Provider Profiles** and increase the failure threshold -3. Check if the provider has changed API limits or requires re-authentication -4. Review latency telemetry — high latency may cause timeout-based failures - ---- - -## Audio Transcription Issues - -### "Unsupported model" error - -- Ensure you're using the correct prefix: `deepgram/nova-3` or `assemblyai/best` -- Verify the provider is connected in **Dashboard → Providers** - -### Transcription returns empty or fails - -- Check supported audio formats: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm` -- Verify file size is within provider limits (typically < 25MB) -- Check provider API key validity in the provider card - ---- - -## Translator Debugging - -Use **Dashboard → Translator** to debug format translation issues: - -| Mode | When to Use | -| ---------------- | -------------------------------------------------------------------------------------------- | -| **Playground** | Compare input/output formats side by side — paste a failing request to see how it translates | -| **Chat Tester** | Send live messages and inspect the full request/response payload including headers | -| **Test Bench** | Run batch tests across format combinations to find which translations are broken | -| **Live Monitor** | Watch real-time request flow to catch intermittent translation issues | - -### Common format issues - -- **Thinking tags not appearing** — Check if the target provider supports thinking and the thinking budget setting -- **Tool calls dropping** — Some format translations may strip unsupported fields; verify in Playground mode -- **System prompt missing** — Claude and Gemini handle system prompts differently; check translation output -- **SDK returns raw string instead of object** — Resolved in v1.x; response sanitizer strips non-standard fields (`x_groq`, `usage_breakdown`, etc.) that cause OpenAI SDK Pydantic validation failures. If you still see this on v3.x+, please file an issue. -- **GLM/ERNIE rejects `system` role** — Resolved in v1.x; role normalizer automatically merges system messages into user messages for incompatible models. If you still see this on v3.x+, please file an issue. -- **`developer` role not recognized** — Resolved in v1.x; automatically converted to `system` for non-OpenAI providers. If you still see this on v3.x+, please file an issue. -- **`json_schema` not working with Gemini** — Resolved in v1.x; `response_format` is now converted to Gemini's `responseMimeType` + `responseSchema`. If you still see this on v3.x+, please file an issue. - ---- - -## Resilience Settings - -### Auto rate-limit not triggering - -- Auto rate-limit only applies to API key providers (not OAuth/subscription) -- Verify **Settings → Resilience → Provider Profiles** has auto-rate-limit enabled -- Check if the provider returns `429` status codes or `Retry-After` headers - -### Tuning exponential backoff - -Provider profiles support these settings: - -- **Base delay** — Initial wait time after first failure (default: 1s) -- **Max delay** — Maximum wait time cap (default: 30s) -- **Multiplier** — How much to increase delay per consecutive failure (default: 2x) - -### Anti-thundering herd - -When many concurrent requests hit a rate-limited provider, OmniRoute uses mutex + auto rate-limiting to serialize requests and prevent cascading failures. This is automatic for API key providers. - ---- - -## Optional RAG / LLM failure taxonomy (16 problems) - -Some OmniRoute users place the gateway in front of RAG or agent stacks. In those setups it is common to see a strange pattern: OmniRoute looks healthy (providers up, routing profiles ok, no rate limit alerts) but the final answer is still wrong. - -In practice these incidents usually come from the downstream RAG pipeline, not from the gateway itself. - -If you want a shared vocabulary to describe those failures you can use the WFGY ProblemMap, an external MIT license text resource that defines sixteen recurring RAG / LLM failure patterns. At a high level it covers: - -- retrieval drift and broken context boundaries -- empty or stale indexes and vector stores -- embedding versus semantic mismatch -- prompt assembly and context window issues -- logic collapse and overconfident answers -- long chain and agent coordination failures -- multi agent memory and role drift -- deployment and bootstrap ordering problems - -The idea is simple: - -1. When you investigate a bad response, capture: - - user task and request - - route or provider combo in OmniRoute - - any RAG context used downstream (retrieved documents, tool calls, etc) -2. Map the incident to one or two WFGY ProblemMap numbers (`No.1` … `No.16`). -3. Store the number in your own dashboard, runbook, or incident tracker next to the OmniRoute logs. -4. Use the corresponding WFGY page to decide whether you need to change your RAG stack, retriever, or routing strategy. - -Full text and concrete recipes live here (MIT license, text only): - -[WFGY ProblemMap README](https://github.com/onestardao/WFGY/blob/main/ProblemMap/README.md) - -You can ignore this section if you do not run RAG or agent pipelines behind OmniRoute. - ---- - -## v3.8.0 Known Issues - -Issues specific to the v3.8.0 release and their current workarounds. If a fix lands in a later patch, the entry will be updated or removed. - -### Devin CLI auth failures - -**Symptoms:** - -- "Devin CLI not found" or "auth failed" when invoking Devin-backed tools -- CLI runtime check reports `installed=false` - -**Causes:** - -- `CLI_DEVIN_BIN` points to a path that does not exist -- Devin CLI is not installed on the host - -**Fix:** - -1. Install the Devin CLI for your platform -2. Set `CLI_DEVIN_BIN=/usr/local/bin/devin` (or the real path) in `.env` -3. Restart OmniRoute and re-test from **Dashboard → CLI Tools** - -### Model cooldown stuck (manual reset) - -**Symptoms:** - -- A model stays listed in cooldown even after the expiration time has passed -- Requests still skip the model in combo routing despite the timestamp being in the past - -**Manual reset:** - -- **Dashboard:** **Settings → Model Cooldowns** → click **Re-enable** on the affected card -- **API:** `DELETE /api/resilience/model-cooldowns` with management auth headers - -### Command Code provider connection fails with 403 - -**Symptoms:** - -- 403 when testing the Command Code provider connection -- The provider card shows "unauthorized" after a fresh add - -**Cause:** The OAuth flow did not complete (callback not received or token not persisted). - -**Fix:** - -- Run `omniroute providers` from the CLI to re-trigger the OAuth flow, or -- Re-run OAuth from **Dashboard → Providers → Command Code → Reconnect** - -### ModelScope returns aggressive 429 cooldowns - -**Symptoms:** - -- Very short or immediate cooldowns on ModelScope after a small burst of requests -- Combo routing skips ModelScope earlier than expected - -**Cause:** ModelScope emits provider-specific `Retry-After` headers. v3.8.0 ships dedicated handling for those headers, so older versions misread them as generic rate-limit hints. - -**Fix:** - -- Ensure you are on v3.8.0 or later -- Verify the `useUpstream429BreakerHints` toggle is enabled under **Settings → Resilience** - -### OMNIROUTE_WS_BRIDGE_SECRET missing in production - -**Symptoms:** - -- 401 on every Codex/Responses WebSocket bridge request when running on a remote production host -- WebSocket bridge handshake closes immediately after connect - -**Cause:** The `OMNIROUTE_WS_BRIDGE_SECRET` env var is missing from the production environment. - -**Fix:** - -1. Generate a random secret: `openssl rand -hex 32` -2. Set `OMNIROUTE_WS_BRIDGE_SECRET=` in the production server env (and any client that talks to the bridge) -3. Restart OmniRoute - -### Responses API: background mode degraded to synchronous - -**Symptoms:** - -- Warning logged: `background mode degraded to synchronous` -- A `background: true` request returns a normal synchronous response instead of a background job handle - -**Cause:** v3.8.0 intentionally degrades `background: true` on the Responses API to synchronous execution while emitting a warning. Full async background execution is a future deliverable. - -**Fix:** - -- Adjust the client to call without `background`, or -- Wait for a later release that ships full async background mode (track the changelog) - ---- - -## Still Stuck? - -- **GitHub Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -- **Architecture**: See [`docs/architecture/ARCHITECTURE.md`](../architecture/ARCHITECTURE.md) for internal details -- **API Reference**: See [`docs/reference/API_REFERENCE.md`](../reference/API_REFERENCE.md) for all endpoints -- **Health Dashboard**: Check **Dashboard → Health** for real-time system status -- **Translator**: Use **Dashboard → Translator** to debug format issues diff --git a/docs/guides/DOCKER_GUIDE.md b/docs/guides/DOCKER_GUIDE.md index 3180c10e3b..8beb141949 100644 --- a/docs/guides/DOCKER_GUIDE.md +++ b/docs/guides/DOCKER_GUIDE.md @@ -336,6 +336,57 @@ Endpoint tunnel panels (Cloudflare, Tailscale, ngrok) can be shown or hidden fro Multi-platform manifest: `linux/amd64` + `linux/arm64` native (Apple Silicon, AWS Graviton, Raspberry Pi). Docker selects the matching architecture automatically; pass `--platform linux/amd64` if you need to force AMD64 emulation on ARM hosts. +### Release Channels + +OmniRoute publishes separate Docker channels for stable releases, active release-branch testing, and development builds. + +| Channel | Source | Mutability | Recommended use | +| --- | --- | --- | --- | +| `:` / `:-web` | Signed/versioned release | Immutable | Production deployments that pin an exact release | +| `:latest` / `:latest-web` | Highest stable release | Mutable stable pointer | Production deployments that intentionally follow stable releases | +| `:next` / `:next-web` | Current default `release/v*` branch | Mutable pre-release pointer | Testing fixes that have landed on the active release branch but are not yet in a stable release | +| `:main` / `:main-web` | `main` branch | Mutable development pointer | Development and integration testing only | + +#### Using the pre-release channel + +The `next` channel is rebuilt on every push to the current default `release/v*` branch and is published for both AMD64 and ARM64. Older maintenance branches cannot overwrite it. The channel provides a pullable image for fixes that have merged into the active release branch before the next stable tag is cut. + +```bash +docker pull diegosouzapw/omniroute:next +docker pull diegosouzapw/omniroute:next-web +``` + +For Docker Compose, override the image tag used by the selected profile, then pull and recreate the service: + +```yaml +services: + omniroute: + image: diegosouzapw/omniroute:next +``` + +```bash +docker compose pull +docker compose up -d +``` + +#### Safety and rollback + +`next` is a floating pre-release channel. It may change on any push to the active release branch and is **not supported for production use**. Pin the image digest while evaluating a specific build: + +```bash +docker pull diegosouzapw/omniroute:next +docker image inspect diegosouzapw/omniroute:next --format '{{index .RepoDigests 0}}' +``` + +Before testing, back up the OmniRoute data volume or bind-mounted data directory. To roll back, restore the previously used stable version or digest and recreate the container: + +```bash +docker pull diegosouzapw/omniroute: +docker compose up -d +``` + +A release-branch build can never move `latest`; only an eligible stable semantic version may promote the stable pointer. The `next` images retain the release image inspection and blocking CRITICAL-vulnerability gate. + ## Important Notes - **SQLite WAL Mode:** `docker stop` should be allowed to finish so OmniRoute can checkpoint the latest changes back into `storage.sqlite`. The bundled Compose files already set a 40s stop grace period. If you run the image directly, keep `--stop-timeout 40`. diff --git a/docs/guides/DOCKER_RELEASE_CHANNELS.md b/docs/guides/DOCKER_RELEASE_CHANNELS.md deleted file mode 100644 index afc47318a0..0000000000 --- a/docs/guides/DOCKER_RELEASE_CHANNELS.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: "Docker Release Channels" -version: 3.8.50 -lastUpdated: 2026-08-06 ---- - -# Docker Release Channels - -OmniRoute publishes separate Docker channels for stable releases, active release-branch testing, and development builds. - -## Channel summary - -| Channel | Source | Mutability | Recommended use | -| --- | --- | --- | --- | -| `:` / `:-web` | Signed/versioned release | Immutable | Production deployments that pin an exact release | -| `:latest` / `:latest-web` | Highest stable release | Mutable stable pointer | Production deployments that intentionally follow stable releases | -| `:next` / `:next-web` | Current default `release/v*` branch | Mutable pre-release pointer | Testing fixes that have landed on the active release branch but are not yet in a stable release | -| `:main` / `:main-web` | `main` branch | Mutable development pointer | Development and integration testing only | - -## Using the pre-release channel - -The `next` channel is rebuilt on every push to the current default `release/v*` branch and is published for both AMD64 and ARM64. Older maintenance branches cannot overwrite it. The channel provides a pullable image for fixes that have merged into the active release branch before the next stable tag is cut. - -```bash -docker pull diegosouzapw/omniroute:next -docker pull diegosouzapw/omniroute:next-web -``` - -For Docker Compose, override the image tag used by the selected profile, then pull and recreate the service: - -```yaml -services: - omniroute: - image: diegosouzapw/omniroute:next -``` - -```bash -docker compose pull -docker compose up -d -``` - -## Safety and rollback - -`next` is a floating pre-release channel. It may change on any push to the active release branch and is **not supported for production use**. Pin the image digest while evaluating a specific build: - -```bash -docker pull diegosouzapw/omniroute:next -docker image inspect diegosouzapw/omniroute:next --format '{{index .RepoDigests 0}}' -``` - -Before testing, back up the OmniRoute data volume or bind-mounted data directory. To roll back, restore the previously used stable version or digest and recreate the container: - -```bash -docker pull diegosouzapw/omniroute: -docker compose up -d -``` - -A release-branch build can never move `latest`; only an eligible stable semantic version may promote the stable pointer. The `next` images retain the release image inspection and blocking CRITICAL-vulnerability gate. diff --git a/docs/guides/TROUBLESHOOTING.md b/docs/guides/TROUBLESHOOTING.md index df515e05bb..c8aaf561a0 100644 --- a/docs/guides/TROUBLESHOOTING.md +++ b/docs/guides/TROUBLESHOOTING.md @@ -38,6 +38,19 @@ Common problems and solutions for OmniRoute. --- +## npm install Warnings (ERESOLVE / peer / deprecated) + +When you run `npm install -g omniroute`, you may see a wall of warnings like `npm warn ERESOLVE`, peer-dependency notices, and `deprecated` messages. **These are expected and harmless.** Your install succeeded if you see `added packages` in the output. + +The warnings come from stale peer-dependency ranges in third-party packages OmniRoute doesn't control: + +1. **`marked-terminal` wants `marked >=1 <16`, found `marked@18`** — works fine in practice; the upstream peer range is just stale. +2. **`deprecated prebuild-install@7.1.3`** — the native-binary fetch helper. Only relevant later if a web-cookie provider reports a missing `tls-client-node` native binary (a separate issue, not caused by this warning). + +**No action needed** — the warnings cannot be fully silenced without forking upstream packages. + +--- + ## Quick Fixes | Problem | Solution | diff --git a/docs/i18n/pl/docs/getting-started/TROUBLESHOOTING.md b/docs/i18n/pl/docs/getting-started/TROUBLESHOOTING.md deleted file mode 100644 index d9f27b0f0b..0000000000 --- a/docs/i18n/pl/docs/getting-started/TROUBLESHOOTING.md +++ /dev/null @@ -1,498 +0,0 @@ ---- -title: "Rozwiązywanie problemów" -version: 3.8.40 -lastUpdated: 2026-06-28 ---- - -# Rozwiązywanie problemów - -> **Dla użytkowników**: Szukasz szybkich poprawek? Zobacz [Szybki przewodnik](#quick-reference) poniżej. - -🌐 **Languages:** 🇺🇸 [English](./TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../i18n/pt-BR/docs/guides/TROUBLESHOOTING.md) | 🇪🇸 [Español](../i18n/es/docs/guides/TROUBLESHOOTING.md) | 🇫🇷 [Français](../i18n/fr/docs/guides/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../i18n/it/docs/guides/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../i18n/ru/docs/guides/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../i18n/zh-CN/docs/guides/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../i18n/de/docs/guides/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../i18n/in/docs/guides/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../i18n/th/docs/guides/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../i18n/uk-UA/docs/guides/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../i18n/ar/docs/guides/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../i18n/ja/docs/guides/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../i18n/vi/docs/guides/TROUBLESHOOTING.md) | 🇧🇬 [Български](../i18n/bg/docs/guides/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../i18n/da/docs/guides/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../i18n/fi/docs/guides/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../i18n/he/docs/guides/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../i18n/hu/docs/guides/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../i18n/id/docs/guides/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../i18n/ko/docs/guides/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../i18n/ms/docs/guides/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../i18n/nl/docs/guides/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../i18n/no/docs/guides/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../i18n/pt/docs/guides/TROUBLESHOOTING.md) | 🇷🇴 [Română](../i18n/ro/docs/guides/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../i18n/pl/docs/guides/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../i18n/sk/docs/guides/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../i18n/sv/docs/guides/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../i18n/phi/docs/guides/TROUBLESHOOTING.md) | 🇨🇿 [Čeština](../i18n/cs/docs/guides/TROUBLESHOOTING.md) - -Typowe problemy i rozwiązania dla OmniRoute. - ---- - -## Szybki przewodnik - -**Nowy w OmniRoute?** Zacznij tutaj — te wskazówki rozwiązują 90% problemów: - -| Widzę to | Co to oznacza | Co zrobić | -| ----------------------- | ---------------------------------- | ------------------------------------------------------------------------------------ | -| "Can't connect" | OmniRoute nie działa | Uruchom `omniroute` lub `docker restart omniroute` | -| "Invalid API key" | Klucz jest błędny lub wygasł | Skopiuj ponownie klucz ze strony providera | -| "Rate limit exceeded" | Wysyłasz zbyt wiele żądań | Poczekaj 1 minutę albo użyj `model: "auto"` do automatycznego fallbacku | -| "Quota exceeded" | Wykorzystałeś darmowy/płatny limit | Podłącz więcej providerów albo użyj darmowych (Kiro, Pollinations) | -| "Slow responses" | Provider jest obciążony lub daleko | Użyj `model: "auto/fast"` albo podłącz szybszego providera (Groq, Cerebras) | -| "Wrong provider used" | `auto` wybrał innego providera | To normalne! `auto` wybiera najlepszego. Wymuś konkretnego: `model: "openai/gpt-4o"` | -| "502 Bad Gateway" | Provider nie działa | Poczekaj i spróbuj ponownie albo użyj `model: "auto"`, aby przełączyć providera | -| "401 Unauthorized" | Błędne dane uwierzytelniające | Sprawdź klucz API albo ponownie uwierzytelnij się przez OAuth | -| "429 Too Many Requests" | Limit zapytań | Poczekaj 1 minutę albo podłącz więcej providerów | - -**Nadal utknąłeś?** Zobacz [Szybkie poprawki](#quick-fixes) poniżej albo zapytaj na [Discordzie](https://discord.gg/U47eFqAXCn). - ---- - -## Ostrzeżenia npm install (ERESOLVE / peer / deprecated) - -Po `npm install -g omniroute` możesz zobaczyć lawinę ostrzeżeń typu `npm warn ERESOLVE`, komunikaty o peer-dependency oraz `deprecated`. **Są one oczekiwane i nieszkodliwe.** Instalacja się powiodła, jeśli w wyniku widać `added packages`. - -Ostrzeżenia pochodzą z przestarzałych zakresów peer-dependency w pakietach firm trzecich, których OmniRoute nie kontroluje: - -1. **`marked-terminal` chce `marked >=1 <16`, znaleziono `marked@18`** — w praktyce działa poprawnie; zakres peer po stronie upstream jest po prostu nieaktualny. -2. **`deprecated prebuild-install@7.1.3`** — helper do pobierania natywnych binarek. Istotny dopiero później, jeśli provider web-cookie zgłosi brak natywnej binarki `tls-client-node` (osobny problem, nie spowodowany tym ostrzeżeniem). - -**Nie trzeba nic robić** — ostrzeżeń nie da się w pełni wyciszyć bez forka pakietów upstream. - ---- - -## Szybkie poprawki - -| Problem | Rozwiązanie | -| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Pierwsze logowanie nie działa | Ustaw `INITIAL_PASSWORD` w `.env` (brak wbudowanego domyślnego hasła) | -| Dashboard otwiera się na złym porcie | Ustaw `PORT=20128` i `NEXT_PUBLIC_BASE_URL=http://localhost:20128` | -| Brak logów na dysku | Ustaw `APP_LOG_TO_FILE=true` i upewnij się, że przechwytywanie call log jest włączone | -| EACCES: permission denied | Ustaw `DATA_DIR=/path/to/writable/dir`, aby nadpisać `~/.omniroute` | -| Strategia routingu się nie zapisuje | Zaktualizuj do najnowszego wydania v3.x (poprawka schematu Zod dla persystencji ustawień weszła we wcześniejszych wersjach) | -| Crash logowania / pusta strona | Sprawdź wersję Node.js — zobacz [Zgodność z Node.js](#nodejs-compatibility) poniżej | -| `dlopen` / `slice is not valid mach-o file` (macOS) | Uruchom `cd $(npm root -g)/omniroute/app && npm rebuild better-sqlite3 && omniroute` — zobacz [przebudowa modułu natywnego na macOS](#macos-native-module-rebuild) poniżej | -| Proxy "fetch failed" | Upewnij się, że konfiguracja proxy jest ustawiona na właściwym poziomie — zobacz [Problemy z proxy](#proxy-issues) poniżej | - ---- - -## Zgodność z Node.js - - - -### Strona logowania się wykrzacza lub pokazuje błąd "Module self-registration" - -**Przyczyna:** Uruchamiasz wersję Node.js poniżej zatwierdzonego bezpiecznego poziomu runtime OmniRoute. Najczęstszy przypadek to starszy patch Node 22 lub 24 poniżej wymaganego przez OmniRoute poziomu bezpieczeństwa. - -**Objawy:** - -- Strona logowania pokazuje pusty ekran lub błąd serwera -- Konsola pokazuje `Error: Module did not self-register` lub podobne błędy natywnych bindingów -- Strona logowania pokazuje **pomarańczowy baner ostrzegawczy** z Twoją wersją Node, jeśli runtime jest poza wspieraną bezpieczną polityką - -**Naprawa:** - -1. Zainstaluj wspierane wydanie Node.js LTS (zalecane: Node.js 24.x): - ```bash - nvm install 24 - nvm use 24 - ``` -2. Sprawdź wersję: `node --version` powinno pokazać `v24.0.0` lub nowsze w linii LTS 24.x -3. Zainstaluj ponownie OmniRoute: `npm install -g omniroute` -4. Uruchom ponownie: `omniroute` - -> **Wspierane bezpieczne wersje:** `>=22.22.2 <23` lub `>=24.0.0 <27`. Node.js 24.x LTS (Krypton) oraz Node.js 26 są w pełni wspierane. - -### macOS: `dlopen` / "slice is not valid mach-o file" - - - -**Przyczyna:** Po globalnym `npm install -g omniroute` natywna binarka `better-sqlite3` w pakiecie mogła zostać skompilowana pod inną architekturę lub ABI Node.js niż ta, która działa lokalnie. To częste na macOS (Apple Silicon i Intel), gdy prebuilt nie pasuje do środowiska. - -**Objawy:** - -- Serwer pada natychmiast przy starcie z błędem `dlopen` -- Błąd zawiera `slice is not valid mach-o file` -- Pełny przykład: - -``` -dlopen(/Users//.nvm/versions/node/v24.14.1/lib/node_modules/omniroute/app/node_modules/better-sqlite3/build/Release/better_sqlite3.node, 0x0001): tried: '...' (slice is not valid mach-o file) -``` - -**Naprawa — przebuduj pod lokalne środowisko (bez downgrade Node.js):** - -```bash -cd $(npm root -g)/omniroute/app -npm rebuild better-sqlite3 -omniroute -``` - -> **Uwaga:** To rekompiluje natywny binding względem lokalnej wersji Node.js i architektury CPU, usuwając niedopasowanie binarki. Oficjalnie wspierany zakres runtime to **`>=22.22.2 <23` lub `>=24.0.0 <27`** (`SUPPORTED_NODE_RANGE` w `src/shared/utils/nodeRuntimeSupport.ts`, zgodny z polem `engines` w `package.json`). Node.js 24.x LTS (Krypton) oraz Node.js 26 są w pełni wspierane z `better-sqlite3` v12.x. - ---- - -## Problemy z proxy - - - -### Walidacja providera pokazuje "fetch failed" - -**Przyczyna:** Endpoint walidacji klucza API (`POST /api/providers/validate`) wcześniej omijał konfigurację proxy, co powodowało błędy w środowiskach wymagających routingu przez proxy. - -**Naprawa (v3.5.5+):** To już naprawione. Walidacja providera idzie przez `runWithProxyContext` i automatycznie respektuje ustawienia proxy na poziomie providera oraz globalne. - -### Token health check kończy się "fetch failed" - -**Przyczyna:** Tło odświeżania tokenów OAuth nie rozwiązywało konfiguracji proxy per połączenie. - -**Naprawa (v3.5.5+):** Scheduler token health check rozwiązuje teraz config proxy per połączenie przed odświeżeniem. Zaktualizuj do v3.5.5+. - -### Proxy SOCKS5 zwraca "invalid onRequestStart method" - -**Przyczyna:** Na Node.js 22 dispatcher undici@8 jest niekompatybilny z wbudowaną implementacją `fetch()` w Node. - -**Naprawa (v3.5.5+):** OmniRoute używa teraz własnej funkcji `fetch()` z undici, gdy aktywny jest dispatcher proxy, co zapewnia spójne zachowanie. Zaktualizuj do v3.5.5+. - ---- - -## Problemy z providerami - -### "Language model did not provide messages" - -**Przyczyna:** Wyczerpany limit (quota) providera. - -**Naprawa:** - -1. Sprawdź tracker limitu w dashboardzie -2. Użyj combo z poziomami fallback -3. Przełącz się na tańszy/darmowy tier - -### Rate limiting - -**Przyczyna:** Wyczerpany limit subskrypcji. - -**Naprawa:** - -- Dodaj fallback: `cc/claude-opus-4-6 → glm/glm-4.7 → if/qwen3.8-max-preview` -- Użyj GLM/MiniMax jako taniego zapasowego - -### Wygasły token OAuth - -OmniRoute automatycznie odświeża tokeny. Jeśli problemy trwają: - -1. Dashboard → Provider → Reconnect -2. Usuń i dodaj ponownie połączenie providera - -### Kiro multi-account: drugie konto unieważnia pierwsze - -**Przyczyna:** Backend Kiro wymusza jedną aktywną sesję na rejestrację klienta OIDC. -Gdy dwa konta współdzielą tego samego zarejestrowanego klienta (połączenia zaimportowane przed v3.8.0), -odświeżenie tokenu jednego konta unieważnia refresh token drugiego. - -**Naprawa (v3.8.0+):** Zaimportuj ponownie dotknięte połączenia. -Od v3.8.0 każde nowe połączenie Kiro utworzone przez **Import Token**, -**Google/GitHub social login** lub **Auto-Import** automatycznie rejestruje własnego -dedykowanego klienta OIDC. Połączenie jest więc w pełni izolowane i odświeżenie jednego -konta nie wpływa na żadne inne. - -Połączenia zaimportowane _przed_ v3.8.0 nie niosą rejestracji klienta per połączenie. -Te połączenia nadal używają współdzielonego endpointu odświeżania social-auth. -Aby uzyskać izolację, usuń stare połączenie z Dashboard → Providers i dodaj je ponownie -przez dowolny z trzech przepływów importu. - -Pełne szczegóły i instrukcja krok po kroku dodawania dwóch kont Kiro obok siebie: -zobacz [`docs/guides/KIRO_SETUP.md`](../guides/KIRO_SETUP.md). - ---- - -## Problemy z chmurą - -### Błędy synchronizacji chmury - -1. Sprawdź, czy `BASE_URL` wskazuje na działającą instancję (np. `http://localhost:20128`) -2. Sprawdź, czy `CLOUD_URL` wskazuje na endpoint chmury (np. `https://omniroute.dev`) -3. Utrzymuj wartości `NEXT_PUBLIC_*` zgodne z wartościami po stronie serwera - -### Cloud `stream=false` zwraca 500 - -**Objaw:** `Unexpected token 'd'...` na endpoincie chmury przy wywołaniach bez streamingu. - -**Przyczyna:** Upstream zwraca payload SSE, a klient oczekuje JSON. - -**Obejście:** Użyj `stream=true` przy bezpośrednich wywołaniach cloud. Lokalny runtime ma fallback SSE→JSON. - -### Cloud pokazuje Connected, ale "Invalid API key" - -1. Utwórz świeży klucz z lokalnego dashboardu (`/api/keys`) -2. Uruchom synchronizację chmury: Enable Cloud → Sync Now -3. Stare/niesynchronizowane klucze mogą nadal zwracać `401` w chmurze - ---- - -## Problemy z Dockerem - -### Narzędzie CLI pokazuje Not Installed - -1. Sprawdź pola runtime: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq` -2. Dla trybu portable: użyj targetu obrazu `runner-cli` (dołączone CLI) -3. Dla trybu host mount: ustaw `CLI_EXTRA_PATHS` i zamontuj katalog bin hosta jako tylko do odczytu -4. Jeśli `installed=true` i `runnable=false`: binarka znaleziona, ale healthcheck się nie powiódł - -### Szybka walidacja runtime - -```bash -curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' -curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' -curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}' -``` - ---- - -## Problemy z kosztami - -### Wysokie koszty - -1. Sprawdź statystyki użycia w Dashboard → Usage -2. Przełącz model główny na GLM/MiniMax -3. Używaj darmowego tieru (Qoder, Kiro) do mniej krytycznych zadań -4. Ustaw budżety kosztów per klucz API: Dashboard → API Keys → Budget - ---- - -## Debugowanie - -### Włącz pliki logów - -Ustaw `APP_LOG_TO_FILE=true` w pliku `.env`. Logi aplikacji trafiają do `logs/`. -Artefakty żądań są przechowywane w `${DATA_DIR}/call_logs/`, gdy pipeline call log jest -włączony w ustawieniach. -Gdy przechwytywanie pipeline jest włączone, ustaw `CALL_LOG_PIPELINE_CAPTURE_STREAM_CHUNKS=false`, aby pominąć -payloady chunków streamu, albo dostrój `CALL_LOG_PIPELINE_MAX_SIZE_KB`, aby zmienić limit artefaktu w KB. - -### Sprawdź zdrowie providerów - -```bash -# Health dashboard -http://localhost:20128/dashboard/health - -# API health check -curl http://localhost:20128/api/monitoring/health -``` - -### Przechowywanie w runtime - -- Stan główny: `${DATA_DIR}/storage.sqlite` (providers, combos, aliases, keys, settings) -- Użycie: tabele SQLite w `storage.sqlite` (`usage_history`, `call_logs`, `proxy_logs`) + opcjonalnie `${DATA_DIR}/call_logs/` -- Logi aplikacji: `/logs/...` (gdy `APP_LOG_TO_FILE=true`) -- Artefakty call log: `${DATA_DIR}/call_logs/YYYY-MM-DD/...` gdy pipeline call log jest włączony - -Akcja **Clean history** na stronie Request Logs czyści `call_logs`, legacy -`request_detail_logs` oraz lokalny katalog artefaktów `${DATA_DIR}/call_logs/`. - ---- - -## Problemy z circuit breakerem - -### Provider utknął w stanie OPEN - -Gdy circuit breaker providera jest OPEN, żądania są blokowane do wygaśnięcia cooldownu. - -**Naprawa:** - -1. Przejdź do **Dashboard → Settings → Resilience** -2. Sprawdź kartę circuit breakera dla dotkniętego providera -3. Kliknij **Reset All**, aby wyczyścić wszystkie breakery, albo poczekaj na wygaśnięcie cooldownu -4. Upewnij się, że provider jest faktycznie dostępny przed resetem - -### Provider wciąż wyzwala circuit breaker - -Jeśli provider wielokrotnie wchodzi w stan OPEN: - -1. Sprawdź **Dashboard → Health → Provider Health** pod kątem wzorca awarii -2. Przejdź do **Settings → Resilience → Provider Profiles** i zwiększ próg awarii -3. Sprawdź, czy provider zmienił limity API lub wymaga ponownego uwierzytelnienia -4. Przejrzyj telemetrię opóźnień — wysoka latencja może powodować awarie oparte na timeoutach - ---- - -## Problemy z transkrypcją audio - -### Błąd "Unsupported model" - -- Upewnij się, że używasz właściwego prefiksu: `deepgram/nova-3` lub `assemblyai/best` -- Sprawdź, czy provider jest podłączony w **Dashboard → Providers** - -### Transkrypcja zwraca pusto lub się nie udaje - -- Sprawdź wspierane formaty audio: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm` -- Upewnij się, że rozmiar pliku mieści się w limitach providera (zazwyczaj < 25MB) -- Sprawdź ważność klucza API na karcie providera - ---- - -## Debugowanie translatora - -Użyj **Dashboard → Translator**, aby debugować problemy z tłumaczeniem formatów: - -| Tryb | Kiedy używać | -| ---------------- | ---------------------------------------------------------------------------------------------- | -| **Playground** | Porównaj formaty wejścia/wyjścia obok siebie — wklej padające żądanie, by zobaczyć tłumaczenie | -| **Chat Tester** | Wysyłaj żywe wiadomości i przeglądaj pełny payload request/response wraz z nagłówkami | -| **Test Bench** | Uruchamiaj testy wsadowe na kombinacjach formatów, by znaleźć zepsute tłumaczenia | -| **Live Monitor** | Obserwuj przepływ żądań w czasie rzeczywistym, by wyłapać przerywane problemy z tłumaczeniem | - -### Typowe problemy z formatami - -- **Brak tagów thinking** — Sprawdź, czy docelowy provider wspiera thinking i ustawienie thinking budget -- **Znikające tool calls** — Niektóre tłumaczenia formatów mogą usuwać nieobsługiwane pola; sprawdź w trybie Playground -- **Brak system prompt** — Claude i Gemini obsługują system prompts inaczej; sprawdź wynik tłumaczenia -- **SDK zwraca surowy string zamiast obiektu** — Naprawione w v1.x; sanitizer odpowiedzi usuwa niestandardowe pola (`x_groq`, `usage_breakdown` itd.), które powodują błędy walidacji Pydantic w OpenAI SDK. Jeśli nadal to widzisz na v3.x+, zgłoś issue. -- **GLM/ERNIE odrzuca rolę `system`** — Naprawione w v1.x; normalizer ról automatycznie scala wiadomości system w user dla niekompatybilnych modeli. Jeśli nadal to widzisz na v3.x+, zgłoś issue. -- **Rola `developer` nierozpoznana** — Naprawione w v1.x; automatycznie konwertowana na `system` dla providerów spoza OpenAI. Jeśli nadal to widzisz na v3.x+, zgłoś issue. -- **`json_schema` nie działa z Gemini** — Naprawione w v1.x; `response_format` jest teraz konwertowany na `responseMimeType` + `responseSchema` Gemini. Jeśli nadal to widzisz na v3.x+, zgłoś issue. - ---- - -## Ustawienia odporności (Resilience) - -### Auto rate-limit się nie uruchamia - -- Auto rate-limit dotyczy tylko providerów z kluczem API (nie OAuth/subskrypcja) -- Sprawdź, czy **Settings → Resilience → Provider Profiles** ma włączony auto-rate-limit -- Sprawdź, czy provider zwraca kody `429` lub nagłówki `Retry-After` - -### Dostrajanie exponential backoff - -Profile providerów wspierają te ustawienia: - -- **Base delay** — Początkowy czas oczekiwania po pierwszej awarii (domyślnie: 1s) -- **Max delay** — Górny limit czasu oczekiwania (domyślnie: 30s) -- **Multiplier** — O ile zwiększać opóźnienie przy kolejnych awariach (domyślnie: 2x) - -### Anti-thundering herd - -Gdy wiele równoległych żądań trafia w providera z limitem zapytań, OmniRoute używa mutexa + auto rate-limiting, aby serializować żądania i zapobiegać awariom kaskadowym. Działa to automatycznie dla providerów z kluczem API. - ---- - -## Opcjonalna taksonomia awarii RAG / LLM (16 problemów) - -Część użytkowników OmniRoute stawia bramkę przed stackami RAG lub agentów. W takich setupach często widać dziwny wzorzec: OmniRoute wygląda na zdrowe (providery w górze, profile routingu OK, brak alertów rate limit), a ostateczna odpowiedź i tak jest błędna. - -W praktyce te incydenty zwykle pochodzą z downstreamowego pipeline'u RAG, a nie z samej bramki. - -Jeśli chcesz wspólnego słownika do opisu tych awarii, możesz użyć WFGY ProblemMap — zewnętrznego zasobu tekstowego na licencji MIT, który definiuje szesnaście powtarzających się wzorców awarii RAG / LLM. Na wysokim poziomie obejmuje: - -- drift retrieval i zerwane granice kontekstu -- puste lub nieaktualne indeksy i magazyny wektorów -- niedopasowanie embeddingów do semantyki -- składanie promptów i problemy z oknem kontekstu -- zapaść logiki i nadmiernie pewne odpowiedzi -- awarie długich łańcuchów i koordynacji agentów -- dryf pamięci i ról w multi-agent -- problemy z deploymentem i kolejnością bootstrapu - -Idea jest prosta: - -1. Gdy badziesz złą odpowiedź, zbierz: - - zadanie użytkownika i żądanie - - trasę lub combo providerów w OmniRoute - - kontekst RAG użyty downstream (pobrane dokumenty, tool calls itd.) -2. Zmapuj incydent na jeden lub dwa numery WFGY ProblemMap (`No.1` … `No.16`). -3. Zapisz numer we własnym dashboardzie, runbooku lub trackerze incydentów obok logów OmniRoute. -4. Użyj odpowiadającej strony WFGY, by zdecydować, czy zmienić stack RAG, retriever, czy strategię routingu. - -Pełny tekst i konkretne przepisy są tutaj (licencja MIT, tylko tekst): - -- [WFGY ProblemMap README](https://github.com/onestardao/WFGY/blob/main/ProblemMap/README.md) - -Możesz zignorować tę sekcję, jeśli nie uruchamiasz pipeline'ów RAG ani agentów za OmniRoute. - ---- - -## Znane problemy v3.8.0 - -Problemy specyficzne dla wydania v3.8.0 i ich obecne obejścia. Gdy poprawka wejdzie w późniejszym patchu, wpis zostanie zaktualizowany lub usunięty. - -### Błędy auth Devin CLI - -**Objawy:** - -- "Devin CLI not found" lub "auth failed" przy wywoływaniu narzędzi opartych o Devin -- Sprawdzenie runtime CLI raportuje `installed=false` - -**Przyczyny:** - -- `CLI_DEVIN_BIN` wskazuje na nieistniejącą ścieżkę -- Devin CLI nie jest zainstalowany na hoście - -**Naprawa:** - -1. Zainstaluj Devin CLI dla swojej platformy -2. Ustaw `CLI_DEVIN_BIN=/usr/local/bin/devin` (lub rzeczywistą ścieżkę) w `.env` -3. Zrestartuj OmniRoute i przetestuj ponownie w **Dashboard → CLI Tools** - -### Cooldown modelu utknął (ręczny reset) - -**Objawy:** - -- Model pozostaje na liście cooldown nawet po upływie czasu wygaśnięcia -- Żądania nadal pomijają model w routingu combo mimo że znacznik czasu jest w przeszłości - -**Ręczny reset:** - -- **Dashboard:** **Settings → Model Cooldowns** → kliknij **Re-enable** na dotkniętej karcie -- **API:** `DELETE /api/resilience/model-cooldowns` z nagłówkami auth zarządzania - -### Połączenie providera Command Code kończy się 403 - -**Objawy:** - -- 403 przy testowaniu połączenia providera Command Code -- Karta providera pokazuje "unauthorized" po świeżym dodaniu - -**Przyczyna:** Przepływ OAuth nie zakończył się (callback nieodebrany lub token niezapisany). - -**Naprawa:** - -- Uruchom `omniroute providers` z CLI, aby ponownie wywołać przepływ OAuth, albo -- Ponów OAuth z **Dashboard → Providers → Command Code → Reconnect** - -### ModelScope zwraca agresywne cooldowny 429 - -**Objawy:** - -- Bardzo krótkie lub natychmiastowe cooldowny na ModelScope po małej serii żądań -- Routing combo pomija ModelScope wcześniej niż oczekiwano - -**Przyczyna:** ModelScope emituje specyficzne dla providera nagłówki `Retry-After`. v3.8.0 zawiera dedykowaną obsługę tych nagłówków, więc starsze wersje odczytują je jako generyczne wskazówki rate-limit. - -**Naprawa:** - -- Upewnij się, że jesteś na v3.8.0 lub nowszej -- Sprawdź, że przełącznik `useUpstream429BreakerHints` jest włączony w **Settings → Resilience** - -### Brak OMNIROUTE_WS_BRIDGE_SECRET w produkcji - -**Objawy:** - -- 401 na każdym żądaniu mostka WebSocket Codex/Responses na zdalnym hoście produkcyjnym -- Handshake mostka WebSocket zamyka się natychmiast po połączeniu - -**Przyczyna:** Zmienna środowiskowa `OMNIROUTE_WS_BRIDGE_SECRET` nie jest ustawiona w środowisku produkcyjnym. - -**Naprawa:** - -1. Wygeneruj losowy sekret: `openssl rand -hex 32` -2. Ustaw `OMNIROUTE_WS_BRIDGE_SECRET=` w env serwera produkcyjnego (oraz każdego klienta łączącego się z mostkiem) -3. Zrestartuj OmniRoute - -### Responses API: tryb background zdegradowany do synchronicznego - -**Objawy:** - -- Zalogowane ostrzeżenie: `background mode degraded to synchronous` -- Żądanie z `background: true` zwraca zwykłą odpowiedź synchroniczną zamiast uchwytu zadania w tle - -**Przyczyna:** v3.8.0 celowo degraduje `background: true` w Responses API do wykonania synchronicznego z ostrzeżeniem. Pełne asynchroniczne wykonanie w tle to przyszła funkcjonalność. - -**Naprawa:** - -- Dostosuj klienta, aby wywoływał bez `background`, albo -- Poczekaj na późniejsze wydanie z pełnym trybem async background (śledź changelog) - ---- - -## Nadal utknąłeś? - -- **GitHub Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -- **Architektura**: Zobacz [`docs/architecture/ARCHITECTURE.md`](../architecture/ARCHITECTURE.md) po szczegóły wewnętrzne -- **API Reference**: Zobacz [`docs/reference/API_REFERENCE.md`](../reference/API_REFERENCE.md) po wszystkie endpointy -- **Health Dashboard**: Sprawdź **Dashboard → Health** pod kątem statusu systemu w czasie rzeczywistym -- **Translator**: Użyj **Dashboard → Translator** do debugowania problemów z formatami diff --git a/docs/ops/QUALITY_GATE_PLAYBOOK.md b/docs/ops/QUALITY_GATE_PLAYBOOK.md index 040b6f3a8e..0e46849976 100644 --- a/docs/ops/QUALITY_GATE_PLAYBOOK.md +++ b/docs/ops/QUALITY_GATE_PLAYBOOK.md @@ -11,6 +11,10 @@ title: "Quality Gate Playbook" > > Benchmarks: OWASP DSOMM · OpenSSF Scorecard · SLSA · SonarQube "Clean as You Code" · > Quality-Ratchet pattern · DORA 2024 · OWASP LLM Top 10 (2025) · mutation-testing best practices. +> +> For the gate-by-gate authoritative reference (what each gate validates, CI job, ratchet vs +> policy, blocking vs advisory), see the +> [Quality Gates Reference](../architecture/QUALITY_GATES.md). --- diff --git a/docs/providers/CHATGPT_WEB.md b/docs/providers/CHATGPT_WEB.md index 188f626712..fc78731766 100644 --- a/docs/providers/CHATGPT_WEB.md +++ b/docs/providers/CHATGPT_WEB.md @@ -123,3 +123,99 @@ If you changed the credential contract (new storage key, new cookie name, change | Token missing from live request | Request is not authenticated | Sign in and send a chat message first | | 401 after Test Connection passed | Expired or rotated session | Re-copy from a fresh live request | | Chunked token fails | Only one chunk pasted | Select all `__Secure-next-auth.session-token.*` chunks | + +--- + +## ChatGPT Web (Codex) + +`ChatGPT Web (Codex)` is an additional provider. The existing +`ChatGPT Web (Plus/Pro)` provider described above stays unchanged for regular +chats, images, and its existing tool emulation. + +### Prerequisites + +- a full Cookie header from a signed-in ChatGPT session; +- Chrome or Chromium for npm, systemd, and PM2 installs; +- with the Docker `web` profile, the internal Chromium service from `docker-compose.yml`; +- an OpenAI tunnel and a ChatGPT custom connector for local Codex tools. + +The tunnel is only needed for tool turns. `pro` is read-only and does not need a +local tool connector. + +### Dashboard setup + +1. Open the **ChatGPT Web (Codex)** provider and add a connection. +2. Paste the full ChatGPT cookie, the tunnel ID, the runtime key, and the name of + the custom connector. +3. Start the check. OmniRoute opens a headless Temporary Chat and also detects + whether `pro` is available for the account. +4. Save the connection. OmniRoute replaces the pasted cookie with the verified + Playwright storage state and stores it together with the runtime key through + the encrypted credential abstraction. + +The raw cookie is not retained after a successful save. When the session expires, +open the connection, paste a fresh full cookie, and re-run the check. The doctor +status in the edit dialog reports browser, storage state, sign-in, Temporary +Chat, tunnel, connector, and tool round-trip separately. + +### Models and combos + +The fixed models are: + +- `chatgpt-web-codex/instant` +- `chatgpt-web-codex/medium` +- `chatgpt-web-codex/high` +- `chatgpt-web-codex/extra-high` +- `chatgpt-web-codex/pro` + +Add one of them to a combo like any other model. The Codex app sends only the +combo name as `model` to the regular Responses endpoint `/v1/responses`. There is +no special endpoint and no Codex-mode switch. + +`pro` does not run local tools. A forced tool makes that combo target +incompatible; with optional tools the turn runs read-only and reports that +limitation as commentary. + +### Security model + +- The native path requires a Responses request, a recognized Codex client, and + matching thread and turn identities. +- Workspace, sandbox, approval policy, and the tool catalog come from the native + Codex shell. Free-form prompt text is not an authority for them. +- ChatGPT receives only a short-lived capability per turn. The MCP broker accepts + only tools that Codex offered in exactly that turn. +- Auto-confirming "Allow once" only returns the tool request to Codex. Codex + alone decides on approval and execution. +- Before the first output, the combo may fall back to another compatible target. + After that, provider, model, connection, and browser turn stay pinned until the + turn completes. +- Cookies, runtime keys, storage state, and capability tokens do not appear in + provider responses or request logs. + +### Headless VPS and Docker + +For npm, systemd, and PM2 installs, OmniRoute detects common Chrome and Chromium +paths. Alternatively, set `CHATGPT_WEB_CODEX_CHROME_PATH`. + +The Docker `web` profile starts `chatgpt-web-codex-browser` on the internal +Compose network. Its CDP port is not published on the host. The protected profile +volume stays separate from the OmniRoute data volume, and the browser gets enough +shared memory. The internal CDP proxy listens only on the Compose network on port +`9223`; Chrome itself stays bound to loopback inside the sidecar. + +A supervisor lease under `DATA_DIR` prevents multiple OmniRoute processes from +owning the same tunnel and broker state. A conflict shows up in the doctor. + +### Interactive recovery + +The normal path is fully headless. When ChatGPT demands an interactive sign-in or +challenge, the existing VNC browser infrastructure can be used as a recovery +path. Browser UI and CDP must then only be reachable over loopback, an +authenticated management connection, or an SSH tunnel; noVNC stays disabled in +normal operation. + +### WebSocket fallback + +When a combo contains `ChatGPT Web (Codex)`, the Responses WebSocket bridge +requests the HTTP/SSE fallback before connecting upstream. The actual transfer +then goes through `/v1/responses`. diff --git a/docs/providers/CHATGPT_WEB_CODEX.md b/docs/providers/CHATGPT_WEB_CODEX.md deleted file mode 100644 index 9af963054d..0000000000 --- a/docs/providers/CHATGPT_WEB_CODEX.md +++ /dev/null @@ -1,94 +0,0 @@ -# ChatGPT Web (Codex) - -`ChatGPT Web (Codex)` ist ein zusätzlicher Provider. Der bestehende Provider -`ChatGPT Web (Plus/Pro)` bleibt für normale Chats, Bilder und dessen bisherige -Tool-Emulation unverändert. - -## Voraussetzungen - -- ein vollständiger Cookie-Header einer angemeldeten ChatGPT-Sitzung; -- Chrome oder Chromium bei npm-, systemd- und PM2-Installationen; -- beim Docker-Profil `web` der interne Chromium-Dienst aus `docker-compose.yml`; -- ein OpenAI-Tunnel und ein ChatGPT-Custom-Connector für lokale Codex-Tools. - -Der Tunnel ist nur für Tool-Runden nötig. `pro` ist read-only und benötigt keinen -lokalen Tool-Connector. - -## Einrichtung in der Weboberfläche - -1. Öffne den Provider `ChatGPT Web (Codex)` und füge eine Connection hinzu. -2. Füge den vollständigen ChatGPT-Cookie, die Tunnel-ID, den Runtime-Key und den - Namen des Custom Connectors ein. -3. Starte die Prüfung. OmniRoute öffnet headless einen Temporary Chat und erkennt - dabei auch, ob `pro` für das Konto verfügbar ist. -4. Speichere die Connection. OmniRoute ersetzt den eingegebenen Cookie durch den - geprüften Playwright-Storage-State und speichert ihn zusammen mit dem Runtime-Key - über die verschlüsselte Credential-Abstraktion. - -Der rohe Cookie wird nach erfolgreichem Speichern nicht zusätzlich aufbewahrt. -Wenn die Sitzung abläuft, öffne die Connection, gib einen frischen vollständigen -Cookie ein und prüfe sie erneut. Der Doctor-Status im Edit-Dialog zeigt Browser, -Storage-State, Anmeldung, Temporary Chat, Tunnel, Connector und Tool-Roundtrip -getrennt an. - -## Modelle und Combos - -Die festen Modelle sind: - -- `chatgpt-web-codex/instant` -- `chatgpt-web-codex/medium` -- `chatgpt-web-codex/high` -- `chatgpt-web-codex/extra-high` -- `chatgpt-web-codex/pro` - -Füge eines davon wie jedes andere Modell zu einer Combo hinzu. Die Codex-App -sendet nur den Combo-Namen als `model` an den normalen Responses-Endpunkt -`/v1/responses`. Es gibt keinen Sonderendpoint und keinen Codex-Modus-Schalter. - -`pro` führt keine lokalen Tools aus. Ein erzwungenes Tool macht dieses Combo-Ziel -inkompatibel; bei optionalen Tools läuft der Turn read-only und meldet diese -Einschränkung als Commentary. - -## Sicherheitsmodell - -- Der native Pfad verlangt einen Responses-Request, einen erkannten Codex-Client - sowie zusammenpassende Thread- und Turn-Identitäten. -- Workspace, Sandbox, Approval-Policy und Toolkatalog stammen aus der nativen - Codex-Hülle. Freier Prompttext ist dafür keine Autorität. -- ChatGPT erhält pro Turn nur eine kurzlebige Capability. Der MCP-Broker akzeptiert - ausschließlich Tools, die Codex in genau diesem Turn angeboten hat. -- Das automatische Bestätigen von „Allow once“ gibt nur den Tool-Wunsch an Codex - zurück. Codex allein entscheidet über Freigabe und Ausführung. -- Vor dem ersten Output darf die Combo auf ein anderes kompatibles Ziel fallen. - Danach bleiben Provider, Modell, Connection und Browserturn bis zum Abschluss - gepinnt. -- Cookies, Runtime-Keys, Storage-State und Capability-Tokens erscheinen nicht in - Providerantworten oder Request-Logs. - -## Headless VPS und Docker - -Bei npm-, systemd- und PM2-Betrieb erkennt OmniRoute übliche Chrome- und -Chromium-Pfade. Alternativ kann `CHATGPT_WEB_CODEX_CHROME_PATH` gesetzt werden. - -Das Docker-Profil `web` startet `chatgpt-web-codex-browser` im internen -Compose-Netz. Sein CDP-Port wird nicht auf dem Host veröffentlicht. Das geschützte -Profilvolume bleibt getrennt vom OmniRoute-Datenvolume und der Browser erhält -ausreichend Shared Memory. Der interne CDP-Proxy lauscht nur im Compose-Netz auf -Port `9223`; Chrome selbst bleibt im Sidecar an Loopback gebunden. - -Eine Supervisor-Lease unter `DATA_DIR` verhindert, dass mehrere OmniRoute-Prozesse -denselben Tunnel- und Brokerzustand besitzen. Ein Konflikt erscheint im Doctor. - -## Interaktive Wiederherstellung - -Der normale Pfad ist vollständig headless. Wenn ChatGPT eine interaktive -Anmeldung oder Challenge verlangt, kann die bestehende VNC-Browser-Infrastruktur -als Recovery-Weg verwendet werden. Browser-UI und CDP dürfen dabei nur über -Loopback, eine authentifizierte Managementverbindung oder einen SSH-Tunnel -erreichbar sein; noVNC bleibt im normalen Betrieb deaktiviert. - -## WebSocket-Fallback - -Enthält eine Combo `ChatGPT Web (Codex)`, fordert die Responses-WebSocket-Brücke -vor der Upstream-Verbindung den HTTP/SSE-Fallback an. Die eigentliche Übertragung -erfolgt dann über `/v1/responses`.