docs(i18n): sync documentation updates to 32 languages

This commit is contained in:
diegosouzapw
2026-04-18 02:51:32 -03:00
parent 857b692aac
commit e5c4e450c0
2062 changed files with 257153 additions and 64249 deletions

File diff suppressed because it is too large Load Diff

229
docs/i18n/ar/CLAUDE.md Normal file
View File

@@ -0,0 +1,229 @@
# CLAUDE.md — AI Agent Session Bootstrap (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../CLAUDE.md) · 🇪🇸 [es](../es/CLAUDE.md) · 🇫🇷 [fr](../fr/CLAUDE.md) · 🇩🇪 [de](../de/CLAUDE.md) · 🇮🇹 [it](../it/CLAUDE.md) · 🇷🇺 [ru](../ru/CLAUDE.md) · 🇨🇳 [zh-CN](../zh-CN/CLAUDE.md) · 🇯🇵 [ja](../ja/CLAUDE.md) · 🇰🇷 [ko](../ko/CLAUDE.md) · 🇸🇦 [ar](../ar/CLAUDE.md) · 🇮🇳 [hi](../hi/CLAUDE.md) · 🇮🇳 [in](../in/CLAUDE.md) · 🇹🇭 [th](../th/CLAUDE.md) · 🇻🇳 [vi](../vi/CLAUDE.md) · 🇮🇩 [id](../id/CLAUDE.md) · 🇲🇾 [ms](../ms/CLAUDE.md) · 🇳🇱 [nl](../nl/CLAUDE.md) · 🇵🇱 [pl](../pl/CLAUDE.md) · 🇸🇪 [sv](../sv/CLAUDE.md) · 🇳🇴 [no](../no/CLAUDE.md) · 🇩🇰 [da](../da/CLAUDE.md) · 🇫🇮 [fi](../fi/CLAUDE.md) · 🇵🇹 [pt](../pt/CLAUDE.md) · 🇷🇴 [ro](../ro/CLAUDE.md) · 🇭🇺 [hu](../hu/CLAUDE.md) · 🇧🇬 [bg](../bg/CLAUDE.md) · 🇸🇰 [sk](../sk/CLAUDE.md) · 🇺🇦 [uk-UA](../uk-UA/CLAUDE.md) · 🇮🇱 [he](../he/CLAUDE.md) · 🇵🇭 [phi](../phi/CLAUDE.md) · 🇧🇷 [pt-BR](../pt-BR/CLAUDE.md) · 🇨🇿 [cs](../cs/CLAUDE.md) · 🇹🇷 [tr](../tr/CLAUDE.md)
---
> Quick-start context for AI coding agents. For deep architecture details, see `AGENTS.md`.
> For contribution workflow, see `CONTRIBUTING.md`.
## بداية سريعة
```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 test:coverage # Unit tests + coverage gate (60% min)
npm run check # lint + test combined
```
### Running a Single Test
```bash
# Node.js native test runner (most tests)
node --import tsx/esm --test tests/unit/your-file.test.mjs
# Vitest (MCP server, autoCombo, cache)
npm run test:vitest
```
---
## نظرة عامة
**OmniRoute** — unified AI proxy/router. One endpoint, 100+ LLM providers, auto-fallback.
| 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 |
### 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
```
---
## Request Pipeline (Abbreviated)
```
Client → /v1/chat/completions (Next.js route)
→ CORS → Zod validation → auth? → policy check → prompt injection guard
→ handleChatCore() [open-sse/handlers/chatCore.ts]
→ cache check → rate limit → combo routing?
→ resolveComboTargets() → handleSingleModel() per target
→ translateRequest() → getExecutor() → executor.execute()
→ fetch() upstream → retry w/ backoff
→ response translation → SSE stream or JSON
```
---
## Key Conventions
### Code Style
- **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
### Database Access
- **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
### Error Handling
- 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)
### الأمان
- **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)
---
## Common Modification Scenarios
### Adding a New Provider
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)
### Adding a New API Route
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
### Adding a New DB Module
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
### Adding a New MCP Tool
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)
### Adding a New A2A Skill
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
---
## Testing Cheat Sheet
| 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` |
**PR rule**: If you change production code in `src/`, `open-sse/`, `electron/`, or `bin/`,
you must include or update tests in the same PR.
---
## Git Workflow
```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
```
**Branch prefixes**: `feat/`, `fix/`, `refactor/`, `docs/`, `test/`, `chore/`
**Commit format** ([Conventional Commits](https://www.conventionalcommits.org/)):
```
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
```
**Scopes**: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`,
`memory`, `skills`.
---
## Environment
- **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`
---
## Hard Rules (Never Violate)
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)

View File

@@ -0,0 +1,132 @@
# Contributor Covenant Code of Conduct (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../CODE_OF_CONDUCT.md) · 🇪🇸 [es](../es/CODE_OF_CONDUCT.md) · 🇫🇷 [fr](../fr/CODE_OF_CONDUCT.md) · 🇩🇪 [de](../de/CODE_OF_CONDUCT.md) · 🇮🇹 [it](../it/CODE_OF_CONDUCT.md) · 🇷🇺 [ru](../ru/CODE_OF_CONDUCT.md) · 🇨🇳 [zh-CN](../zh-CN/CODE_OF_CONDUCT.md) · 🇯🇵 [ja](../ja/CODE_OF_CONDUCT.md) · 🇰🇷 [ko](../ko/CODE_OF_CONDUCT.md) · 🇸🇦 [ar](../ar/CODE_OF_CONDUCT.md) · 🇮🇳 [hi](../hi/CODE_OF_CONDUCT.md) · 🇮🇳 [in](../in/CODE_OF_CONDUCT.md) · 🇹🇭 [th](../th/CODE_OF_CONDUCT.md) · 🇻🇳 [vi](../vi/CODE_OF_CONDUCT.md) · 🇮🇩 [id](../id/CODE_OF_CONDUCT.md) · 🇲🇾 [ms](../ms/CODE_OF_CONDUCT.md) · 🇳🇱 [nl](../nl/CODE_OF_CONDUCT.md) · 🇵🇱 [pl](../pl/CODE_OF_CONDUCT.md) · 🇸🇪 [sv](../sv/CODE_OF_CONDUCT.md) · 🇳🇴 [no](../no/CODE_OF_CONDUCT.md) · 🇩🇰 [da](../da/CODE_OF_CONDUCT.md) · 🇫🇮 [fi](../fi/CODE_OF_CONDUCT.md) · 🇵🇹 [pt](../pt/CODE_OF_CONDUCT.md) · 🇷🇴 [ro](../ro/CODE_OF_CONDUCT.md) · 🇭🇺 [hu](../hu/CODE_OF_CONDUCT.md) · 🇧🇬 [bg](../bg/CODE_OF_CONDUCT.md) · 🇸🇰 [sk](../sk/CODE_OF_CONDUCT.md) · 🇺🇦 [uk-UA](../uk-UA/CODE_OF_CONDUCT.md) · 🇮🇱 [he](../he/CODE_OF_CONDUCT.md) · 🇵🇭 [phi](../phi/CODE_OF_CONDUCT.md) · 🇧🇷 [pt-BR](../pt-BR/CODE_OF_CONDUCT.md) · 🇨🇿 [cs](../cs/CODE_OF_CONDUCT.md) · 🇹🇷 [tr](../tr/CODE_OF_CONDUCT.md)
---
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@@ -4,41 +4,61 @@
---
شكرا لاهتمامك بالمساهمة! يغطي هذا الدليل كل ما تحتاجه للبدء.---##إعداد التطوير### Prerequisites
Thank you for your interest in contributing! This guide covers everything you need to get started.
-**Node.js**>= 18 < 24 (موصى به: 22 LTS) -**npm**10+ -**جيت**### النسخ والتثبيت`bash
استنساخ بوابة https://github.com/diegosouzapw/OmniRoute.git
قرص مضغوط OmniRoute
تثبيت npm`
---
## Development Setup
### Prerequisites
- **Node.js** >= 18 < 24 (recommended: 22 LTS)
- **npm** 10+
- **Git**
### Clone & Install
```bash
git clone https://github.com/diegosouzapw/OmniRoute.git
cd OmniRoute
npm install
```
### Environment Variables
````bash
# قم بإنشاء .env الخاص بك من القالب
```bash
# Create your .env from the template
cp .env.example .env
# توليد الأسرار المطلوبة
صدى "JWT_SECRET=$(openssl rand -base64 48)" >> .env
صدى "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env```
# Generate required secrets
echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env
echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env
```
المساهمة في التنمية الرئيسية:
Key variables for development:
| فنية | التطوير الافتراضي | الوصف |
| Variable | Development Default | Description |
| ---------------------- | ------------------------ | --------------------- |
| "ميناء" | `20128` | منفذ الخادم |
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | عنوان URL الأساسي للواجهة |
| `JWT_SECRET` | (أنشئ أعلاه) | سر توقيع JWT |
| `INITIAL_PASSWORD` | "التغيير" | كلمة المرور الأولى لتسجيل الدخول |
| `APP_LOG_LEVEL` | `معلومات` | تسجيل مستوى الإسهاب |### إعدادات لوحة التحكم
| `PORT` | `20128` | Server port |
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | Base URL for frontend |
| `JWT_SECRET` | (generate above) | JWT signing secret |
| `INITIAL_PASSWORD` | `CHANGEME` | First login password |
| `APP_LOG_LEVEL` | `info` | Log verbosity level |
توفر أدوات تعديل لوحة المعلومات للمستخدم للميزات التي يمكن تهيئتها أيضًا عبر البيئات المتنوعة:
### Dashboard Settings
| تحديد الموقع | تغيير | الوصف |
The dashboard provides UI toggles for features that can also be configured via environment variables:
| Setting Location | Toggle | Description |
| ------------------- | ------------------ | ------------------------------ |
| الإعدادات → متقدمة | وضع الرقعة | أرشيف الطلبات التصحيح (UI) |
| الإعدادات → عام | رؤية الشريط الجانبي | إخفاء/ إخفاء أقسام الفصل الجانبي |
| Settings → Advanced | Debug Mode | Enable debug request logs (UI) |
| Settings → General | Sidebar Visibility | Show/hide sidebar sections |
يتم تخزين هذه الإعدادات في قاعدة البيانات وتستمر من خلال عمليات إعادة تشغيل التشغيل، مما يؤدي إلى تجاوز إعدادات env var الافتراضية عند ضبطها.### التشغيل محليًا```bash
These settings are stored in the database and persist across restarts, overriding env var defaults when set.
### Running Locally
```bash
# Development mode (hot reload)
npm run dev
@@ -48,156 +68,187 @@ npm run start
# Common port configuration
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
````
```
عناوين URL الافتراضية:
Default URLs:
-**لوحة المعلومات**: `http://localhost:20128/dashboard` -**واجهة برمجة التطبيقات**: `http://localhost:20128/v1`---## Git Workflow
- **Dashboard**: `http://localhost:20128/dashboard`
- **API**: `http://localhost:20128/v1`
> ⚠️**لا تلتزم مطلقًا بـ "الرئيسي".**استخدم ميزات الميزات دائمًا.```bash
> git checkout -b feat/your-feature-name
> #...إجراءات جديدة...
> git الالتزام -m "الفذ: وصف التغيير الخاص بك"
> git Push -u Origin feat/your-feature-name
---
# قم بتسجيل الطلب على GitHub```### Branch Naming
## Git Workflow
| المبادئ | الحصاد |
| --------------- | ------------------------- | ------------------ |
| `الفذ/` | مميزات جديدة |
| `/` | إصلاحات الشويب |
| `إعادة البناء/` | إعادة هيكلة الكود |
| `المستندات/` | تأثيرات التوثيق |
| `اختبار/` | الإضافات/إصلاحات الاختبار |
| `العمل الرتيب/` | الأدوات، CI، التبعيات | ### رسائل الالتزام |
> ⚠️ **NEVER commit directly to `main`.** Always use feature branches.
اتبع [الالتزامات التقليدية](https://www.conventionalcommits.org/):`
الفذ: إضافة قاطع الدائرة لمكالمات المزود
الإصلاح: حل حالة حافة التحقق السري من JWT
المستندات: قم بتحديث SECURITY.md مع حماية معلومات تحديد الهوية الشخصية (PII).
الاختبار: إضافة اختبارات وحدة الملاحظة
refactor(db): توحيد جداول حدود المعدل`
```bash
git checkout -b feat/your-feature-name
# ... make changes ...
git commit -m "feat: describe your change"
git push -u origin feat/your-feature-name
# Open a Pull Request on GitHub
```
النطاقات: `db`، `sse`، `oauth`، `dashboard`، `api`، `cli`، `docker`، `ci`، `mcp`، `a2a`، `memory`، `skills`.---## Running Tests
### Branch Naming
````bash
# جميع الاختبارات (الوحدة + فيتيست + النظام البيئي + e2e)
اختبار تشغيل npm: الكل
| Prefix | Purpose |
| ----------- | ------------------------- |
| `feat/` | New features |
| `fix/` | Bug fixes |
| `refactor/` | Code restructuring |
| `docs/` | Documentation changes |
| `test/` | Test additions/fixes |
| `chore/` | Tooling, CI, dependencies |
# ملف اختبار فردي (مشغل الاختبار الأصلي لـ Node.js — تستخدمه معظم الاختبارات)
العقدة - استيراد tsx/esm - اختبارات الاختبار/الوحدة/your-file.test.mjs
### Commit Messages
# Vitest (خادم MCP، autoCombo، ذاكرة التخزين المؤقت)
اختبار تشغيل npm: vitest
Follow [Conventional Commits](https://www.conventionalcommits.org/):
# اختبارات E2E (يتطلب الكاتب المسرحي)
اختبار تشغيل npm: e2e
```
feat: add circuit breaker for provider calls
fix: resolve JWT secret validation edge case
docs: update SECURITY.md with PII protection
test: add observability unit tests
refactor(db): consolidate rate limit tables
```
# عملاء البروتوكول E2E (نقل MCP، A2A)
اختبار تشغيل npm: البروتوكولات: e2e
Scopes: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`.
# اختبارات توافق النظام البيئي
اختبار تشغيل npm: النظام البيئي
---
# التغطية (60% الحد الأدنى من البيانات/السطور/الوظائف/الفروع)
اختبار تشغيل npm: التغطية
تغطية تشغيل npm: تقرير
## Running Tests
# فحص الوبر + التنسيق
npm تشغيل الوبر
فحص تشغيل npm```
```bash
# All tests (unit + vitest + ecosystem + e2e)
npm run test:all
تغطية التعليقات:
# Single test file (Node.js native test runner — most tests use this)
node --import tsx/esm --test tests/unit/your-file.test.ts
- `npm run test:coverage` يقيس المصدر لمجموعة اختبار الوحدة الرئيسية، ويستبعد `tests/**`، بما في ذلك `open-sse/**`
- يجب أن تحافظ على طلبات التنظيف على بوابة التغطية الشاملة عند**60% أو أعلى**للكشوفات والخطوط والوظائف والأروع
- إذا قام ممثل العلاقات العامة تغيير رمز الإنتاج في `src/` أو `open-sse/` أو `electron/` أو `bin/`، فيجب عليه إضافة أو تحديث النقاشة التلقائية في نفس العلاقات العامة
- `تغطية تشغيل npm: التقرير' يطبع التقرير التفصيلي لكل ملف على المدى الطويل من أحدث طرق التغطية
- `اختبار تشغيل npm:التغطية:التراث` يحافظ على قياس الأقدم للمقارنة التاريخية
- راجع`docs/COVERAGE_PLAN.md` للحصول على خارطة طريق تحسين التغطية العامة### سحب متطلبات الطلب
# Vitest (MCP server, autoCombo, cache)
npm run test:vitest
قبل فتح أو دمج العلاقات العامة:
# E2E tests (requires Playwright)
npm run test:e2e
- اختبار تشغيل npm: الوحدة
- اختبار تشغيل npm: التغطية
- تأكد من بقاء بوابة التغطية عند**60%+**لجميع المعايير
- تتضمن ملفات الاختبار التي تم تغييرها أو الهاتفا في وصف العلاقات العامة عند تغيير رمز الإنتاج
- التحقق من نتيجة SonarQube على PR عندما يتم التأكد من أسرار المشروع في CI
# Protocol clients E2E (MCP transports, A2A)
npm run test:protocols:e2e
الاختبار الحالي:**ملفات اختبار 122 وحدة**تغطي:
# Ecosystem compatibility tests
npm run test:ecosystem
- تحويل المترجمين باستمرار
- الحد من المعدل، وقواطع الضوء، والمرونة
- ذاكرة تخزين مؤقتة الدلالية، والعجز، وتتبع التقدم
- عمليات قاعدة البيانات والمخطط (21 وحدة قاعدة بيانات)
- تدفقات OAuth والمصادقة
- التحقق من صحة نقطة نهاية واجهة برمجة التطبيقات (Zod v4)
- أدوات خادمة MCP وكارثة النطاق
- لأنظمة الذاكرة والمهارات---## Code Style
# Coverage (60% min statements/lines/functions/branches)
npm run test:coverage
npm run coverage:report
-**ESLint**— يسمح npm run lint قبل الالتزام
-**Prettier**— يتم بشكل متزايد من خلال ``التجهيز المرحلي`` عند الالتزام (مسافتان، فواصل منقوطة، علامات رسل مزدوجة، عرض 100 حرف، فاصلة زائدة es5)
-**TypeScript**— يستخدم جميع أكواد `src/` `.ts`/`.tsx`؛ `open-sse/` يستخدم `.ts`/`.js`؛ مستند باستخدام TSDoc (`@param`، `@returns`، `@throws`)
-**لا يوجد `eval()`**- يفرض ESLint `no-eval`، `no-implied-eval`، `no-new-func`.
-**التحقق من صحة Zod**— استخدم مخطط Zod v4 للتأكد من صحة واجهة برمجة التطبيقات (API).
-**التسميه**: الملفات = الجمله/علبة الكباب، المكونات = PascalCase، الثوابت = UPPER_SNAKE---## Project Structure
# Lint + format check
npm run lint
npm run check
```
````
Coverage notes:
src/ # تايب سكريبت (.ts / .tsx)
├── التطبيق/ # Next.js 16 App Router
│ ├── (لوحة المعلومات)/ # صفحات لوحة المعلومات (23 قسم)
│ ├── واجهة برمجة التطبيقات/ # مسارات واجهة برمجة التطبيقات (51 دليلاً)
│ └── تسجيل الدخول/ # صفحات المصادقة (.tsx)
├── المجال/ # محرك السياسة (policyEngine، comboResolver، costRules، إلخ.)
├── lib/ # منطق العمل الأساسي (.ts)
│ ├── a2a/ # خادم بروتوكول وكيل إلى وكيل v0.3
│ ├── acp/ # تسجيل بروتوكول اتصال الوكيل
│ ├── الامتثال/ # محرك سياسة الامتثال
│ ├── db/ # طبقة قاعدة بيانات SQLite (21 وحدة + 16 عملية ترحيل)
│ ├── الذاكرة/ # ذاكرة المحادثة المستمرة
│ ├── oauth/ # موفرو OAuth والخدمات والأدوات المساعدة
│ ├── المهارات/ # إطار المهارات الموسعة
│ ├── الاستخدام/ # تتبع الاستخدام وحساب التكلفة
│ └── localDb.ts # طبقة إعادة التصدير فقط - لا تقم أبدًا بإضافة المنطق هنا
├── البرامج الوسيطة/ # طلب البرامج الوسيطة (promptInjectionGuard)
├── mitm/ # وكيل MITM (الشهادة، DNS، التوجيه المستهدف)
├── مشترك/
│ ├── المكونات/ # مكونات التفاعل (.tsx)
│ ├── الثوابت/ # تعريفات الموفر (60+)، نطاقات MCP، استراتيجيات التوجيه
│ ├── utils/ # قاطع الدائرة، المطهر، مساعدي المصادقة
│ └── التحقق من الصحة/ # مخططات Zod v4
└── sse/ # خط أنابيب الوكيل SSE
- `npm run test:coverage` measures source coverage for the main unit test suite, excludes `tests/**`, and includes `open-sse/**`
- Pull requests must keep the overall coverage gate at **60% or higher** for statements, lines, functions, and branches
- If a PR changes production code in `src/`, `open-sse/`, `electron/`, or `bin/`, it must add or update automated tests in the same PR
- `npm run coverage:report` prints the detailed file-by-file report from the latest coverage run
- `npm run test:coverage:legacy` preserves the older metric for historical comparison
- See `docs/COVERAGE_PLAN.md` for the phased coverage improvement roadmap
open-sse/ # @omniroute/open-sse Workspace
├── المنفذون/ # 14 منفذو الطلبات الخاصة بموفر الخدمة
├── المعالجات/ # 11 معالجات الطلب (الدردشة والردود والتضمين والصور وما إلى ذلك)
├── mcp-server/ # خادم MCP (25 أداة، 3 عمليات نقل، 10 نطاقات)
├── الخدمات/ # 36+ خدمة (combo، autoCombo، RateLimitManager، إلخ.)
├── مترجم/ # مترجمو التنسيق (OpenAI ↔ كلود ↔ الجوزاء ↔ الردود ↔ أولاما)
├── محول/ # محول API الردود
└── utils/ # 22 وحدة مساعدة (الدفق، TLS، الوكيل، التسجيل)
### Pull Request Requirements
إلكترون/ # تطبيق إلكترون لسطح المكتب (متعدد المنصات)
Before opening or merging a PR:
الاختبارات/
├── الوحدة/ # مشغل اختبار Node.js (122 ملف اختبار)
├── التكامل/ # اختبارات التكامل
├── e2e/ # اختبارات الكاتب المسرحي
├── الأمان/ # اختبارات الأمان
├── المترجم/ # اختبارات خاصة بالمترجم
└── تحميل/ # اختبارات التحميلمستندات/ # التوثيق
├── ARCHITECTURE.md # بنية النظام
├── API_REFERENCE.md # جميع نقاط النهاية
├── USER_GUIDE.md # إعداد الموفر، تكامل CLI
├── استكشاف الأخطاء وإصلاحها.md # المشكلات الشائعة
├── MCP-SERVER.md # خادم MCP (25 أداة)
├── A2A-SERVER.md # بروتوكول الوكيل A2A
├── AUTO-COMBO.md # محرك التحرير والسرد التلقائي
├── تكامل أدوات CLI-TOOLS.md # تكامل أدوات CLI
├── COVERAGE_PLAN.md # اختبار خطة تحسين التغطية
├── openapi.yaml # مواصفات OpenAPI
└── adr/ # سجلات قرارات الهندسة المعمارية```
- Run `npm run test:unit`
- Run `npm run test:coverage`
- Ensure the coverage gate stays at **60%+** for all metrics
- Include the changed or added test files in the PR description when production code changed
- Check the SonarQube result on the PR when the project secrets are configured in CI
Current test status: **122 unit test files** covering:
- Provider translators and format conversion
- Rate limiting, circuit breaker, and resilience
- Semantic cache, idempotency, progress tracking
- Database operations and schema (21 DB modules)
- OAuth flows and authentication
- API endpoint validation (Zod v4)
- MCP server tools and scope enforcement
- Memory and Skills systems
---
## Code Style
- **ESLint** — Run `npm run lint` before committing
- **Prettier** — Auto-formatted via `lint-staged` on commit (2 spaces, semicolons, double quotes, 100 char width, es5 trailing commas)
- **TypeScript** — All `src/` code uses `.ts`/`.tsx`; `open-sse/` uses `.ts`/`.js`; document with TSDoc (`@param`, `@returns`, `@throws`)
- **No `eval()`** — ESLint enforces `no-eval`, `no-implied-eval`, `no-new-func`
- **Zod validation** — Use Zod v4 schemas for all API input validation
- **Naming**: Files = camelCase/kebab-case, components = PascalCase, constants = UPPER_SNAKE
---
## Project Structure
```
src/ # TypeScript (.ts / .tsx)
├── app/ # Next.js 16 App Router
│ ├── (dashboard)/ # Dashboard pages (23 sections)
│ ├── api/ # API routes (51 directories)
│ └── login/ # Auth pages (.tsx)
├── domain/ # Policy engine (policyEngine, comboResolver, costRules, etc.)
├── lib/ # Core business logic (.ts)
│ ├── a2a/ # Agent-to-Agent v0.3 protocol server
│ ├── acp/ # Agent Communication Protocol registry
│ ├── compliance/ # Compliance policy engine
│ ├── db/ # SQLite database layer (21 modules + 16 migrations)
│ ├── memory/ # Persistent conversational memory
│ ├── oauth/ # OAuth providers, services, and utilities
│ ├── skills/ # Extensible skill framework
│ ├── usage/ # Usage tracking and cost calculation
│ └── localDb.ts # Re-export layer only — never add logic here
├── middleware/ # Request middleware (promptInjectionGuard)
├── mitm/ # MITM proxy (cert, DNS, target routing)
├── shared/
│ ├── components/ # React components (.tsx)
│ ├── constants/ # Provider definitions (60+), MCP scopes, routing strategies
│ ├── utils/ # Circuit breaker, sanitizer, auth helpers
│ └── validation/ # Zod v4 schemas
└── sse/ # SSE proxy pipeline
open-sse/ # @omniroute/open-sse workspace
├── executors/ # 14 provider-specific request executors
├── handlers/ # 11 request handlers (chat, responses, embeddings, images, etc.)
├── mcp-server/ # MCP server (25 tools, 3 transports, 10 scopes)
├── services/ # 36+ services (combo, autoCombo, rateLimitManager, etc.)
├── translator/ # Format translators (OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama)
├── transformer/ # Responses API transformer
└── utils/ # 22 utility modules (stream, TLS, proxy, logging)
electron/ # Electron desktop app (cross-platform)
tests/
├── unit/ # Node.js test runner (122 test files)
├── integration/ # Integration tests
├── e2e/ # Playwright tests
├── security/ # Security tests
├── translator/ # Translator-specific tests
└── load/ # Load tests
docs/ # Documentation
├── ARCHITECTURE.md # System architecture
├── API_REFERENCE.md # All endpoints
├── USER_GUIDE.md # Provider setup, CLI integration
├── TROUBLESHOOTING.md # Common issues
├── MCP-SERVER.md # MCP server (25 tools)
├── A2A-SERVER.md # A2A agent protocol
├── AUTO-COMBO.md # Auto-combo engine
├── CLI-TOOLS.md # CLI tools integration
├── COVERAGE_PLAN.md # Test coverage improvement plan
├── openapi.yaml # OpenAPI specification
└── adr/ # Architecture Decision Records
```
---
@@ -205,31 +256,56 @@ open-sse/ # @omniroute/open-sse Workspace
### Step 1: Register Provider Constants
أضف إلى `src/shared/constants/providers.ts` - تم التحقق من صحة Zod عند تحميل الوحدة.### الخطوة 2: إضافة Executor (إذا كانت هناك حاجة إلى منطق مخصص)
Add to `src/shared/constants/providers.ts` — Zod-validated at module load.
موجود بالفعل منفذ تنفيذي في open-sse/executors/your-provider.ts لتوسيع المنفذ الأساسي.### الخطوة 3: إضافة مترجم (إذا كان تنسيق غير OpenAI)
### Step 2: Add Executor (if custom logic needed)
يجب أن تكون موجودة في الطلب المترجم/الاستجابة في `open-sse/translator/`.### الخطوة 4: إضافة تكوين OAuth (إذا كان يعتمد على OAuth)
Create executor in `open-sse/executors/your-provider.ts` extending the base executor.
إضافة بيانات موثوقة OAuth في `src/lib/oauth/constants/oauth.ts` وتطبيقات في `src/lib/oauth/services/`.### الخطوة 5: تسجيل النماذج
### Step 3: Add Translator (if non-OpenAI format)
أضف تعريفات الارتباطات في "open-sse/config/providerRegistry.ts".### الخطوة 6: إضافة الاختبارات
Create request/response translators in `open-sse/translator/`.
اكتب السيولة الوحدة في `الاختبارات/الوحدة/` التي تغطي الحد الأدنى:
### Step 4: Add OAuth Config (if OAuth-based)
- تسجيل المزود
- ترجمة الطلب/الرد
-تسبب سبب---## Pull Request Checklist
Add OAuth credentials in `src/lib/oauth/constants/oauth.ts` and service in `src/lib/oauth/services/`.
- [ ] اجتياز الاختبار (`اختبار npm`)
- [ ] طباعات القلم (`npm run lint`)
- [ ] نجاح البناء (`npm run build`)
- [ ] تمت إضافة أنواع TypeScript للوظائف والواجهات العامة الجديدة
- [ ] لا توجد أسرار ضمنية أو قيم بيعة
- [ ] تم التحقق من صحة جميع المدخلات باستخدام مخططات Zod
- [ ] تم تحديث سجل التغيير (في حالة التغيير الذي يواجهه المستخدم)
- [ ] تم تحديث الوثائق (إن وجدت)---## Releasing
### Step 5: Register Models
تم إدارة الاختلاف عبر سير العمل `/generate-release`. عند إنشاء إصدار GitHub جديد، يتم**نشر المنتج اليدوي إلى npm**عبر إجراءات GitHub.---## Getting Help
Add model definitions in `open-sse/config/providerRegistry.ts`.
-**الهندسة المعمارية**: تجدد [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) -**مرجع واجهة برمجة التطبيقات**: راجع [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md) -**المشاكل**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -**ADRs**: راجع `docs/adr/`
### Step 6: Add Tests
Write unit tests in `tests/unit/` covering at minimum:
- Provider registration
- Request/response translation
- Error handling
---
## Pull Request Checklist
- [ ] Tests pass (`npm test`)
- [ ] Linting passes (`npm run lint`)
- [ ] Build succeeds (`npm run build`)
- [ ] TypeScript types added for new public functions and interfaces
- [ ] No hardcoded secrets or fallback values
- [ ] All inputs validated with Zod schemas
- [ ] CHANGELOG updated (if user-facing change)
- [ ] Documentation updated (if applicable)
---
## Releasing
Releases are managed via the `/generate-release` workflow. When a new GitHub Release is created, the package is **automatically published to npm** via GitHub Actions.
---
## Getting Help
- **Architecture**: See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
- **API Reference**: See [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md)
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
- **ADRs**: See `docs/adr/` for architectural decision records

19
docs/i18n/ar/GEMINI.md Normal file
View File

@@ -0,0 +1,19 @@
# Security and Cleanliness Rules for AI Assistants (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../GEMINI.md) · 🇪🇸 [es](../es/GEMINI.md) · 🇫🇷 [fr](../fr/GEMINI.md) · 🇩🇪 [de](../de/GEMINI.md) · 🇮🇹 [it](../it/GEMINI.md) · 🇷🇺 [ru](../ru/GEMINI.md) · 🇨🇳 [zh-CN](../zh-CN/GEMINI.md) · 🇯🇵 [ja](../ja/GEMINI.md) · 🇰🇷 [ko](../ko/GEMINI.md) · 🇸🇦 [ar](../ar/GEMINI.md) · 🇮🇳 [hi](../hi/GEMINI.md) · 🇮🇳 [in](../in/GEMINI.md) · 🇹🇭 [th](../th/GEMINI.md) · 🇻🇳 [vi](../vi/GEMINI.md) · 🇮🇩 [id](../id/GEMINI.md) · 🇲🇾 [ms](../ms/GEMINI.md) · 🇳🇱 [nl](../nl/GEMINI.md) · 🇵🇱 [pl](../pl/GEMINI.md) · 🇸🇪 [sv](../sv/GEMINI.md) · 🇳🇴 [no](../no/GEMINI.md) · 🇩🇰 [da](../da/GEMINI.md) · 🇫🇮 [fi](../fi/GEMINI.md) · 🇵🇹 [pt](../pt/GEMINI.md) · 🇷🇴 [ro](../ro/GEMINI.md) · 🇭🇺 [hu](../hu/GEMINI.md) · 🇧🇬 [bg](../bg/GEMINI.md) · 🇸🇰 [sk](../sk/GEMINI.md) · 🇺🇦 [uk-UA](../uk-UA/GEMINI.md) · 🇮🇱 [he](../he/GEMINI.md) · 🇵🇭 [phi](../phi/GEMINI.md) · 🇧🇷 [pt-BR](../pt-BR/GEMINI.md) · 🇨🇿 [cs](../cs/GEMINI.md) · 🇹🇷 [tr](../tr/GEMINI.md)
---
## 1. File Placement & Organization
- **Test Files**: ALL unit tests, integration tests, ecosystem tests, or Vitest files MUST strictly be placed within the `tests/` directory (e.g., `tests/unit/`, `tests/integration/`). NEVER create test files in the project root (`/`).
- **Scripts and Utilities**: ALL maintenance, debugging, generation, or experimental scripts (`.cjs`, `.mjs`, `.js`, `.ts`) MUST be placed strictly inside the `scripts/` directory or `scripts/scratch/` for temporary one-offs. NEVER dump loose scripts in the project root (`/`).
**The Project Root MUST ONLY CONTAIN:**
- Configuration files (`vitest.config.ts`, `next.config.mjs`, `eslint.config.mjs`, etc.)
- Dependency files (`package.json`, `package-lock.json`)
- Documentation files (`README.md`, `CHANGELOG.md`, `AGENTS.md`)
- CI/CD files and ignore definitions (`.gitignore`, `.dockerignore`)
When creating _any_ validation tests or one-off logic scripts, default to using `scripts/scratch/` or the `tests/unit/` directories according to your goals. Do not pollute the `/` root context.

View File

@@ -391,10 +391,10 @@ When a call fails, the dev doesn't know if it was a rate limit, expired token, w
- **Unified Logs Dashboard** — 4 tabs: Request Logs, Proxy Logs, Audit Logs, Console
- **Console Log Viewer** — Real-time terminal-style viewer with color-coded levels, auto-scroll, search, filter
- **SQLite Proxy Logs** — Persistent logs that survive server restarts
- **SQLite Summary Logs** — Request and proxy log indexes stay queryable across restarts without loading large payload blobs into SQLite
- **Translator Playground** — 4 debugging modes: Playground (format translation), Chat Tester (round-trip), Test Bench (batch), Live Monitor (real-time)
- **Request Telemetry** — p50/p95/p99 latency + X-Request-Id tracing
- **File-Based Logging with Rotation** — App logs rotate by size, retention days, and archive count; call log artifacts rotate by retention days and file count
- **File-Based Detail Artifacts** — App logs rotate by size, retention days, and archive count; detailed request/response payloads live in `DATA_DIR/call_logs/` and rotate independently of SQLite summaries
- **System Info Report** — `npm run system-info` generates `system-info.txt` with your full environment (Node version, OmniRoute version, OS, CLI tools, Docker/PM2 status). Attach it when reporting issues for instant triage.
</details>
@@ -699,7 +699,7 @@ During deep debugging, long histories with tool results quickly exceed provider
```txt
Combo: "maximize-claude"
1. cc/claude-opus-4-6
1. cc/claude-opus-4-7
2. glm/glm-4.7
3. if/kimi-k2-thinking
@@ -723,7 +723,7 @@ Outcome: stable free coding workflow
```txt
Combo: "always-on"
1. cc/claude-opus-4-6
1. cc/claude-opus-4-7
2. cx/gpt-5.2-codex
3. glm/glm-4.7
4. minimax/MiniMax-M2.1
@@ -1515,7 +1515,7 @@ OmniRoute v3.6 is built as an operational platform, not just a relay proxy.
```txt
Combo: "my-coding-stack"
1. cc/claude-opus-4-6
1. cc/claude-opus-4-7
2. nvidia/llama-3.3-70b
3. glm/glm-4.7
4. if/kimi-k2-thinking
@@ -1654,7 +1654,7 @@ Dashboard → Providers → Connect Claude Code
→ 5-hour + weekly quota tracking
Models:
cc/claude-opus-4-6
cc/claude-opus-4-7
cc/claude-sonnet-4-5-20250929
cc/claude-haiku-4-5-20251001
```
@@ -1854,7 +1854,7 @@ Dashboard → Combos → Create New
Name: premium-coding
Models:
1. cc/claude-opus-4-6 (Subscription primary)
1. cc/claude-opus-4-7 (Subscription primary)
2. glm/glm-4.7 (Cheap backup, $0.6/1M)
3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M)
@@ -1884,7 +1884,7 @@ Cost: $0 forever!
Settings → Models → Advanced:
OpenAI API Base URL: http://localhost:20128/v1
OpenAI API Key: [from OmniRoute dashboard]
Model: cc/claude-opus-4-6
Model: cc/claude-opus-4-7
```
### Claude Code
@@ -1994,7 +1994,7 @@ opencode
**Rate limiting**
- Subscription quota out → Fallback to GLM/MiniMax
- Add combo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
- Add combo: `cc/claude-opus-4-7 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth token expired**
@@ -2027,8 +2027,10 @@ opencode
**No request logs**
- Request artifacts are written to `DATA_DIR/call_logs/` as one JSON file per request
- `call_logs` in SQLite stores summary metadata for the Request Logs table and analytics views
- Detailed request/response payloads are written to `DATA_DIR/call_logs/` as one JSON artifact per request
- Enable pipeline capture from Dashboard → Logs → Request Logs if you need detailed per-stage payloads
- `Export Logs` reads the artifact files on demand, while `Export All` includes the `call_logs/` directory alongside `storage.sqlite`
- Set `APP_LOG_TO_FILE=true` if you also want application console logs in `logs/application/app.log`
- Adjust `APP_LOG_MAX_FILE_SIZE`, `APP_LOG_RETENTION_DAYS`, `APP_LOG_MAX_FILES`, and `CALL_LOG_MAX_ENTRIES` as needed
@@ -2324,9 +2326,23 @@ gh release create v2.0.0 --title "v2.0.0" --generate-notes
## 📊 Star History
## Stargazers over time
<a href="https://www.star-history.com/?repos=diegosouzapw%2Fomniroute&type=date&legend=top-left">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=diegosouzapw/omniroute&type=date&theme=dark&legend=top-left" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=diegosouzapw/omniroute&type=date&legend=top-left" />
<img alt="Star History Chart" src="https://api.star-history.com/chart?repos=diegosouzapw/omniroute&type=date&legend=top-left" />
</picture>
</a>
## [![Stargazers over time](https://starchart.cc/diegosouzapw/OmniRoute.svg?variant=adaptive)](https://starchart.cc/diegosouzapw/OmniRoute)
## 🌍 StarMapper
<a href="https://starmapper.bruniaux.com/diegosouzapw/omniroute">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://starmapper.bruniaux.com/api/map-image/diegosouzapw/omniroute?theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://starmapper.bruniaux.com/api/map-image/diegosouzapw/omniroute?theme=light" />
<img alt="StarMapper" src="https://starmapper.bruniaux.com/api/map-image/diegosouzapw/omniroute" />
</picture>
</a>
## 🙏 Acknowledgments

View File

@@ -6,136 +6,174 @@
## Reporting Vulnerabilities
إذا وجدت ثغرة أمنية في OmniRoute، فيرجى إمدادها بطريقة مختلفة:
If you discover a security vulnerability in OmniRoute, please report it responsibly:
1.**لا**تفتح مشكلة عامة على GitHub 2. استخدم [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new) 3. تشمل: الوصف، وخطوات الاستنساخ، والأثر للمناسب## Response Timeline
1. **DO NOT** open a public GitHub issue
2. Use [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new)
3. Include: description, reproduction steps, and potential impact
| المرحلة | الهدف |
| -------------- | ------------------------ | --------- |
| شكر وتقدير | 48 ساعة |
| الفرز والتقييم | 5 أيام عمل |
| الإصدار | التعديل 14 يوم عمل (حرج) | # التغيير |
## Response Timeline
| النسخة | حالة الدعم |
| ------- | ------------ | -------------------- |
| 3.4.x | ✅ المشتريات |
| 3.0.x | ✅ الأمان |
| < 3.0.0 | ❌ غير مدعوم | ---## البنية الأمنية |
| Stage | Target |
| ------------------- | --------------------------- |
| Acknowledgment | 48 hours |
| Triage & Assessment | 5 business days |
| Patch Release | 14 business days (critical) |
تم تطبيق نموذج OmniRoute متعدد الأمان: `
طلب ← CORS ← مصادقة مفتاح API ← منع الاشتراك الرسمي ← معقم الإدخال ← محدد المعدل ← قاطع ← الموفر`### 🔐 Authentication & Authorization
## Supported Versions
| غرض | التنفيذ |
| -------------------------------------- | ------------------------------------------------------------------------------ | ------------------------- |
| **تسجيل الدخول إلى لوحة التحكم** | اعتماد تعتمد على كلمة المرور باستخدام رموز JWT (ملفات تعريف الارتباط HttpOnly) |
| **مصادقة مفتاح واجهة برمجة التطبيقات** | مفاتيح موقعة من HMAC مع التحقق من صحة CRC |
| **OAuth 2.0 + PKCE** | مصادقة الموفر المنشط (Claude، Codex، Gemini، Cursor، إلخ) |
| **تحديث الرمز المميز** | التحديث التلقائي لرمز OAuth قبل انتهاء الصلاحية |
| **ملفات تعريف الارتباط التنسيقة** | `AUTH_COOKIE_SECURE=true` لبيئات HTTPS |
| **نطاقات MCP** | 10 نطاقات تفصيلية للتحكم في الوصول إلى أداة MCP | ### 🛡️ التشفير عند الراحة |
| Version | Support Status |
| ------- | -------------- |
| 3.6.x | ✅ Active |
| 3.5.x | ✅ Security |
| < 3.5.0 | ❌ Unsupported |
يتم قراءة كافة التفاصيل المخزنة في SQLite باستخدام**AES-256-GCM**مع اشتقاق مفتاح التشفير:
---
- لوحة مفاتيح برمجة التطبيقات، ورموز الوصول، ورموز التحديث، والرموز المعروفة
- النسخة البرتغالية: `enc:v1:<iv>:<ciphertext>:<authTag>`
- وضع العبور (نص عادي) عندما لا يتم تعيين `STORAGE_ENCRYPTION_KEY````bash
## Security Architecture
# إنشاء مفتاح التشفير:
OmniRoute implements a multi-layered security model:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)```
```
Request → CORS → API Key Auth → Prompt Injection Guard → Input Sanitizer → Rate Limiter → Circuit Breaker → Provider
```
### 🔐 Authentication & Authorization
| Feature | Implementation |
| -------------------- | ---------------------------------------------------------- |
| **Dashboard Login** | Password-based auth with JWT tokens (HttpOnly cookies) |
| **API Key Auth** | HMAC-signed keys with CRC validation |
| **OAuth 2.0 + PKCE** | Secure provider auth (Claude, Codex, Gemini, Cursor, etc.) |
| **Token Refresh** | Automatic OAuth token refresh before expiry |
| **Secure Cookies** | `AUTH_COOKIE_SECURE=true` for HTTPS environments |
| **MCP Scopes** | 10 granular scopes for MCP tool access control |
### 🛡️ Encryption at Rest
All sensitive data stored in SQLite is encrypted using **AES-256-GCM** with scrypt key derivation:
- API keys, access tokens, refresh tokens, and ID tokens
- Versioned format: `enc:v1:<iv>:<ciphertext>:<authTag>`
- Passthrough mode (plaintext) when `STORAGE_ENCRYPTION_KEY` is not set
```bash
# Generate encryption key:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
```
### 🧠 Prompt Injection Guard
بسبب الوسيطة التي تكتشف وتمنع الهجمات الرابعة في طلبات LLM:
Middleware that detects and blocks prompt injection attacks in LLM requests:
| نوع النمط | دان | مثال |
| ------------------- | ----- | -------------------------------- |
| تجاوز النظام | عالية | " تجاهل كافة التعليمات السابقة" |
| اختطاف الدور | عالية | "أنت الآن دان، يمكنك فعل أي شيء" |
| لغرض الشفاء | مي | فواصل مشفرة لكسر نطاق السياقة |
| دان/الهروب من السجن | عالية | أسباب مطالبة الهروب من السجن |
| تسرب التعليمات | مي | "أرني متشوق النظام الخاص بك" |
| Pattern Type | Severity | Example |
| ------------------- | -------- | ---------------------------------------------- |
| System Override | High | "ignore all previous instructions" |
| Role Hijack | High | "you are now DAN, you can do anything" |
| Delimiter Injection | Medium | Encoded separators to break context boundaries |
| DAN/Jailbreak | High | Known jailbreak prompt patterns |
| Instruction Leak | Medium | "show me your system prompt" |
قم بالتكوين عبر معلومات اللوحة (الإعدادات → الأمان) أو `.env`:`env
INPUT_SANITIZER_ENABLED=صحيح
INPUT_SANITIZER_MODE=block # تحذير | كتلة | تنقيح`
Configure via dashboard (Settings → Security) or `.env`:
```env
INPUT_SANITIZER_ENABLED=true
INPUT_SANITIZER_MODE=block # warn | block | redact
```
### 🔒 PII Redaction
الكشف التلقائي والتنقيح الاختياري لمعلومات التعريف الشخصية:
Automatic detection and optional redaction of personally identifiable information:
| نوع معلومات تحديد الهوية الشخصية | نمط | الاستبدال |
| ----------------------------------- | --------------------- | ------------------ | ------ |
| البريد الإلكتروني | `user@domain.com` | `[EMAIL_REDACTED]` |
| CPF (البرازيل) | `123.456.789-00` | `[CPF_REDACTED]` |
| CNPJ (البرازيل) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` |
| بطاقة الائتمان | `4111-1111-1111-1111` | `[CC_REDACTED]` |
| هاتف | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
| الضمان الاجتماعي (الولايات المتحدة) | `123-45-6789` | `[SSN_REDACTED]` | ```env |
| PII Type | Pattern | Replacement |
| ------------- | --------------------- | ------------------ |
| Email | `user@domain.com` | `[EMAIL_REDACTED]` |
| CPF (Brazil) | `123.456.789-00` | `[CPF_REDACTED]` |
| CNPJ (Brazil) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` |
| Credit Card | `4111-1111-1111-1111` | `[CC_REDACTED]` |
| Phone | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
| SSN (US) | `123-45-6789` | `[SSN_REDACTED]` |
```env
PII_REDACTION_ENABLED=true
````
```
### 🌐 Network Security
| | الوصف |
| Feature | Description |
| ------------------------ | ---------------------------------------------------------------- |
|**كورس**| أصلية قابلة للتكوين (`CORS_ORIGIN` env var، افتراضية `*`) |
|**تصفية IP**| نطاقات IP المخصصة لها/القائمة المحظورة في لوحة المعلومات |
|**تحديد المعدل**| حدود الحدود لكل الحدود بدقة تلقائية |
|**القطيع الغذائي الرعد**| يمنع Mutex + القفل لكل اتصال 502s المتتالية |
|**بصمة TLS**| انتحال بصمة TLS الشبيهة بالمتصفح الرئيسي لاكتشاف الروبوتات |
|**بصمة سطر مود**| التنسيق/النص لكل موفر لمطابقة التوقيعات CLI الأصلية |### 🔌 متوافقة والتوافر
| **CORS** | Configurable origin control (`CORS_ORIGIN` env var, default `*`) |
| **IP Filtering** | Allowlist/blocklist IP ranges in dashboard |
| **Rate Limiting** | Per-provider rate limits with automatic backoff |
| **Anti-Thundering Herd** | Mutex + per-connection locking prevents cascading 502s |
| **TLS Fingerprint** | Browser-like TLS fingerprint spoofing to reduce bot detection |
| **CLI Fingerprint** | Per-provider header/body ordering to match native CLI signatures |
| | الوصف |
### 🔌 Resilience & Availability
| Feature | Description |
| ----------------------- | ------------------------------------------------------------------ |
|**قاطع القراءات**| 3 حالات (مغلق → → مفتوح مفتوح) لكل، بسبب SQLite |
|**طلب العجز**| نافذة dedup لمدة 5 ثواني للتحميلات المكررة |
|**التراجع الأسي**| إعادة المحاولة الجديدة مع زيادة |
|**لوحة المعلومات الصحية**| صحة لرعاية خدمة الوقت الحقيقي |### 📋 مراقبة كاملة
| **Circuit Breaker** | 3-state (Closed → Open → Half-Open) per provider, SQLite-persisted |
| **Request Idempotency** | 5-second dedup window for duplicate requests |
| **Exponential Backoff** | Automatic retry with increasing delays |
| **Health Dashboard** | Real-time provider health monitoring |
| | الوصف |
### 📋 Compliance
| Feature | Description |
| ------------------ | ----------------------------------------------------------- |
|**الاحتفاظ بالسجل**| التنظيف التلقائي بعد `CALL_LOG_RETENTION_DAYS` |
|**إلغاء الاشتراك في عدم التسجيل**| تعمل علامة noLog لكل مفتاح API على تسجيل الطلبات |
|**سجل التدقيق**| الإجراءات الإدارية التي تم تتبعها في جدول `audit_log` |
|**تدقيق MCP**| تسجيل التدقيق التجاري من SQLite لجميع أدوات الاتصال MCP |
|**التحقق من صحة زود**| تم التحقق من صحة جميع مدخلات واجهة برمجة التطبيقات (API) باستخدام مخططات Zod v4 عند تحميل الوحدة النموذجية |---## متغيرات البيئة المطلوبة
| **Log Retention** | Automatic cleanup after `CALL_LOG_RETENTION_DAYS` |
| **No-Log Opt-out** | Per API key `noLog` flag disables request logging |
| **Audit Log** | Administrative actions tracked in `audit_log` table |
| **MCP Audit** | SQLite-backed audit logging for all MCP tool calls |
| **Zod Validation** | All API inputs validated with Zod v4 schemas at module load |
يجب ضبط جميع الاستخدامات قبل إنشاء الضيوف. سوف يفشل العميل بسرعة**إذا كان مفقودًا أو ضعيف.```bash
#مطلوب — لن يبدأ بدون ما يلي:
JWT_SECRET=$(openssl rand -base64 48) # دقيقة 32 حرفًا
API_KEY_SECRET=$(openssl rand -hex 32) # دقيقة 16 حرفًا
---
#موصى به — يتيح التشفير في حالة عدم النشاط:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)```
## Required Environment Variables
يرفض المعلم تعلمياً القيم والضعيفة مثل `changeme` أو `secret` أو `password`.---## Docker Security
All secrets must be set before starting the server. The server will **fail fast** if they are missing or weak.
- استخدم المستخدم غير جيجا في الإنتاج
- منزل جبلار كمجلدات للقراءة فقط
- لا تنسى أبدًا بنسخ ملفات `.env` إلى صور Docker
- استخدام `.dockerignore` لاستبعاد الملفات الحساسة
- اضبط `AUTH_COOKIE_SECURE=true` عندما يكون خلف HTTPS```bash
تشغيل عامل الميناء -d \
--اسم الطريق الشامل \
--إعادة التشغيل ما لم تتوقف \
--للقراءة فقط \
-ص20128:20128\
-v بيانات المسار الشامل:/app/data \
```bash
# REQUIRED — server will not start without these:
JWT_SECRET=$(openssl rand -base64 48) # min 32 chars
API_KEY_SECRET=$(openssl rand -hex 32) # min 16 chars
# RECOMMENDED — enables encryption at rest:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
```
The server actively rejects known-weak values like `changeme`, `secret`, or `password`.
---
## Docker Security
- Use non-root user in production
- Mount secrets as read-only volumes
- Never copy `.env` files into Docker images
- Use `.dockerignore` to exclude sensitive files
- Set `AUTH_COOKIE_SECURE=true` when behind HTTPS
```bash
docker run -d \
--name omniroute \
--restart unless-stopped \
--read-only \
-p 20128:20128 \
-v omniroute-data:/app/data \
-e JWT_SECRET="$(openssl rand -base64 48)" \
-e API_KEY_SECRET = "$ (openssl rand -hex 32)" \
-e STORAGE_ENCRYPTION_KEY = "$(openssl rand -hex 32)" \
diegosouzapw/omniroute:latest```
-e API_KEY_SECRET="$(openssl rand -hex 32)" \
-e STORAGE_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
diegosouzapw/omniroute:latest
```
---
## Dependencies
- يسمح له بدقيق npm
- حافظ على تحديثات التبعيات
- يستخدم المشروع "husky" + "lint-staged" لفحوصات ما قبل التنفيذ
- يقوم بخط أنابيب CI يسمح بمتطلبات أمان ESLint في كل خطوة
- تم التحقق من صحة ثوابت الموفر عند تحميل الوحدة عبر Zod (`src/shared/validation/providerSchema.ts`)
````
- Run `npm audit` regularly
- Keep dependencies updated
- The project uses `husky` + `lint-staged` for pre-commit checks
- CI pipeline runs ESLint security rules on every push
- Provider constants validated at module load via Zod (`src/shared/validation/providerSchema.ts`)

View File

@@ -0,0 +1,63 @@
# Feature: Smart Auto-Combos — Dynamic model composition (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1041-smart-auto-combos.md) · 🇪🇸 [es](../../../es/_ideia/defer/1041-smart-auto-combos.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1041-smart-auto-combos.md) · 🇩🇪 [de](../../../de/_ideia/defer/1041-smart-auto-combos.md) · 🇮🇹 [it](../../../it/_ideia/defer/1041-smart-auto-combos.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1041-smart-auto-combos.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1041-smart-auto-combos.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1041-smart-auto-combos.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1041-smart-auto-combos.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1041-smart-auto-combos.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1041-smart-auto-combos.md) · 🇮🇳 [in](../../../in/_ideia/defer/1041-smart-auto-combos.md) · 🇹🇭 [th](../../../th/_ideia/defer/1041-smart-auto-combos.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1041-smart-auto-combos.md) · 🇮🇩 [id](../../../id/_ideia/defer/1041-smart-auto-combos.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1041-smart-auto-combos.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1041-smart-auto-combos.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1041-smart-auto-combos.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1041-smart-auto-combos.md) · 🇳🇴 [no](../../../no/_ideia/defer/1041-smart-auto-combos.md) · 🇩🇰 [da](../../../da/_ideia/defer/1041-smart-auto-combos.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1041-smart-auto-combos.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1041-smart-auto-combos.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1041-smart-auto-combos.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1041-smart-auto-combos.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1041-smart-auto-combos.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1041-smart-auto-combos.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1041-smart-auto-combos.md) · 🇮🇱 [he](../../../he/_ideia/defer/1041-smart-auto-combos.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1041-smart-auto-combos.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1041-smart-auto-combos.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1041-smart-auto-combos.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1041-smart-auto-combos.md)
---
> GitHub Issue: #1041 — opened by @oyi77 on 2026-04-07
> Status: 📋 Cataloged | Priority: High
## 📝 Original Request
When a user first sets up OmniRoute they manually build an Auto-Combo that reflects current credentials. The combo gets stale immediately when new API keys/providers are added or better models are released.
**Proposed: "Smart Combo" mode** — combo member list is re-evaluated at routing time against all currently active credentials, rather than being a fixed array.
## 💬 Community Discussion
### Participants
- @oyi77 — Original requester (power user, contributor)
- @kilo-code-bot — Flagged similarity to #563 (91%), but author explained distinction
### Key Points
- **#563 (closed)** was about routing an incoming model pattern to a specific combo (routing layer)
- **This issue** is about the combo's own member list being dynamic (composition layer)
- Combo should auto-update when credentials/providers change
- Should respect user-configured constraints (exclude lists, priority overrides)
## 🎯 Refined Feature Description
Add a "Smart" toggle to combo creation that makes the combo's model member list dynamically computed at routing time. Instead of storing fixed model IDs, it evaluates all currently active credentials/models and selects the best options.
### What it solves
- Stale combos when new API keys are added
- Models not being used when newly synced from models.dev
- Disabled credentials still being tried
### How it should work (high level)
1. User creates combo with "Smart" toggle ON
2. Configures filters/constraints (provider whitelist/blacklist, model pattern regex, cost tier limits)
3. At request time, combo engine queries active credentials + model catalog
4. Dynamically computes the member list based on filters + scoring (LKGP, latency, cost)
5. Routes using the dynamically computed list with the selected strategy
### Affected areas
- `open-sse/services/combo.ts` — core routing engine
- `open-sse/services/autoCombo/` — auto-combo scoring
- `src/lib/db/combos.ts` — combo schema changes
- `src/shared/validation/schemas.ts` — new combo type schema
- Dashboard combo creation UI
## 📎 Attachments & References
- Discussion with @kilo-code-bot distinguishing from #563
## 🔗 Related Ideas
- Related to [980-lkgp-routing](./980-lkgp-routing.md) — LKGP could feed scoring
- Related to [785-task-class-routing](./785-task-class-routing.md) — task-aware routing

View File

@@ -0,0 +1,64 @@
# Feature: Providers as dynamic plugins/addons (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1112-providers-dynamic-plugins.md) · 🇪🇸 [es](../../../es/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇩🇪 [de](../../../de/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇮🇹 [it](../../../it/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇮🇳 [in](../../../in/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇹🇭 [th](../../../th/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇮🇩 [id](../../../id/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇳🇴 [no](../../../no/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇩🇰 [da](../../../da/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇮🇱 [he](../../../he/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1112-providers-dynamic-plugins.md)
---
> GitHub Issue: #1112 — opened by @diegosouzapw on 2026-04-10T09:36:17Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem
Currently, adding new providers requires deep integration across the codebase (`open-sse/executors`, `open-sse/config/providerRegistry.ts`, etc.). It's somewhat modularized but not a true drop-in system, making it harder for the community to contribute new providers as simple add-ons.
### Proposed Solution
Implement a dynamic drop-in plugin system that loads providers at runtime from a dedicated `plugins/` or `addons/` directory, allowing users to just drop a `.js` / `.ts` file or folder into the directory to register a new provider without modifying core code.
### Implementation Ideas
- Expose a stable Plugin API or SDK (`ProviderDefinition` interface).
- Dynamic imports to load files from `addons/providers/` at startup.
- Update the UI to show dynamically loaded providers alongside built-in ones.
### Current Workarounds
Currently, any new provider must be hardcoded into the TypeScript source code and the project needs to be recompiled.
### Additional Context
Source: Discussion #1084
## 💬 Community Discussion
(No comments yet, originated from discussion)
## 🎯 Refined Feature Description
Create a robust standard plugin interface where a self-contained JS/TS bundle can define:
- Metadata (ID, name, auth format)
- `executor` logic (how to request)
- Config schemas
And drop it into a `/addons/` folder. The app loads these dynamically on boot via `import()` or `require()`.
### What it solves
Decouples new provider implementations from the core codebase.
Enables closed-source or specialized community providers.
Simplifies PRs (less modification of core registries).
### Affected areas
- `open-sse/config/providerRegistry.ts` (needs dynamic loading phase)
- Next.js build config (allowing external requires)
## 📎 Attachments & References
N/A
## 🔗 Related Ideas
N/A

View File

@@ -0,0 +1,105 @@
# Feature: [Feature] Add plan-aware GitHub Copilot model filtering and refresh the GitHub model catalog (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇪🇸 [es](../../../es/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇩🇪 [de](../../../de/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇮🇹 [it](../../../it/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇮🇳 [in](../../../in/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇹🇭 [th](../../../th/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇮🇩 [id](../../../id/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇳🇴 [no](../../../no/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇩🇰 [da](../../../da/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇮🇱 [he](../../../he/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md)
---
> GitHub Issue: #1168 — opened by @demiolawunmi on 2026-04-11T23:09:31Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem / Use Case
It would be helpful to improve the GitHub Copilot integration by making model availability plan-aware and updating the listed models to match GitHubs current documentation.
Right now, the available model list appears out of sync with GitHubs latest Copilot docs, and there is no clear way to distinguish which models should be shown for different Copilot entitlements. GitHubs documentation notes that model availability can vary by plan and by client, and that some models may not be available depending on the users plan.
This creates confusion for users on GitHub Copilot Student, because Student does not have the same model access as Pro+. GitHubs plans docs say Copilot Student includes unlimited completions, access to premium models in Copilot Chat, and a monthly premium request allowance, while Copilot Pro+ includes full access to all available models in Copilot Chat. :contentReference[oaicite:1]{index=1}
As a result, the integration can currently expose models that are not actually available for a users GitHub Copilot plan, and the displayed GitHub model list may not reflect the current supported model catalog from GitHubs docs.
Copilot student only has access to these models: Claude Haiku 4.5 Gemini 2.5 Pro Gemini 3 Flash Gemini 3.1 Pro GPT-4.1 GPT-5 mini GPT-5.1 GPT-5.2 GPT-5.2-Codex GPT-5.3-Codex GPT-5.4 mini Grok Code Fast 1 Raptor mini
### Proposed Solution
Add plan-aware handling for the GitHub Copilot provider.
Suggested behavior:
- Allow the GitHub provider to distinguish between Copilot Free, Student, Pro, and Pro+.
- Only show models that are actually available for the selected or detected plan.
- Clearly label models as included vs premium where relevant.
- Refresh the GitHub Copilot model catalog so it stays aligned with GitHubs current supported-model documentation.
- If plan auto-detection is not possible, add a manual setting so users can choose their Copilot entitlement.
This would make the GitHub provider more accurate and would prevent users from selecting models that GitHub does not make available under their current plan. GitHubs docs already distinguish plans and supported models, so reflecting that in OmniRoute would improve correctness and UX. :contentReference[oaicite:3]{index=3}
### Alternatives Considered
Current workarounds are limited:
- Manually ignore models that are not available under the users plan.
- Manually compare OmniRoutes GitHub model list against GitHubs docs.
- Use trial and error to see which models actually work.
These workarounds are inconvenient and easy to get wrong, especially because GitHubs supported model list and plan access can change over time. :contentReference[oaicite:4]{index=4}
### Acceptance Criteria
- GitHub Copilot models are filtered by plan entitlement (at minimum: Free, Student, Pro, Pro+).
- Unsupported GitHub Copilot models are hidden or clearly marked unavailable for the selected plan.
- The GitHub providers model list matches GitHubs current supported-model documentation.
- If plan detection is not automatic, a manual plan selector is available in provider settings.
- Existing non-GitHub providers remain unaffected.
- Tests cover plan-based filtering and GitHub model list updates.
### Area
Provider Support
### Related Provider(s)
Github Copilot
### Additional Context
GitHubs official documentation currently separates Copilot plans and supported AI models. The docs also state that Pro+ has full access to all available models, while other plans have different limits and allowances. GitHub also notes that supported models vary by client and that some models may not be available depending on the plan. :contentReference[oaicite:5]{index=5}
Because of that, plan-aware filtering would make the GitHub provider more accurate and less confusing, especially for Copilot Student users.
### Expected Test Plan
- Add unit tests for GitHub provider plan-based model filtering.
- Add coverage for Student, Pro, and Pro+ model visibility behavior.
- Add or update tests for the GitHub provider model registry / model list sync.
- Verify that unavailable models are hidden or marked correctly.
- Verify that existing provider integrations remain unchanged.
## 💬 Community Discussion
No community comments yet.
## 🎯 Refined Feature Description
(Requires manual/AI refinement)
### What it solves
- TBD
### How it should work (high level)
1. TBD
### Affected areas
- TBD
## 📎 Attachments & References
- TBD
## 🔗 Related Ideas
- TBD

View File

@@ -0,0 +1,63 @@
# Feature: Add TPS (Tokens Per Second) Metric (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1182-tps-metric.md) · 🇪🇸 [es](../../../es/_ideia/defer/1182-tps-metric.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1182-tps-metric.md) · 🇩🇪 [de](../../../de/_ideia/defer/1182-tps-metric.md) · 🇮🇹 [it](../../../it/_ideia/defer/1182-tps-metric.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1182-tps-metric.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1182-tps-metric.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1182-tps-metric.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1182-tps-metric.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1182-tps-metric.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1182-tps-metric.md) · 🇮🇳 [in](../../../in/_ideia/defer/1182-tps-metric.md) · 🇹🇭 [th](../../../th/_ideia/defer/1182-tps-metric.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1182-tps-metric.md) · 🇮🇩 [id](../../../id/_ideia/defer/1182-tps-metric.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1182-tps-metric.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1182-tps-metric.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1182-tps-metric.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1182-tps-metric.md) · 🇳🇴 [no](../../../no/_ideia/defer/1182-tps-metric.md) · 🇩🇰 [da](../../../da/_ideia/defer/1182-tps-metric.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1182-tps-metric.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1182-tps-metric.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1182-tps-metric.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1182-tps-metric.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1182-tps-metric.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1182-tps-metric.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1182-tps-metric.md) · 🇮🇱 [he](../../../he/_ideia/defer/1182-tps-metric.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1182-tps-metric.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1182-tps-metric.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1182-tps-metric.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1182-tps-metric.md)
---
> GitHub Issue: #1182 — opened by @uwuclxdy on 2026-04-12
> Status: ⏭️ DEFER | Priority: Medium
## 📝 Original Request
Add a Tokens Per Second (TPS) metric to the OmniRoute dashboard to measure and display the speed of model responses. This would help users compare provider/model performance and make informed routing decisions.
## 💬 Community Discussion
### Participants
- @uwuclxdy — Original requester, active contributor (also opened #1339, #1364)
- 3 comments in discussion thread
### Key Points
- TPS is a key metric for comparing streaming performance across providers
- Would require measuring token output rate during streaming responses
- Useful for both real-time display (per-request) and historical aggregation
- Could feed into routing decisions (e.g., prefer faster providers for interactive use)
## 🎯 Refined Feature Description
Instrument the streaming response pipeline to measure and display Tokens Per Second (TPS) — the rate at which tokens are generated — per request, per model, and per provider.
### What it solves
- No visibility into streaming response speed across providers/models
- Cannot compare provider performance objectively
- Cannot make routing decisions based on throughput
### How it should work (high level)
1. During streaming responses, track the time between the first and last token
2. Count output tokens from the response `usage` field or chunk count
3. Calculate TPS = total_output_tokens / (last_token_time - first_token_time)
4. Display TPS on: individual request logs, provider metrics, combo metrics
5. Optionally expose TPS via the MCP server `get_provider_metrics` tool
6. Store historical TPS data for trend analysis in the dashboard
### Affected areas
- `open-sse/handlers/chatCore.ts` — instrument streaming for timing
- `open-sse/services/usage.ts` — store TPS alongside existing usage metrics
- `src/lib/db/detailedLogs.ts` — add TPS column to detailed logs
- `src/app/(dashboard)/dashboard/logs/` — display TPS in log entries
- `src/app/(dashboard)/dashboard/endpoint/` — display TPS in provider/combo metrics
- DB migrations — new `tps` column in relevant tables
## 📎 Attachments & References
- No external references
## 🔗 Related Ideas
- TPS data could feed into [1041-smart-auto-combos](./1041-smart-auto-combos.md) scoring
- Related to [980-lkgp-routing](./980-lkgp-routing.md) — throughput as routing signal

View File

@@ -0,0 +1,65 @@
# Feature: [Feature] Add GLM 5.1 support and fix tool-calling compatibility (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇪🇸 [es](../../../es/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇩🇪 [de](../../../de/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇮🇹 [it](../../../it/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇮🇳 [in](../../../in/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇹🇭 [th](../../../th/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇮🇩 [id](../../../id/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇳🇴 [no](../../../no/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇩🇰 [da](../../../da/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇮🇱 [he](../../../he/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md)
---
> GitHub Issue: #1199 — opened by @CmetankaJDD on 2026-04-13T07:57:20Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
## Summary
Please add support for GLM 5.1 in OmniRoute.
At the moment, GLM 5.1 appears to have problems with tool usage / tool calling, which makes it hard to use in agent-style workflows.
## Current behavior
- GLM 5.1 is not available or not fully supported as a first-class model option.
- When trying to use tools with GLM 5.1, requests fail / tool usage does not work correctly.
## Expected behavior
- GLM 5.1 should be supported as a selectable model/provider option.
- Tool calling should work correctly with the model, following the same OpenAI-compatible tool schema behavior expected by OmniRoute clients.
## Why this matters
GLM 5.1 is useful for users who want broader model coverage in OmniRoute, and tool-calling support is required for many coding assistants, agents, and structured workflows.
## Suggested scope
- Add GLM 5.1 model support
- Validate request/response compatibility for tools
- Ensure tool call messages are translated correctly if provider-specific mapping is needed
- Add a basic regression test for tool usage with GLM 5.1
## 💬 Community Discussion
No community comments yet.
## 🎯 Refined Feature Description
(Requires manual/AI refinement)
### What it solves
- TBD
### How it should work (high level)
1. TBD
### Affected areas
- TBD
## 📎 Attachments & References
- TBD
## 🔗 Related Ideas
- TBD

View File

@@ -0,0 +1,114 @@
# Feature: [Feature] Native support for Tavily Extract, Crawl, Map, and Research endpoints (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇪🇸 [es](../../../es/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇩🇪 [de](../../../de/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇮🇹 [it](../../../it/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇮🇳 [in](../../../in/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇹🇭 [th](../../../th/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇮🇩 [id](../../../id/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇳🇴 [no](../../../no/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇩🇰 [da](../../../da/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇮🇱 [he](../../../he/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md)
---
> GitHub Issue: #1217 — opened by @edwardsconnects90 on 2026-04-13T15:57:08Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem / Use Case
OmniRoute registers Tavily as a search provider (`tavily-search` in `searchRegistry.ts`) and successfully proxies `/v1/search` requests. However, the Tavily API exposes four additional endpoints that are widely used by MCP integrations and AI agents:
- `POST /extract` — extract structured content from URLs
- `POST /crawl` — crawl websites with configurable depth/breadth
- `POST /map` — map website structure (URL discovery)
- `POST /research` — deep multi-source research with async polling (`GET /research/:id`)
When a client (e.g., Tavily MCP server) is configured with `TAVILY_BASE_URL` pointing to OmniRoute, only `/v1/search` works. The other four endpoints return **HTTP 404**, forcing users to either bypass OmniRoute entirely or maintain a separate proxy layer.
This breaks the value proposition of OmniRoute as a unified gateway — Tavily credentials must be managed in two places, and usage of extract/crawl/map/research cannot be tracked or logged through OmniRoute's analytics.
### Proposed Solution
Add four new API routes that proxy requests to the corresponding Tavily API endpoints, reusing the existing `tavily-search` provider credentials from `provider_connections`:
1. `POST /v1/extract``https://api.tavily.com/extract`
2. `POST /v1/crawl``https://api.tavily.com/crawl`
3. `POST /v1/map``https://api.tavily.com/map`
4. `POST /v1/research``https://api.tavily.com/research`
5. `GET /v1/research/:id``https://api.tavily.com/research/:id` (polling for async results)
The routes should:
- Resolve the Tavily API key from the existing `tavily-search` provider connection (same decryption path as `/v1/search`)
- Inject `api_key` into the request body and `Authorization: Bearer` header before forwarding
- Forward the request body as-is (passthrough) — no transformation needed
- Stream the response back to the client
- Record usage in call logs for analytics/cost tracking
- Respect the existing API key policy (`enforceApiKeyPolicy`) if enabled
### Alternatives Considered
1. **Client-side direct connection** — configure the MCP server to hit `api.tavily.com` directly. This works but defeats the purpose of OmniRoute as a centralized gateway, duplicates credential management, and loses visibility into usage analytics.
2. **Separate reverse proxy** — run a lightweight proxy (nginx or Node.js) alongside OmniRoute that routes Tavily-specific endpoints directly while sending `/v1/search` through OmniRoute. Adds operational complexity and splits configuration.
3. **Runtime hotfix** — monkey-patch `http.createServer` via `NODE_OPTIONS --require` to intercept the four routes before Next.js handles them. This is the current workaround and functions correctly, but it is fragile (bypasses OmniRoute's auth, logging, and cost tracking) and adds maintenance burden with each OmniRoute upgrade.
### Acceptance Criteria
- `POST /v1/extract` returns 200 with Tavily's response when given valid `urls` in the body
- `POST /v1/crawl` returns 200 with crawled page content
- `POST /v1/map` returns 200 with discovered URL list
- `POST /v1/research` returns 200 with `request_id` and `status: pending`
- `GET /v1/research/:id` returns the research result or current polling status
- All five endpoints resolve credentials from the existing `tavily-search` provider connection — no additional configuration required
- Requests are logged in OmniRoute's call log and visible in the dashboard analytics
- API key policy enforcement works consistently across all Tavily endpoints
- Existing `/v1/search` behavior (multi-provider selection, caching, cost tracking) is not affected
### Area
Proxy / Routing
### Related Provider(s)
Tavily (`tavily-search`)
### Additional Context
The Tavily MCP server (v0.2.18, official package `tavily-mcp` from `github.com/tavily-ai/tavily-mcp`) is commonly used with Claude Code, Cursor, and other AI coding tools. It supports the `TAVILY_BASE_URL` environment variable, making it straightforward to route through OmniRoute. The server registers all five tools (`tavily_search`, `tavily_extract`, `tavily_crawl`, `tavily_map`, `tavily_research`) and expects all endpoints to be available at the configured base URL.
The `research` endpoint is asynchronous — it returns a `request_id` on POST, and the client polls `GET /research/:id` until `status` changes to `completed` or `failed`. The MCP server implements exponential backoff polling (2s initial, 1.5x factor, 10s max interval) with a timeout of 5 minutes (mini) or 15 minutes (pro/auto).
Architecturally, these routes are simpler than `/v1/search` — they do not require multi-provider selection, response normalization, or request coalescing. A straightforward passthrough with credential injection and call logging would be sufficient.
### Expected Test Plan
- Add unit tests for each new route handler (extract, crawl, map, research, research polling)
- Add integration test verifying credential resolution from `provider_connections`
- Verify that call logs are recorded for each endpoint
- Verify that API key policy enforcement applies
- Keep `npm run test:coverage` at 60%+
## 💬 Community Discussion
No community comments yet.
## 🎯 Refined Feature Description
(Requires manual/AI refinement)
### What it solves
- TBD
### How it should work (high level)
1. TBD
### Affected areas
- TBD
## 📎 Attachments & References
- TBD
## 🔗 Related Ideas
- TBD

View File

@@ -0,0 +1,60 @@
# Feature: Add MiniMax OAuth Provider (Device-Code + PKCE) (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1251-minimax-oauth-provider.md) · 🇪🇸 [es](../../../es/_ideia/defer/1251-minimax-oauth-provider.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1251-minimax-oauth-provider.md) · 🇩🇪 [de](../../../de/_ideia/defer/1251-minimax-oauth-provider.md) · 🇮🇹 [it](../../../it/_ideia/defer/1251-minimax-oauth-provider.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1251-minimax-oauth-provider.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1251-minimax-oauth-provider.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1251-minimax-oauth-provider.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1251-minimax-oauth-provider.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1251-minimax-oauth-provider.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1251-minimax-oauth-provider.md) · 🇮🇳 [in](../../../in/_ideia/defer/1251-minimax-oauth-provider.md) · 🇹🇭 [th](../../../th/_ideia/defer/1251-minimax-oauth-provider.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1251-minimax-oauth-provider.md) · 🇮🇩 [id](../../../id/_ideia/defer/1251-minimax-oauth-provider.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1251-minimax-oauth-provider.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1251-minimax-oauth-provider.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1251-minimax-oauth-provider.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1251-minimax-oauth-provider.md) · 🇳🇴 [no](../../../no/_ideia/defer/1251-minimax-oauth-provider.md) · 🇩🇰 [da](../../../da/_ideia/defer/1251-minimax-oauth-provider.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1251-minimax-oauth-provider.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1251-minimax-oauth-provider.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1251-minimax-oauth-provider.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1251-minimax-oauth-provider.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1251-minimax-oauth-provider.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1251-minimax-oauth-provider.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1251-minimax-oauth-provider.md) · 🇮🇱 [he](../../../he/_ideia/defer/1251-minimax-oauth-provider.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1251-minimax-oauth-provider.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1251-minimax-oauth-provider.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1251-minimax-oauth-provider.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1251-minimax-oauth-provider.md)
---
> GitHub Issue: #1251 — opened by @Tasogarre on 2026-04-14
> Status: ⏭️ DEFER | Priority: Low
## 📝 Original Request
Add MiniMax as an OAuth-based provider using the device-code + PKCE flow. MiniMax is an AI model provider that offers models accessible through their API, and the author proposes using a device-code OAuth flow (similar to GitHub CLI's auth flow) combined with PKCE for security.
## 💬 Community Discussion
### Participants
- @Tasogarre — Original requester, provided detailed OAuth flow specification
### Key Points
- Device-code + PKCE is a different OAuth pattern from OmniRoute's existing OAuth flows (browser redirect-based)
- Existing OAuth providers (Claude Code, Antigravity, Codex, GitHub Copilot, Cursor, etc.) use standard redirect flows
- Implementing device-code flow would require new OAuth infrastructure in `src/lib/oauth/`
- No community discussion beyond the initial proposal
## 🎯 Refined Feature Description
Add MiniMax as an OAuth provider using the device-code grant type with PKCE, enabling users to authenticate via a displayed code + URL (like `gh auth login`) rather than browser redirects.
### What it solves
- Adds MiniMax model provider access to OmniRoute
- Introduces device-code OAuth flow type for headless/terminal environments
- Could benefit other future providers that use device-code authentication
### How it should work (high level)
1. User clicks "Connect MiniMax" in the dashboard
2. Dashboard displays a device code and URL (e.g., "Go to minimax.chat/device and enter code: ABCD-1234")
3. User visits URL, enters code, authorizes the application
4. OmniRoute polls the token endpoint until authorization is complete
5. Stores OAuth tokens and refreshes automatically
### Affected areas
- `src/lib/oauth/constants/oauth.ts` — new OAuth config for MiniMax
- `src/lib/oauth/` — new device-code flow handler (distinct from existing redirect flows)
- `open-sse/executors/` — new or default executor for MiniMax API
- `src/shared/constants/providers.ts` — register in `OAUTH_PROVIDERS`
- `open-sse/config/providerRegistry.ts` — model registration
- Dashboard OAuth modal — new device-code UI variant
## 📎 Attachments & References
- Author provided detailed OAuth flow specification in the issue body (2795 chars)
## 🔗 Related Ideas
- Related to existing OAuth providers architecture in `src/lib/oauth/`

View File

@@ -0,0 +1,58 @@
# Feature: Add Freepik Pikaso Image Generation Provider (Cookie/Subscription-Based) (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1276-freepik-pikaso-provider.md) · 🇪🇸 [es](../../../es/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇩🇪 [de](../../../de/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇮🇹 [it](../../../it/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇮🇳 [in](../../../in/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇹🇭 [th](../../../th/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇮🇩 [id](../../../id/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇳🇴 [no](../../../no/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇩🇰 [da](../../../da/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇮🇱 [he](../../../he/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1276-freepik-pikaso-provider.md)
---
> GitHub Issue: #1276 — opened by @RaviTharuma on 2026-04-15
> Status: ⏭️ DEFER | Priority: Low
## 📝 Original Request
Add Freepik Pikaso as a cookie/subscription-based image generation provider. Pikaso is Freepik's AI image generation tool that uses a session cookie for authentication and can be accessed through their web API.
The author (@RaviTharuma) is a known contributor who built the Perplexity Web and Grok Web executors.
## 💬 Community Discussion
### Participants
- @RaviTharuma — Original requester, contributor (built Perplexity Web + Grok Web executors)
### Key Points
- Would follow the same cookie-based executor pattern as Grok Web and Perplexity Web
- Freepik Pikaso uses subscription-based access (cookie auth)
- Needs reverse-engineering of the Pikaso API endpoints and response format
- No community discussion beyond the initial proposal
## 🎯 Refined Feature Description
Add a new cookie-based image generation executor for Freepik Pikaso, following the established pattern of web-subscription providers (Grok Web, Perplexity Web).
### What it solves
- Enables Freepik Pikaso subscribers to route image generation through OmniRoute
- Extends image generation provider coverage alongside existing DALL-E, SD WebUI, ComfyUI
### How it should work (high level)
1. User provides their Freepik session cookie in the dashboard
2. OmniRoute sends image generation requests to Pikaso's internal API
3. Responses are translated to the standard OmniRoute image generation format
4. Supports text-to-image generation with style/model parameters
### Affected areas
- `open-sse/executors/` — new `freepik-pikaso.ts` executor
- `src/shared/constants/providers.ts` — register in `WEB_COOKIE_PROVIDERS` or image-specific catalog
- `open-sse/handlers/imageGeneration.ts` — add Pikaso routing support
- `open-sse/config/providerRegistry.ts` — model registration
## 📎 Attachments & References
- No external references provided yet; needs API traffic capture
## 🔗 Related Ideas
- Same pattern as Grok Web and Perplexity Web cookie-based executors

View File

@@ -0,0 +1,75 @@
# Feature: Per-Key Token Rate Limiting (TPM/TPD) (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇪🇸 [es](../../../es/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇩🇪 [de](../../../de/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇮🇹 [it](../../../it/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇮🇳 [in](../../../in/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇹🇭 [th](../../../th/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇮🇩 [id](../../../id/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇳🇴 [no](../../../no/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇩🇰 [da](../../../da/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇮🇱 [he](../../../he/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1305-per-key-token-rate-limiting.md)
---
> GitHub Issue: #1305 — opened by @kaccang on 2026-04-16
> Status: ⏭️ DEFER | Priority: Medium
## 📝 Original Request
OmniRoute already supports per-key request-based limits, but subscription-based API operators also need token-based limits to control upstream cost exposure. A single request to a large-context model can consume far more compute and cost than a normal request while still counting as only one request.
**Use case examples (from author):**
- Lite plan: 32K tokens/minute, 5M tokens/day
- Pro plan: 64K tokens/minute, 15M tokens/day
**Proposed fields:**
- `max_tokens_per_minute` (TPM)
- `max_tokens_per_day` (TPD)
Returns HTTP 429 with `token_limit_exceeded` reason when exceeded.
## 💬 Community Discussion
### Participants
- @kaccang — Original requester, detailed operator-focused use case
### Key Points
- Addresses operators selling subscription-based AI API products through OmniRoute
- Request-only limits are insufficient for long-context or high-output models
- Token accounting should use actual usage from upstream response `usage` fields
- Must handle both streaming and non-streaming accounting paths
- Backward compatible — keys without token limits keep existing behavior
## 🎯 Refined Feature Description
Add optional per-API-key token-based rate limiting alongside existing request-based limits, enabling operators to enforce fair-use policies based on actual token consumption.
### What it solves
- Disproportionate cost exposure from large-context requests that count as single requests
- Inability to sell token-based subscription plans through OmniRoute
- Lack of per-customer cost protection for mixed model catalogs with varying context windows
### How it should work (high level)
1. Add `max_tokens_per_minute` and `max_tokens_per_day` optional fields to API key configuration
2. After each response, extract `usage.total_tokens` from the upstream response
3. Account consumed tokens to the authenticated key using sliding window counters
4. Before each request, check if the key has remaining token budget for the current window
5. If budget exceeded, return 429 with `token_limit_exceeded` error code and `Retry-After` header
6. For streaming responses, account tokens from the final usage chunk (`stream_options.include_usage`)
7. Dashboard UI: display TPM/TPD fields in the API key creation/edit modal
### Affected areas
- `src/lib/db/apiKeys.ts` — new columns for TPM/TPD limits
- `open-sse/services/rateLimitManager.ts` — token-based window tracking
- `open-sse/handlers/chatCore.ts` — post-response token accounting
- `src/app/api/v1/` routes — pre-request token budget check
- `src/app/(dashboard)/dashboard/settings/` — API key modal UI extension
- DB migrations — new columns on `api_keys` table
## 📎 Attachments & References
- Author's detailed acceptance criteria and test plan in issue body
## 🔗 Related Ideas
- Directly related to [1320-rate-limit-headers](./1320-rate-limit-headers.md) — expose token limits via standard headers

View File

@@ -0,0 +1,71 @@
# Feature: Standard Rate Limit Headers for Requests, Tokens, Resets, and Retry-After (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1320-rate-limit-headers.md) · 🇪🇸 [es](../../../es/_ideia/defer/1320-rate-limit-headers.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1320-rate-limit-headers.md) · 🇩🇪 [de](../../../de/_ideia/defer/1320-rate-limit-headers.md) · 🇮🇹 [it](../../../it/_ideia/defer/1320-rate-limit-headers.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1320-rate-limit-headers.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1320-rate-limit-headers.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1320-rate-limit-headers.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1320-rate-limit-headers.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1320-rate-limit-headers.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1320-rate-limit-headers.md) · 🇮🇳 [in](../../../in/_ideia/defer/1320-rate-limit-headers.md) · 🇹🇭 [th](../../../th/_ideia/defer/1320-rate-limit-headers.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1320-rate-limit-headers.md) · 🇮🇩 [id](../../../id/_ideia/defer/1320-rate-limit-headers.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1320-rate-limit-headers.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1320-rate-limit-headers.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1320-rate-limit-headers.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1320-rate-limit-headers.md) · 🇳🇴 [no](../../../no/_ideia/defer/1320-rate-limit-headers.md) · 🇩🇰 [da](../../../da/_ideia/defer/1320-rate-limit-headers.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1320-rate-limit-headers.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1320-rate-limit-headers.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1320-rate-limit-headers.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1320-rate-limit-headers.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1320-rate-limit-headers.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1320-rate-limit-headers.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1320-rate-limit-headers.md) · 🇮🇱 [he](../../../he/_ideia/defer/1320-rate-limit-headers.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1320-rate-limit-headers.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1320-rate-limit-headers.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1320-rate-limit-headers.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1320-rate-limit-headers.md)
---
> GitHub Issue: #1320 — opened by @kaccang on 2026-04-16
> Status: ⏭️ DEFER | Priority: Medium
## 📝 Original Request
When a client is throttled, it should receive machine-readable rate-limit information via standard HTTP headers so it can back off correctly. Without explicit response headers, clients guess retry timing, producing unnecessary retry loops that increase pressure on the gateway.
**Proposed headers (from author):**
Request-based:
- `X-RateLimit-Limit-Requests-Minute` / `X-RateLimit-Remaining-Requests-Minute` / `X-RateLimit-Reset-Requests-Minute`
- `X-RateLimit-Limit-Requests-Day` / `X-RateLimit-Remaining-Requests-Day` / `X-RateLimit-Reset-Requests-Day`
Token-based (if configured):
- `X-RateLimit-Limit-Tokens-Minute` / `X-RateLimit-Remaining-Tokens-Minute` / `X-RateLimit-Reset-Tokens-Minute`
- `X-RateLimit-Limit-Tokens-Day` / `X-RateLimit-Remaining-Tokens-Day` / `X-RateLimit-Reset-Tokens-Day`
On 429: `Retry-After` header.
## 💬 Community Discussion
### Participants
- @kaccang — Original requester, also opened #1305 (per-key token rate limiting)
### Key Points
- Aligns with OpenAI's rate-limit header convention
- Useful for SDKs, automation tools, and customer dashboards
- Backward compatible — clients that don't consume headers are unaffected
- Author provided detailed acceptance criteria and test plan
## 🎯 Refined Feature Description
Expose current rate-limit state via standard HTTP response headers on all API responses, and include `Retry-After` on 429 responses.
### What it solves
- Clients cannot determine remaining quota without trial-and-error
- SDKs and automation tools lack machine-readable throttling signals
- Unnecessary retry loops when clients guess retry timing
### How it should work (high level)
1. On every successful response, inject rate-limit headers reflecting the authenticated key's current state
2. On 429 responses, include `Retry-After` with the number of seconds until the next window
3. Request-based and token-based headers are independent — only include what is configured
4. Headers are derived from the existing `rateLimitManager` state, no new persistence needed
### Affected areas
- `open-sse/services/rateLimitManager.ts` — expose current window state
- `open-sse/handlers/chatCore.ts` — inject headers into response
- `src/app/api/v1/` routes — inject headers at route level
- `src/middleware/` — potential centralized header injection
## 📎 Attachments & References
- Author's test plan included in the issue body
## 🔗 Related Ideas
- Directly related to [1305-per-key-token-rate-limiting](./1305-per-key-token-rate-limiting.md) — both address rate-limit observability

View File

@@ -0,0 +1,59 @@
# Feature: API Key Routing Rules for Custom Endpoints (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1339-api-key-routing-rules.md) · 🇪🇸 [es](../../../es/_ideia/defer/1339-api-key-routing-rules.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1339-api-key-routing-rules.md) · 🇩🇪 [de](../../../de/_ideia/defer/1339-api-key-routing-rules.md) · 🇮🇹 [it](../../../it/_ideia/defer/1339-api-key-routing-rules.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1339-api-key-routing-rules.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1339-api-key-routing-rules.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1339-api-key-routing-rules.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1339-api-key-routing-rules.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1339-api-key-routing-rules.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1339-api-key-routing-rules.md) · 🇮🇳 [in](../../../in/_ideia/defer/1339-api-key-routing-rules.md) · 🇹🇭 [th](../../../th/_ideia/defer/1339-api-key-routing-rules.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1339-api-key-routing-rules.md) · 🇮🇩 [id](../../../id/_ideia/defer/1339-api-key-routing-rules.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1339-api-key-routing-rules.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1339-api-key-routing-rules.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1339-api-key-routing-rules.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1339-api-key-routing-rules.md) · 🇳🇴 [no](../../../no/_ideia/defer/1339-api-key-routing-rules.md) · 🇩🇰 [da](../../../da/_ideia/defer/1339-api-key-routing-rules.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1339-api-key-routing-rules.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1339-api-key-routing-rules.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1339-api-key-routing-rules.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1339-api-key-routing-rules.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1339-api-key-routing-rules.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1339-api-key-routing-rules.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1339-api-key-routing-rules.md) · 🇮🇱 [he](../../../he/_ideia/defer/1339-api-key-routing-rules.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1339-api-key-routing-rules.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1339-api-key-routing-rules.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1339-api-key-routing-rules.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1339-api-key-routing-rules.md)
---
> GitHub Issue: #1339 — opened by @uwuclxdy on 2026-04-16
> Status: ⏭️ DEFER | Priority: Medium
## 📝 Original Request
When using a custom OpenAI endpoint with multiple API keys, the only available routing option is "round-robin". The user wants the ability to configure routing strategies per-provider (e.g., "exhaust first key before using second"), similar to how combo-level strategies already work.
The user included a screenshot of the API key popup in the dashboard, highlighting that there's no strategy selector available at the provider/connection level.
## 💬 Community Discussion
### Participants
- @uwuclxdy — Original requester, active contributor (also opened #1364, #1182)
### Key Points
- Currently, routing strategies (priority, weighted, fill-first, round-robin, etc.) are only configurable at the combo level
- Provider-level multi-key rotation is hardcoded to round-robin
- User wants "fill-first" (exhaust first key before next) for cost optimization
- Affects custom OpenAI-compatible and Anthropic-compatible providers
## 🎯 Refined Feature Description
Extend the provider connection management to allow per-provider API key routing strategy selection, mirroring the 13 strategies already available at the combo level.
### What it solves
- Users with multiple API keys for the same provider cannot control which key is used first
- Round-robin wastes quota evenly across keys instead of exhausting free/cheaper tiers first
- No parity between combo-level routing flexibility and provider-level key management
### How it should work (high level)
1. Add a "Key Routing Strategy" dropdown to the provider detail page's connection/key management popup
2. Support at minimum: `round-robin`, `priority`, `fill-first`, `random`
3. Store the per-provider strategy in the `provider_connections` table or a new column
4. The combo routing engine respects per-provider key strategy when dispatching requests
### Affected areas
- `open-sse/services/combo.ts` — key selection within a provider target
- `src/lib/db/providers.ts` — store per-provider key strategy
- `src/app/(dashboard)/dashboard/providers/[id]/page.tsx` — UI for strategy selection
- `src/shared/validation/schemas.ts` — new schema for provider key strategy
## 📎 Attachments & References
- Screenshot of API key popup: https://github.com/user-attachments/assets/d26049ba-0dba-4c64-8ed4-8f68e8c00252
## 🔗 Related Ideas
- Related to combo routing engine strategies in `open-sse/services/combo.ts`

View File

@@ -0,0 +1,41 @@
# Feature: Task-Class Routing with Escalation/De-escalation (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/785-task-class-routing.md) · 🇪🇸 [es](../../../es/_ideia/defer/785-task-class-routing.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/785-task-class-routing.md) · 🇩🇪 [de](../../../de/_ideia/defer/785-task-class-routing.md) · 🇮🇹 [it](../../../it/_ideia/defer/785-task-class-routing.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/785-task-class-routing.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/785-task-class-routing.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/785-task-class-routing.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/785-task-class-routing.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/785-task-class-routing.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/785-task-class-routing.md) · 🇮🇳 [in](../../../in/_ideia/defer/785-task-class-routing.md) · 🇹🇭 [th](../../../th/_ideia/defer/785-task-class-routing.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/785-task-class-routing.md) · 🇮🇩 [id](../../../id/_ideia/defer/785-task-class-routing.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/785-task-class-routing.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/785-task-class-routing.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/785-task-class-routing.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/785-task-class-routing.md) · 🇳🇴 [no](../../../no/_ideia/defer/785-task-class-routing.md) · 🇩🇰 [da](../../../da/_ideia/defer/785-task-class-routing.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/785-task-class-routing.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/785-task-class-routing.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/785-task-class-routing.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/785-task-class-routing.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/785-task-class-routing.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/785-task-class-routing.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/785-task-class-routing.md) · 🇮🇱 [he](../../../he/_ideia/defer/785-task-class-routing.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/785-task-class-routing.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/785-task-class-routing.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/785-task-class-routing.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/785-task-class-routing.md)
---
> GitHub Issue: #785 — opened by @igormorais123 on 2026-03-30
> Status: 📋 Cataloged | Priority: Medium
## 📝 Original Request
Map incoming requests to specialized combos based on 7 task classes (bulk_low_risk, code_generation, security_critical, etc.) with automatic escalation to premium models for complex tasks and de-escalation to economy for simple ones.
## 🎯 Refined Feature Description
OmniRoute already has `taskAwareRouter.ts` and `intentClassifier.ts` that provide basic task-aware routing. This request expands that with a formal escalation/de-escalation engine based on task classification.
### What it solves
- Same combo used for trivial and critical tasks
- No automatic quality scaling based on difficulty
### How it should work
1. Classify incoming request into a task class (using existing `intentClassifier`)
2. Map task class → combo selection rules (which combo, which strategy)
3. Apply escalation rules (complex request → premium model)
4. Apply de-escalation (trivial → cheap model)
### Affected areas
- `open-sse/services/taskAwareRouter.ts` — extend classification
- `open-sse/services/intentClassifier.ts` — more task classes
- `open-sse/services/combo.ts` — task-class routing integration
- Settings UI — task-class configuration
## 🔗 Related Ideas
- Related to [980-lkgp-routing](./980-lkgp-routing.md) — LKGP scoring
- Related to [1041-smart-auto-combos](./1041-smart-auto-combos.md) — dynamic combos
- Part of @igormorais123's series

View File

@@ -0,0 +1,20 @@
# Feature: AutoResearch — Recursive Self-Improvement Loop (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/787-auto-research.md) · 🇪🇸 [es](../../../es/_ideia/defer/787-auto-research.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/787-auto-research.md) · 🇩🇪 [de](../../../de/_ideia/defer/787-auto-research.md) · 🇮🇹 [it](../../../it/_ideia/defer/787-auto-research.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/787-auto-research.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/787-auto-research.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/787-auto-research.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/787-auto-research.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/787-auto-research.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/787-auto-research.md) · 🇮🇳 [in](../../../in/_ideia/defer/787-auto-research.md) · 🇹🇭 [th](../../../th/_ideia/defer/787-auto-research.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/787-auto-research.md) · 🇮🇩 [id](../../../id/_ideia/defer/787-auto-research.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/787-auto-research.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/787-auto-research.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/787-auto-research.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/787-auto-research.md) · 🇳🇴 [no](../../../no/_ideia/defer/787-auto-research.md) · 🇩🇰 [da](../../../da/_ideia/defer/787-auto-research.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/787-auto-research.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/787-auto-research.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/787-auto-research.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/787-auto-research.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/787-auto-research.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/787-auto-research.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/787-auto-research.md) · 🇮🇱 [he](../../../he/_ideia/defer/787-auto-research.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/787-auto-research.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/787-auto-research.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/787-auto-research.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/787-auto-research.md)
---
> GitHub Issue: #787 — opened by @igormorais123 on 2026-03-30
> Status: 📋 Cataloged | Priority: Low
## 📝 Original Request
Implement an autonomous optimization loop where an AI agent iterates hundreds of routing configurations against evaluation datasets, inspired by Karpathy's AutoResearch paradigm.
## 🎯 Refined Feature Description
An ambitious research-grade feature that would require significant infrastructure (evaluation datasets, automated benchmarking, config mutation engine). Beyond current scope but catalogs a valid long-term vision.
## 🔗 Related Ideas
- Part of @igormorais123's series: [792](./792-team-of-rivals.md), [797](./797-hierarchical-router.md), [801](./801-cross-provider-diversity.md), [785](./785-task-class-routing.md)

View File

@@ -0,0 +1,20 @@
# Feature: Multi-Provider Code Review Pipeline (Team of Rivals) (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/792-team-of-rivals.md) · 🇪🇸 [es](../../../es/_ideia/defer/792-team-of-rivals.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/792-team-of-rivals.md) · 🇩🇪 [de](../../../de/_ideia/defer/792-team-of-rivals.md) · 🇮🇹 [it](../../../it/_ideia/defer/792-team-of-rivals.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/792-team-of-rivals.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/792-team-of-rivals.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/792-team-of-rivals.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/792-team-of-rivals.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/792-team-of-rivals.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/792-team-of-rivals.md) · 🇮🇳 [in](../../../in/_ideia/defer/792-team-of-rivals.md) · 🇹🇭 [th](../../../th/_ideia/defer/792-team-of-rivals.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/792-team-of-rivals.md) · 🇮🇩 [id](../../../id/_ideia/defer/792-team-of-rivals.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/792-team-of-rivals.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/792-team-of-rivals.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/792-team-of-rivals.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/792-team-of-rivals.md) · 🇳🇴 [no](../../../no/_ideia/defer/792-team-of-rivals.md) · 🇩🇰 [da](../../../da/_ideia/defer/792-team-of-rivals.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/792-team-of-rivals.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/792-team-of-rivals.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/792-team-of-rivals.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/792-team-of-rivals.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/792-team-of-rivals.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/792-team-of-rivals.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/792-team-of-rivals.md) · 🇮🇱 [he](../../../he/_ideia/defer/792-team-of-rivals.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/792-team-of-rivals.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/792-team-of-rivals.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/792-team-of-rivals.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/792-team-of-rivals.md)
---
> GitHub Issue: #792 — opened by @igormorais123 on 2026-03-30
> Status: 📋 Cataloged | Priority: Low
## 📝 Original Request
Send critical tasks to 2-3 providers in parallel (Planner, Critic, Executor, Quality Reviewer), each from different providers for cognitive diversity.
## 🎯 Refined Feature Description
Advanced multi-agent orchestration pattern outside OmniRoute's core scope as a proxy/router. Better suited for an orchestration framework built on top of OmniRoute.
## 🔗 Related Ideas
- Part of @igormorais123's series: [797](./797-hierarchical-router.md), [801](./801-cross-provider-diversity.md), [785](./785-task-class-routing.md), [787](./787-auto-research.md)

View File

@@ -0,0 +1,20 @@
# Feature: Hierarchical Router — Direct vs Multi-Agent orchestration (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/797-hierarchical-router.md) · 🇪🇸 [es](../../../es/_ideia/defer/797-hierarchical-router.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/797-hierarchical-router.md) · 🇩🇪 [de](../../../de/_ideia/defer/797-hierarchical-router.md) · 🇮🇹 [it](../../../it/_ideia/defer/797-hierarchical-router.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/797-hierarchical-router.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/797-hierarchical-router.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/797-hierarchical-router.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/797-hierarchical-router.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/797-hierarchical-router.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/797-hierarchical-router.md) · 🇮🇳 [in](../../../in/_ideia/defer/797-hierarchical-router.md) · 🇹🇭 [th](../../../th/_ideia/defer/797-hierarchical-router.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/797-hierarchical-router.md) · 🇮🇩 [id](../../../id/_ideia/defer/797-hierarchical-router.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/797-hierarchical-router.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/797-hierarchical-router.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/797-hierarchical-router.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/797-hierarchical-router.md) · 🇳🇴 [no](../../../no/_ideia/defer/797-hierarchical-router.md) · 🇩🇰 [da](../../../da/_ideia/defer/797-hierarchical-router.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/797-hierarchical-router.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/797-hierarchical-router.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/797-hierarchical-router.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/797-hierarchical-router.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/797-hierarchical-router.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/797-hierarchical-router.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/797-hierarchical-router.md) · 🇮🇱 [he](../../../he/_ideia/defer/797-hierarchical-router.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/797-hierarchical-router.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/797-hierarchical-router.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/797-hierarchical-router.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/797-hierarchical-router.md)
---
> GitHub Issue: #797 — opened by @igormorais123 on 2026-03-30
> Status: 📋 Cataloged | Priority: Low
## 📝 Original Request
Two-tier routing layer classifying requests into fast direct path (single model) or multi-agent orchestration (planner → critic → executor).
## 🎯 Refined Feature Description
This is an advanced orchestration concept that goes well beyond OmniRoute's scope as a proxy/router. OmniRoute already has `taskAwareRouter.ts` and `intentClassifier.ts` which provide basic task-aware routing, but full multi-agent orchestration is an application-layer concern.
## 🔗 Related Ideas
- Part of @igormorais123's series: [792](./792-team-of-rivals.md), [801](./801-cross-provider-diversity.md), [785](./785-task-class-routing.md), [787](./787-auto-research.md)

View File

@@ -0,0 +1,27 @@
# Feature: Cross-Provider Cognitive Diversity (Role-to-Provider Mapping) (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/801-cross-provider-diversity.md) · 🇪🇸 [es](../../../es/_ideia/defer/801-cross-provider-diversity.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/801-cross-provider-diversity.md) · 🇩🇪 [de](../../../de/_ideia/defer/801-cross-provider-diversity.md) · 🇮🇹 [it](../../../it/_ideia/defer/801-cross-provider-diversity.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/801-cross-provider-diversity.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/801-cross-provider-diversity.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/801-cross-provider-diversity.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/801-cross-provider-diversity.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/801-cross-provider-diversity.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/801-cross-provider-diversity.md) · 🇮🇳 [in](../../../in/_ideia/defer/801-cross-provider-diversity.md) · 🇹🇭 [th](../../../th/_ideia/defer/801-cross-provider-diversity.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/801-cross-provider-diversity.md) · 🇮🇩 [id](../../../id/_ideia/defer/801-cross-provider-diversity.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/801-cross-provider-diversity.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/801-cross-provider-diversity.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/801-cross-provider-diversity.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/801-cross-provider-diversity.md) · 🇳🇴 [no](../../../no/_ideia/defer/801-cross-provider-diversity.md) · 🇩🇰 [da](../../../da/_ideia/defer/801-cross-provider-diversity.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/801-cross-provider-diversity.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/801-cross-provider-diversity.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/801-cross-provider-diversity.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/801-cross-provider-diversity.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/801-cross-provider-diversity.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/801-cross-provider-diversity.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/801-cross-provider-diversity.md) · 🇮🇱 [he](../../../he/_ideia/defer/801-cross-provider-diversity.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/801-cross-provider-diversity.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/801-cross-provider-diversity.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/801-cross-provider-diversity.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/801-cross-provider-diversity.md)
---
> GitHub Issue: #801 — opened by @igormorais123 on 2026-03-30
> Status: 📋 Cataloged | Priority: Low
## 📝 Original Request
Enforce that different roles in multi-model review pipelines use different providers to maximize failure diversity. A planner and its critic should never be the same provider.
## 🎯 Refined Feature Description
This is an advanced orchestration pattern. OmniRoute already supports multi-provider combos but doesn't enforce cognitive diversity between roles. This would require significant architectural changes to add role-based routing.
### Affected areas
- Would require a new orchestration layer above combo routing
- Significant scope for a routing proxy
## 🔗 Related Ideas
- Related to [792-team-of-rivals](./792-team-of-rivals.md)
- Related to [797-hierarchical-router](./797-hierarchical-router.md)
- Part of @igormorais123's 5-issue series (#785, #787, #792, #797, #801)

View File

@@ -0,0 +1,47 @@
# Feature: LKGP (Last Known Good Providers) Routing (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/980-lkgp-routing.md) · 🇪🇸 [es](../../../es/_ideia/defer/980-lkgp-routing.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/980-lkgp-routing.md) · 🇩🇪 [de](../../../de/_ideia/defer/980-lkgp-routing.md) · 🇮🇹 [it](../../../it/_ideia/defer/980-lkgp-routing.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/980-lkgp-routing.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/980-lkgp-routing.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/980-lkgp-routing.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/980-lkgp-routing.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/980-lkgp-routing.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/980-lkgp-routing.md) · 🇮🇳 [in](../../../in/_ideia/defer/980-lkgp-routing.md) · 🇹🇭 [th](../../../th/_ideia/defer/980-lkgp-routing.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/980-lkgp-routing.md) · 🇮🇩 [id](../../../id/_ideia/defer/980-lkgp-routing.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/980-lkgp-routing.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/980-lkgp-routing.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/980-lkgp-routing.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/980-lkgp-routing.md) · 🇳🇴 [no](../../../no/_ideia/defer/980-lkgp-routing.md) · 🇩🇰 [da](../../../da/_ideia/defer/980-lkgp-routing.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/980-lkgp-routing.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/980-lkgp-routing.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/980-lkgp-routing.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/980-lkgp-routing.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/980-lkgp-routing.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/980-lkgp-routing.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/980-lkgp-routing.md) · 🇮🇱 [he](../../../he/_ideia/defer/980-lkgp-routing.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/980-lkgp-routing.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/980-lkgp-routing.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/980-lkgp-routing.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/980-lkgp-routing.md)
---
> GitHub Issue: #980 — opened by @diegosouzapw on 2026-04-04
> Status: 📋 Cataloged | Priority: Medium
> Source: Discussion 919 by @oyi77
## 📝 Original Request
Implement a dynamic weighting algorithm in the combo routing engine that uses latency and recent success rate (LKGP) alongside healthchecks.
## 💬 Community Discussion
### Participants
- @diegosouzapw — Issue creator
- @oyi77 — Original discussion author
## 🎯 Refined Feature Description
LKGP routing tracks which provider connections have been performing well recently (low latency, high success rate) and dynamically adjusts routing weights to prefer them. Unlike static priority, this adapts in real-time.
### What it solves
- Static priority can't adapt to transient provider degradation
- Healthchecks are periodic — LKGP uses real request metrics
### How it should work
1. Track last N request outcomes per connection (success/fail, latency)
2. Compute a LKGP score = f(success_rate, avg_latency, recency)
3. Use LKGP scores as dynamic weights in combo routing
4. Decay old metrics over time
### Affected areas
- `open-sse/services/combo.ts` — routing weight calculation
- `src/lib/db/domainState.ts` — LKGP metric storage
- Dashboard — LKGP score visualization
## 🔗 Related Ideas
- Related to [1041-smart-auto-combos](./1041-smart-auto-combos.md)
- Related to [785-task-class-routing](./785-task-class-routing.md)

View File

@@ -0,0 +1,43 @@
# Feature: Providers-independent approach (Universal Model IDs) (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1023-providers-independent.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1023-providers-independent.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1023-providers-independent.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1023-providers-independent.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1023-providers-independent.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1023-providers-independent.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1023-providers-independent.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1023-providers-independent.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1023-providers-independent.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1023-providers-independent.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1023-providers-independent.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1023-providers-independent.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1023-providers-independent.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1023-providers-independent.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1023-providers-independent.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1023-providers-independent.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1023-providers-independent.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1023-providers-independent.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1023-providers-independent.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1023-providers-independent.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1023-providers-independent.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1023-providers-independent.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1023-providers-independent.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1023-providers-independent.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1023-providers-independent.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1023-providers-independent.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1023-providers-independent.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1023-providers-independent.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1023-providers-independent.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1023-providers-independent.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1023-providers-independent.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1023-providers-independent.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1023-providers-independent.md)
---
> GitHub Issue: #1023 — opened by @ralphilius on 2026-04-06
> Status: 📋 Cataloged | Priority: Medium
## 📝 Original Request
When connecting to multiple providers that serve the same models, users need to switch prefixes in coding tool configs. Proposes universal constant model IDs that work regardless of provider, making OmniRoute appear as a single provider.
## 💬 Community Discussion
### Participants
- @ralphilius — Original requester
### Key Points
- Pain point: switching provider prefixes in client configs when rotating providers
- Wants "set and forget" configuration
## 🎯 Refined Feature Description
This is essentially the model alias system that already exists. Users can create aliases like `claude-sonnet``anthropic/claude-sonnet-4` so their clients always use the same model name regardless of which provider serves it.
### What it solves
- Already solved by existing Model Aliases feature (`/dashboard/settings` → Model Aliases)
### Affected areas
- May need better documentation/discoverability of existing aliases feature
## 📎 Attachments & References
- Existing feature: Model Aliases in dashboard settings
## 🔗 Related Ideas
- This overlaps with existing Model Aliases functionality — may just need documentation/UI improvements

View File

@@ -0,0 +1,80 @@
# Feature: Native Playground LLM Dashboard - Built-in testing page (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1046-native-playground.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1046-native-playground.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1046-native-playground.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1046-native-playground.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1046-native-playground.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1046-native-playground.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1046-native-playground.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1046-native-playground.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1046-native-playground.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1046-native-playground.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1046-native-playground.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1046-native-playground.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1046-native-playground.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1046-native-playground.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1046-native-playground.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1046-native-playground.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1046-native-playground.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1046-native-playground.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1046-native-playground.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1046-native-playground.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1046-native-playground.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1046-native-playground.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1046-native-playground.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1046-native-playground.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1046-native-playground.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1046-native-playground.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1046-native-playground.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1046-native-playground.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1046-native-playground.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1046-native-playground.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1046-native-playground.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1046-native-playground.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1046-native-playground.md)
---
> GitHub Issue: #1046 — opened by @diegosouzapw on 2026-04-07
> Status: 📋 Cataloged | Priority: High
> Duplicate of: #234 (92% similarity per Kilo)
## 📝 Original Request
**Source:** Discussion #1035 by @rilham97
Add a built-in playground or test page in the OmniRoute dashboard where users can easily test their configured LLMs, verify model names, and check the response body formatting directly.
### Implementation Ideas
- A lightweight React component in the `/dashboard` route.
- A simple chat or raw completion interface to send test requests to the OmniRoute proxy endpoint.
### Current Workarounds
Users can use lightweight local clients like OpenClaw, or standard terminal/browser curl requests to test the API.
## 💬 Community Discussion
### Participants
- @diegosouzapw — Issue creator (from discussion)
- @rilham97 — Original requester, provided design references
- @kilo-code-bot — Auto-triage (duplicate of #234, 92%)
### Key Points
- This is a highly requested feature with a prior duplicate (#234)
- @rilham97 provided concrete UI references:
- https://app.fireworks.ai/playground
- https://ai.nahcrof.com/
## 🎯 Refined Feature Description
A built-in playground page at `/dashboard/playground` that allows users to:
1. Select any configured combo or provider+model
2. Send chat completion requests with customizable parameters (temperature, max_tokens, system prompt)
3. View full response including metadata (tokens used, latency, cost)
4. Toggle between streaming and non-streaming modes
5. View raw request/response JSON for debugging
### What it solves
- Eliminates need for external tools to test model configuration
- Provides instant feedback on whether a combo/provider is working
- Helps debug response format issues without leaving the dashboard
### How it should work (high level)
1. User navigates to `/dashboard/playground`
2. Selects a combo or specific provider/model from dropdown
3. Types a message in a chat interface
4. Clicks Send → sees streaming response
5. Can inspect raw JSON, token usage, and latency metrics
### Affected areas
- `src/app/(dashboard)/dashboard/playground/` — new page
- `src/app/api/` — may use existing `/v1/chat/completions` internally
- i18n — new translation keys across 30 languages
- Sidebar navigation — add new menu item
## 📎 Attachments & References
- Fireworks AI Playground: https://app.fireworks.ai/playground
- AI Nahcrof playground: https://ai.nahcrof.com/
- Original discussion: #1035
## 🔗 Related Ideas
- Related to #234 (original playground request, 92% similarity)

View File

@@ -0,0 +1,61 @@
# Feature: [Feature] Headroom support (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1100-headroom-support.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1100-headroom-support.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1100-headroom-support.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1100-headroom-support.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1100-headroom-support.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1100-headroom-support.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1100-headroom-support.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1100-headroom-support.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1100-headroom-support.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1100-headroom-support.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1100-headroom-support.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1100-headroom-support.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1100-headroom-support.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1100-headroom-support.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1100-headroom-support.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1100-headroom-support.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1100-headroom-support.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1100-headroom-support.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1100-headroom-support.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1100-headroom-support.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1100-headroom-support.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1100-headroom-support.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1100-headroom-support.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1100-headroom-support.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1100-headroom-support.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1100-headroom-support.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1100-headroom-support.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1100-headroom-support.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1100-headroom-support.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1100-headroom-support.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1100-headroom-support.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1100-headroom-support.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1100-headroom-support.md)
---
> GitHub Issue: #1100 — opened by @mkizilov on 2026-04-10T00:15:46Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem / Use Case
Right now there is problematic to running Headroom because it needs to be routed via omniroute. Maybe implement some easier way to do it?
https://github.com/chopratejas/headroom
### Proposed Solution
https://github.com/chopratejas/headroom
### Acceptance Criteria
some turn on\off switch to use headroom right in the UI
### Area
Proxy / Routing
## 💬 Community Discussion
(No comments yet)
## 🎯 Refined Feature Description
Headroom is an open-source UI for interacting with LLMs. The user wants to integrate/run Headroom directly through OmniRoute's UI with a simple switch, rather than having to separately deploy and configure Headroom to route traffic through OmniRoute.
### What it solves
- Removes the deployment friction for using a chat UI (Headroom) with our local API endpoints.
- Unifies the experience within our dashboard.
### How it should work (high level)
1. Add an internal proxy or embedding layer for Headroom's static UI.
2. In the OmniRoute dashboard, provide a switch or dedicated "Chat UI" route to launch headroom.
3. Auto-configure the Headroom UI to use `http://localhost:20128/v1` and the user's OmniRoute APIs automatically.
### Affected areas
- `src/app/(dashboard)/`
- `open-sse/services/`
- Next.js rewrite/proxy configs or Docker compose templates.
## 📎 Attachments & References
- https://github.com/chopratejas/headroom
## 🔗 Related Ideas
- 1046-native-playground (already implemented a native playground, which might solve their primary need)

View File

@@ -0,0 +1,65 @@
# Feature: [Feature] whitelist models for specific API KEY (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1110-whitelist-models-api-key.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1110-whitelist-models-api-key.md)
---
> GitHub Issue: #1110 — opened by @0xtbug on 2026-04-10T09:26:02Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem / Use Case
For better API KEY management, the system needs to support a customized model list (whitelist) for specific API KEYs. This is crucial for access control, cost limitation, and offering tiered services.
For example:
- api_key_1 (Admin/Pro): can access all models (\*).
- api_key_2 (Basic): can only access specific, perhaps cheaper, models like gpt-3.5-turbo, claude-3-haiku.
- api_key_3 (Vendor): can access all models from a specific provider alongside specific extra models (e.g., anthropic/\*, model_extra_1).
### Proposed Solution
1. Data Schema Update: Add a new optional property (e.g., allowed_models as an array of strings) to the API Key database/schema. Support wildcards or provider namespaces (e.g., _, openai/_, gpt-4).
2. Middleware / Validation Logic: Modify the authentication middleware. After validating the API Key, intercept the request payload to check if the requested model is within the key's allowed list.
3. Interception: If the requested model is not in the API Key's whitelist, reject the request with a 403 Forbidden status and a clear error message (e.g., "Model not allowed for this API key").
4. Admin Dashboard (If UI exists): Add a multi-select dropdown in the API Key creation interface so admins can easily configure permitted models for the new key.
### Alternatives Considered
- Using a Separate Reverse Proxy (API Gateway). Drawback: Adds infrastructure complexity.
- Deploying Different Instances. Drawback: Highly resource-intensive.
### Acceptance Criteria
- API keys with \* access (or no restrictions) can successfully call all available models (200 OK).
- API keys attempting to call unsupported models are rejected with 403 Forbidden.
- Support wildcard parsing logic (`openai/*`).
- No significant performance latency.
## 💬 Community Discussion
- @kilo-code-bot — Triaged this issue as a duplicate of #781 (Similarity score: 90%). Tagged `kilo-duplicate`.
## 🎯 Refined Feature Description
Allow administrators to restrict which specific models/combos an OmniRoute API Key can invoke. Currently, an OmniRoute key grants access to all configured combos. This feature would restrict that access at the routing layer (`chatCore.ts` or auth middleware).
### What it solves
Allows the creation of "cheap" keys for casual tools and "expensive" keys for priority workflows.
### Affected areas
- `src/lib/db/apiKeys.ts`
- `open-sse/handlers/chatCore.ts` (or the Auth plugin)
- Dashboard `ApiKeysView.tsx`
## 📎 Attachments & References
N/A
## 🔗 Related Ideas
> This feature is a duplicate of #781. Consider marking it as ALREADY EXISTS or NOT FIT depending on #781 status.

View File

@@ -0,0 +1,42 @@
# Feature: Automated installation for Hermes (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1129-automated-hermes.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1129-automated-hermes.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1129-automated-hermes.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1129-automated-hermes.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1129-automated-hermes.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1129-automated-hermes.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1129-automated-hermes.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1129-automated-hermes.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1129-automated-hermes.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1129-automated-hermes.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1129-automated-hermes.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1129-automated-hermes.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1129-automated-hermes.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1129-automated-hermes.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1129-automated-hermes.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1129-automated-hermes.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1129-automated-hermes.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1129-automated-hermes.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1129-automated-hermes.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1129-automated-hermes.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1129-automated-hermes.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1129-automated-hermes.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1129-automated-hermes.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1129-automated-hermes.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1129-automated-hermes.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1129-automated-hermes.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1129-automated-hermes.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1129-automated-hermes.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1129-automated-hermes.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1129-automated-hermes.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1129-automated-hermes.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1129-automated-hermes.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1129-automated-hermes.md)
---
> GitHub Issue: #1129 — opened by @Snodgrass-Wilkerschnoz on 2026-04-10
> Status: ❌ NOT FIT | Priority: TBD
## 📝 Original Request
### Problem / Use Case
Id like to simply configure Hermes to work with OmniRoute with an Hermes-led step-through configuration to simplify onboarding and avoid manual config.
### Proposed Solution
Step-though initial config for Hermes.
### Acceptance Criteria
-Direct Hermes to install OmniRoute
-After installation, Hermes walks through config
-Configuration is written to OmniRoute and can be controlled successfully by Hermes
## 💬 Community Discussion
### Participants
- @Snodgrass-Wilkerschnoz — Original requester
## 🎯 Refined Feature Description
Create an automated deployment script inside the Hermes Agent configuration wizard to download, install, and interface with OmniRoute.
### Why it does not fit
Hermes Agent is a completely separate application that utilizes APIs. Any installer logic dictating "Hermes walks through config" would technically reside exclusively inside the Hermes Agent repository's source code, not inside the OmniRoute proxy itself. Expanding the OmniRoute proxy engine to package installation routines for external autonomous agents violates OmniRoute's architectural boundaries as a headless unified proxy wrapper.
## 🔗 Related Ideas
- N/A

View File

@@ -0,0 +1,40 @@
# Feature: [Feature] venice.ai inference provider (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1132-venice-ai-provider.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1132-venice-ai-provider.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1132-venice-ai-provider.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1132-venice-ai-provider.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1132-venice-ai-provider.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1132-venice-ai-provider.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1132-venice-ai-provider.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1132-venice-ai-provider.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1132-venice-ai-provider.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1132-venice-ai-provider.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1132-venice-ai-provider.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1132-venice-ai-provider.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1132-venice-ai-provider.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1132-venice-ai-provider.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1132-venice-ai-provider.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1132-venice-ai-provider.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1132-venice-ai-provider.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1132-venice-ai-provider.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1132-venice-ai-provider.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1132-venice-ai-provider.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1132-venice-ai-provider.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1132-venice-ai-provider.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1132-venice-ai-provider.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1132-venice-ai-provider.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1132-venice-ai-provider.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1132-venice-ai-provider.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1132-venice-ai-provider.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1132-venice-ai-provider.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1132-venice-ai-provider.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1132-venice-ai-provider.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1132-venice-ai-provider.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1132-venice-ai-provider.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1132-venice-ai-provider.md)
---
> GitHub Issue: #1132 — opened by @neurocis on 2026-04-11
> Status: 🔁 EXISTS | Priority: None
## 📝 Original Request
### Problem / Use Case
Please add an OpenAI compatible Inference provider as 1st class citizen (venice.ai)
### Proposed Solution
Please add venice.ai as a 1st class AI Inference provider.
### Acceptance Criteria
API endpoint: https://api.venice.ai/api/v1
## 💬 Community Discussion
### Participants
- @neurocis — Original requester
## 🎯 Refined Feature Description
Add native proxy support and UI configuration mapping for the Venice AI inference network.
### Why it already exists
This specific provider endpoint implementation `https://api.venice.ai/api/v1` and configuration was completely fulfilled in an earlier version cycle during our ecosystem adoption of 60+ upstream target definitions. Venice AI is already registered and can be configured normally through the Provider Dashboard.
## 🔗 Related Ideas
- N/A

View File

@@ -0,0 +1,39 @@
# Feature: Filter for Custom Model (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1191-filter-custom-model.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1191-filter-custom-model.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1191-filter-custom-model.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1191-filter-custom-model.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1191-filter-custom-model.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1191-filter-custom-model.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1191-filter-custom-model.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1191-filter-custom-model.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1191-filter-custom-model.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1191-filter-custom-model.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1191-filter-custom-model.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1191-filter-custom-model.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1191-filter-custom-model.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1191-filter-custom-model.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1191-filter-custom-model.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1191-filter-custom-model.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1191-filter-custom-model.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1191-filter-custom-model.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1191-filter-custom-model.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1191-filter-custom-model.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1191-filter-custom-model.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1191-filter-custom-model.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1191-filter-custom-model.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1191-filter-custom-model.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1191-filter-custom-model.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1191-filter-custom-model.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1191-filter-custom-model.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1191-filter-custom-model.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1191-filter-custom-model.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1191-filter-custom-model.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1191-filter-custom-model.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1191-filter-custom-model.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1191-filter-custom-model.md)
---
> GitHub Issue: #1191 — opened by @tjengbudi on 2026-04-13
> Status: 🔁 ALREADY EXISTS
## 📝 Original Request
The user requests a filter/search functionality for custom models in the provider detail page, to help find specific models in large catalogs.
## 💬 Community Discussion
### Participants
- @tjengbudi — Original requester
- 2 comments in discussion thread
### Key Points
- User may not have discovered the existing filter functionality
- The model filter bar may not be sufficiently visible on the page
## 🎯 Resolution
This functionality **already exists** in OmniRoute:
**Location:** Provider Detail Page (`/dashboard/providers/<id>`) → Models section
**How it works:**
1. Navigate to Dashboard → Providers → click on any provider
2. Scroll down to the Models section
3. The search/filter input at the top of the model list filters by name, ID, and aliases
4. Implementation: `modelFilter` state (line 989 in `page.tsx`) with `matchesModelCatalogQuery()` function
The filter supports searching by model name, model ID, and configured aliases. It works for both built-in and custom models.

View File

@@ -0,0 +1,75 @@
# Feature: [Feature] gpt-image-1 and gpt-iamge-1.5 support (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md)
---
> GitHub Issue: #1195 — opened by @cryptiklemur on 2026-04-13T04:51:30Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem / Use Case
Image generation should support gpt-image-x models
### Proposed Solution
Image generation should support gpt-image-x models
### Alternatives Considered
_No response_
### Acceptance Criteria
Can select gpt-image-1 or 1.5
### Area
Provider Support
### Related Provider(s)
OpenAI
### Additional Context
_No response_
### Expected Test Plan
_No response_
## 💬 Community Discussion
- @kilo-code-bot: This issue appears to be a duplicate of https://github.com/diegosouzapw/OmniRoute/issues/973.
> **Support for Image Generation with Custom OpenAI-Compatible Providers** (#973)
Similarity score: 91%
...
## 🎯 Refined Feature Description
(Requires manual/AI refinement)
### What it solves
- TBD
### How it should work (high level)
1. TBD
### Affected areas
- TBD
## 📎 Attachments & References
- TBD
## 🔗 Related Ideas
- TBD

View File

@@ -0,0 +1,93 @@
# Feature: [Feature] Add configurable stagger delay between token health check sweep iterations (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md)
---
> GitHub Issue: #1220 — opened by @edwardsconnects90 on 2026-04-13T16:43:19Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem / Use Case
The proactive token health check sweep iterates all OAuth connections sequentially but with **no delay** between iterations. When running with multiple SOCKS5 proxies (one per account), all proxy connections are initiated in rapid succession — effectively simultaneously from the proxy perspective. This causes proxy overload, connection timeouts, and failed token refreshes across all accounts in the same sweep cycle.
With multiple dedicated SOCKS5 proxies, the sweep fires all connections within milliseconds. Logs show all "Refreshing ..." entries appearing in a burst (<100ms total for all accounts).
### Proposed Solution
Add a configurable stagger delay after each iteration of the sweep loop in `tokenHealthCheck.ts`, controlled by a `HEALTHCHECK_STAGGER_MS` environment variable (default: `3000` ms). When set to `0`, staggering is disabled.
The implementation is a single `await new Promise(resolve => setTimeout(resolve, STAGGER_MS))` at the end of each loop iteration inside the sweep function.
| Variable | Default | Description |
| ------------------------ | ------- | ----------------------------------------------------------------------------------------------- |
| `HEALTHCHECK_STAGGER_MS` | `3000` | Delay in milliseconds between consecutive token health check iterations. Set to `0` to disable. |
With the stagger in place, inter-iteration gaps become ~3-7s (configured stagger + proxy round-trip time), confirming that connections no longer pile up simultaneously.
### Alternatives Considered
- **Client-side rate limiting per proxy:** More complex, requires tracking per-proxy concurrency. The stagger approach is simpler and sufficient for the sequential sweep loop.
- **Parallel sweep with concurrency limit:** Would require rewriting the sweep loop to use a worker pool. Overkill for the current use case where sequential + stagger is adequate.
### Acceptance Criteria
- Health check sweep has a configurable delay between iterations via `HEALTHCHECK_STAGGER_MS` env variable
- Default delay is 3000ms
- Setting to 0 disables the stagger
- Consecutive "Refreshing ..." log entries are spaced by at least `HEALTHCHECK_STAGGER_MS` milliseconds
- All existing health check functionality remains unchanged
### Area
Proxy / Routing
### Related Provider(s)
Codex (OpenAI) — affects all OAuth providers when multiple connections use dedicated SOCKS5 proxies
### Additional Context
- **Impact without fix:** All proxy connections open simultaneously → proxy overload → universal token refresh failure each sweep cycle
- **Impact with fix:** Connections spread over `N x STAGGER_MS` total sweep duration → each proxy gets exclusive window → reliable token refreshes
- Total sweep duration increases proportionally (e.g. 10 connections x 3s = ~30s minimum), which is acceptable given sweeps run on intervals of minutes to hours
- **Optional UI enhancement:** Settings panel could expose `HEALTHCHECK_STAGGER_MS` as a numeric input under Provider Health Check settings
- Current workaround: build-time patch (`patch-stagger-healthcheck.cjs`) injects `setTimeout` delay into compiled webpack chunks
### Expected Test Plan
- Add unit test for sweep loop verifying inter-iteration delay when `HEALTHCHECK_STAGGER_MS > 0`
- Add unit test verifying no delay when `HEALTHCHECK_STAGGER_MS=0`
- Integration test: run sweep with multiple connections, verify log timestamps show expected stagger spacing
## 💬 Community Discussion
- @diegosouzapw: Thanks for the well-thought-out proposal, @edwardsconnects90. The stagger logic is sound.
We're accepting this as an enhancement. The implementation is straightforward — a configurable `HEALTHCHECK_S...
## 🎯 Refined Feature Description
(Requires manual/AI refinement)
### What it solves
- TBD
### How it should work (high level)
1. TBD
### Affected areas
- TBD
## 📎 Attachments & References
- TBD
## 🔗 Related Ideas
- TBD

View File

@@ -0,0 +1,35 @@
# Feature: Enforce Passing All Tests / Workflows Before Release (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1364-enforce-tests-before-release.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1364-enforce-tests-before-release.md)
---
> GitHub Issue: #1364 — opened by @uwuclxdy on 2026-04-17
> Status: 🔁 ALREADY EXISTS
## 📝 Original Request
The user is trying to use the latest version but reports the last two releases (v3.6.6, v3.6.7) were broken. Proposes creating a release workflow or gate that prevents creating a new release until all tests and workflows pass.
## 💬 Community Discussion
### Participants
- @uwuclxdy — Original requester
- @chalitbkb — Linked to #1355 (same CLI issue)
### Key Points
- The specific breakage was the CLI entry point shipping as raw TypeScript (`.ts` instead of compiled `.mjs`)
- The test suite itself was passing — the issue was a missing build step in the publishing pipeline
- Community identified this as related to #1355
## 🎯 Resolution
This functionality **already exists** in OmniRoute:
1. **`/generate-release` workflow** — runs full test suite (`npm run test:all`) before creating any release
2. **Pre-push git hooks** — block pushes if tests fail
3. **lint-staged** — runs prettier + eslint on every commit
The v3.6.6/v3.6.7 breakage was specifically caused by a missing CLI build step (not a test failure), which has been fixed in v3.6.8 with `bin/omniroute.mjs`. The release pipeline gap has been closed.

View File

@@ -0,0 +1,24 @@
# Feature: 9router to OmniRoute migration tool (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/804-9router-migration.md) · 🇪🇸 [es](../../../es/_ideia/notfit/804-9router-migration.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/804-9router-migration.md) · 🇩🇪 [de](../../../de/_ideia/notfit/804-9router-migration.md) · 🇮🇹 [it](../../../it/_ideia/notfit/804-9router-migration.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/804-9router-migration.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/804-9router-migration.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/804-9router-migration.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/804-9router-migration.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/804-9router-migration.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/804-9router-migration.md) · 🇮🇳 [in](../../../in/_ideia/notfit/804-9router-migration.md) · 🇹🇭 [th](../../../th/_ideia/notfit/804-9router-migration.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/804-9router-migration.md) · 🇮🇩 [id](../../../id/_ideia/notfit/804-9router-migration.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/804-9router-migration.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/804-9router-migration.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/804-9router-migration.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/804-9router-migration.md) · 🇳🇴 [no](../../../no/_ideia/notfit/804-9router-migration.md) · 🇩🇰 [da](../../../da/_ideia/notfit/804-9router-migration.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/804-9router-migration.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/804-9router-migration.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/804-9router-migration.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/804-9router-migration.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/804-9router-migration.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/804-9router-migration.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/804-9router-migration.md) · 🇮🇱 [he](../../../he/_ideia/notfit/804-9router-migration.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/804-9router-migration.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/804-9router-migration.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/804-9router-migration.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/804-9router-migration.md)
---
> GitHub Issue: #804 — opened by @md-riaz on 2026-03-30
> Status: 📋 Cataloged | Priority: Low
## 📝 Original Request
User trying OmniRoute but can't migrate existing 9router setup. Starting OmniRoute replaces 9router directly.
## 🎯 Refined Feature Description
A migration utility was **already implemented in v3.5.4** — JSON-based settings import/export for legacy 9router configurations, with security-hardened redaction.
### What it solves
- Already solved in v3.5.4
## 🔗 Related Ideas
- None — already implemented

View File

@@ -0,0 +1,55 @@
# Feature: Native Termux (Android/arm64) Support (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/833-termux-android-support.md) · 🇪🇸 [es](../../../es/_ideia/notfit/833-termux-android-support.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/833-termux-android-support.md) · 🇩🇪 [de](../../../de/_ideia/notfit/833-termux-android-support.md) · 🇮🇹 [it](../../../it/_ideia/notfit/833-termux-android-support.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/833-termux-android-support.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/833-termux-android-support.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/833-termux-android-support.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/833-termux-android-support.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/833-termux-android-support.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/833-termux-android-support.md) · 🇮🇳 [in](../../../in/_ideia/notfit/833-termux-android-support.md) · 🇹🇭 [th](../../../th/_ideia/notfit/833-termux-android-support.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/833-termux-android-support.md) · 🇮🇩 [id](../../../id/_ideia/notfit/833-termux-android-support.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/833-termux-android-support.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/833-termux-android-support.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/833-termux-android-support.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/833-termux-android-support.md) · 🇳🇴 [no](../../../no/_ideia/notfit/833-termux-android-support.md) · 🇩🇰 [da](../../../da/_ideia/notfit/833-termux-android-support.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/833-termux-android-support.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/833-termux-android-support.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/833-termux-android-support.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/833-termux-android-support.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/833-termux-android-support.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/833-termux-android-support.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/833-termux-android-support.md) · 🇮🇱 [he](../../../he/_ideia/notfit/833-termux-android-support.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/833-termux-android-support.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/833-termux-android-support.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/833-termux-android-support.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/833-termux-android-support.md)
---
> GitHub Issue: #833 — opened by @marojiro on 2026-03-30
> Status: 📋 Cataloged | Priority: Medium
> Duplicate of: #821 (92% similarity per Kilo)
## 📝 Original Request
OmniRoute can't run on Termux (Android/arm64) due to three blockers:
1. **`keytar` fails to compile** on Node 22+ — useless on Android (no system keychain)
2. **`better-sqlite3` missing `binding.gyp`** — bundled binary is x86_64, can't rebuild without sources
3. **`isNativeBinaryCompatible()` rejects Android** — `process.platform` returns "android" but ELF binary is detected as "linux"
### Proposed Fix for #3
```javascript
// Before:
if (target.platform !== runtimePlatform || ...
// After:
if ((target.platform !== runtimePlatform && !(target.platform === "linux" && runtimePlatform === "android")) || ...
```
## 💬 Community Discussion
- @kilo-code-bot flagged duplicate of #821
## 🎯 Refined Feature Description
Three concrete, small changes to unblock Termux users:
### What it solves
- OmniRoute unusable on Android devices (Termux)
- Growing mobile developer use case (coding on tablets/phones)
### How it should work
1. Make `keytar` optional with try/catch wrapper
2. Ensure `better-sqlite3` can be rebuilt from source on arm64
3. Treat `android` as equivalent to `linux` in platform checks
### Affected areas
- `scripts/native-binary-compat.mjs` — platform check fix (one-liner)
- `package.json` — make keytar optional dependency
- Docker/build — ensure better-sqlite3 sources are included
## 🔗 Related Ideas
- Duplicate of #821 — consolidate fixes

View File

@@ -0,0 +1,38 @@
# Feature: Use Codex GPT models in Claude Code CLI (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/907-codex-in-claude-code.md) · 🇪🇸 [es](../../../es/_ideia/notfit/907-codex-in-claude-code.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/907-codex-in-claude-code.md) · 🇩🇪 [de](../../../de/_ideia/notfit/907-codex-in-claude-code.md) · 🇮🇹 [it](../../../it/_ideia/notfit/907-codex-in-claude-code.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/907-codex-in-claude-code.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/907-codex-in-claude-code.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/907-codex-in-claude-code.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/907-codex-in-claude-code.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/907-codex-in-claude-code.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/907-codex-in-claude-code.md) · 🇮🇳 [in](../../../in/_ideia/notfit/907-codex-in-claude-code.md) · 🇹🇭 [th](../../../th/_ideia/notfit/907-codex-in-claude-code.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/907-codex-in-claude-code.md) · 🇮🇩 [id](../../../id/_ideia/notfit/907-codex-in-claude-code.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/907-codex-in-claude-code.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/907-codex-in-claude-code.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/907-codex-in-claude-code.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/907-codex-in-claude-code.md) · 🇳🇴 [no](../../../no/_ideia/notfit/907-codex-in-claude-code.md) · 🇩🇰 [da](../../../da/_ideia/notfit/907-codex-in-claude-code.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/907-codex-in-claude-code.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/907-codex-in-claude-code.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/907-codex-in-claude-code.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/907-codex-in-claude-code.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/907-codex-in-claude-code.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/907-codex-in-claude-code.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/907-codex-in-claude-code.md) · 🇮🇱 [he](../../../he/_ideia/notfit/907-codex-in-claude-code.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/907-codex-in-claude-code.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/907-codex-in-claude-code.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/907-codex-in-claude-code.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/907-codex-in-claude-code.md)
---
> GitHub Issue: #907 — opened by @tranduykhanh030 on 2026-04-02
> Status: 📋 Cataloged | Priority: Low
## 📝 Original Request
User asks how to use GPT models in Claude Code CLI through OmniRoute, noting that OmniRoute "doesn't provide an output for Claude Code."
## 💬 Community Discussion
- No community comments
## 🎯 Refined Feature Description
This is **already a core feature** of OmniRoute. OmniRoute acts as an OpenAI-compatible proxy that Claude Code can connect to, routing requests to any configured provider including Codex/GPT models.
### What it solves
- Already solved — this is a documentation/discoverability issue
### How it works (already)
1. Configure OmniRoute with Codex/OpenAI credentials
2. Set Claude Code's `ANTHROPIC_BASE_URL` to OmniRoute's endpoint
3. Claude Code sends requests → OmniRoute routes to GPT models
### Affected areas
- Documentation improvement needed — better quickstart guide for Claude Code users
## 🔗 Related Ideas
- None — existing functionality

View File

@@ -0,0 +1,42 @@
# Feature: Telegram Integration (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/945-telegram-integration.md) · 🇪🇸 [es](../../../es/_ideia/notfit/945-telegram-integration.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/945-telegram-integration.md) · 🇩🇪 [de](../../../de/_ideia/notfit/945-telegram-integration.md) · 🇮🇹 [it](../../../it/_ideia/notfit/945-telegram-integration.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/945-telegram-integration.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/945-telegram-integration.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/945-telegram-integration.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/945-telegram-integration.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/945-telegram-integration.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/945-telegram-integration.md) · 🇮🇳 [in](../../../in/_ideia/notfit/945-telegram-integration.md) · 🇹🇭 [th](../../../th/_ideia/notfit/945-telegram-integration.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/945-telegram-integration.md) · 🇮🇩 [id](../../../id/_ideia/notfit/945-telegram-integration.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/945-telegram-integration.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/945-telegram-integration.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/945-telegram-integration.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/945-telegram-integration.md) · 🇳🇴 [no](../../../no/_ideia/notfit/945-telegram-integration.md) · 🇩🇰 [da](../../../da/_ideia/notfit/945-telegram-integration.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/945-telegram-integration.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/945-telegram-integration.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/945-telegram-integration.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/945-telegram-integration.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/945-telegram-integration.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/945-telegram-integration.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/945-telegram-integration.md) · 🇮🇱 [he](../../../he/_ideia/notfit/945-telegram-integration.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/945-telegram-integration.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/945-telegram-integration.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/945-telegram-integration.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/945-telegram-integration.md)
---
> GitHub Issue: #945 — opened by @inteligenciamilgrau on 2026-04-03
> Status: 📋 Cataloged | Priority: Low
## 📝 Original Request
OpenClaw integrates with Telegram but only talks to OpenClaw. Request to add Telegram integration so users can chat with all CLIs (Claude Code, Codex, Gemini CLI) through Telegram.
## 💬 Community Discussion
### Participants
- @inteligenciamilgrau — Original requester
- @oyi77 — Objected: "this shouldn't be in the router, imagine OpenRouter with Telegram integration — feels weird"
- @daniil-pogorelov — Suggested "just make a bot"
### Key Points
- Community split: some think it belongs in an orchestrator/agent layer, not a router
- Could be implemented as external bot using OmniRoute's API
- Scope creep concern for a routing proxy
## 🎯 Refined Feature Description
This is out of scope for OmniRoute's core mission as a proxy/router. Telegram integration belongs in an application/orchestrator layer that consumes OmniRoute's API, not inside OmniRoute itself.
### What it solves
- N/A — better served by external bot
### Affected areas
- N/A — recommend external implementation
## 🔗 Related Ideas
- None — this is a distinct concern from routing

View File

@@ -0,0 +1,50 @@
# Feature: Image Generation for Custom OpenAI-Compatible Providers (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/973-custom-provider-image-gen.md) · 🇪🇸 [es](../../../es/_ideia/notfit/973-custom-provider-image-gen.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/973-custom-provider-image-gen.md) · 🇩🇪 [de](../../../de/_ideia/notfit/973-custom-provider-image-gen.md) · 🇮🇹 [it](../../../it/_ideia/notfit/973-custom-provider-image-gen.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/973-custom-provider-image-gen.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/973-custom-provider-image-gen.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/973-custom-provider-image-gen.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/973-custom-provider-image-gen.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/973-custom-provider-image-gen.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/973-custom-provider-image-gen.md) · 🇮🇳 [in](../../../in/_ideia/notfit/973-custom-provider-image-gen.md) · 🇹🇭 [th](../../../th/_ideia/notfit/973-custom-provider-image-gen.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/973-custom-provider-image-gen.md) · 🇮🇩 [id](../../../id/_ideia/notfit/973-custom-provider-image-gen.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/973-custom-provider-image-gen.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/973-custom-provider-image-gen.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/973-custom-provider-image-gen.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/973-custom-provider-image-gen.md) · 🇳🇴 [no](../../../no/_ideia/notfit/973-custom-provider-image-gen.md) · 🇩🇰 [da](../../../da/_ideia/notfit/973-custom-provider-image-gen.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/973-custom-provider-image-gen.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/973-custom-provider-image-gen.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/973-custom-provider-image-gen.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/973-custom-provider-image-gen.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/973-custom-provider-image-gen.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/973-custom-provider-image-gen.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/973-custom-provider-image-gen.md) · 🇮🇱 [he](../../../he/_ideia/notfit/973-custom-provider-image-gen.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/973-custom-provider-image-gen.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/973-custom-provider-image-gen.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/973-custom-provider-image-gen.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/973-custom-provider-image-gen.md)
---
> GitHub Issue: #973 — opened by @hralamin6 on 2026-04-04
> Status: 📋 Cataloged | Priority: Medium
## 📝 Original Request
Custom OpenAI-compatible providers support text completions but image generation doesn't work. Returns "Unknown embedding provider" errors. Requests full compatibility for image generation with custom providers.
## 💬 Community Discussion
### Participants
- @hralamin6 — Original requester (followed up asking for update)
### Key Points
- Text completions work correctly with custom providers
- Image generation fails with unknown provider errors
- User expects `/v1/images/generations` to route through custom providers
## 🎯 Refined Feature Description
Extend the image generation handler to support routing requests to custom OpenAI-compatible providers, not just hardcoded providers.
### What it solves
- Custom providers with image generation capabilities can't be used for image tasks
- Users running local image generation servers (e.g., ComfyUI, SD WebUI) behind an OpenAI-compatible wrapper
### How it should work
1. When `/v1/images/generations` receives a request with a custom provider model
2. Look up the custom provider's base URL
3. Forward the request to `{baseUrl}/v1/images/generations`
4. Return the response unchanged
### Affected areas
- `open-sse/handlers/imageGeneration.ts` — add custom provider routing
- `open-sse/config/providerRegistry.ts` — image capability flag
- Custom provider node configuration — add image generation toggle
## 🔗 Related Ideas
- Related to [960-openrouter-embedding-image](./960-openrouter-embedding-image.md) — same pattern for embeddings

View File

@@ -0,0 +1,44 @@
# Feature: Prompt Caching support for Codex Models (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/982-codex-prompt-caching.md) · 🇪🇸 [es](../../../es/_ideia/notfit/982-codex-prompt-caching.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/982-codex-prompt-caching.md) · 🇩🇪 [de](../../../de/_ideia/notfit/982-codex-prompt-caching.md) · 🇮🇹 [it](../../../it/_ideia/notfit/982-codex-prompt-caching.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/982-codex-prompt-caching.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/982-codex-prompt-caching.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/982-codex-prompt-caching.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/982-codex-prompt-caching.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/982-codex-prompt-caching.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/982-codex-prompt-caching.md) · 🇮🇳 [in](../../../in/_ideia/notfit/982-codex-prompt-caching.md) · 🇹🇭 [th](../../../th/_ideia/notfit/982-codex-prompt-caching.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/982-codex-prompt-caching.md) · 🇮🇩 [id](../../../id/_ideia/notfit/982-codex-prompt-caching.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/982-codex-prompt-caching.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/982-codex-prompt-caching.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/982-codex-prompt-caching.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/982-codex-prompt-caching.md) · 🇳🇴 [no](../../../no/_ideia/notfit/982-codex-prompt-caching.md) · 🇩🇰 [da](../../../da/_ideia/notfit/982-codex-prompt-caching.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/982-codex-prompt-caching.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/982-codex-prompt-caching.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/982-codex-prompt-caching.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/982-codex-prompt-caching.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/982-codex-prompt-caching.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/982-codex-prompt-caching.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/982-codex-prompt-caching.md) · 🇮🇱 [he](../../../he/_ideia/notfit/982-codex-prompt-caching.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/982-codex-prompt-caching.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/982-codex-prompt-caching.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/982-codex-prompt-caching.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/982-codex-prompt-caching.md)
---
> GitHub Issue: #982 — opened by @diegosouzapw on 2026-04-04
> Status: 📋 Cataloged | Priority: Medium
> Source: Discussion 584 by @alfonsofeliz
## 📝 Original Request
Add native prompt caching passthrough for Codex models via standard upstream cache-control headers. Update the translator layer to transparently pass those along.
## 💬 Community Discussion
### Participants
- @diegosouzapw — Issue creator
- @alfonsofeliz — Original discussion author
### Key Points
- Codex (OpenAI) supports prompt caching but OmniRoute may strip the relevant headers
- Need to ensure cache-control headers flow through the translation layer
## 🎯 Refined Feature Description
Ensure the Codex executor and translator preserve upstream prompt caching headers and parameters. The OpenAI API supports `cached_tokens` in usage responses — ensure these are not stripped during translation.
### What it solves
- Codex users losing prompt cache benefits when routing through OmniRoute
- Reduced API costs through proper cache utilization
### Affected areas
- `open-sse/executors/codex.ts` — header passthrough
- `open-sse/translator/` — cache header preservation
- Token accounting — recognize cached tokens in usage stats
## 🔗 Related Ideas
- Partially addressed already in v3.5.4 (Anthropic cache token accounting)

View File

@@ -0,0 +1,143 @@
# 1. Título da Feature (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇪🇸 [es](../../../es/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇩🇪 [de](../../../de/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇮🇹 [it](../../../it/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇮🇳 [in](../../../in/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇹🇭 [th](../../../th/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇮🇩 [id](../../../id/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇳🇴 [no](../../../no/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇩🇰 [da](../../../da/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇮🇱 [he](../../../he/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/feature-43-governanca-de-ownership-por-credencial.md)
---
Feature 19 — Governança de Ownership por Credencial
## 2. Objetivo
Introduzir modelo opcional de ownership por credencial (API key/OAuth account) para separar visibilidade e ação por usuário em ambientes compartilhados.
## 3. Motivação
Quando múltiplas pessoas usam a mesma instância, falta granularidade de ownership para limitar exposição de credenciais e dados de uso.
## 4. Problema Atual (Antes)
- Modelo atual é centrado em autenticação simples.
- Não há vínculo forte entre usuário e credenciais gerenciadas.
- Dados podem ser vistos/alterados além do necessário em ambiente compartilhado.
### Antes vs Depois
| Dimensão | Antes | Depois |
| --------------------------------- | ------------ | ------------------------- |
| Controle de acesso por credencial | Não granular | Ownership explícito |
| Privacidade de chaves/contas | Limitada | Mascaramento por não-dono |
| Auditoria por ator | Parcial | Mais precisa |
## 5. Estado Futuro (Depois)
Camada de ownership com regras de leitura/escrita por usuário e visão administrativa consolidada.
## 6. O que Ganhamos
- Segurança operacional em times.
- Menos risco de alteração acidental de credenciais de terceiros.
- Base para RBAC progressivo.
## 7. Escopo
- Modelo de ownership em storage.
- Regras de autorização por rota de provider/keys/oauth.
- Mascaramento de campos sensíveis para não-donos.
## 8. Fora de Escopo
- IAM corporativo completo.
- SSO empresarial nesta fase.
## 9. Arquitetura Proposta
```mermaid
flowchart TD
A[request autenticada] --> B[resolve user]
B --> C[check ownership/resource]
C -->|allow| D[action]
C -->|deny| E[403]
D --> F[audit event]
```
## 10. Mudanças Técnicas Detalhadas
Arquivos de referência:
- `src/lib/db/providers.js`
- `src/app/api/providers/*`
- `src/app/api/keys/*`
- `src/app/api/oauth/*`
Direção técnica:
1. Adicionar tabela/namespace de ownership por recurso.
2. Enriquecer middleware de autorização para rotas de gestão.
3. Em listagens, mascarar dados sensíveis para não-donos.
## 11. Impacto em APIs Públicas / Interfaces / Tipos
- APIs novas: possivelmente endpoints admin de ownership.
- APIs alteradas: filtros adicionais em rotas de gestão.
- Compatibilidade: **potencialmente breaking em comportamento**, não em schema.
- Recomendação: introduzir por feature flag.
## 12. Passo a Passo de Implementação Futura
1. Definir modelo de ownership no storage.
2. Migrar fluxo de criação de credencial para gravar owner.
3. Aplicar filtros em GET/PUT/DELETE sensíveis.
4. Implementar mascaramento e trilha de auditoria.
5. Cobrir testes de autorização.
## 13. Plano de Testes
Cenários positivos:
1. Usuário dono lê e altera sua credencial.
2. Admin enxerga e gerencia tudo.
Cenários de erro:
3. Usuário não-dono recebe 403 em alteração.
Regressão:
4. Single-user continua funcional sem overhead excessivo.
Compatibilidade retroativa:
5. Credenciais antigas sem owner recebem owner default/migração controlada.
## 14. Critérios de Aceite
- [ ] Given credencial com owner, When não-dono tenta alterar, Then recebe 403.
- [ ] Given admin, When consulta credenciais, Then visibilidade total é preservada.
- [ ] Given usuário comum, When lista recursos, Then dados sensíveis de terceiros são mascarados.
## 15. Riscos e Mitigações
- Risco: complexidade de autorização crescer rápido.
- Mitigação: política simples inicial (owner/admin), sem hierarquia complexa.
## 16. Plano de Rollout
1. Ativar em ambientes multiusuário primeiro.
2. Medir impacto de autorização.
3. Expandir para todas as rotas de gestão.
## 17. Métricas de Sucesso
- Redução de operações indevidas em credenciais de terceiros.
- Aumento de rastreabilidade por usuário.
## 18. Dependências entre Features
- Reforça `feature-observabilidade-de-auditoria-e-acoes-administrativas-21.md`.
## 19. Checklist Final da Feature
- [ ] Modelo de ownership definido.
- [ ] Autorização aplicada em rotas críticas.
- [ ] Mascaramento implementável.
- [ ] Testes de permissão cobrindo owner/admin.

View File

@@ -0,0 +1,79 @@
# Feature: Persist API-Key via Docker Volume to Avoid Regeneration (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/viable/1350-persist-api-key-docker.md) · 🇪🇸 [es](../../../es/_ideia/viable/1350-persist-api-key-docker.md) · 🇫🇷 [fr](../../../fr/_ideia/viable/1350-persist-api-key-docker.md) · 🇩🇪 [de](../../../de/_ideia/viable/1350-persist-api-key-docker.md) · 🇮🇹 [it](../../../it/_ideia/viable/1350-persist-api-key-docker.md) · 🇷🇺 [ru](../../../ru/_ideia/viable/1350-persist-api-key-docker.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/viable/1350-persist-api-key-docker.md) · 🇯🇵 [ja](../../../ja/_ideia/viable/1350-persist-api-key-docker.md) · 🇰🇷 [ko](../../../ko/_ideia/viable/1350-persist-api-key-docker.md) · 🇸🇦 [ar](../../../ar/_ideia/viable/1350-persist-api-key-docker.md) · 🇮🇳 [hi](../../../hi/_ideia/viable/1350-persist-api-key-docker.md) · 🇮🇳 [in](../../../in/_ideia/viable/1350-persist-api-key-docker.md) · 🇹🇭 [th](../../../th/_ideia/viable/1350-persist-api-key-docker.md) · 🇻🇳 [vi](../../../vi/_ideia/viable/1350-persist-api-key-docker.md) · 🇮🇩 [id](../../../id/_ideia/viable/1350-persist-api-key-docker.md) · 🇲🇾 [ms](../../../ms/_ideia/viable/1350-persist-api-key-docker.md) · 🇳🇱 [nl](../../../nl/_ideia/viable/1350-persist-api-key-docker.md) · 🇵🇱 [pl](../../../pl/_ideia/viable/1350-persist-api-key-docker.md) · 🇸🇪 [sv](../../../sv/_ideia/viable/1350-persist-api-key-docker.md) · 🇳🇴 [no](../../../no/_ideia/viable/1350-persist-api-key-docker.md) · 🇩🇰 [da](../../../da/_ideia/viable/1350-persist-api-key-docker.md) · 🇫🇮 [fi](../../../fi/_ideia/viable/1350-persist-api-key-docker.md) · 🇵🇹 [pt](../../../pt/_ideia/viable/1350-persist-api-key-docker.md) · 🇷🇴 [ro](../../../ro/_ideia/viable/1350-persist-api-key-docker.md) · 🇭🇺 [hu](../../../hu/_ideia/viable/1350-persist-api-key-docker.md) · 🇧🇬 [bg](../../../bg/_ideia/viable/1350-persist-api-key-docker.md) · 🇸🇰 [sk](../../../sk/_ideia/viable/1350-persist-api-key-docker.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/viable/1350-persist-api-key-docker.md) · 🇮🇱 [he](../../../he/_ideia/viable/1350-persist-api-key-docker.md) · 🇵🇭 [phi](../../../phi/_ideia/viable/1350-persist-api-key-docker.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/viable/1350-persist-api-key-docker.md) · 🇨🇿 [cs](../../../cs/_ideia/viable/1350-persist-api-key-docker.md) · 🇹🇷 [tr](../../../tr/_ideia/viable/1350-persist-api-key-docker.md)
---
> GitHub Issue: #1350 — opened by @raphaelnugas on 2026-04-16
> Status: ✅ VIABLE | Priority: MEDIUM
## 📝 Original Request
Every time OmniRoute is updated via Docker and a backup is restored, the API key is changed, forcing all integrated systems to regenerate and reconfigure. This causes service disruption in production environments where multiple systems depend on the key.
**Steps to reproduce (from author):**
1. Install/update OmniRoute via Docker
2. Restore the backup
3. Previous API key is no longer valid
4. Need to generate a new API key and distribute to all clients
**Proposed solutions (from author):**
1. Store API key in a file within the persisted Docker volume (`DATA_DIR/api_key`) so it survives container recreation
2. Support setting the API key via an environment variable (`OMNI_API_KEY`) that can be mounted as a Docker secret
**Acceptance Criteria (from author):**
- API key stored in Docker volume file (`DATA_DIR`)
- After container restart/update, same API key is used
- After backup restore, original API key remains valid
- If no API key file exists (first install), a new key is generated automatically
## 💬 Community Discussion
### Participants
- @raphaelnugas — Original requester, production user with multi-system integrations
### Key Points
- Critical for production Docker deployments where multiple downstream services rely on the API key
- Current behavior regenerates keys on container recreation, breaking all integrations
- Two complementary approaches proposed: file-based persistence and env var override
- No objections or alternative proposals
## 🎯 Refined Feature Description
Make OmniRoute's internal API key persistent across Docker container recreations by storing it in the Docker volume (`DATA_DIR`) and optionally allowing it to be set via an environment variable.
### What it solves
- API key changes after Docker container recreation, breaking all downstream integrations
- Service disruption requiring manual key regeneration and distribution after every update
- Lack of declarative key management support for infrastructure-as-code Docker deployments
### How it should work (high level)
1. On startup, check for `OMNI_API_KEY` environment variable — if set, use it as the API key (highest priority)
2. If no env var, check for `DATA_DIR/api_key` file — if exists, read key from file
3. If neither exists (first-time install), generate a new key and persist it to `DATA_DIR/api_key`
4. After any key generation or change via the dashboard, update the `DATA_DIR/api_key` file
5. On backup restore, if the backup contains a different key, prefer the file-based key (or prompt user)
6. Document the `OMNI_API_KEY` env var in the Docker Compose example and README
### Affected areas
- `src/lib/db/apiKeys.ts` — modify key generation/loading to check file + env var
- `src/lib/db/core.ts` — startup key initialization sequence
- Docker configuration — update `docker-compose.yml` example with `OMNI_API_KEY` support
- Documentation — update Docker deployment docs with key persistence guidance
- `src/app/api/settings/` — key change should persist to file
## 📎 Attachments & References
- No external references
## 🔗 Related Ideas
- No directly related ideas in the backlog

View File

@@ -0,0 +1,67 @@
# Feature: Limit Database Backup Count (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/viable/1367-limit-db-backup-count.md) · 🇪🇸 [es](../../../es/_ideia/viable/1367-limit-db-backup-count.md) · 🇫🇷 [fr](../../../fr/_ideia/viable/1367-limit-db-backup-count.md) · 🇩🇪 [de](../../../de/_ideia/viable/1367-limit-db-backup-count.md) · 🇮🇹 [it](../../../it/_ideia/viable/1367-limit-db-backup-count.md) · 🇷🇺 [ru](../../../ru/_ideia/viable/1367-limit-db-backup-count.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/viable/1367-limit-db-backup-count.md) · 🇯🇵 [ja](../../../ja/_ideia/viable/1367-limit-db-backup-count.md) · 🇰🇷 [ko](../../../ko/_ideia/viable/1367-limit-db-backup-count.md) · 🇸🇦 [ar](../../../ar/_ideia/viable/1367-limit-db-backup-count.md) · 🇮🇳 [hi](../../../hi/_ideia/viable/1367-limit-db-backup-count.md) · 🇮🇳 [in](../../../in/_ideia/viable/1367-limit-db-backup-count.md) · 🇹🇭 [th](../../../th/_ideia/viable/1367-limit-db-backup-count.md) · 🇻🇳 [vi](../../../vi/_ideia/viable/1367-limit-db-backup-count.md) · 🇮🇩 [id](../../../id/_ideia/viable/1367-limit-db-backup-count.md) · 🇲🇾 [ms](../../../ms/_ideia/viable/1367-limit-db-backup-count.md) · 🇳🇱 [nl](../../../nl/_ideia/viable/1367-limit-db-backup-count.md) · 🇵🇱 [pl](../../../pl/_ideia/viable/1367-limit-db-backup-count.md) · 🇸🇪 [sv](../../../sv/_ideia/viable/1367-limit-db-backup-count.md) · 🇳🇴 [no](../../../no/_ideia/viable/1367-limit-db-backup-count.md) · 🇩🇰 [da](../../../da/_ideia/viable/1367-limit-db-backup-count.md) · 🇫🇮 [fi](../../../fi/_ideia/viable/1367-limit-db-backup-count.md) · 🇵🇹 [pt](../../../pt/_ideia/viable/1367-limit-db-backup-count.md) · 🇷🇴 [ro](../../../ro/_ideia/viable/1367-limit-db-backup-count.md) · 🇭🇺 [hu](../../../hu/_ideia/viable/1367-limit-db-backup-count.md) · 🇧🇬 [bg](../../../bg/_ideia/viable/1367-limit-db-backup-count.md) · 🇸🇰 [sk](../../../sk/_ideia/viable/1367-limit-db-backup-count.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/viable/1367-limit-db-backup-count.md) · 🇮🇱 [he](../../../he/_ideia/viable/1367-limit-db-backup-count.md) · 🇵🇭 [phi](../../../phi/_ideia/viable/1367-limit-db-backup-count.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/viable/1367-limit-db-backup-count.md) · 🇨🇿 [cs](../../../cs/_ideia/viable/1367-limit-db-backup-count.md) · 🇹🇷 [tr](../../../tr/_ideia/viable/1367-limit-db-backup-count.md)
---
> GitHub Issue: #1367 — opened by @gmonchain on 2026-04-17
> Status: ✅ VIABLE | Priority: MEDIUM
## 📝 Original Request
The application currently generates too many database backup files without an option to limit the number of backups stored. This leads to unnecessary storage usage and complicates backup management. The user requests a feature that allows setting a maximum number of backups retained, with automatic deletion of older backups when the limit is reached.
**Acceptance Criteria (from author):**
- Users can set a maximum backup count in the settings
- When the backup count exceeds the limit, the system automatically deletes older backups
- The user interface notifies users when a backup has been deleted
- No errors occur during the backup storage and deletion process
## 💬 Community Discussion
### Participants
- @gmonchain — Original requester, provided screenshot of excessive backups and clear acceptance criteria
### Key Points
- User showed a screenshot with many accumulated backup files
- The request is straightforward: add a configurable cap and auto-prune
- No objections or alternative proposals
- User also suggested a notification when pruning occurs
## 🎯 Refined Feature Description
Add a configurable maximum backup count setting to the OmniRoute dashboard. When the number of stored backups exceeds this limit, the system should automatically delete the oldest backups to free storage space.
### What it solves
- Unbounded growth of backup files consuming disk space
- Manual cleanup burden on users running OmniRoute for extended periods
- Storage issues on Docker deployments with limited volume sizes
### How it should work (high level)
1. Add a `maxBackupCount` setting to the `key_value` table (namespace: `settings`, key: `maxBackupCount`)
2. Provide a UI control in Dashboard → Settings → Backup section for configuring the limit (default: unlimited / 0)
3. After every successful backup creation, count existing backups
4. If count exceeds `maxBackupCount`, delete the oldest backups until the count is within the limit
5. Log a message when backups are pruned (visible in the console and optionally in the dashboard notification area)
6. Expose the setting via the MCP server and API for programmatic access
### Affected areas
- `src/lib/db/backup.ts` — add pruning logic after backup creation
- `src/lib/db/settings.ts` — add `maxBackupCount` setting with default
- `src/app/api/settings/` — expose new setting via API
- `src/app/(dashboard)/dashboard/settings/` — add UI control for backup limit
- i18n — new translation keys for backup limit UI labels
## 📎 Attachments & References
- Screenshot showing excessive backup files: https://github.com/user-attachments/assets/a0529f40-37d9-45db-a925-a5491f98671a
## 🔗 Related Ideas
- No directly related ideas in the backlog

View File

@@ -0,0 +1,75 @@
# Feature: Reduce GPU Usage of the UI (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇪🇸 [es](../../../es/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇫🇷 [fr](../../../fr/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇩🇪 [de](../../../de/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇮🇹 [it](../../../it/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇷🇺 [ru](../../../ru/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇯🇵 [ja](../../../ja/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇰🇷 [ko](../../../ko/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇸🇦 [ar](../../../ar/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇮🇳 [hi](../../../hi/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇮🇳 [in](../../../in/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇹🇭 [th](../../../th/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇻🇳 [vi](../../../vi/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇮🇩 [id](../../../id/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇲🇾 [ms](../../../ms/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇳🇱 [nl](../../../nl/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇵🇱 [pl](../../../pl/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇸🇪 [sv](../../../sv/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇳🇴 [no](../../../no/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇩🇰 [da](../../../da/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇫🇮 [fi](../../../fi/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇵🇹 [pt](../../../pt/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇷🇴 [ro](../../../ro/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇭🇺 [hu](../../../hu/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇧🇬 [bg](../../../bg/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇸🇰 [sk](../../../sk/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇮🇱 [he](../../../he/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇵🇭 [phi](../../../phi/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇨🇿 [cs](../../../cs/_ideia/viable/1369-reduce-gpu-usage-ui.md) · 🇹🇷 [tr](../../../tr/_ideia/viable/1369-reduce-gpu-usage-ui.md)
---
> GitHub Issue: #1369 — opened by @sergedc on 2026-04-17
> Status: ✅ VIABLE | Priority: HIGH
## 📝 Original Request
When on `/dashboard/limits` or `/dashboard/logs`, the GPU usage (Nvidia RTX 3060 mobile) spikes to 30% in Windows 11 Task Manager. This only happens when the tab is active — switching to another tab drops GPU to 0%. Returning to those pages brings it back to 30%.
The root cause is the browser being forced to re-composite expensive `backdrop-filter: blur()` layers every time re-renders happen following the frequent API calls to update logs and limits data.
**Reproduction**: Requires a 4K screen with high DPI to observe the spike.
### Proposed Solutions (from author)
**A. Replace blurs with solid colors** (biggest impact):
- `Sidebar.tsx`: Remove `bg-vibrancy backdrop-blur-xl`, use opaque `bg-sidebar`
- `Header.tsx`: Remove `bg-bg/80 backdrop-blur-xl`, use opaque `bg-bg`
**B. Memoize data** to skip identical re-renders:
- In `RequestLoggerV2.tsx` and `ProxyLogger.tsx`, only call `setLogs` if data actually changed (JSON comparison)
**C. Add `content-visibility: auto`** to table rows to skip painting off-screen rows, limiting repaint blast radius.
## 💬 Community Discussion
### Participants
- @sergedc — Original requester, provided root cause analysis and 3 concrete solutions
### Key Points
- Issue is specific to pages with frequent data refresh cycles (logs, limits)
- GPU spike is caused by CSS `backdrop-filter: blur()` compositing on every React re-render
- All 3 proposed solutions are complementary and low-risk
- No other comments or objections
## 🎯 Refined Feature Description
Reduce unnecessary GPU utilization on dashboard pages that perform frequent data polling by eliminating expensive CSS compositing effects and preventing unnecessary React re-renders.
### What it solves
- 30% GPU spike on dashboard pages with frequent data refreshes (logs, limits)
- Browser forced to re-composite expensive backdrop-filter blur layers every re-render cycle
- Particularly impactful on high-DPI 4K displays where compositing cost is multiplied
### How it should work (high level)
1. Replace `backdrop-blur-xl` with opaque solid backgrounds in `Sidebar.tsx` and `Header.tsx`
2. Add data memoization in `RequestLoggerV2.tsx` and `ProxyLogger.tsx` — compare incoming data with previous state before triggering a re-render
3. Add `content-visibility: auto` CSS to log/limit table rows to skip painting off-screen content
4. Verify visual appearance is maintained (opaque backgrounds should still look good in both light/dark themes)
### Affected areas
- `src/shared/components/Sidebar.tsx` — replace blur with opaque background
- `src/shared/components/Header.tsx` — replace blur with opaque background
- `src/app/(dashboard)/dashboard/logs/` — memoize log data fetches
- `src/app/(dashboard)/dashboard/limits/` — memoize limit data fetches
- Global CSS / Tailwind — `content-visibility: auto` utility
## 📎 Attachments & References
- No external references; author provided inline analysis
## 🔗 Related Ideas
- No directly related ideas in the backlog

View File

@@ -0,0 +1,81 @@
# Feature: Add Meta Muse Spark (meta.ai) Web Subscription Provider (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../../_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇪🇸 [es](../../../../es/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇫🇷 [fr](../../../../fr/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇩🇪 [de](../../../../de/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇮🇹 [it](../../../../it/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇷🇺 [ru](../../../../ru/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇨🇳 [zh-CN](../../../../zh-CN/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇯🇵 [ja](../../../../ja/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇰🇷 [ko](../../../../ko/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇸🇦 [ar](../../../../ar/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇮🇳 [hi](../../../../hi/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇮🇳 [in](../../../../in/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇹🇭 [th](../../../../th/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇻🇳 [vi](../../../../vi/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇮🇩 [id](../../../../id/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇲🇾 [ms](../../../../ms/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇳🇱 [nl](../../../../nl/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇵🇱 [pl](../../../../pl/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇸🇪 [sv](../../../../sv/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇳🇴 [no](../../../../no/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇩🇰 [da](../../../../da/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇫🇮 [fi](../../../../fi/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇵🇹 [pt](../../../../pt/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇷🇴 [ro](../../../../ro/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇭🇺 [hu](../../../../hu/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇧🇬 [bg](../../../../bg/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇸🇰 [sk](../../../../sk/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇺🇦 [uk-UA](../../../../uk-UA/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇮🇱 [he](../../../../he/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇵🇭 [phi](../../../../phi/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇧🇷 [pt-BR](../../../../pt-BR/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇨🇿 [cs](../../../../cs/_ideia/viable/need_details/1308-meta-muse-spark-provider.md) · 🇹🇷 [tr](../../../../tr/_ideia/viable/need_details/1308-meta-muse-spark-provider.md)
---
> GitHub Issue: #1308 — opened by @dhaern on 2026-04-16
> Status: ❓ NEEDS DETAIL | Priority: Medium
## 📝 Original Request
Add Meta Muse Spark (meta.ai) as a web subscription provider, supporting cookie-based access to the chat interface for text generation. The proposal covers three model variants:
- `muse-spark` — instant mode
- `muse-spark-thinking` — thinking mode
- `muse-spark-contemplating` — deep reasoning mode
The proposed auth flow involves a 3-step cookie acquisition process:
1. GET meta.ai → extract `lsd` + `dtsg` tokens from HTML
2. POST `useAbraAcceptTOSForTempUserMutation` → get access token
3. POST `graph.meta.ai/graphql` with `abra_sess` cookie
## 💬 Community Discussion
### Participants
- @dhaern — Original requester, detailed proposal with auth flow, model variants, and file structure
- @RaviTharuma — Contributor (built Grok Web + Perplexity Web executors), provided feasibility analysis
### Key Points
- **@RaviTharuma's analysis is critical:**
- Auth pattern similar to Grok/Perplexity Web executors — feasible
- Primary reference `Strvm/meta-ai-api` (398 stars) is 2 years stale (Llama 3 era)
- Meta's multi-step auth is harder than Grok/Perplexity (3 steps vs 1 cookie)
- Facebook's anti-bot infrastructure is more aggressive (DTSG tokens, Captcha challenges)
- Found `dyagz/LLM-Proxy-API` (Apr 2026) — uses Playwright browser automation, suggesting API may be locked down
- **Two possible approaches:**
1. **Cookie + GraphQL** (preferred) — stateless, clean, follows existing executor pattern
2. **Playwright browser automation** — works but heavy, single-session, requires browser process
- **Blocker:** Needs fresh API traffic capture from meta.ai to verify current GraphQL mutations
## 🎯 Refined Feature Description
Add a cookie-based executor for Meta Muse Spark following the same pattern as Grok Web and Perplexity Web executors, supporting text generation through meta.ai's GraphQL API.
### What it solves
- Enables Meta AI subscribers to route requests through OmniRoute
- Adds a major free-tier AI model provider to the catalog
- Extends web-subscription provider coverage
### How it should work (high level)
1. User provides their `abra_sess` cookie from meta.ai in the dashboard
2. OmniRoute sends GraphQL mutations to `graph.meta.ai/graphql`
3. Supports streaming responses via NDJSON or SSE (to be confirmed from traffic capture)
4. Maps to three model variants: instant, thinking, contemplating
### Affected areas
- `open-sse/executors/` — new `meta-ai.ts` executor
- `src/shared/constants/providers.ts` — register in `WEB_COOKIE_PROVIDERS`
- `open-sse/config/providerRegistry.ts` — model registration (3 variants)
- Dashboard provider UI — new provider card with cookie auth
### What is needed to proceed
1. Fresh network traffic capture from meta.ai (HAR export or request/response bodies)
2. Confirmation of current GraphQL mutation names for Muse Spark
3. Verification of whether pure HTTP/GraphQL approach is still viable (vs. Playwright-only)
## 📎 Attachments & References
- `Strvm/meta-ai-api` (398 stars): https://github.com/Strvm/meta-ai-api — primary reference (stale)
- `dyagz/LLM-Proxy-API` (Apr 2026): browser-backed proxy for meta.ai — alternative approach
## 🔗 Related Ideas
- Same pattern as Grok Web (`open-sse/executors/grok-web.ts`) and Perplexity Web executors

View File

@@ -4,23 +4,37 @@
---
> بروتوكول وكيل إلى وكيل v0.3 — OmniRoute كوكيل توجيه ذكي## Agent Discovery```bash
> curl http://localhost:20128/.well-known/agent.json
> Agent-to-Agent Protocol v0.3 — OmniRoute as an intelligent routing agent
````
## Agent Discovery
إرجاع بطاقة الوكيل التي تصف قدرات OmniRoute ومهاراتها ومتطلبات المصادقة.---## Authentication
```bash
curl http://localhost:20128/.well-known/agent.json
```
تتطلب جميع الطلبات `/a2a` مفتاح برمجة التطبيقات عبر رأس `الإعلان`:```
التفويض: الحامل YOUR_OMNIROUTE_API_KEY```
Returns the Agent Card describing OmniRoute's capabilities, skills, and authentication requirements.
إذا لم يتم تكوين أي مفتاح API على الخادم، فسيتم تجاوز المصادقة.---
---
## Authentication
All `/a2a` requests require an API key via the `Authorization` header:
```
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
```
If no API key is configured on the server, authentication is bypassed.
---
## JSON-RPC 2.0 Methods
### `message/send` — Synchronous Execution
يرسل رسالة إلى المهارة وينتظر الرد الكامل.```bash
Sends a message to a skill and waits for the complete response.
```bash
curl -X POST http://localhost:20128/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
@@ -34,137 +48,153 @@ curl -X POST http://localhost:20128/a2a \
"metadata": {"model": "auto", "combo": "fast-coding"}
}
}'
````
```
**إجابة:**`json
**Response:**
```json
{
"jsonrpc": "2.0",
"المعرف": "1"،
"النتيجة": {
"المهمة": { "المعرف": "uuid"، "الحالة": "مكتمل" }،
"المصنوعات": [{ "النوع": "نص"، "محتوى": "..." }]،
"البيانات الوصفية": {
"routing_explanation": "سونيتة claude مختارة عبر الموفر \"anthropic\" (زمن الوصول: 1200 مللي ثانية، التكلفة: 0.003 USD)"،
"cost_envelope": { "المقدرة": 0.005، "الفعلي": 0.003، "العملة": "USD" }،
""resilience_trace": [
{ "الحدث": "primary_selected"، "provider": "anthropic"، "timestamp": "..." }
"policy_verdict": { "مسموح": صحيح، "السبب": "ضمن حدود الميزانية والحصة" }
"id": "1",
"result": {
"task": { "id": "uuid", "state": "completed" },
"artifacts": [{ "type": "text", "content": "..." }],
"metadata": {
"routing_explanation": "Selected claude-sonnet via provider \"anthropic\" (latency: 1200ms, cost: $0.003)",
"cost_envelope": { "estimated": 0.005, "actual": 0.003, "currency": "USD" },
"resilience_trace": [
{ "event": "primary_selected", "provider": "anthropic", "timestamp": "..." }
],
"policy_verdict": { "allowed": true, "reason": "within budget and quota limits" }
}
}
}`
}
```
### `message/stream` — SSE Streaming
نفس `الرسالة/الإرسال` ولكنها تُرجع الأحداث المرسلة من الخادم للبث في الوقت الفعلي.```bash
Same as `message/send` but returns Server-Sent Events for real-time streaming.
```bash
curl -N -X POST http://localhost:20128/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{
"jsonrpc": "2.0",
"id": "1",
"method": "message/stream",
"params": {
"skill": "smart-routing",
"messages": [{"role": "user", "content": "Explain quantum computing"}]
}
}'
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{
"jsonrpc": "2.0",
"id": "1",
"method": "message/stream",
"params": {
"skill": "smart-routing",
"messages": [{"role": "user", "content": "Explain quantum computing"}]
}
}'
```
````
**SSE Events:**
**أحداث SSE:**```
البيانات: {"jsonrpc": "2.0"، "method": "message/stream"، "params": {"task": {"id": "..."، "state": "working"}، "chunk": {"type": "text"، "content": "..."}}}
```
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"working"},"chunk":{"type":"text","content":"..."}}}
: نبضات القلب 2026-03-03T17:00:00Z
: heartbeat 2026-03-03T17:00:00Z
البيانات: {"jsonrpc": "2.0"، "method": "message/stream"، "params": {"task": {"id": "..."، "state": "Completed"}، "بيانات التعريف": {...}}}```
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"completed"},"metadata":{...}}}
```
### `tasks/get` — Query Task Status
```bash
حليقة -X POST http://localhost:20128/a2a \
-H "نوع المحتوى: application/json" \
-H "التفويض: حامل YOUR_KEY" \
-d '{"jsonrpc": "2.0"، "id": "2"، "method": "tasks/get"، "params": {"taskId": "TASK_UUID"}}'```
curl -X POST http://localhost:20128/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{"jsonrpc":"2.0","id":"2","method":"tasks/get","params":{"taskId":"TASK_UUID"}}'
```
### `tasks/cancel` — Cancel a Task
```bash
حليقة -X POST http://localhost:20128/a2a \
-H "نوع المحتوى: application/json" \
-H "التفويض: حامل YOUR_KEY" \
-d '{"jsonrpc": "2.0"، "id": "3"، "method": "tasks/cancel"، "params": {"taskId": "TASK_UUID"}}'```
curl -X POST http://localhost:20128/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{"jsonrpc":"2.0","id":"3","method":"tasks/cancel","params":{"taskId":"TASK_UUID"}}'
```
---
## Available Skills
| مهارة | الوصف |
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------- |
| `التوجيه الذكي` | تطالب الطرق عبر خط أنابيب OmniRoute الذكي. إرجاع الاستجابة مع شرح التوجيه والتكلفة وتتبع المرونة. |
| `إدارة الحصص` | يجيب على استفسارات اللغة الطبيعية حول حصص الموفرين، ويقترح مجموعات مجانية، ويوفر تصنيفات الحصص. |---
| Skill | Description |
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------ |
| `smart-routing` | Routes prompts through OmniRoute's intelligent pipeline. Returns response with routing explanation, cost, and resilience trace. |
| `quota-management` | Answers natural-language queries about provider quotas, suggests free combos, and provides quota rankings. |
---
## Task Lifecycle
````
```
submitted → working → completed
→ failed
→ cancelled
```
تم الإرسال ← العمل ← مكتمل
→ فشل
→ ألغيت```
- Tasks expire after 5 minutes (configurable)
- Terminal states: `completed`, `failed`, `cancelled`
- Event log tracks every state transition
- تنتهي المهام بعد 5 دقائق (قابلة للتكوين)
- حالات الوحدة الطرفية: "مكتمل"، "فشل"، "تم الإلغاء".
- سجل الأحداث يتتبع كل انتقال للحالة---
---
## Error Codes
| الكود | معنى |
| :----- | :----------------------------------- | --- |
| -32700 | خطأ في التحليل (JSON غير صالح) |
| -32600 | طلب غير صالح / غير مصرح به |
| -32601 | لم يتم العثور على الطريقة أو المهارة |
| -32602 | معلمات غير صالحة |
| -32603 | خطأ داخلي | --- |
| Code | Meaning |
| :----- | :----------------------------- |
| -32700 | Parse error (invalid JSON) |
| -32600 | Invalid request / Unauthorized |
| -32601 | Method or skill not found |
| -32602 | Invalid params |
| -32603 | Internal error |
---
## Integration Examples
### Python (requests)
````python
طلبات الاستيراد
```python
import requests
resp = request.post("http://localhost:20128/a2a", json={
"jsonrpc": "2.0"، "id": "1"،
"الطريقة": "رسالة/إرسال"،
"المعلمات": {
"المهارة": "التوجيه الذكي"،
resp = requests.post("http://localhost:20128/a2a", json={
"jsonrpc": "2.0", "id": "1",
"method": "message/send",
"params": {
"skill": "smart-routing",
"messages": [{"role": "user", "content": "Hello"}]
}
}, headers={"Authorization": "Bearer YOUR_KEY"})
النتيجة = resp.json () ["النتيجة"]
طباعة (نتيجة ["المصنوعات"] [0] ["المحتوى"])
طباعة (نتيجة ["بيانات التعريف"] ["routing_explanation"])```
result = resp.json()["result"]
print(result["artifacts"][0]["content"])
print(result["metadata"]["routing_explanation"])
```
### TypeScript (fetch)
```typescript
const resp = انتظار الجلب("http://localhost:20128/a2a", {
الطريقة: "POST"،
رؤوس: {
"نوع المحتوى": "application/json"،
التفويض: "الحامل YOUR_KEY"،
const resp = await fetch("http://localhost:20128/a2a", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer YOUR_KEY",
},
الجسم: JSON.stringify({
جسونربك: "2.0"،
المعرف: "1"،
الطريقة: "رسالة/إرسال"،
المعلمات: {
المهارة: "التوجيه الذكي"،
الرسائل: [{ الدور: "المستخدم"، المحتوى: "مرحبًا" }]،
body: JSON.stringify({
jsonrpc: "2.0",
id: "1",
method: "message/send",
params: {
skill: "smart-routing",
messages: [{ role: "user", content: "Hello" }],
},
}),
});
const { result } = انتظار resp.json();
console.log(result.metadata.routing_explanation);```
````
const { result } = await resp.json();
console.log(result.metadata.routing_explanation);
```

View File

@@ -4,17 +4,25 @@
---
مرجع كامل لجميع نهاية نقاط OmniRoute API.---## Table of Contents
Complete reference for all OmniRoute API endpoints.
- [إكمالات الدردشة](#إكمالات الدردشة)
- [التضمينات](#التضمينات)
- [ إنشاء الصور ](#image-generation)
- [قائمة التطورات](#list-models)
- [نقاط نهاية التوافق](#نقاط نهاية التوافق)
- [ذاكرة التخزين المؤقتة الدلالية](#ذاكرة التخزين المؤقتة الدلالية)
- [لوحة التحكم والإدارة](#dashboard--management)
- [معالجة الطلب](#request-processing)
- [المصادقة](#المصادقة)---## Chat Completions
---
## Table of Contents
- [Chat Completions](#chat-completions)
- [Embeddings](#embeddings)
- [Image Generation](#image-generation)
- [List Models](#list-models)
- [Compatibility Endpoints](#compatibility-endpoints)
- [Semantic Cache](#semantic-cache)
- [Dashboard & Management](#dashboard--management)
- [Request Processing](#request-processing)
- [Authentication](#authentication)
---
## Chat Completions
```bash
POST /v1/chat/completions
@@ -32,20 +40,24 @@ Content-Type: application/json
### Custom Headers
| رأس | | الوصف |
| ------------------------ | ---- | -------------------------------------------- |
| `X-OmniRoute-No-Cache` | طلب | اضبط على "صحيح" لتجاوز ذاكرة التخزين المؤقتة |
| `X-OmniRoute-Progress` | طلب | اضبط على "صحيح" لأحداث التقدم |
| `معرف الاستماع X` | طلب | مفتاح جلسة لوجه الفعل |
| `x_session_id` | طلب | يتم أيضًا قبول التكيف البيئي (HTTP) |
| `مفتاح العجز` | طلب | مفتاح Dedup (نافذة 5 ثواني) |
| `معرف الطلب X` | طلب | مفتاح إلغاء الحذف الحذف |
| `X-OmniRoute-Cache` | الرد | `HIT` أو `MISS` (غير متدفق) |
| `X-OmniRoute-Idempotent` | الرد | `صحيح` إذا تم إلغاء التكرار |
| `X-OmniRoute-Progress` | الرد | `ممكن تشغيل` في حالة تتبع التقدم |
| `معرف جلسة X-OmniRoute` | الرد | الرقم التعريفي الفعال الذي يستخدمه OmniRoute |
| Header | Direction | Description |
| ------------------------ | --------- | ------------------------------------------------ |
| `X-OmniRoute-No-Cache` | Request | Set to `true` to bypass cache |
| `X-OmniRoute-Progress` | Request | Set to `true` for progress events |
| `X-Session-Id` | Request | Sticky session key for external session affinity |
| `x_session_id` | Request | Underscore variant also accepted (direct HTTP) |
| `Idempotency-Key` | Request | Dedup key (5s window) |
| `X-Request-Id` | Request | Alternative dedup key |
| `X-OmniRoute-Cache` | Response | `HIT` or `MISS` (non-streaming) |
| `X-OmniRoute-Idempotent` | Response | `true` if deduplicated |
| `X-OmniRoute-Progress` | Response | `enabled` if progress tracking on |
| `X-OmniRoute-Session-Id` | Response | Effective session ID used by OmniRoute |
> لاحظ Nginx: إذا كنت تعتمد على التكييف الهوائي (على سبيل المثال `x_session_id`)، إلا بتمكين `الشرطات الكهربائية_in_headers on;`.---## Embeddings
> Nginx note: if you rely on underscore headers (for example `x_session_id`), enable `underscores_in_headers on;`.
---
## Embeddings
```bash
POST /v1/embeddings
@@ -58,31 +70,35 @@ Content-Type: application/json
}
```
مقدمو خدمة متاحون: Nebius، وOpenAI، وMistral، وTogether AI، وFireworks، وNVIDIA.```bash
Available providers: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA, **OpenRouter**, **GitHub Models**.
# قائمة بجميع نماذج التضمين
الحصول على /v1/embeddings```
```bash
# List all embedding models
GET /v1/embeddings
```
---
## Image Generation
````bash
ما بعد /v1/صور/أجيال
التفويض: حامل مفتاح API الخاص بك
نوع المحتوى: application/json
```bash
POST /v1/images/generations
Authorization: Bearer your-api-key
Content-Type: application/json
{
"نموذج": "openai/dall-e-3"،
"prompt": "غروب الشمس الجميل فوق الجبال"،
"الحجم": "1024x1024"
}```
"model": "openai/dall-e-3",
"prompt": "A beautiful sunset over mountains",
"size": "1024x1024"
}
```
الموفرون المتاحون: OpenAI (DALL-E xAI (Grok Image)، Together AI (FLUX)، Fireworks AI.```bash
Available providers: OpenAI (DALL-E, GPT Image 1), xAI (Grok Image), Together AI (FLUX), Fireworks AI, Nebius (FLUX), Hyperbolic, NanoBanana, **OpenRouter**, SD WebUI (local), ComfyUI (local).
```bash
# List all image models
GET /v1/images/generations
````
```
---
@@ -99,26 +115,32 @@ Authorization: Bearer your-api-key
## Compatibility Endpoints
| الطريقة | المسار | التنسيق |
| -------- | --------------------------- | --------------------- | -------------------------------- |
| مشاركة | `/v1/chat/completions` | أوبن آي |
| مشاركة | `/v1/messages` | انثروبى |
| مشاركة | `/v1/الردود` | ردود OpenAI |
| مشاركة | `/v1/embeddings` | أوبن آي |
| مشاركة | `/v1/images/أجيال` | أوبن آي |
| احصل على | `/v1/ النماذج` | أوبن آي |
| مشاركة | `/v1/messages/count_tokens` | انثروبى |
| احصل على | `/v1beta/models` | الجوزاء |
| مشاركة | `/v1beta/models/{...path}` | الجوزاء توليد المحتوى |
| مشاركة | `/v1/api/chat` | أولاما | ### مسارات الموفر المخصصة```bash |
| Method | Path | Format |
| ------ | --------------------------- | ---------------------- |
| POST | `/v1/chat/completions` | OpenAI |
| POST | `/v1/messages` | Anthropic |
| POST | `/v1/responses` | OpenAI Responses |
| POST | `/v1/embeddings` | OpenAI |
| POST | `/v1/images/generations` | OpenAI |
| GET | `/v1/models` | OpenAI |
| POST | `/v1/messages/count_tokens` | Anthropic |
| GET | `/v1beta/models` | Gemini |
| POST | `/v1beta/models/{...path}` | Gemini generateContent |
| POST | `/v1/api/chat` | Ollama |
### Dedicated Provider Routes
```bash
POST /v1/providers/{provider}/chat/completions
POST /v1/providers/{provider}/embeddings
POST /v1/providers/{provider}/images/generations
```
````
The provider prefix is auto-added if missing. Mismatched models return `400`.
تتم إضافة المبادئ الأصلية للمنتج الأصلي في حالة اشتعالها. الاستعلام عن الارتباطات غير المتطابقة "400".---## Semantic Cache
---
## Semantic Cache
```bash
# Get cache stats
@@ -126,21 +148,24 @@ GET /api/cache/stats
# Clear all caches
DELETE /api/cache/stats
````
```
المثال النموذجي:`json
Response example:
```json
{
"ذاكرة التخزين المؤقت الدلالية": {
"حجم الذاكرة": 42،
"memoryMaxSize": 500،
"حجم ديسيبل": 128،
"معدل الإصابة": 0.65
"semanticCache": {
"memorySize": 42,
"memoryMaxSize": 500,
"dbSize": 128,
"hitRate": 0.65
},
"العجز": {
"المفاتيح النشطة": 3،
"windows": 5000
"idempotency": {
"activeKeys": 3,
"windowMs": 5000
}
}`
}
```
---
@@ -148,241 +173,316 @@ DELETE /api/cache/stats
### Authentication
| نقطة النهاية | الطريقة | الوصف |
| ----------------------------- | -------------- | ------------------------ | ----------------------- |
| `/api/auth/login` | مشاركة | تسجيل الدخول |
| `/api/auth/logout` | مشاركة | تسجيل الخروج |
| `/api/settings/require-login` | الحصول على/وضع | تبديل تسجيل الدخول مطلوب | ### Provider Management |
| Endpoint | Method | Description |
| ----------------------------- | ------- | --------------------- |
| `/api/auth/login` | POST | Login |
| `/api/auth/logout` | POST | Logout |
| `/api/settings/require-login` | GET/PUT | Toggle login required |
| نقطة النهاية | الطريقة | الوصف |
| ---------------------------- | ------------------ | --------------------------- | --------------- |
| `/api/providers` | الحصول على/النشر | قائمة / إنشاء مقدمي الخدمات |
| `/api/providers/[id]` | الحصول على/وضع/حذف | إدارة مزود |
| `/api/providers/[id]/test` | مشاركة | اختبار اتصال الموفر |
| `/api/providers/[id]/models` | احصل على | قائمة نماذج المزود |
| `/api/providers/validate` | مشاركة | التحقق من صحة تكوين الموفر |
| `/api/provider-nodes*` | منوعه | إدارة عقدة الموفر |
| `/api/provider-models` | الحصول على/نشر/حذف | نماذج مخصصة | ### OAuth Flows |
### Provider Management
| نقطة النهاية | الطريقة | الوصف |
| -------------------------------- | ------- | ------------------------ | -------------------- |
| `/api/oauth/[provider]/[action]` | متنوع | OAuth الخاص بموفر الخدمة | ### Routing & Config |
| Endpoint | Method | Description |
| ---------------------------- | --------------------- | ---------------------------------------------- |
| `/api/providers` | GET/POST | List / create providers |
| `/api/providers/[id]` | GET/PUT/DELETE | Manage a provider |
| `/api/providers/[id]/test` | POST | Test provider connection |
| `/api/providers/[id]/models` | GET | List provider models |
| `/api/providers/validate` | POST | Validate provider config |
| `/api/provider-nodes*` | Various | Provider node management |
| `/api/provider-models` | GET/POST/PATCH/DELETE | Custom models (add, update, hide/show, delete) |
| نقطة النهاية | الطريقة | الوصف |
| --------------------- | ---------------- | --------------------------------- | --------------------- |
| `/api/models/alias` | الحصول على/النشر | الأسماء المستعارة للنموذج |
| `/api/models/catalog` | احصل على | جميع الموديلات حسب المزود + النوع |
| `/api/combos*` | متنوع | إدارة التحرير والسرد |
| `/api/keys*` | متنوع | إدارة مفاتيح API |
| `/api/pricing` | احصل على | التسعير النموذجي | ### Usage & Analytics |
### OAuth Flows
| نقطة النهاية | الطريقة | الوصف |
| --------------------------- | -------- | --------------------- | ------------ |
| `/api/usage/history` | احصل على | تاريخ الاستخدام |
| `/api/usage/logs` | احصل على | سجلات الاستخدام |
| `/api/usage/request-logs` | احصل على | سجلات على مستوى الطلب |
| `/api/usage/[connectionId]` | احصل على | الاستخدام لكل اتصال | ### Settings |
| Endpoint | Method | Description |
| -------------------------------- | ------- | ----------------------- |
| `/api/oauth/[provider]/[action]` | Various | Provider-specific OAuth |
| نقطة النهاية | الطريقة | الوصف |
| ------------------------------- | ---------------------- | ----------------------------------------------- | -------------- |
| `/api/settings` | الحصول على/وضع/التصحيح | الإعدادات العامة |
| `/api/settings/proxy` | الحصول على/وضع | تكوين وكيل الشبكة |
| `/api/settings/proxy/test` | مشاركة | اختبار اتصال الوكيل |
| `/api/settings/ip-filter` | الحصول على/وضع | القائمة المسموح بها/القائمة المحظورة لعناوين IP |
| `/api/settings/thinking-budget` | الحصول على/وضع | الميزانية الرمزية المنطقية |
| `/api/settings/system-prompt` | الحصول على/وضع | موجه النظام العالمي | ### Monitoring |
### Routing & Config
| نقطة النهاية | الطريقة | الوصف |
| ------------------------ | -------------- | -------------------------------------------------------------------------------------------------- | -------------------------- |
| `/api/sessions` | احصل على | تتبع الجلسة النشطة |
| `/api/rate-limits` | احصل على | حدود المعدل لكل حساب |
| `/api/monitoring/health` | احصل على | التحقق من الصحة + ملخص الموفر (`catalogCount`، `configuredCount`، `activeCount`، `monitoredCount`) |
| `/api/cache/stats` | الحصول على/حذف | إحصائيات ذاكرة التخزين المؤقت / مسح | ### Backup & Export/Import |
| Endpoint | Method | Description |
| --------------------- | -------- | ----------------------------- |
| `/api/models/alias` | GET/POST | Model aliases |
| `/api/models/catalog` | GET | All models by provider + type |
| `/api/combos*` | Various | Combo management |
| `/api/keys*` | Various | API key management |
| `/api/pricing` | GET | Model pricing |
| نقطة النهاية | الطريقة | الوصف |
| --------------------------- | -------- | -------------------------------------------------- | -------------- |
| `/api/db-backups` | احصل على | قائمة النسخ الاحتياطية المتاحة |
| `/api/db-backups` | ضع | إنشاء نسخة احتياطية يدوية |
| `/api/db-backups` | مشاركة | استعادة من نسخة احتياطية محددة |
| `/api/db-backups/export` | احصل على | تنزيل قاعدة البيانات كملف .sqlite |
| `/api/db-backups/import` | مشاركة | قم بتحميل ملف .sqlite لاستبدال قاعدة البيانات |
| `/api/db-backups/exportAll` | احصل على | قم بتنزيل النسخة الاحتياطية الكاملة كأرشيف .tar.gz | ### Cloud Sync |
### Usage & Analytics
| نقطة النهاية | الطريقة | الوصف |
| ---------------------- | ------- | ------------------------ | ----------- |
| `/api/sync/cloud` | متنوع | عمليات المزامنة السحابية |
| `/api/sync/initialize` | مشاركة | تهيئة المزامنة |
| `/api/cloud/*` | متنوع | إدارة السحابة | ### Tunnels |
| Endpoint | Method | Description |
| --------------------------- | ------ | -------------------- |
| `/api/usage/history` | GET | Usage history |
| `/api/usage/logs` | GET | Usage logs |
| `/api/usage/request-logs` | GET | Request-level logs |
| `/api/usage/[connectionId]` | GET | Per-connection usage |
| نقطة النهاية | الطريقة | الوصف |
| -------------------------- | -------- | ------------------------------------------------------------- | ------------- |
| `/api/tunnels/cloudflared` | احصل على | اقرأ حالة تثبيت/تشغيل Cloudflare Quick Tunnel للوحة المعلومات |
| `/api/tunnels/cloudflared` | مشاركة | تمكين أو تعطيل نفق Cloudflare السريع (`الإجراء=تمكين/تعطيل`) | ### CLI Tools |
### Settings
| نقطة النهاية | الطريقة | الوصف |
| ---------------------------------- | -------- | ------------------- |
| `/api/cli-tools/claude-settings` | احصل على | حالة كلود CLI |
| `/api/cli-tools/codex-settings` | احصل على | حالة Codex CLI |
| `/api/cli-tools/droid-settings` | احصل على | حالة Droid CLI |
| `/api/cli-tools/openclaw-settings` | احصل على | حالة OpenClaw CLI |
| `/api/cli-tools/runtime/[toolId]` | احصل على | وقت تشغيل CLI العام |
| Endpoint | Method | Description |
| ------------------------------- | ------------- | ---------------------- |
| `/api/settings` | GET/PUT/PATCH | General settings |
| `/api/settings/proxy` | GET/PUT | Network proxy config |
| `/api/settings/proxy/test` | POST | Test proxy connection |
| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist |
| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget |
| `/api/settings/system-prompt` | GET/PUT | Global system prompt |
تتضمن استجابات واجهة سطر الأوامر: `تم التثبيت`، و`القابل للتشغيل`، و`الأمر`، و`commandPath`، و`runtimeMode`، و`السبب`.### ACP Agents
### Monitoring
| نقطة النهاية | الطريقة | الوصف |
| ----------------- | -------- | -------------------------------------------------------------- |
| `/api/acp/agents` | احصل على | قم بإدراج جميع الوكلاء المكتشفين (المضمنين + المخصصين) بالحالة |
| `/api/acp/agents` | مشاركة | إضافة وكيل مخصص أو تحديث ذاكرة التخزين المؤقت للكشف |
| `/api/acp/agents` | حذف | قم بإزالة وكيل مخصص بواسطة معلمة الاستعلام `id` |
| Endpoint | Method | Description |
| ------------------------ | ---------- | ---------------------------------------------------------------------------------------------------- |
| `/api/sessions` | GET | Active session tracking |
| `/api/rate-limits` | GET | Per-account rate limits |
| `/api/monitoring/health` | GET | Health check + provider summary (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`) |
| `/api/cache/stats` | GET/DELETE | Cache stats / clear |
تتضمن استجابة GET `الوكلاء []` (المعرف، الاسم، الثنائي، الإصدار، المثبت، البروتوكول، isCustom) و`الملخص` (الإجمالي، المثبت، غير موجود، مدمج، مخصص).### Resilience & Rate Limits
### Backup & Export/Import
| نقطة النهاية | الطريقة | الوصف |
| ----------------------- | ------------------ | ------------------------------------ | --------- |
| `/api/المرونة` | الحصول على/التصحيح | الحصول على/تحديث ملفات تعريف المرونة |
| `/api/resilience/reset` | مشاركة | إعادة ضبط قواطع الدائرة |
| `/api/rate-limits` | احصل على | حالة حد المعدل لكل حساب |
| `/api/rate-limit` | احصل على | تكوين حد المعدل العالمي | ### Evals |
| Endpoint | Method | Description |
| --------------------------- | ------ | --------------------------------------- |
| `/api/db-backups` | GET | List available backups |
| `/api/db-backups` | PUT | Create a manual backup |
| `/api/db-backups` | POST | Restore from a specific backup |
| `/api/db-backups/export` | GET | Download database as .sqlite file |
| `/api/db-backups/import` | POST | Upload .sqlite file to replace database |
| `/api/db-backups/exportAll` | GET | Download full backup as .tar.gz archive |
| نقطة النهاية | الطريقة | الوصف |
| ------------ | ---------------- | ------------------------------------- | ------------ |
| `/api/evals` | الحصول على/النشر | قائمة مجموعات التقييم / تشغيل التقييم | ### Policies |
### Cloud Sync
| نقطة النهاية | الطريقة | الوصف |
| --------------- | ------------------ | -------------------- | -------------- |
| `/api/policies` | الحصول على/نشر/حذف | إدارة سياسات التوجيه | ### Compliance |
| Endpoint | Method | Description |
| ---------------------- | ------- | --------------------- |
| `/api/sync/cloud` | Various | Cloud sync operations |
| `/api/sync/initialize` | POST | Initialize sync |
| `/api/cloud/*` | Various | Cloud management |
| نقطة النهاية | الطريقة | الوصف |
| --------------------------- | -------- | ---------------------------- | ------------------------------ |
| `/api/compliance/audit-log` | احصل على | سجل تدقيق الامتثال (آخر رقم) | ### v1beta (Gemini-Compatible) |
### Tunnels
| نقطة النهاية | الطريقة | الوصف |
| -------------------------- | -------- | ------------------------------------ |
| `/v1beta/models` | احصل على | قائمة النماذج بصيغة الجوزاء |
| `/v1beta/models/{...path}` | مشاركة | الجوزاء `توليد المحتوى` نقطة النهاية |
| Endpoint | Method | Description |
| -------------------------- | ------ | ----------------------------------------------------------------------- |
| `/api/tunnels/cloudflared` | GET | Read Cloudflare Quick Tunnel install/runtime status for the dashboard |
| `/api/tunnels/cloudflared` | POST | Enable or disable the Cloudflare Quick Tunnel (`action=enable/disable`) |
تعكس نقاط النهاية هذه تنسيق Gemini API للعملاء الذين يتوقعون توافق Gemini SDK الأصلي.### Internal / System APIs
### CLI Tools
| نقطة النهاية | الطريقة | الوصف |
| --------------- | -------- | -------------------------------------------------- |
| `/api/init` | احصل على | فحص تهيئة التطبيق (يستخدم عند التشغيل لأول مرة) |
| `/api/tags` | احصل على | علامات النماذج المتوافقة مع Ollama (لعملاء Ollama) |
| `/api/restart` | مشاركة | تشغيل إعادة تشغيل الخادم الرشيقة |
| `/api/shutdown` | مشاركة | تشغيل إيقاف تشغيل الخادم بشكل رشيق |
| Endpoint | Method | Description |
| ---------------------------------- | ------ | ------------------- |
| `/api/cli-tools/claude-settings` | GET | Claude CLI status |
| `/api/cli-tools/codex-settings` | GET | Codex CLI status |
| `/api/cli-tools/droid-settings` | GET | Droid CLI status |
| `/api/cli-tools/openclaw-settings` | GET | OpenClaw CLI status |
| `/api/cli-tools/runtime/[toolId]` | GET | Generic CLI runtime |
> **ملاحظة:**يتم استخدام نقاط النهاية هذه داخليًا بواسطة النظام أو للتوافق مع عميل Ollama. ولا يتم استدعاؤها عادة من قبل المستخدمين النهائيين.---
CLI responses include: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
### ACP Agents
| Endpoint | Method | Description |
| ----------------- | ------ | -------------------------------------------------------- |
| `/api/acp/agents` | GET | List all detected agents (built-in + custom) with status |
| `/api/acp/agents` | POST | Add custom agent or refresh detection cache |
| `/api/acp/agents` | DELETE | Remove a custom agent by `id` query param |
GET response includes `agents[]` (id, name, binary, version, installed, protocol, isCustom) and `summary` (total, installed, notFound, builtIn, custom).
### Resilience & Rate Limits
| Endpoint | Method | Description |
| ----------------------- | --------- | ------------------------------- |
| `/api/resilience` | GET/PATCH | Get/update resilience profiles |
| `/api/resilience/reset` | POST | Reset circuit breakers |
| `/api/rate-limits` | GET | Per-account rate limit status |
| `/api/rate-limit` | GET | Global rate limit configuration |
### Evals
| Endpoint | Method | Description |
| ------------ | -------- | --------------------------------- |
| `/api/evals` | GET/POST | List eval suites / run evaluation |
### Policies
| Endpoint | Method | Description |
| --------------- | --------------- | ----------------------- |
| `/api/policies` | GET/POST/DELETE | Manage routing policies |
### Compliance
| Endpoint | Method | Description |
| --------------------------- | ------ | ----------------------------- |
| `/api/compliance/audit-log` | GET | Compliance audit log (last N) |
### v1beta (Gemini-Compatible)
| Endpoint | Method | Description |
| -------------------------- | ------ | --------------------------------- |
| `/v1beta/models` | GET | List models in Gemini format |
| `/v1beta/models/{...path}` | POST | Gemini `generateContent` endpoint |
These endpoints mirror Gemini's API format for clients that expect native Gemini SDK compatibility.
### Internal / System APIs
| Endpoint | Method | Description |
| ------------------------ | ------ | ---------------------------------------------------- |
| `/api/init` | GET | Application initialization check (used on first run) |
| `/api/tags` | GET | Ollama-compatible model tags (for Ollama clients) |
| `/api/restart` | POST | Trigger graceful server restart |
| `/api/shutdown` | POST | Trigger graceful server shutdown |
| `/api/system/env/repair` | POST | Repair OAuth provider environment variables |
| `/api/system-info` | GET | Generate system diagnostics report |
> **Note:** These endpoints are used internally by the system or for Ollama client compatibility. They are not typically called by end users.
### OAuth Environment Repair _(v3.6.1+)_
```bash
POST /api/system/env/repair
Content-Type: application/json
{
"provider": "claude-code"
}
```
Repairs missing or corrupted OAuth environment variables for a specific provider. Returns:
```json
{
"success": true,
"repaired": ["CLAUDE_CODE_OAUTH_CLIENT_ID", "CLAUDE_CODE_OAUTH_CLIENT_SECRET"],
"backupPath": "/home/user/.omniroute/backups/env-repair-2026-04-11.bak"
}
```
---
## Audio Transcription
````bash
```bash
POST /v1/audio/transcriptions
التفويض: حامل مفتاح API الخاص بك
نوع المحتوى: بيانات متعددة الأجزاء/النموذج```
Authorization: Bearer your-api-key
Content-Type: multipart/form-data
```
قم بنسخ الملفات الصوتية باستخدام Deepgram أو AssemblyAI.
Transcribe audio files using Deepgram or AssemblyAI.
**طلب:**```bash
**Request:**
```bash
curl -X POST http://localhost:20128/v1/audio/transcriptions \
-H "Authorization: Bearer your-api-key" \
-F "file=@recording.mp3" \
-F "model=deepgram/nova-3"
````
```
**إجابة:**`json
**Response:**
```json
{
"text": "مرحبًا، هذا هو المحتوى الصوتي المكتوب.",
"مهمة": "نسخ"،
"اللغة": "ar"،
"المدة": 12.5
}`
"text": "Hello, this is the transcribed audio content.",
"task": "transcribe",
"language": "en",
"duration": 12.5
}
```
**مقدمو الخدمة المدعومين:**`deepgram/nova-3`assemblyai/best`.
**Supported providers:** `deepgram/nova-3`, `assemblyai/best`.
**الصيغ المدعومة:**`mp3`، `wav`، `m4a`، `flac`، `ogg`، `webm`.---
**Supported formats:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
---
## Ollama Compatibility
للعملاء الذين يستخدمون تنسيق واجهة برمجة تطبيقات Olma:```bash
For clients that use Ollama's API format:
```bash
# Chat endpoint (Ollama format)
POST /v1/api/chat
# Model listing (Ollama format)
GET /api/tags
```
````
Requests are automatically translated between Ollama and internal formats.
ترجمة الطلبات الأصلية بين التنسيقات التنسيقات الداخلية.---## Telemetry
---
## Telemetry
```bash
# Get latency telemetry summary (p50/p95/p99 per provider)
GET /api/telemetry/summary
````
```
**إجابة:**`json
**Response:**
```json
{
"مقدمو الخدمات": {
"providers": {
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
"github": { "p50": 180، "p95": 620، "p99": 950، "count": 320 }
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
}
}`
}
```
---
## Budget
````bash
# احصل على حالة الميزانية لجميع مفاتيح API
الحصول على /api/usage/budget
```bash
# Get budget status for all API keys
GET /api/usage/budget
# تعيين أو تحديث الميزانية
# Set or update a budget
POST /api/usage/budget
نوع المحتوى: application/json
Content-Type: application/json
{
"معرف المفتاح": "مفتاح-123"،
"الحد": 50.00،
"الفترة": "الشهرية"
}```
"keyId": "key-123",
"limit": 50.00,
"period": "monthly"
}
```
---
## Model Availability
```bash
# احصل على توفر النموذج في الوقت الفعلي عبر جميع مقدمي الخدمة
الحصول على /api/models/availability
# Get real-time model availability across all providers
GET /api/models/availability
# التحقق من توفر طراز معين
# Check availability for a specific model
POST /api/models/availability
نوع المحتوى: application/json
Content-Type: application/json
{
"نموذج": "كلود السوناتة-4-5-20250929"
}```
"model": "claude-sonnet-4-5-20250929"
}
```
---
## Request Processing
1. يرسل العميل طلبًا إلى `/v1/*`
2. يستدعي معالج المسار "handleChat"، أو "handleEmbedding"، أو "handleAudioTranscription"، أو "handleImageGeneration".
3. تم حل النموذج (المزود/النموذج المباشر أو الاسم المستعار/السرد)
4. تم تحديد بيانات الاعتماد من قاعدة البيانات المحلية مع تصفية توفر الحساب
5. للدردشة: `handleChatCore` - اكتشاف التنسيق، والترجمة، والتحقق من ذاكرة التخزين المؤقت، والتحقق من الكفاءة
6. يقوم منفذ الموفر بإرسال طلب المنبع
7. تتم ترجمة الاستجابة مرة أخرى إلى تنسيق العميل (الدردشة) أو إعادتها كما هي (التضمينات/الصور/الصوت)
8. تم تسجيل الاستخدام/التسجيل
9. يتم تطبيق الإجراء الاحتياطي على الأخطاء وفقًا لقواعد التحرير والسرد
1. Client sends request to `/v1/*`
2. Route handler calls `handleChat`, `handleEmbedding`, `handleAudioTranscription`, or `handleImageGeneration`
3. Model is resolved (direct provider/model or alias/combo)
4. Credentials selected from local DB with account availability filtering
5. For chat: `handleChatCore` — format detection, translation, cache check, idempotency check
6. Provider executor sends upstream request
7. Response translated back to client format (chat) or returned as-is (embeddings/images/audio)
8. Usage/logging recorded
9. Fallback applies on errors according to combo rules
مرجع البنية الكاملة: [`ARCHITECTURE.md`](ARCHITECTURE.md)---
Full architecture reference: [`ARCHITECTURE.md`](ARCHITECTURE.md)
---
## Authentication
- تستخدم مسارات لوحة المعلومات (`/dashboard/*`) ملف تعريف الارتباط `auth_token`
- يستخدم تسجيل الدخول تجزئة كلمة المرور المحفوظة؛ الرجوع إلى `INITIAL_PASSWORD`
- `requireLogin` قابل للتبديل عبر `/api/settings/require-login`
- تتطلب المسارات `/v1/*` بشكل اختياري مفتاح Bearer API عندما يكون `REQUIRE_API_KEY=true`
````
- Dashboard routes (`/dashboard/*`) use `auth_token` cookie
- Login uses saved password hash; fallback to `INITIAL_PASSWORD`
- `requireLogin` toggleable via `/api/settings/require-login`
- `/v1/*` routes optionally require Bearer API key when `REQUIRE_API_KEY=true`

View File

@@ -4,7 +4,7 @@
---
_Last updated: 2026-03-28_
_Last updated: 2026-04-15_
## Executive Summary
@@ -13,18 +13,27 @@ It provides a single OpenAI-compatible endpoint (`/v1/*`) and routes traffic acr
Core capabilities:
- OpenAI-compatible API surface for CLI/tools (28 providers)
- 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)
- OAuth + API-key provider connection management
- 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` (4 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 (`<think>...</think>`) 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
- 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
@@ -40,11 +49,30 @@ Core capabilities:
- 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
- Resilience UI dashboard with real-time circuit breaker status
- Modular OAuth providers (12 individual modules under `src/lib/oauth/providers/`)
- 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
Primary runtime model:
@@ -75,15 +103,15 @@ Main pages under `src/app/(dashboard)/dashboard/`:
- `/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, model routing rules
- `/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 and evaluations
- `/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
- `/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
@@ -186,9 +214,12 @@ Management domains:
- 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)
- Compliance audit: `src/app/api/compliance/audit-log` (GET, with pagination + structured metadata)
- 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
## 2) SSE + Translation Core
@@ -225,6 +256,14 @@ Services (business logic):
- 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
Domain layer modules:
@@ -242,7 +281,7 @@ Domain layer modules:
- 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
OAuth provider modules (12 individual files under `src/lib/oauth/providers/`):
OAuth provider modules (13 individual files under `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`
@@ -276,6 +315,10 @@ Domain State DB (SQLite):
- 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
## 5) Cloud Sync
@@ -593,6 +636,10 @@ flowchart LR
- `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
### Routing and Execution Core
@@ -617,15 +664,22 @@ flowchart LR
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.
| Executor | Provider(s) | Special Handling |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- |
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, Qoder, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Dynamic URL/header config per provider |
| `AntigravityExecutor` | Google Antigravity | Custom project/session IDs, Retry-After parsing |
| `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 |
| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream binary format → SSE conversion |
| `GeminiCLIExecutor` | Gemini CLI | Google OAuth token refresh cycle |
| 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 |
All other providers (including custom compatible nodes) use the `DefaultExecutor`.
@@ -643,7 +697,10 @@ All other providers (including custom compatible nodes) use the `DefaultExecutor
| Cursor | cursor | Custom checksum | ✅ | ✅ | ❌ | ❌ |
| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Usage limits |
| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ Per request |
| Qoder | openai | OAuth (Basic) | ✅ | ✅ | ✅ | ⚠️ 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 | ✅ | ✅ | ❌ | ❌ |
@@ -656,6 +713,17 @@ All other providers (including custom compatible nodes) use the `DefaultExecutor
| 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 | ✅ | ✅ | ❌ | ❌ |
## Format Translation Coverage
@@ -753,6 +821,12 @@ legacy compatibility. The current runtime contract uses:
- SQLite schema migrations and auto-upgrade hooks at startup
- legacy JSON → SQLite migration compatibility path
## 6) SSRF / Outbound URL Guard
- `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`
## Observability and Operational Signals
Runtime visibility sources:
@@ -807,7 +881,7 @@ Environment variables actively used by code:
8. Settings page is organized into 5 tabs: Security, Routing (6 global strategies: fill-first, round-robin, p2c, random, least-used, cost-optimized), Resilience (editable rate limits, circuit breaker, policies, **Context Relay** handoff config), AI (thinking budget, system prompt, prompt cache), Advanced (proxy).
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 24+ detection**: `/api/settings/require-login` returns `nodeVersion` and `nodeCompatible` fields. The login page renders a warning banner when the runtime is incompatible.
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.
## Operational Verification Checklist

View File

@@ -4,52 +4,64 @@
---
> نماذج النماذج الذاتية الإدارة مع تسجيل التعديلات التكيفية## How It Works
> Self-managing model chains with adaptive scoring
يقوم محرك التحرير والسرد التلقائي باختيار أفضل/نموذج ديناميكي لكل طلب باستخدام**وظيفة تسجيل مكونة من 6 اختيارات**:
## How It Works
| عامل | الوزن | الوصف |
| :-------------- | :---- | :------------------------------------- | ------------- |
| الحصة | 0.20 | القدرة المتبقية [0..1] |
| الصحة | 0.25 | الفاصل: مغلق=1.0، نصف=0.5، مفتوح=0.0 |
| تكلفة الاستثمار | 0.20 | التكلفة العكسية (أرخص = الدرجة الأعلى) |
| الكمون | 0.15 | الكمون العكسي p95 (أسرع = الأعلى) |
| تاسكفيت | 0.10 | نموذج × درجة اللياقة البدنية لنوع مهم |
| | 0.10 | متباينة في الوصول إلى زمن/الأخطاء | ## Mode Packs |
The Auto-Combo Engine dynamically selects the best provider/model for each request using a **6-factor scoring function**:
| حزمة | التركيز | الوزن الرئيسي |
| :----------------------- | :--------- | :------------------ | ---------------- |
| 🚀**الشحن السريع** | السرعة | الكمون: 0.35 |
| 💰**توفير التكلفة** | اقتصاد | تكلفة التكلفة: 0.40 |
| 🎯**الجودة الجديدة** | أفضل نموذج | المهمة فيت: 0.40 |
| 📡**غير متصل بالإنترنت** | التوفر | الحصة: 0.40 | ## الشفاء الذاتي |
| Factor | Weight | Description |
| :--------- | :----- | :---------------------------------------------- |
| Quota | 0.20 | Remaining capacity [0..1] |
| Health | 0.25 | Circuit breaker: CLOSED=1.0, HALF=0.5, OPEN=0.0 |
| CostInv | 0.20 | Inverse cost (cheaper = higher score) |
| LatencyInv | 0.15 | Inverse p95 latency (faster = higher) |
| TaskFit | 0.10 | Model × task type fitness score |
| Stability | 0.10 | Low variance in latency/errors |
-**الاستبعاد المؤقت**: النتيجة < 0.2 ← تم الاستبعاد لمدة 5 صباحا ( التراجع المتقدم، الأقصى 30 دقيقة) -**التوعية بقاطع الدورة**: مفتوح → مدمر التدمير؛ HALF_OPEN → طلبات التحقيق -**وضع الحادث**: >50% متوقع → ثم الاستكشاف المتوقع -**استرداد فترة التهدئة**: بعد الاختفاء، يكون الطلب الأول من "تحقيق" مع مهلة الأقل## Bandit Exploration
## Mode Packs
يتم توجيه 5% من الطلبات (القابلة للتكوين) إلى موفر خدمات غير آمنة للاستكشاف. معطل في الحادث.## API```bash
| Pack | Focus | Key Weight |
| :---------------------- | :----------- | :--------------- |
| 🚀 **Ship Fast** | Speed | latencyInv: 0.35 |
| 💰 **Cost Saver** | Economy | costInv: 0.40 |
| 🎯 **Quality First** | Best model | taskFit: 0.40 |
| 📡 **Offline Friendly** | Availability | quota: 0.40 |
## Self-Healing
- **Temporary exclusion**: Score < 0.2 → excluded for 5 min (progressive backoff, max 30 min)
- **Circuit breaker awareness**: OPEN → auto-excluded; HALF_OPEN → probe requests
- **Incident mode**: >50% OPEN → disable exploration, maximize stability
- **Cooldown recovery**: After exclusion, first request is a "probe" with reduced timeout
## Bandit Exploration
5% of requests (configurable) are routed to random providers for exploration. Disabled in incident mode.
## API
```bash
# Create auto-combo
curl -X POST http://localhost:20128/api/combos/auto \
-H "Content-Type: application/json" \
-d '{"id":"my-auto","name":"Auto Coder","candidatePool":["anthropic","google","openai"],"modePack":"ship-fast"}'
-H "Content-Type: application/json" \
-d '{"id":"my-auto","name":"Auto Coder","candidatePool":["anthropic","google","openai"],"modePack":"ship-fast"}'
# List auto-combos
curl http://localhost:20128/api/combos/auto
```
## Task Fitness
تم تسجيل أكثر من 30 نموذجًا عبر 6 أنواع من المهام (`الترميز`، و`المراجعة`، و`التخطيط`، و`التحليل`، و`تصحيح سبب`، و`التوثيق`). محترف أحرف البدل (على سبيل المثال، `*-coder` → درجة ترميز عالية).## Files
30+ models scored across 6 task types (`coding`, `review`, `planning`, `analysis`, `debugging`, `documentation`). Supports wildcard patterns (e.g., `*-coder`high coding score).
| ملف | الحصاد |
## Files
| File | Purpose |
| :------------------------------------------- | :------------------------------------ |
| `open-sse/services/autoCombo/scoring.ts` | وظيفة الهديف وتطبيع التكيف |
| `open-sse/services/autoCombo/taskFitness.ts` | نموذج × مهمة بحث اللياقة البدنية |
| `open-sse/services/autoCombo/engine.ts` | الاختيار المنطقي، قطاع الطرق، ميزانية الإنفاق |
| `open-sse/services/autoCombo/selfHealing.ts` | الابعاد، التفاصيل، حالة الحادث |
| `open-sse/services/autoCombo/modePacks.ts` | 4 ملفات تعريف للوزن |
| `src/app/api/combos/auto/route.ts` | ريست API |
```
| `open-sse/services/autoCombo/scoring.ts` | Scoring function & pool normalization |
| `open-sse/services/autoCombo/taskFitness.ts` | Model × task fitness lookup |
| `open-sse/services/autoCombo/engine.ts` | Selection logic, bandit, budget cap |
| `open-sse/services/autoCombo/selfHealing.ts` | Exclusion, probes, incident mode |
| `open-sse/services/autoCombo/modePacks.ts` | 4 weight profiles |
| `src/app/api/combos/auto/route.ts` | REST API |

View File

@@ -4,9 +4,13 @@
---
يشرح هذا الدليل كيفية تثبيت وتكوين جميع أدوات CLI البسيطة للذكاء الاصطناعي والمدعم
استخدام**OmniRoute**ك واجهة خلفية موحدة، مما يتيح لك إدارة المفاتيح التركية،
تتبع التكلفة، وتبديل الارتباطات، والتسجيل عبر كل أداة.---## How It Works
This guide explains how to install and configure all supported AI coding CLI tools
to use **OmniRoute** as the unified backend, giving you centralized key management,
cost tracking, model switching, and request logging across every tool.
---
## How It Works
```
Claude / Codex / OpenCode / Cline / KiloCode / Continue / Kiro / Cursor / Copilot
@@ -18,131 +22,154 @@ Claude / Codex / OpenCode / Cline / KiloCode / Continue / Kiro / Cursor / Copilo
Anthropic / OpenAI / Gemini / DeepSeek / Groq / Mistral / ...
```
**الفوائد:**
**Benefits:**
- مفتاح API واحد لإبتكار جميع الأدوات
- تتبع التكلفة عبر جميع CLIs في لوحة المعلومات
- النموذج النموذجي دون إعادة كل أداة
- يعمل محليا وعلى الموقع البعيد (VPS)---## Supported Tools (Dashboard Source of Truth)
- One API key to manage all tools
- Cost tracking across all CLIs in the dashboard
- Model switching without reconfiguring every tool
- Works locally and on remote servers (VPS)
يتم إنشاء بطاقة معلومات اللوحة في `/dashboard/cli-tools` من `src/shared/constants/cliTools.ts`.
القائمة الحالية (v3.0.0-rc.16):
---
| أداة | معرف | الأمر | وضع الإعداد | طريقة التثبيت |
| --------------------- | ---------------- | ------------- | ----------- | ------------------ | ----------------------------------------- |
| **كود كلود** | "كلود" | "كلود" | ببيئة | نم |
| **مخطوطة OpenAI** | `المخطوطة` | `المخطوطة` | مخصص | نم |
| **مصنع الروبوت** | "الروبوت" | "الروبوت" | مخصص | المجمعة/CLI |
| **أوبنكلاو** | `مخلب مفتوح` | `مخلب مفتوح` | مخصص | المجمعة/CLI |
| **المؤشر** | `المؤشر` | التطبيق | دليل | تطبيق سطح المكتب |
| **كلاين** | `كلاين` | `كلاين` | مخصص | نم |
| **كيلو كود** | `كيلو` | `الكيلو كود` | مخصص | نم |
| **تابع** | `متابعة` | امتداد | دليل | كود مقابل |
| **مضادة الجاذبية** | `مضادة الجاذبية` | | ميتوم | أومنيروتي |
| **جيثب مساعد الطيار** | `مساعد الطيار` | امتداد | مخصص | كود مقابل |
| **الكود مفتوح** | `الرمز مفتوح` | `الرمز مفتوح` | دليل | نم |
| **كيرو آي** | `كيرو` | التطبيق/كلي | ميتوم | سطح المكتب/سطر مود | ### مزامنة بصمة CLI (الوكلاء + الإعدادات) |
## Supported Tools (Dashboard Source of Truth)
استخدم `/dashboard/agents` و`Settings > CLI Fingerprint` src/shared/constants/cliCompatProviders.ts.
يؤدي ذلك إلى تفاصيل البطاقات الموفر المعتمدة ببطاقات CLI والمعارف القديمة.
The dashboard cards in `/dashboard/cli-tools` are generated from `src/shared/constants/cliTools.ts`.
Current list (v3.0.0-rc.16):
| معرف واجهة سطر مود | معرف بصمة الإصبع |
| ----------------------------------------------------------------------------------------------------- | ---------------- |
| `كيلو` | `الكيلو كود` |
| `مساعد الطيار` | `جيثب` |
| `كلود` / `كوديكس` / `مضاد الجاذبية` / `كيرو` / `المؤشر` / `كلاين` / `opencode` / `droid` / `openclaw` | نفس المعرف |
| Tool | ID | Command | Setup Mode | Install Method |
| ------------------ | ------------- | ---------- | ---------- | -------------- |
| **Claude Code** | `claude` | `claude` | env | npm |
| **OpenAI Codex** | `codex` | `codex` | custom | npm |
| **Factory Droid** | `droid` | `droid` | custom | bundled/CLI |
| **OpenClaw** | `openclaw` | `openclaw` | custom | bundled/CLI |
| **Cursor** | `cursor` | app | guide | desktop app |
| **Cline** | `cline` | `cline` | custom | npm |
| **Kilo Code** | `kilo` | `kilocode` | custom | npm |
| **Continue** | `continue` | extension | guide | VS Code |
| **Antigravity** | `antigravity` | internal | mitm | OmniRoute |
| **GitHub Copilot** | `copilot` | extension | custom | VS Code |
| **OpenCode** | `opencode` | `opencode` | guide | npm |
| **Kiro AI** | `kiro` | app/cli | mitm | desktop/CLI |
| **Qwen Code** | `qwen` | `qwen` | custom | npm |
لا تزال المعرفات القديمة مقبولة للتوافق: `مساعد الطيار`، `كيمي كودينج`، `كوين`.---## Step 1 — Get an OmniRoute API Key
### CLI fingerprint sync (Agents + Settings)
1. تسجيل الدخول إلى لوحة التحكم OmniRoute →**API Manager**(`/dashboard/api-manager`)
2. انقر**إنشاء مفتاح واجهة برمجة التطبيقات**
3. أعطته اسمًا (على سبيل المثال، "أدوات cli") وتحديد جميع الأذونات
4. انسخ المفتاح — ستحتاج إليه لكل واجهة سطر الأوامر (CLI) أدناه
`/dashboard/agents` and `Settings > CLI Fingerprint` use `src/shared/constants/cliCompatProviders.ts`.
This keeps provider IDs aligned with CLI cards and legacy IDs.
> يبدو مفتاحك كما يلي: `sk-xxxxxxxxxxxxxxxxxx-xxxxxxxxx`---## Step 2 — Install CLI Tools
| CLI ID | Fingerprint Provider ID |
| ---------------------------------------------------------------------------------------------------- | ----------------------- |
| `kilo` | `kilocode` |
| `copilot` | `github` |
| `claude` / `codex` / `antigravity` / `kiro` / `cursor` / `cline` / `opencode` / `droid` / `openclaw` | same ID |
تتطلب جميع المستندات المستندة إلى npm Node.js 18+:```bash
Legacy IDs still accepted for compatibility: `copilot`, `kimi-coding`, `qwen`.
# كلود كود (أنثروبي)
---
تثبيت npm -g @anthropic-ai/claude-code
## Step 1 — Get an OmniRoute API Key
# مخطوطة OpenAI
1. Open the OmniRoute dashboard → **API Manager** (`/dashboard/api-manager`)
2. Click **Create API Key**
3. Give it a name (e.g. `cli-tools`) and select all permissions
4. Copy the key — you'll need it for every CLI below
تثبيت npm -g @openai/codex
> Your key looks like: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`
# الكود المفتوح
---
تثبيت npm -g opencode-ai
## Step 2 — Install CLI Tools
# كلاين
All npm-based tools require Node.js 18+:
تثبيت npm -g cline
```bash
# Claude Code (Anthropic)
npm install -g @anthropic-ai/claude-code
# كيلو كود
# OpenAI Codex
npm install -g @openai/codex
تثبيت npm -g كيلوكود
# OpenCode
npm install -g opencode-ai
# Kiro CLI (أمازون - يتطلب تجعيد + فك الضغط)
# Cline
npm install -g cline
apt-get install -y unzip # على Debian/Ubuntu
حليقة -fsSL https://cli.kiro.dev/install | باش
تصدير PATH = "$HOME/.local/bin:$PATH" # إضافة إلى ~/.bashrc```
# KiloCode
npm install -g kilocode
**يؤكد:**```bash
claude --version # 2.x.x
codex --version # 0.x.x
opencode --version # x.x.x
cline --version # 2.x.x
kilocode --version # x.x.x (or: kilo --version)
kiro-cli --version # 1.x.x
# Kiro CLI (Amazon — requires curl + unzip)
apt-get install -y unzip # on Debian/Ubuntu
curl -fsSL https://cli.kiro.dev/install | bash
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
```
````
**Verify:**
```bash
claude --version # 2.x.x
codex --version # 0.x.x
opencode --version # x.x.x
cline --version # 2.x.x
kilocode --version # x.x.x (or: kilo --version)
kiro-cli --version # 1.x.x
```
---
## Step 3 — Set Global Environment Variables
إضافة إلى `~/.bashrc` (أو `~/.zshrc`)، ثم قم ويسمح `المصدر ~/.bashrc`:```bash
# نقطة النهاية العالمية OmniRoute
تصدير OPENAI_BASE_URL = "http://localhost:20128/v1"
تصدير OPENAI_API_KEY = "sk-your-omniroute-key"
تصدير ANTHROPIC_BASE_URL = "http://localhost:20128/v1"
تصدير ANTHROPIC_API_KEY = "sk-your-omniroute-key"
تصدير GEMINI_BASE_URL = "http://localhost:20128/v1"
تصدير GEMINI_API_KEY = "sk-your-omniroute-key"```
Add to `~/.bashrc` (or `~/.zshrc`), then run `source ~/.bashrc`:
> بالنسبة إلى**الخادم البعيد**، استبدل `localhost:20128` بعنوان IP للخادم أو المجال،
> على سبيل المثال `http://192.168.0.15:20128`.---
```bash
# OmniRoute Universal Endpoint
export OPENAI_BASE_URL="http://localhost:20128/v1"
export OPENAI_API_KEY="sk-your-omniroute-key"
export ANTHROPIC_BASE_URL="http://localhost:20128/v1"
export ANTHROPIC_API_KEY="sk-your-omniroute-key"
export GEMINI_BASE_URL="http://localhost:20128/v1"
export GEMINI_API_KEY="sk-your-omniroute-key"
```
> For a **remote server** replace `localhost:20128` with the server IP or domain,
> e.g. `http://192.168.0.15:20128`.
---
## Step 4 — Configure Each Tool
### Claude Code
```bash
# عبر سطر الأوامر:
مجموعة تكوين كلود - عنوان URL لواجهة برمجة التطبيقات العالمية http://localhost:20128/v1
# Via CLI:
claude config set --global api-base-url http://localhost:20128/v1
# أو قم بإنشاء ~/.claude/settings.json:
# Or create ~/.claude/settings.json:
mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF
{
"apiBaseUrl": "http://localhost:20128/v1",
"apiKey": "مفتاح sk-your-omniroute-"
"apiKey": "sk-your-omniroute-key"
}
EOF```
EOF
```
**اختبار:**`كلود "قل مرحبا"`---
**Test:** `claude "say hello"`
---
### OpenAI Codex
```bash
mkdir -p ~/.codex && cat > ~/.codex/config.yaml << EOF
نموذج: السيارات
model: auto
apiKey: sk-your-omniroute-key
رابط واجهة برمجة التطبيقات: http://localhost:20128/v1
EOF```
apiBaseUrl: http://localhost:20128/v1
EOF
```
**اختبار:**`مخطوطة "ما هو 2+2؟"'---
**Test:** `codex "what is 2+2?"`
---
### OpenCode
@@ -150,14 +177,19 @@ EOF```
mkdir -p ~/.config/opencode && cat > ~/.config/opencode/config.toml << EOF
[provider.openai]
base_url = "http://localhost:20128/v1"
api_key = "مفتاح sk-omniroute"
EOF```
api_key = "sk-your-omniroute-key"
EOF
```
**اختبار:**`الرمز المفتوح`---
**Test:** `opencode`
---
### Cline (CLI or VS Code)
**وضع سطر الأوامر:**```bash
**CLI mode:**
```bash
mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF
{
"apiProvider": "openai",
@@ -165,125 +197,202 @@ mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF
"openAiApiKey": "sk-your-omniroute-key"
}
EOF
````
```
**وضع رمز VS:**
إعدادات امتداد Cline ← موفر واجهة برمجة التطبيقات: `متوافق مع OpenAI` ← عنوان URL الأساسي: `http://localhost:20128/v1`
**VS Code mode:**
Cline extension settings → API Provider: `OpenAI Compatible` → Base URL: `http://localhost:20128/v1`
استخدام لوحة معلومات OmniRoute →**أدوات CLI → Cline → تطبيق المتاح**.---### KiloCode (CLI or VS Code)
Or use the OmniRoute dashboard → **CLI Tools → Cline → Apply Config**.
**وضع سطر مود:**`bash
كيلو كود --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key`
---
**إعدادات رمز VS:**```json
### KiloCode (CLI or VS Code)
**CLI mode:**
```bash
kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key
```
**VS Code settings:**
```json
{
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
"kilo-code.apiKey": "sk-your-omniroute-key"
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
"kilo-code.apiKey": "sk-your-omniroute-key"
}
```
````
Or use the OmniRoute dashboard → **CLI Tools → KiloCode → Apply Config**.
استخدام لوحة معلومات OmniRoute →**CLI → KiloCode → تطبيق تفعيل**.---### Continue (VS Code Extension)
---
تحرير `~/.continue/config.yaml`:```yaml
النماذج:
- الاسم: OmniRoute
المزود: openai
نموذج: السيارات
واجهة برمجة التطبيقات: http://localhost:20128/v1
### Continue (VS Code Extension)
Edit `~/.continue/config.yaml`:
```yaml
models:
- name: OmniRoute
provider: openai
model: auto
apiBase: http://localhost:20128/v1
apiKey: sk-your-omniroute-key
الافتراضي: صحيح```
default: true
```
أعد تشغيل VS Code بعد التحرير.---
Restart VS Code after editing.
---
### Kiro CLI (Amazon)
```bash
# قم بتسجيل الدخول إلى حساب AWS/Kiro الخاص بك:
كيرو كلي تسجيل الدخول
# Login to your AWS/Kiro account:
kiro-cli login
# تستخدم واجهة سطر الأوامر (CLI) مصادقة خاصة بها — ليست هناك حاجة إلى OmniRoute كواجهة خلفية لـ Kiro CLI نفسها.
# استخدم kiro-cli بجانب OmniRoute لأدوات أخرى.
حالة كيرو كلي```
# The CLI uses its own auth — OmniRoute is not needed as backend for Kiro CLI itself.
# Use kiro-cli alongside OmniRoute for other tools.
kiro-cli status
```
---
### Qwen Code (Alibaba)
Qwen Code supports OpenAI-compatible API endpoints via environment variables or `settings.json`.
**Option 1: Environment variables (`~/.qwen/.env`)**
```bash
mkdir -p ~/.qwen && cat > ~/.qwen/.env << EOF
OPENAI_API_KEY="sk-your-omniroute-key"
OPENAI_BASE_URL="http://localhost:20128/v1"
OPENAI_MODEL="auto"
EOF
```
**Option 2: `settings.json` with model providers**
```json
// ~/.qwen/settings.json
{
"env": {
"OPENAI_API_KEY": "sk-your-omniroute-key",
"OPENAI_BASE_URL": "http://localhost:20128/v1"
},
"modelProviders": {
"openai": [
{
"id": "omniroute-default",
"name": "OmniRoute (Auto)",
"envKey": "OPENAI_API_KEY",
"baseUrl": "http://localhost:20128/v1"
}
]
}
}
```
**Option 3: Inline CLI flags**
```bash
OPENAI_BASE_URL="http://localhost:20128/v1" \
OPENAI_API_KEY="sk-your-omniroute-key" \
OPENAI_MODEL="auto" \
qwen
```
> For a **remote server** replace `localhost:20128` with the server IP or domain.
**Test:** `qwen "say hello"`
### Cursor (Desktop App)
>**ملاحظة:**يقوم المؤشر بتوجيه الطلبات عبر السحابة الخاصة به. لتكامل OmniRoute،
> قم بتمكين**Cloud Endpoint**في إعدادات OmniRoute واستخدم عنوان URL للنطاق العام الخاص بك.
> **Note:** Cursor routes requests through its cloud. For OmniRoute integration,
> enable **Cloud Endpoint** in OmniRoute Settings and use your public domain URL.
عبر واجهة المستخدم الرسومية:**الإعدادات → النماذج → مفتاح OpenAI API**
Via GUI: **Settings → Models → OpenAI API Key**
- عنوان URL الأساسي: `https://your-domain.com/v1`
- مفتاح API: مفتاح OmniRoute الخاص بك---
- Base URL: `https://your-domain.com/v1`
- API Key: your OmniRoute key
---
## Dashboard Auto-Configuration
تقوم لوحة معلومات OmniRoute بأتمتة التكوين لمعظم الأدوات:
The OmniRoute dashboard automates configuration for most tools:
1. انتقل إلى `http://localhost:20128/dashboard/cli-tools`
2. قم بتوسيع أي بطاقة أداة
3. حدد مفتاح API الخاص بك من القائمة المنسدلة
4. انقر فوق**تطبيق التكوين**(إذا تم اكتشاف الأداة على أنها مثبتة)
5. أو انسخ مقتطف التكوين الذي تم إنشاؤه يدويًا---
1. Go to `http://localhost:20128/dashboard/cli-tools`
2. Expand any tool card
3. Select your API key from the dropdown
4. Click **Apply Config** (if tool is detected as installed)
5. Or copy the generated config snippet manually
---
## Built-in Agents: Droid & OpenClaw
**Droid**و**OpenClaw**هما وكيلان للذكاء الاصطناعي مدمجان مباشرة في OmniRoute — لا حاجة للتثبيت.
يتم تشغيلها كمسارات داخلية وتستخدم توجيه نموذج OmniRoute تلقائيًا.
**Droid** and **OpenClaw** are AI agents built directly into OmniRoute — no installation needed.
They run as internal routes and use OmniRoute's model routing automatically.
- الوصول: `http://localhost:20128/dashboard/agents`
- التكوين: نفس المجموعات ومقدمي الخدمات مثل جميع الأدوات الأخرى
- لا يلزم تثبيت مفتاح API أو CLI---
- Access: `http://localhost:20128/dashboard/agents`
- Configure: same combos and providers as all other tools
- No API key or CLI install required
---
## Available API Endpoints
| نقطة النهاية | الوصف | استخدم لـ |
| Endpoint | Description | Use For |
| -------------------------- | ----------------------------- | --------------------------- |
| `/v1/chat/completions` | الدردشة القياسية (جميع مقدمي الخدمة) | جميع الأدوات الحديثة |
| `/v1/الردود` | واجهة برمجة تطبيقات الردود (تنسيق OpenAI) | الدستور الغذائي، سير العمل الوكيل |
| `/v1/الإكمال` | إكمال النص القديم | الأدوات القديمة التي تستخدم `المطالبة:` |
| `/v1/embeddings` | تضمينات النص | راج، بحث |
| `/v1/images/أجيال` | توليد الصور | DALL-E، الجريان، وما إلى ذلك |
| `/v1/audio/speech` | تحويل النص إلى كلام | أحد عشر مختبرًا، OpenAI TTS |
| `/v1/audio/transcriptions` | تحويل الكلام إلى نص | ديبجرام، الجمعية AI |---
| `/v1/chat/completions` | Standard chat (all providers) | All modern tools |
| `/v1/responses` | Responses API (OpenAI format) | Codex, agentic workflows |
| `/v1/completions` | Legacy text completions | Older tools using `prompt:` |
| `/v1/embeddings` | Text embeddings | RAG, search |
| `/v1/images/generations` | Image generation | DALL-E, Flux, etc. |
| `/v1/audio/speech` | Text-to-speech | ElevenLabs, OpenAI TTS |
| `/v1/audio/transcriptions` | Speech-to-text | Deepgram, AssemblyAI |
---
## استكشاف الأخطاء
| خطأ | السبب | إصلاح |
| Error | Cause | Fix |
| ------------------------- | ----------------------- | ------------------------------------------ |
| `تم رفض الاتصال` | OmniRoute لا يعمل | `pm2 ابدأ في كل الاتجاهات` |
| `401 غير مصرح به' | مفتاح API خاطئ | قم بتسجيل الدخول `/dashboard/api-manager` |
| `لم يتم تكوين التحرير والسرد` | لا يوجد مجموعة توجيه نشطة | تم الإعداد في `/dashboard/combos` |
| `نموذج غير صالح` | الموديل غير موجود في الكتالوج | استخدم "تلقائي" أو حدد "/dashboard/providers" |
| يظهر سطر الأوامر "غير مثبت" | ثنائي ليس في PATH | حدد `أي <command>` |
| `كيرو كلي: غير موجود` | ليس في المسار | `تصدير المسار = "$HOME/.local/bin:$PATH"` |---
| `Connection refused` | OmniRoute not running | `pm2 start omniroute` |
| `401 Unauthorized` | Wrong API key | Check in `/dashboard/api-manager` |
| `No combo configured` | No active routing combo | Set up in `/dashboard/combos` |
| `invalid model` | Model not in catalog | Use `auto` or check `/dashboard/providers` |
| CLI shows "not installed" | Binary not in PATH | Check `which <command>` |
| `kiro-cli: not found` | Not in PATH | `export PATH="$HOME/.local/bin:$PATH"` |
---
## Quick Setup Script (One Command)
```bash
# تثبيت جميع واجهات سطر الأوامر (CLI) وتكوين OmniRoute (استبدلها بمفتاحك وعنوان URL الخاص بالخادم)
# Install all CLIs and configure for OmniRoute (replace with your key and server URL)
OMNIROUTE_URL="http://localhost:20128/v1"
OMNIROUTE_KEY="sk-your-omniroute-key"
تثبيت npm -g @anthropic-ai/clude-code @openai/codex opencode-ai cline Kilocode
npm install -g @anthropic-ai/claude-code @openai/codex opencode-ai cline kilocode @qwen-code/qwen-code
# كيرو كلي
apt-get install -y unzip 2>/dev/null; حليقة -fsSL https://cli.kiro.dev/install | باش
# Kiro CLI
apt-get install -y unzip 2>/dev/null; curl -fsSL https://cli.kiro.dev/install | bash
# كتابة التكوينات
# Write configs
mkdir -p ~/.claude ~/.codex ~/.config/opencode ~/.continue
cat > ~/.claude/settings.json <<< "{\"apiBaseUrl\":\"$OMNIROUTE_URL\",\"apiKey\":\"$OMNIROUTE_KEY\"}"
cat > ~/.codex/config.yaml <<< "model: auto\napiKey: $OMNIROUTE_KEY\napiBaseUrl: $OMNIROUTE_URL"
القط >> ~/.bashrc << EOF
تصدير OPENAI_BASE_URL="$OMNIROUTE_URL"
تصدير OPENAI_API_KEY = "$OMNIROUTE_KEY"
تصدير ANTHROPIC_BASE_URL="$OMNIROUTE_URL"
تصدير ANTHROPIC_API_KEY = "$OMNIROUTE_KEY"
cat > ~/.claude/settings.json <<< "{\"apiBaseUrl\":\"$OMNIROUTE_URL\",\"apiKey\":\"$OMNIROUTE_KEY\"}"
cat > ~/.codex/config.yaml <<< "model: auto\napiKey: $OMNIROUTE_KEY\napiBaseUrl: $OMNIROUTE_URL"
cat >> ~/.bashrc << EOF
export OPENAI_BASE_URL="$OMNIROUTE_URL"
export OPENAI_API_KEY="$OMNIROUTE_KEY"
export ANTHROPIC_BASE_URL="$OMNIROUTE_URL"
export ANTHROPIC_API_KEY="$OMNIROUTE_KEY"
EOF
المصدر ~/.bashrc
صدى " ✅ تم تثبيت جميع واجهات سطر الأوامر (CLI) وتكوينها لـ OmniRoute"```
````
source ~/.bashrc
echo "✅ All CLIs installed and configured for OmniRoute"
```

View File

@@ -4,13 +4,21 @@
---
> دليل شامل ومناسب للمبتدئين إلى مدير المدير AI**omniroute**متعدد الموفرين.---## 1. What Is omniroute?
> A comprehensive, beginner-friendly guide to the **omniroute** multi-provider AI proxy router.
omniroute هو**جهاز وكيل التوجيه**يقع بين عملاء الذكاء الاصطناعي (Claude CLI، وCodex، وCursor IDE، وما إلى ذلك) وموفري الذكاء الاصطناعي (Anthropic، وGoogle، وOpenAI، وAWS، وGitHub، وما إلى ذلك). يحل مشكلة واحدة كبيرة:
---
> **يتحدث عملاء الذكاء الاصطناعي المختلفون "لغات" مختلفة (تنسيقات واجهة برمجة التطبيقات)، ويتوقع مقدمو خدمات الذكاء الاصطناعي المختلفون "لغات مختلفة" أيضاً.**يترجم المسار الشامل بما فيه الكفاية.
## 1. What Is omniroute?
فكر في الأمر التالي مترجم عالمي في الأمم المتحدة - يمكن لأي مندوبات أي لغة، والمترجم هل يمكن أن يترجمها لأي مندوب آخر.---## 2. Architecture Overview
omniroute is a **proxy router** that sits between AI clients (Claude CLI, Codex, Cursor IDE, etc.) and AI providers (Anthropic, Google, OpenAI, AWS, GitHub, etc.). It solves one big problem:
> **Different AI clients speak different "languages" (API formats), and different AI providers expect different "languages" too.** omniroute translates between them automatically.
Think of it like a universal translator at the United Nations — any delegate can speak any language, and the translator converts it for any other delegate.
---
## 2. Architecture Overview
```mermaid
graph LR
@@ -57,38 +65,44 @@ graph LR
### Core Principle: Hub-and-Spoke Translation
تمر جميع ترجمةات عبر**تنسيق OpenAI كمركز**:`
تنسيق العميل → [OpenAI Hub] → تنسيق الموفر (طلب)
تنسيق الموفر → [OpenAI Hub] → تنسيق العميل (الاستجابة)`
All format translation passes through **OpenAI format as the hub**:
هذا يعني أنك تحتاج فقط إلى مترجمين**N**(واحد لكل تنسيق) بدلاً من**N²**(كل زوج).---
```
Client Format → [OpenAI Hub] → Provider Format (request)
Provider Format → [OpenAI Hub] → Client Format (response)
```
This means you only need **N translators** (one per format) instead of **N²** (every pair).
---
## 3. Project Structure
````
الطريق الشامل/
├── open-sse/ ← مكتبة الوكيل الأساسية (محمول، لا إطاري)
│ ├── Index.js ← نقطة الدخول الرئيسية، تصدر كل شيء
│ ├── التكوين/ ← التكوين والثوابت
│ ├── المنفذون/ ← تنفيذ الطلب الخاص بالمزود
│ ├── معالجات/ ← طلب تنسيق التعامل
│ ├── الخدمات/ ← منطق الأعمال (المصادقة، النماذج، الاحتياطي، الاستخدام)
│ ├── مترجم/ ← تنسيق محرك الترجمة
│ ├── طلب/ ← طلب مترجمين (8 ملفات)
│ │ ├── استجابة/ ← مترجمو الاستجابة (7 ملفات)
│ │ └── مساعدون/ ← أدوات الترجمة المشتركة (6 ملفات)
│ └── المرافق/ ← وظائف المرافق
├── src/ ← طبقة التطبيق (وقت تشغيل Express/Worker)
│ ├── التطبيق/ ← واجهة مستخدم الويب، مسارات واجهة برمجة التطبيقات، البرامج الوسيطة
│ ├── lib/ ← قاعدة البيانات والمصادقة وكود المكتبة المشتركة
│ ├── mitm/ ← أدوات الوكيل الوسيطة
│ ├── النماذج/ ← نماذج قواعد البيانات
│ ├── مشترك/ ← أدوات مساعدة مشتركة (مغلفات حول open-sse)
│ ├── sse/ ← معالجات نقطة النهاية SSE
│ └── المتجر/ ← إدارة الدولة
├── البيانات/ ← بيانات وقت التشغيل (بيانات الاعتماد والسجلات)
│ └── Provider-credentials.json (تجاوز بيانات الاعتماد الخارجية، gitignored)
└── اختبار/ ← اختبار المرافق```
```
omniroute/
├── open-sse/ ← Core proxy library (portable, framework-agnostic)
├── index.js ← Main entry point, exports everything
├── config/ ← Configuration & constants
├── executors/ ← Provider-specific request execution
├── handlers/ ← Request handling orchestration
├── services/ ← Business logic (auth, models, fallback, usage)
├── translator/ ← Format translation engine
│ ├── request/ ← Request translators (8 files)
│ │ ├── response/ ← Response translators (7 files)
└── helpers/ ← Shared translation utilities (6 files)
└── utils/ ← Utility functions
├── src/ ← Application layer (Express/Worker runtime)
├── app/ ← Web UI, API routes, middleware
├── lib/ ← Database, auth, and shared library code
├── mitm/ ← Man-in-the-middle proxy utilities
├── models/ ← Database models
├── shared/ ← Shared utilities (wrappers around open-sse)
├── sse/ ← SSE endpoint handlers
└── store/ ← State management
├── data/ ← Runtime data (credentials, logs)
└── provider-credentials.json (external credentials override, gitignored)
└── tester/ ← Test utilities
```
---
@@ -96,40 +110,45 @@ graph LR
### 4.1 Config (`open-sse/config/`)
**المصدر الوحيد للحقيقة**لجميع إعدادات الموفر.
The **single source of truth** for all provider configuration.
| ملف | الغرض |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `الثوابت.ts` | كائن `PROVIDERS` يحتوي على عناوين URL الأساسية وبيانات اعتماد OAuth (الافتراضية) والرؤوس ومطالبات النظام الافتراضية لكل موفر. يحدد أيضًا `HTTP_STATUS` و`ERROR_TYPES` و`COOLDOWN_MS` و`BACKOFF_CONFIG` و`SKIP_PATTERNS`. |
| "credentialLoader.ts" | يقوم بتحميل بيانات الاعتماد الخارجية من "data/provider-credentials.json" ويدمجها في الإعدادات الافتراضية المضمنة في "PROVIDERS". يحافظ على الأسرار خارج نطاق التحكم بالمصدر مع الحفاظ على التوافق مع الإصدارات السابقة. |
| `providerModels.ts` | سجل النموذج المركزي: الأسماء المستعارة لموفر الخرائط → معرفات النموذج. وظائف مثل `getModels()` و`getProviderByAlias()`. |
| `codexInstructions.ts` | تعليمات النظام التي تم إدخالها في طلبات الدستور الغذائي (قيود التحرير، قواعد الاختبار، سياسات الموافقة). |
| `defaultThinkingSignature.ts` | توقيعات "التفكير" الافتراضية لنماذج كلود وجيميني. |
| `olmaModels.ts` | تعريف المخطط لنماذج أولاما المحلية (الاسم، الحجم، العائلة، التكميم). |#### Credential Loading Flow
| File | Purpose |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `constants.ts` | `PROVIDERS` object with base URLs, OAuth credentials (defaults), headers, and default system prompts for every provider. Also defines `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG`, and `SKIP_PATTERNS`. |
| `credentialLoader.ts` | Loads external credentials from `data/provider-credentials.json` and merges them over the hardcoded defaults in `PROVIDERS`. Keeps secrets out of source control while maintaining backwards compatibility. |
| `providerModels.ts` | Central model registry: maps provider aliases → model IDs. Functions like `getModels()`, `getProviderByAlias()`. |
| `codexInstructions.ts` | System instructions injected into Codex requests (editing constraints, sandbox rules, approval policies). |
| `defaultThinkingSignature.ts` | Default "thinking" signatures for Claude and Gemini models. |
| `ollamaModels.ts` | Schema definition for local Ollama models (name, size, family, quantization). |
#### Credential Loading Flow
```mermaid
مخطط انسيابي TD
A["يبدأ التطبيق"] --> B["constants.ts يحدد مقدمي الخدمة\nبإعدادات افتراضية مضمنة"]
B --> C{"data/provider-credentials.json\nexists؟"}
ج -->|نعم| D["credentialLoader يقرأ JSON"]
ج -->|لا| E["استخدام الإعدادات الافتراضية المشفرة"]
D --> F{"لكل موفر في JSON"}
F --> G{"الموفر موجود\nفي الموفرين؟"}
ز -->|لا| H["تحذير السجل، تخطي"]
ز -->|نعم| أنا{"القيمة هي كائن؟"}
أنا -->|لا| J["تحذير السجل، تخطي"]
أنا -->|نعم| K["دمج معرف العميل، ClientSecret،\ntokenUrl، authUrl، RefreshUrl"]
ك --> ف
ح --> ف
ي --> ف
F -->|تم| L["الموفرون جاهزون\nببيانات اعتماد مدمجة"]
ه --> ل```
flowchart TD
A["App starts"] --> B["constants.ts defines PROVIDERS\nwith hardcoded defaults"]
B --> C{"data/provider-credentials.json\nexists?"}
C -->|Yes| D["credentialLoader reads JSON"]
C -->|No| E["Use hardcoded defaults"]
D --> F{"For each provider in JSON"}
F --> G{"Provider exists\nin PROVIDERS?"}
G -->|No| H["Log warning, skip"]
G -->|Yes| I{"Value is object?"}
I -->|No| J["Log warning, skip"]
I -->|Yes| K["Merge clientId, clientSecret,\ntokenUrl, authUrl, refreshUrl"]
K --> F
H --> F
J --> F
F -->|Done| L["PROVIDERS ready with\nmerged credentials"]
E --> L
```
---
### 4.2 Executors (`open-sse/executors/`)
يقوم المنفذون بتغليف**المنطق الخاص بالمزود**باستخدام**نمط الإستراتيجية**. يتجاوز كل منفذ الأساليب الأساسية حسب الحاجة.```mermaid
Executors encapsulate **provider-specific logic** using the **Strategy Pattern**. Each executor overrides base methods as needed.
```mermaid
classDiagram
class BaseExecutor {
+buildUrl(model, stream, options)
@@ -175,35 +194,42 @@ classDiagram
BaseExecutor <|-- CodexExecutor
BaseExecutor <|-- GeminiCLIExecutor
BaseExecutor <|-- GithubExecutor
````
```
| المنفذ | مقدم | التخصص الرئيسي |
| -------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| `base.ts` | — | قاعدة الملخصات: إنشاء عنوان URL، والرؤوس، ومنطقة إعادة المحاولة، وتحديث بيانات الاعتماد |
| `default.ts` | كلود، جيميني، أوبن آي آي، جي إل إم، كيمي، ميني ماكس | تحديث رمز OAuth العام للموفرين الكلاسيكيين |
| `مكافحة الجاذبية.ts` | جوجل كلود كود | إنشاء معرف المشروع/الجلسة، وإرجاع عناوين URL الإعلامية، بعد محاولة تحديد موقع رسائل الخطأ ("إعادة بعد 2 ساعة و7 دقائق و23 ثانية") |
| `cursor.ts` | منطقة تطوير متعددة للمؤشر | **الأكثر مخاطرًا**: مصادقة التسجيل الاختباري SHA-256، وترميز طلب Protobuf، وEventStream ثنائي → تحليل اتصال SSE |
| `codex.ts` | OpenAI Codex | حجم تعليمات النظام، وإدارة مستويات التفكير، تجديد المعلمات غير المدعومة |
| `الجوزاء-cli.ts` | جوجل الجوزاء CLI | إنشاء عنوان URL مخصص (`streamGenerateContent`)، وتحديث رمز OAuth المميز لـ Google |
| `جيثب.ts` | جيثب مساعد الطيار | نظام رمزي ثنائي (GitHub OAuth + Copilot token)، محاكاة رأس VSCode |
| `kiro.ts` | AWS CodeWhisperer | التحليل الثنائي لـ AWS EventStream، وإطارات أحداث AMZN، والتقدير المميز |
| `index.ts` | — | المصنع: اسم موفر ← فئة المنفذ، مع خيار بديل افتراضي | ---### 4.3 Handlers (`open-sse/handlers/`) |
| Executor | Provider | Key Specializations |
| ---------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `base.ts` | — | Abstract base: URL building, headers, retry logic, credential refresh |
| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Generic OAuth token refresh for standard providers |
| `antigravity.ts` | Google Cloud Code | Project/session ID generation, multi-URL fallback, custom retry parsing from error messages ("reset after 2h7m23s") |
| `cursor.ts` | Cursor IDE | **Most complex**: SHA-256 checksum auth, Protobuf request encoding, binary EventStream → SSE response parsing |
| `codex.ts` | OpenAI Codex | Injects system instructions, manages thinking levels, removes unsupported parameters |
| `gemini-cli.ts` | Google Gemini CLI | Custom URL building (`streamGenerateContent`), Google OAuth token refresh |
| `github.ts` | GitHub Copilot | Dual token system (GitHub OAuth + Copilot token), VSCode header mimicking |
| `kiro.ts` | AWS CodeWhisperer | AWS EventStream binary parsing, AMZN event frames, token estimation |
| `index.ts` | — | Factory: maps provider name → executor class, with default fallback |
**طبقة تأتي**— تترتب على الترجمة والتنفيذ والتدفق ويسبب سبب.
---
| ملف | الحصاد |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| `chatCore.ts` | **المنسق المركزي**(~ 600 سطر). لاحظ مع دورة حياة الطلب الكامل: اكتشاف ← الترجمة ← رحلة مميزة ← عزيزي القارئ/غير المتدفق ← تحديث ← أسباب ← تسجيل الاستخدام. |
| `responsesHandler.ts` | محول برمجة تطبيقات الخاصة بـ OpenAI: تحويل تنسيق الردود ← إرسال ملفات الدردشة ← إرسال إلى `chatCore` ← تحويل SSE مرة أخرى إلى تنسيق الردود. |
| `embeddings.ts` | محرك إنشاء التضمين: يحل نموذج التضمين → الموفر، ويرسل إلى واجهة برمجة تطبيقات الموفر، ويعيد الاتصال بالتضمين المتوافق مع OpenAI. يدعم 6+ مقدمي الخدمات. |
| `imageGeneration.ts` | معالج إنشاء الصور: يحل نموذج الصورة → الموفر، ويدعم الأوضاع المتوافقة مع OpenAI، وGemini-image (Antigravity)، والوضع الاحتياطي (Nebius). إرجاع صور base64 أو URL. | #### دورة حياة الطلب (chatCore.ts)```mermaid |
### 4.3 Handlers (`open-sse/handlers/`)
The **orchestration layer** — coordinates translation, execution, streaming, and error handling.
| File | Purpose |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chatCore.ts` | **Central orchestrator** (~600 lines). Handles the complete request lifecycle: format detection → translation → executor dispatch → streaming/non-streaming response → token refresh → error handling → usage logging. |
| `responsesHandler.ts` | Adapter for OpenAI's Responses API: converts Responses format → Chat Completions → sends to `chatCore` → converts SSE back to Responses format. |
| `embeddings.ts` | Embedding generation handler: resolves embedding model → provider, dispatches to provider API, returns OpenAI-compatible embedding response. Supports 6+ providers. |
| `imageGeneration.ts` | Image generation handler: resolves image model → provider, supports OpenAI-compatible, Gemini-image (Antigravity), and fallback (Nebius) modes. Returns base64 or URL images. |
#### Request Lifecycle (chatCore.ts)
```mermaid
sequenceDiagram
participant Client
participant chatCore
participant Translator
participant Executor
participant Provider
participant Client
participant chatCore
participant Translator
participant Executor
participant Provider
Client->>chatCore: Request (any format)
chatCore->>chatCore: Detect source format
@@ -230,14 +256,15 @@ participant Provider
chatCore->>Executor: Retry with credential refresh
chatCore->>chatCore: Account fallback logic
end
````
```
---
### 4.4 Services (`open-sse/services/`)
منطق الأعمال الذي يدعم المعالجات والمنفذين.| File | Purpose |
Business logic that supports the handlers and executors.
| File | Purpose |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `provider.ts` | **Format detection** (`detectFormat`): analyzes request body structure to identify Claude/OpenAI/Gemini/Antigravity/Responses formats (includes `max_tokens` heuristic for Claude). Also: URL building, header building, thinking config normalization. Supports `openai-compatible-*` and `anthropic-compatible-*` dynamic providers. |
| `model.ts` | Model string parsing (`claude/model-name``{provider: "claude", model: "model-name"}`), alias resolution with collision detection, input sanitization (rejects path traversal/control chars), and model info resolution with async alias getter support. |
@@ -273,7 +300,7 @@ sequenceDiagram
Cache-->>R1: New access token
Cache-->>R2: Same access token (shared)
Cache->>Cache: Delete cache entry
````
```
#### Account Fallback State Machine
@@ -321,18 +348,22 @@ flowchart LR
### 4.5 Translator (`open-sse/translator/`)
**محرك استعداد**باستخدام نظام التوقيع الذاتي.#### الكائنات```mermaid
The **format translation engine** using a self-registering plugin system.
#### الهندسة
```mermaid
graph TD
subgraph "Request Translation"
A["Claude → OpenAI"]
B["Gemini → OpenAI"]
C["Antigravity → OpenAI"]
D["OpenAI Responses → OpenAI"]
E["OpenAI → Claude"]
F["OpenAI → Gemini"]
G["OpenAI → Kiro"]
H["OpenAI → Cursor"]
end
subgraph "Request Translation"
A["Claude → OpenAI"]
B["Gemini → OpenAI"]
C["Antigravity → OpenAI"]
D["OpenAI Responses → OpenAI"]
E["OpenAI → Claude"]
F["OpenAI → Gemini"]
G["OpenAI → Kiro"]
H["OpenAI → Cursor"]
end
subgraph "Response Translation"
I["Claude → OpenAI"]
@@ -343,149 +374,182 @@ end
N["OpenAI → Antigravity"]
O["OpenAI → Responses"]
end
```
````
| Directory | Files | Description |
| ------------ | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `request/` | 8 translators | Convert request bodies between formats. Each file self-registers via `register(from, to, fn)` on import. |
| `response/` | 7 translators | Convert streaming response chunks between formats. Handles SSE event types, thinking blocks, tool calls. |
| `helpers/` | 6 helpers | Shared utilities: `claudeHelper` (system prompt extraction, thinking config), `geminiHelper` (parts/contents mapping), `openaiHelper` (format filtering), `toolCallHelper` (ID generation, missing response injection), `maxTokensHelper`, `responsesApiHelper`. |
| `index.ts` | — | Translation engine: `translateRequest()`, `translateResponse()`, state management, registry. |
| `formats.ts` | — | Format constants: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. |
| الدليل | ملفات | الوصف |
| ------------ | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `طلب/` | 8 مترجمين | تحويل أجسام بين الصيغ. يتم تسجيل كل ملف ذاتيًا عبر "التسجيل (من، إلى، fn)" عند الاستيراد. |
| `الاستجابة/` | 7 مترجمين | تحويل قطع المضخّم بين الصيغة. للتعرف على أنواع أحداث SSE وكتل التفكير وأدوات الأدوات. |
| `المساعدين/` | 6 مساعدين | الأداة المساعدة المشتركة: `cludeHelper` (استخراج النظام، البحث المطلوب البحث)، `geminiHelper` (تخطيط الأجزاء/المحتويات)، `openaiHelper` (خيار مناسب)، `toolCallHelper` (إنشاء المعرف، البحث المطلوب المطلوبة)، `maxTokensHelper`، `responsesApiHelper`. |
| `index.ts` | — | ترجمة المحرك: `translateRequest()`، `translateResponse()`، إدارة الحالة، التسجيل. |
| `formats.ts` | — | ثوابت عادة: `OPENAI`، `CLAUDE`، `GEMINI`، `ANTIGRAVITY`، `KIRO`، `CURSOR`، `OPENAI_RESPONSES`. |#### التصميم الرئيسي: المكونات الإضافية ذاتية التسجيل```javascript
#### Key Design: Self-Registering Plugins
```javascript
// Each translator file calls register() on import:
import { register } from "../index.js";
register("claude", "openai", translateClaudeToOpenAI);
// The index.js imports all translator files, triggering registration:
import "./request/claude-to-openai.js"; // ← self-registers
````
```
---
### 4.6 Utils (`open-sse/utils/`)
| ملف | الحصاد |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------- |
| "خطأ.ts" | إنشاء كلمات للأخطاء (تنسيق متوافق مع OpenAI)، وسبب المشكلة، واستخراجها، وحاول إعادة محاولة Antigravity من رسائل الخطأ، وأخطاء SSE. |
| "stream.ts" | **SSE Transform Stream**— خط أنابيب البث الأساسي. وضعان: "الترجمة" (ترجمة كاملة) و"العبور" (التطبيع + الطلب المستخدم). وأخذ بعين الاعتبار التخزين المؤقت للقطعة وتقدير استخدامها وتتبع طول الفيديو. تجنب مثيلات وحدة التشفير/وحدة فك التشفير لكل حالة DC المشتركة. |
| `streamHelpers.ts` | SSE ذات المستوى المنخفض: `parseSSELine` (متسامح مع المسافات البيضاء)، `hasValuableContent` ( تصفية أدوات الفارغة لـ OpenAI/Claude/Gemini)، `fixInvalidId`formatSSE` (تسلسل SSE مدرك للتنسيق مع `perf_metrics`). |
| `usageTracking.ts` | استخدام النسخة المميزة من أي تنسيق (Claude/OpenAI/Gemini/Responses)، والاستعانة بـ DNS لكل رمز مميز للأداة/الرسالة، والمخزن المؤقت (هامش أمان 2000 رمز مميز)، وتصفية الخاصيات بالتنسيق، وتسجيل وحدة التحكم مع ANSI. |
| `requestLogger.ts` | Legacy file-based request logging helper kept for compatibility. Current deployments should prefer `APP_LOG_TO_FILE` for application logs and the call log pipeline for persisted request artifacts. |
| `bypassHandler.ts` | ويمثل خيارًا محددًا لـ Claude CLI (عنوان الإنتاج، والحماية، والعد) ويعيد ميزة دون الاتصال بأي مكان. يدعم كل من الدف وغير الدف. لذلك عمدا على نطاق كلود CLI. |
| `networkProxy.ts` | يحل عنوان URL للوكلاء لموفر معين مع الأسبقية: تفعيل الخاص بالموفر → تفعيل العام → متغيرات البيئة (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). يدعم استثناءات `NO_PROXY`. اختيارية ذاكرة تخزين مؤقتة لمدة 30 ثانية. | #### خط أنابيب تدفق SSE```mermaid |
| File | Purpose |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `error.ts` | Error response building (OpenAI-compatible format), upstream error parsing, Antigravity retry-time extraction from error messages, SSE error streaming. |
| `stream.ts` | **SSE Transform Stream** — the core streaming pipeline. Two modes: `TRANSLATE` (full format translation) and `PASSTHROUGH` (normalize + extract usage). Handles chunk buffering, usage estimation, content length tracking. Per-stream encoder/decoder instances avoid shared state. |
| `streamHelpers.ts` | Low-level SSE utilities: `parseSSELine` (whitespace-tolerant), `hasValuableContent` (filters empty chunks for OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (format-aware SSE serialization with `perf_metrics` cleanup). |
| `usageTracking.ts` | Token usage extraction from any format (Claude/OpenAI/Gemini/Responses), estimation with separate tool/message char-per-token ratios, buffer addition (2000 tokens safety margin), format-specific field filtering, console logging with ANSI colors. |
| `requestLogger.ts` | Legacy file-based request logging helper kept for compatibility. Current deployments should prefer `APP_LOG_TO_FILE` for application logs and the call log pipeline for persisted request artifacts. |
| `bypassHandler.ts` | Intercepts specific patterns from Claude CLI (title extraction, warmup, count) and returns fake responses without calling any provider. Supports both streaming and non-streaming. Intentionally limited to Claude CLI scope. |
| `networkProxy.ts` | Resolves outbound proxy URL for a given provider with precedence: provider-specific config → global config → environment variables (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Supports `NO_PROXY` exclusions. Caches config for 30s. |
#### SSE Streaming Pipeline
```mermaid
flowchart TD
A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"]
B --> C["Buffer lines\n(split on newline)"]
C --> D["parseSSELine()\n(trim whitespace, parse JSON)"]
D --> E{"Mode?"}
E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"]
E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"]
F --> H["hasValuableContent()\nfilter empty chunks"]
G --> H
H -->|"Has content"| I["extractUsage()\ntrack token counts"]
H -->|"Empty"| J["Skip chunk"]
I --> K["formatSSE()\nserialize + clean perf_metrics"]
K --> L["TextEncoder\n(per-stream instance)"]
L --> M["Enqueue to\nclient stream"]
A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"]
B --> C["Buffer lines\n(split on newline)"]
C --> D["parseSSELine()\n(trim whitespace, parse JSON)"]
D --> E{"Mode?"}
E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"]
E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"]
F --> H["hasValuableContent()\nfilter empty chunks"]
G --> H
H -->|"Has content"| I["extractUsage()\ntrack token counts"]
H -->|"Empty"| J["Skip chunk"]
I --> K["formatSSE()\nserialize + clean perf_metrics"]
K --> L["TextEncoder\n(per-stream instance)"]
L --> M["Enqueue to\nclient stream"]
style A fill:#f9f,stroke:#333
style M fill:#9f9,stroke:#333
```
#### Request Logger Session Structure
```
logs/
└── claude_gemini_claude-sonnet_20260208_143045/
├── 1_req_client.json ← Raw client request
├── 2_req_source.json ← After initial conversion
├── 3_req_openai.json ← OpenAI intermediate format
├── 4_req_target.json ← Final target format
├── 5_res_provider.txt ← Provider SSE chunks (streaming)
├── 5_res_provider.json ← Provider response (non-streaming)
├── 6_res_openai.txt ← OpenAI intermediate chunks
├── 7_res_client.txt ← Client-facing SSE chunks
└── 6_error.json ← Error details (if any)
````
├── 1_req_client.json ← Raw client request
├── 2_req_source.json ← After initial conversion
├── 3_req_openai.json ← OpenAI intermediate format
├── 4_req_target.json ← Final target format
├── 5_res_provider.txt ← Provider SSE chunks (streaming)
├── 5_res_provider.json ← Provider response (non-streaming)
├── 6_res_openai.txt ← OpenAI intermediate chunks
├── 7_res_client.txt ← Client-facing SSE chunks
└── 6_error.json ← Error details (if any)
```
---
### 4.7 Application Layer (`src/`)
| الدليل | الحصاد |
| Directory | Purpose |
| ------------- | ---------------------------------------------------------------------- |
| `src/app/` | واجهة مستخدم الويب، مسارات واجهة برمجة التطبيقات (API)، البرامج الأساسية السريعة، معالجات رد اتصال OAuth |
| `src/lib/` | إلى قاعدة الوصول إلى البيانات (`localDb.ts`usageDb.ts`)، المصادقة، البرمجة |
| `src/mitm/` | أداة مساعدة للوسيط لاعتراض حركة المرور |
| `src/models/` | تعريفات قواعد البيانات |
| `src/shared/` | أغلفة حول وظائف open-sse (المزود، الدفق، الخطأ، إلخ) |
| `src/sse/` | معالجات نقطة نهاية SSE التي تتوفر في مكتبة open-sse بمسارات Express |
| `src/store/` | إدارة التطبيق |#### مسارات API البارزة
| `src/app/` | Web UI, API routes, Express middleware, OAuth callback handlers |
| `src/lib/` | Database access (`localDb.ts`, `usageDb.ts`), authentication, shared |
| `src/mitm/` | Man-in-the-middle proxy utilities for intercepting provider traffic |
| `src/models/` | Database model definitions |
| `src/shared/` | Wrappers around open-sse functions (provider, stream, error, etc.) |
| `src/sse/` | SSE endpoint handlers that wire the open-sse library to Express routes |
| `src/store/` | Application state management |
| الطريق | طرق | الحصاد |
#### Notable API Routes
| Route | Methods | Purpose |
| --------------------------------------------- | --------------- | ------------------------------------------------------------------------------------- |
| `/api/provider-models` | الحصول على/نشر/حذف | CRUD للنماذج المتخصصة لكل |
| `/api/models/catalog` | احصل على | مجمع كتالوج لجميع الارتباطات (الدردشة، التضمين، الصورة، تخصيص) مجمعة حسب الموفر |
| `/api/settings/proxy` | الحصول على/وضع/حذف | الجاهزة التفصيلي (`العالمي/الموفرون/المجموعات/المفاتيح`) |
| `/api/settings/proxy/test` | مشاركة | التحقق من صحة الاتصال الوكيل وإرجاع IP/زمن الوصول العام |
| `/v1/providers/[provider]/chat/completions` | مشاركة | عمليات البحث عن الاختيار المناسب لكل شخص مع التحقق من صحة النموذج |
| `/v1/providers/[provider]/embeddings` | مشاركة | عمليات تضمين التخصص حسب الاختيار مع نموذج التحقق من الصحة |
| `/v1/providers/[provider]/images/ Generations` | مشاركة | إنشاء صور مخصصة لكل وثيقة معتمدة من نموذج صحة |
| `/api/settings/ip-filter` | الحصول على/وضع | قائمة IP الخاصة بها/إدارة القائمة المحظورة |
| `/api/settings/thinking-budget` | الحصول على/وضع | المحددة المحددة الرمز (العبور/التلقائي/المخصص/التكيفي) |
| `/api/settings/system-prompt` | الحصول على/وضع | القطع المؤقتة لأدوات البناء العالمية |
| `/api/sessions` | احصل على | تحديد العضوية ومعاييرها |
| `/api/rate-limits` | احصل على | الحالة لا يمكن تعديلها لكل حساب |---## 5. Key Design Patterns
| `/api/provider-models` | GET/POST/DELETE | CRUD for custom models per provider |
| `/api/models/catalog` | GET | Aggregated catalog of all models (chat, embedding, image, custom) grouped by provider |
| `/api/settings/proxy` | GET/PUT/DELETE | Hierarchical outbound proxy configuration (`global/providers/combos/keys`) |
| `/api/settings/proxy/test` | POST | Validates proxy connectivity and returns public IP/latency |
| `/v1/providers/[provider]/chat/completions` | POST | Dedicated per-provider chat completions with model validation |
| `/v1/providers/[provider]/embeddings` | POST | Dedicated per-provider embeddings with model validation |
| `/v1/providers/[provider]/images/generations` | POST | Dedicated per-provider image generation with model validation |
| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist management |
| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget configuration (passthrough/auto/custom/adaptive) |
| `/api/settings/system-prompt` | GET/PUT | Global system prompt injection for all requests |
| `/api/sessions` | GET | Active session tracking and metrics |
| `/api/rate-limits` | GET | Per-account rate limit status |
---
## 5. Key Design Patterns
### 5.1 Hub-and-Spoke Translation
تتم ترجمة جميع الاحتمالات من خلال**تنسيق OpenAI كمحور**. لا تتطلب إضافة موفر جديد سوى كتابة**زوج واحد**من المترجمين (من/ إلى OpenAI)، وليس عدد N من المترجمين.### 5.2 Executor Strategy Pattern
All formats translate through **OpenAI format as the hub**. Adding a new provider only requires writing **one pair** of translators (to/from OpenAI), not N pairs.
كل ما لديها فئة تنفيذية مخصصة ترث من "BaseExecutor". تم تصنيع المصنع الموجود في "executors/index.ts" وبالتالي أصبح المصنع جاهزًا في وقت التشغيل.### 5.3 نظام البرنامج الإضافي للتسجيل الذاتي
### 5.2 Executor Strategy Pattern
وحدات المترجمة نفسها عند الاستيراد عبر ``تسجيل ()'. إن إضافة مترجم جديد يعني مجرد إنشاء ملف واستيراده.### 5.4 Account Fallback with Exponential Backoff
Each provider has a dedicated executor class inheriting from `BaseExecutor`. The factory in `executors/index.ts` selects the right one at runtime.
عندما يقوم بتقديم خدمة بإرجاع 429/401/500، يمكن أن يتكامل مع الحساب التالي، مع تطبيق أحدث الحداثات الأسية (1ث → 2ث → 4ث → 2 دقيقة الضرر التام).### 5.5 Combo Model Chains
### 5.3 Self-Registering Plugin System
يقوم "التحرير والسرد" بتجميع سلاسل "المزود/النموذج" حاسوبياً. في حالة الفشل الأول، يتم الرجوع إلى المنتج الأصلي.### 5.6 الترجمة المتدفقة ذات الحالة
Translator modules register themselves on import via `register()`. Adding a new translator is just creating a file and importing it.
الحفاظ على ترجمة الأجزاء ذات الحالة عبر SSE (تتبع كتلة التفكير، وتراكم الاتصال بالجهة، وفهرسة كتلة المحتوى) عبر تقنية `initState()`.### 5.7 المخزن المؤقت لسلامة الاستخدام
### 5.4 Account Fallback with Exponential Backoff
تم إضافة مخزن مؤقت مكون من 2000 رمز مميز إلى الحد الأقصى من الاستخدام لمساعدة العملاء على الوصول إلى حدود النافذة بسبب الحمل الزائد من مطالبات النظام وترجمة السائقين.---## 6. Supported Formats
When a provider returns 429/401/500, the system can switch to the next account, applying exponential cooldowns (1s → 2s → 4s → max 2min).
| التنسيق | | المعرف |
### 5.5 Combo Model Chains
A "combo" groups multiple `provider/model` strings. If the first fails, fallback to the next automatically.
### 5.6 Stateful Streaming Translation
Response translation maintains state across SSE chunks (thinking block tracking, tool call accumulation, content block indexing) via the `initState()` mechanism.
### 5.7 Usage Safety Buffer
A 2000-token buffer is added to reported usage to prevent clients from hitting context window limits due to overhead from system prompts and format translation.
---
## 6. Supported Formats
| Format | Direction | Identifier |
| ----------------------- | --------------- | ------------------ |
| استكمالات الدردشة OpenAI | المصدر + الهدف | `أوبيني` |
| برمجة تطبيقات استجابات OpenAI | المصدر + الهدف | `الردود المفتوحة` |
| أنثروب كلود | المصدر + الهدف | "كلود" |
| جوجل الجوزاء | المصدر + الهدف | `الجوزاء` |
| جوجل الجوزاء CLI | الهدف فقط | `الجوزاء-كلي` |
| مكافحة الجاذبية | المصدر + الهدف | `مضادة الجاذبية` |
| أوس كيرو | الهدف فقط | `كيرو` |
| |مؤثر الهدف فقط | `المؤشر` |---## 7. Supported Providers
| OpenAI Chat Completions | source + target | `openai` |
| OpenAI Responses API | source + target | `openai-responses` |
| Anthropic Claude | source + target | `claude` |
| Google Gemini | source + target | `gemini` |
| Google Gemini CLI | target only | `gemini-cli` |
| Antigravity | source + target | `antigravity` |
| AWS Kiro | target only | `kiro` |
| Cursor | target only | `cursor` |
| مقدم | طريقة المصادقة | المنفذ | المذكرة الرئيسية |
---
## 7. Supported Providers
| Provider | Auth Method | Executor | Key Notes |
| ------------------------ | ---------------------- | ----------- | --------------------------------------------- |
| أنثروب كلود | واجهة برمجة التطبيقات الرئيسية أو OAuth | افتراضي | يستخدم رأس `x-api-key` |
| جوجل الجوزاء | واجهة برمجة التطبيقات الرئيسية أو OAuth | افتراضي | يستخدم رأس `x-goog-api-key` |
| جوجل الجوزاء CLI | أووث | الجوزاء كلي | يستخدم نقطة نهاية "streamGenerateContent" |
| مكافحة الجاذبية | أووث | مكافحة الجاذبية | شراء عناوين URL الخاصة بها، إعادة محاولة البحث عن المواقع |
| أوبن آي | واجهة برمجة التطبيقات الرئيسية | افتراضي | مصادقة الحامل |
| الدستور الغذائي | أووث | الدستور الغذائي | يدخل تعليمات النظام ويدير التفكير |
| جيثب مساعد الطيار | OAuth + رمز مساعد الطيار | جيثب | رمز مزدوج، محاكاة رأس VSCode |
| كيرو (AWS) | AWS SSO OIDC أو اجتماعي | كيرو | تحليل دفق الأحداث الثنائية |
| بيئة تطوير متكاملة للمؤشر | تصويت الاختياري | |مؤثر ترميز Protobuf، الجلسات الاختباري SHA-256 |
| كوين | أووث | افتراضي | المصادقة القياسية |
| قدير | OAuth (أساسي + حامل) | افتراضي | رأس المصادقة |
| اوبن راوتر | واجهة برمجة التطبيقات الرئيسية | افتراضي | مصادقة الحامل |
| جي إل إم، كيمي، ميني ماكس | واجهة برمجة التطبيقات الرئيسية | افتراضي | متوافق مع كلود، استخدم `x-api-key` |
| `متوافق مع openai-*` | واجهة برمجة التطبيقات الرئيسية | افتراضي | برمجة: أي نقطة نهاية متوافقة مع OpenAI |
| `متوافق مع البشر-*` | واجهة برمجة التطبيقات الرئيسية | افتراضي | برمجة: أي نقطة نهاية متوافقة مع كلود |---## 8. Data Flow Summary
| Anthropic Claude | API key or OAuth | Default | Uses `x-api-key` header |
| Google Gemini | API key or OAuth | Default | Uses `x-goog-api-key` header |
| Google Gemini CLI | OAuth | GeminiCLI | Uses `streamGenerateContent` endpoint |
| Antigravity | OAuth | Antigravity | Multi-URL fallback, custom retry parsing |
| OpenAI | API key | Default | Standard Bearer auth |
| Codex | OAuth | Codex | Injects system instructions, manages thinking |
| GitHub Copilot | OAuth + Copilot token | Github | Dual token, VSCode header mimicking |
| Kiro (AWS) | AWS SSO OIDC or Social | Kiro | Binary EventStream parsing |
| Cursor IDE | Checksum auth | Cursor | Protobuf encoding, SHA-256 checksums |
| Qwen | OAuth | Default | Standard auth |
| Qoder | OAuth (Basic + Bearer) | Default | Dual auth header |
| OpenRouter | API key | Default | Standard Bearer auth |
| GLM, Kimi, MiniMax | API key | Default | Claude-compatible, use `x-api-key` |
| `openai-compatible-*` | API key | Default | Dynamic: any OpenAI-compatible endpoint |
| `anthropic-compatible-*` | API key | Default | Dynamic: any Claude-compatible endpoint |
---
## 8. Data Flow Summary
### Streaming Request
@@ -502,7 +566,7 @@ flowchart LR
I --> J["formatSSE()"]
J --> K["Client receives\ntranslated SSE"]
K --> L["logUsage()\nsaveRequestUsage()"]
````
```
### Non-Streaming Request

View File

@@ -4,124 +4,155 @@
---
آخر تحديث: 2026-03-28##
Last updated: 2026-03-28
هناك تفاصيل تفصيلية متعددة حول كيفية حساب التقرير. للتخطيط، واحد منهم فقط مفيد.
## Baseline
| متري | النطاق | بقدر / سطور | فرع | الوظائف | تعليقات |
| ------------ | -------------------------------------- | ----------: | -----: | ------: | ----------------------------------------------- |
| تراث | اختبار تشغيل npm القديم: غلاف | 79.42% | 75.15% | 67.94% | مضخم: يحصي اختبارات الاختبار ويستبعد `open-sse` |
| التشخيص | المصدر فقط، التمييز و السبب `open-sse` | 68.16% | 63.55% | 64.06% | مفيد فقط لعزل `src/**` |
| خط الأساس له | المصدر فقط، لغرض القسم `open-sse` | 56.95% | 66.05% | 57.80% | هذا هو خط الأساس لتحسين المشروع |
There are multiple coverage numbers depending on how the report is computed. For planning, only one of them is useful.
خط الأساس به هو الرقم المطلوب وتحسينه.## Rules
| Metric | Scope | Statements / Lines | Branches | Functions | Notes |
| -------------------- | ----------------------------------------------------- | -----------------: | -------: | --------: | --------------------------------------------------- |
| Legacy | Old `npm run test:coverage` | 79.42% | 75.15% | 67.94% | Inflated: counts test files and excludes `open-sse` |
| Diagnostic | Source-only, excluding tests and excluding `open-sse` | 68.16% | 63.55% | 64.06% | Useful only to isolate `src/**` |
| Recommended baseline | Source-only, excluding tests and including `open-sse` | 56.95% | 66.05% | 57.80% | This is the project-wide baseline to improve |
- تستهدف تحديد الملفات المصدر، وليس على "الاختبارات/\*\*".
- `open-sse/**` هو جزء من المنتج ويجب أن يختفي في نطاقه.
- يجب ألا تحدد الكود الجديد من المناطق التي تم لمسها.
- تفضيل الاختبار ونتائج الجهة على تفاصيل التنفيذ.
- تفضيلات متطلبات بيانات SQLite المطر والتركيبات الصغيرة على الارتباطات المتخصصة لـ src/lib/db/\*\*`.## مجموعة الأوامر الحالية
The recommended baseline is the number to optimize against.
- `اختبار تشغيل npm: التغطية`
- بوابة المصدر الرئيسي لمجموعة اختبار الوحدة
- إنشاء ملخص النص، وhtml، وملخص json، ولكوف
- `تغطية تشغيل npm: تقرير`
- تقرير مفصل لملف الآخر من العملية الأخيرة
- `اختبار تشغيل npm:التغطية:تراث`
- لتحدث التاريخية فقط## المعالم
## Rules
| المرحلة | الهدف | التركيز |
| --------------- | ------------: | ------------------------------------------------- |
| المرحلة 1 | 60% لذلك/سطور | مكاسب سريعة وتغطية شاملة لمختلف الفئات |
| المرحلة الثانية | 65% لذلك/سطور | أسس قاعدة البيانات والطريق |
| المرحلة 3 | 70% لذلك/سطور | التحقق من صحة الموفر وتحليلات الاستخدام |
| الخطوة الرابعة | 75% لذلك/سطور | مترجمون ومساعدون `open-sse' |
| المرحلة الخامسة | 80% لذلك/سطور | رامات وروعة الزجاجة `open-sse` |
| المرحلة السادسة | 85% لذلك/سطور | الحالات القصوى، الديون الدينية، وأجنحة الانحدار |
| المرحلة السابعة | 90% لذلك/سطور | الاجتياح النهائي، الإغلاق الشامل، السقاطة الساكنة |
- Coverage targets apply to source files, not to `tests/**`.
- `open-sse/**` is part of the product and must remain in scope.
- New code should not reduce coverage in touched areas.
- Prefer testing behavior and branch outcomes over implementation details.
- Prefer temp SQLite databases and small fixtures over broad mocks for `src/lib/db/**`.
يجب أن ترتكز الجذور والوظائف مع كل مرحلة، ولكن الهدف الأساسي الثابت هو البيانات/السطور.## النقاط الساخنة ذات الأولوية
## Current command set
توفر هذه الملفات أو المناطق أفضل عائد للمراحل التالية:1. "فتح sse/معالجات".
- `npm run test:coverage`
- Main source coverage gate for the unit test suite
- Generates `text-summary`, `html`, `json-summary`, and `lcov`
- `npm run coverage:report`
- Detailed file-by-file report from the latest run
- `npm run test:coverage:legacy`
- Historical comparison only
- `chatCore.ts` بنسبة 7.57%
- الدليل الشامل بنسبة 29.07% 2.`open-sse/translator/request`
- الرد المرسل إليه 36.39%
- لا يزال العديد من المترجمين على مقربة من تغطية ما يكفي من رقم واحد
## Milestones
3. "open-sse/translator/response".
- الرد المرسل إليه 8.07%
4. "open-sse/المنفذين".
- البريد المرسل إليه 36.62% 5.`src/lib/db`
- `models.ts` بنسبة 20.66%
- "المفاتيح الجديدة" بنسبة 34.46%
- `modelComboMappings.ts` بنسبة 36.25%
- `settings.ts` عند 46.40%
- `webhooks.ts' بنسبة 33.33%
6.`src/lib/usage`
- `usageHistory.ts` بنسبة 21.12%
- `usageStats.ts` بنسبة 9.56%
- `costCalculator.ts` بنسبة 30.00% 7.`src/lib/providers`
- `validation.ts` بنسبة 41.16%
5. ملفات المساعدة وواجهة برمجة التطبيقات (API) ذات القدرة الضعيفة على فقدان القليل
| Phase | Target | Focus |
| ------- | ---------------------: | ------------------------------------------------- |
| Phase 1 | 60% statements / lines | Quick wins and low-risk utility coverage |
| Phase 2 | 65% statements / lines | DB and route foundations |
| Phase 3 | 70% statements / lines | Provider validation and usage analytics |
| Phase 4 | 75% statements / lines | `open-sse` translators and helpers |
| Phase 5 | 80% statements / lines | `open-sse` handlers and executor branches |
| Phase 6 | 85% statements / lines | Harder edge cases, branch debt, regression suites |
| Phase 7 | 90% statements / lines | Final sweep, gap closure, strict ratchet |
Branches and functions should ratchet upward with each phase, but the primary hard target is statements / lines.
## Priority hotspots
These files or areas offer the best return for the next phases:
1. `open-sse/handlers`
- `chatCore.ts` at 7.57%
- Overall directory at 29.07%
2. `open-sse/translator/request`
- Overall directory at 36.39%
- Many translators are still near single-digit coverage
3. `open-sse/translator/response`
- Overall directory at 8.07%
4. `open-sse/executors`
- Overall directory at 36.62%
5. `src/lib/db`
- `models.ts` at 20.66%
- `registeredKeys.ts` at 34.46%
- `modelComboMappings.ts` at 36.25%
- `settings.ts` at 46.40%
- `webhooks.ts` at 33.33%
6. `src/lib/usage`
- `usageHistory.ts` at 21.12%
- `usageStats.ts` at 9.56%
- `costCalculator.ts` at 30.00%
7. `src/lib/providers`
- `validation.ts` at 41.16%
8. Low-risk utility and API files for early gains
- `src/shared/utils/upstreamError.ts`
- `src/shared/utils/apiAuth.ts`
- `src/lib/api/errorResponse.ts`
- `src/app/api/settings/require-login/route.ts`
- `src/app/api/providers/[id]/models/route.ts`## قائمة التحقق من التنفيذ### Phase 1: 56.95% -> 60%
- `src/app/api/providers/[id]/models/route.ts`
- [x] مقياس التغطية بحيث يعكس اللون الأفضل من ملفات الاختبار
- [x] تستخدم بنص التغطية القديم للمقارنة
- [x] قام بعدم وجود خط الأساس ونقاط الاتصال في الريبو
- [ ] إضافة السيولة المركزية للمرافق المتعددة:
## Execution checklist
### Phase 1: 56.95% -> 60%
- [x] Fix coverage metric so it reflects source code instead of test files
- [x] Keep a legacy coverage script for comparison
- [x] Record the baseline and hotspots in-repo
- [ ] Add focused tests for low-risk utilities:
- `src/shared/utils/upstreamError.ts`
- `src/shared/utils/fetchTimeout.ts`
- `src/lib/api/errorResponse.ts`
- `src/shared/utils/apiAuth.ts`
- `src/lib/display/names.ts`
- [ ] إضافة السيولة لـ:
- [ ] Add route tests for:
- `src/app/api/settings/require-login/route.ts`
- `src/app/api/providers/[id]/models/route.ts`### المرحلة الثانية: 60% -> 65%
- `src/app/api/providers/[id]/models/route.ts`
- [ ] إضافة السيولة المدعومة بقاعدة البيانات لـ:
### Phase 2: 60% -> 65%
- [ ] Add DB-backed tests for:
- `src/lib/db/modelComboMappings.ts`
- `src/lib/db/settings.ts`
- `src/lib/db/registeredKeys.ts`
- [ ] اشتباكات الفرع في:
- [ ] Cover branch behavior in:
- `src/lib/providers/validation.ts`
- `src/app/api/v1/embeddings/route.ts`
- `src/app/api/v1/moderations/route.ts`### المرحلة الثالثة: 65% -> 70%
- `src/app/api/v1/moderations/route.ts`
- [ ] إضافة السيولة تحليلات الاستخدام لـ:
### Phase 3: 65% -> 70%
- [ ] Add usage analytics tests for:
- `src/lib/usage/usageHistory.ts`
- `src/lib/usage/usageStats.ts`
- `src/lib/usage/costCalculator.ts`
- [ ] التغطية المكثفة للمحتوى الإبداعي متنوع ### المرحلة 4: 70% -> 75%
- [ ] Expand route coverage for proxy management and settings branches
- [ ] تغطية مساعدي المترجم ومسارات الترجمة المركزية:
### Phase 4: 70% -> 75%
- [ ] Cover translator helpers and central translation paths:
- `open-sse/translator/index.ts`
- `open-sse/translator/helpers/*`
- `open-sse/translator/request/*`
- `open-sse/translator/response/*`### المرحلة الخامسة: 75% -> 80%
- `open-sse/translator/response/*`
- [ ] إضافة السيولة على مستوى رام لـ:
### Phase 5: 75% -> 80%
- [ ] Add handler-level tests for:
- `open-sse/handlers/chatCore.ts`
- `open-sse/handlers/responsesHandler.js`
- `open-sse/handlers/imageGeneration.js`
- `open-sse/handlers/embeddings.js`
- [ ] إضافة المنفذ الفرعي للمصادقة الخاصة بالموفر، لتقديم المحاولة، وتجاوزات نقطة النهاية### المرحلة 6: 80% -> 85%
- [ ] Add executor branch coverage for provider-specific auth, retries, and endpoint overrides
- [ ] دمج المزيد من مجموعات الأحداث المتقدمة في مسار التغطية الرئيسية
- [ ] الزيادة الوظيفية للوحدات قاعدة البيانات ذات التغطية الضعيفة للمنشئ/المساعد
- [ ] إغلاق فجوات الفروع في "settings.ts"، و"registeredKeys.ts"، و"validation.ts"، ومساعدي المترجم### المرحلة السابعة: 85% -> 90%
### Phase 6: 80% -> 85%
- [ ] بعض القضايا ذات الميزانية المحدودة المتبقية على أدوات الحظر
- [ ] إضافة نسبة الانحدار لكل خطأ إنتاجي تم اكتشافه وإصلاحه أثناء الدفع إلى 90%
- [ ] رفع بوابة التغطية في CI فقط بعد أن يكون الخط المحلي الأساسي قائمًا لتشغيلتين متتاليتين على الأقل## Ratchet Policy
- [ ] Merge more edge-case suites into the main coverage path
- [ ] Increase function coverage for DB modules with weak constructor/helper coverage
- [ ] Close branch gaps in `settings.ts`, `registeredKeys.ts`, `validation.ts`, and translator helpers
قم بالتأكيد بعتبات تشغيل npm: التغطية فقط بعد التجاوز الفعلي فعليًا، المرحلة الرئيسية التالية في مخزن الراحة.
### Phase 7: 85% -> 90%
سلسلة السقاطة لسبب:
- [ ] Treat the remaining low-coverage files as blockers
- [ ] Add regression tests for every uncovered production bug fixed during the push to 90%
- [ ] Raise the coverage gate in CI only after the local baseline is stable for at least two consecutive runs
## Ratchet policy
Update `npm run test:coverage` thresholds only after the project actually exceeds the next milestone with a comfortable buffer.
Recommended ratchet sequence:
1. 55/60/55
2. 60/62/58
@@ -132,6 +163,8 @@
7. 85/80/84
8. 90/85/88
الترتيب هو "أسطر البيانات / الفروع / الوظائف".## الثغرة المعروفة
Order is `statements-lines / branches / functions`.
يقيس أمر التغطية الحالية لمجموعة العقد الرئيسية بمشاركة المصدر الذي يتم الوصول إليه منه، بما في ذلك `open-sse`. لم أدمج بعد تغطية Vitest في التقرير الموحد الواحد. وقد تم إنجاز هذا لاحقًا، ولكن لا تزيد سرعة زيادة الذاكرة بنسبة 60% -> 80%.
## Known gap
The current coverage command measures the main Node unit suite and includes source reached from it, including `open-sse`. It does not yet merge Vitest coverage into a single unified report. That merge is worth doing later, but it is not a blocker for starting the 60% -> 80% climb.

View File

@@ -0,0 +1,669 @@
# Environment Variables Reference (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/ENVIRONMENT.md) · 🇪🇸 [es](../../es/docs/ENVIRONMENT.md) · 🇫🇷 [fr](../../fr/docs/ENVIRONMENT.md) · 🇩🇪 [de](../../de/docs/ENVIRONMENT.md) · 🇮🇹 [it](../../it/docs/ENVIRONMENT.md) · 🇷🇺 [ru](../../ru/docs/ENVIRONMENT.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/ENVIRONMENT.md) · 🇯🇵 [ja](../../ja/docs/ENVIRONMENT.md) · 🇰🇷 [ko](../../ko/docs/ENVIRONMENT.md) · 🇸🇦 [ar](../../ar/docs/ENVIRONMENT.md) · 🇮🇳 [hi](../../hi/docs/ENVIRONMENT.md) · 🇮🇳 [in](../../in/docs/ENVIRONMENT.md) · 🇹🇭 [th](../../th/docs/ENVIRONMENT.md) · 🇻🇳 [vi](../../vi/docs/ENVIRONMENT.md) · 🇮🇩 [id](../../id/docs/ENVIRONMENT.md) · 🇲🇾 [ms](../../ms/docs/ENVIRONMENT.md) · 🇳🇱 [nl](../../nl/docs/ENVIRONMENT.md) · 🇵🇱 [pl](../../pl/docs/ENVIRONMENT.md) · 🇸🇪 [sv](../../sv/docs/ENVIRONMENT.md) · 🇳🇴 [no](../../no/docs/ENVIRONMENT.md) · 🇩🇰 [da](../../da/docs/ENVIRONMENT.md) · 🇫🇮 [fi](../../fi/docs/ENVIRONMENT.md) · 🇵🇹 [pt](../../pt/docs/ENVIRONMENT.md) · 🇷🇴 [ro](../../ro/docs/ENVIRONMENT.md) · 🇭🇺 [hu](../../hu/docs/ENVIRONMENT.md) · 🇧🇬 [bg](../../bg/docs/ENVIRONMENT.md) · 🇸🇰 [sk](../../sk/docs/ENVIRONMENT.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/ENVIRONMENT.md) · 🇮🇱 [he](../../he/docs/ENVIRONMENT.md) · 🇵🇭 [phi](../../phi/docs/ENVIRONMENT.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/ENVIRONMENT.md) · 🇨🇿 [cs](../../cs/docs/ENVIRONMENT.md) · 🇹🇷 [tr](../../tr/docs/ENVIRONMENT.md)
---
> Complete reference for every environment variable recognized by OmniRoute.
> For a quick-start template, see [`.env.example`](../.env.example).
---
## Table of Contents
- [1. Required Secrets](#1-required-secrets)
- [2. Storage & Database](#2-storage--database)
- [3. Network & Ports](#3-network--ports)
- [4. Security & Authentication](#4-security--authentication)
- [5. Input Sanitization & PII Protection](#5-input-sanitization--pii-protection)
- [6. Tool & Routing Policies](#6-tool--routing-policies)
- [7. URLs & Cloud Sync](#7-urls--cloud-sync)
- [8. Outbound Proxy](#8-outbound-proxy)
- [9. CLI Tool Integration](#9-cli-tool-integration)
- [10. Internal Agent & MCP Integrations](#10-internal-agent--mcp-integrations)
- [11. OAuth Provider Credentials](#11-oauth-provider-credentials)
- [12. Provider User-Agent Overrides](#12-provider-user-agent-overrides)
- [13. CLI Fingerprint Compatibility](#13-cli-fingerprint-compatibility)
- [14. API Key Providers](#14-api-key-providers)
- [15. Timeout Settings](#15-timeout-settings)
- [16. Logging](#16-logging)
- [17. Memory Optimization](#17-memory-optimization)
- [18. Pricing Sync](#18-pricing-sync)
- [19. Model Sync (Dev)](#19-model-sync-dev)
- [20. Provider-Specific Settings](#20-provider-specific-settings)
- [21. Proxy Health](#21-proxy-health)
- [22. Debugging](#22-debugging)
- [23. GitHub Integration](#23-github-integration)
- [Deployment Scenarios](#deployment-scenarios)
- [Audit: Removed / Dead Variables](#audit-removed--dead-variables)
---
## 1. Required Secrets
These **must** be set before the first run. Without them, the application will either refuse to start or operate with insecure defaults.
| Variable | Required | Default | Source File | Description |
| ------------------ | -------- | -------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `JWT_SECRET` | **Yes** | _(none)_ | `src/lib/auth` | Signs/verifies all dashboard session cookies (JWT). Generate with `openssl rand -base64 48`. |
| `API_KEY_SECRET` | **Yes** | _(none)_ | `src/lib/db/apiKeys.ts` | AES encryption key for API key values at rest in SQLite. Generate with `openssl rand -hex 32`. |
| `INITIAL_PASSWORD` | **Yes** | `123456` | Bootstrap script | Sets the initial admin dashboard password. **Change before first use.** After login, change via Dashboard → Settings → Security. |
### Generation Commands
```bash
# Generate all three secrets at once:
echo "JWT_SECRET=$(openssl rand -base64 48)"
echo "API_KEY_SECRET=$(openssl rand -hex 32)"
echo "INITIAL_PASSWORD=$(openssl rand -base64 16)"
```
> [!CAUTION]
> Never commit `.env` files with real secrets to version control. The `.gitignore` already excludes `.env`, but verify before pushing.
---
## 2. Storage & Database
OmniRoute uses **SQLite** (via `better-sqlite3`) for all persistence. These variables control data location, encryption, and lifecycle.
| Variable | Default | Source File | Description |
| -------------------------------- | -------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `DATA_DIR` | `~/.omniroute/` | `src/lib/db/core.ts` | Root directory for SQLite DB, backups, and data files. Override for Docker volumes or custom paths. |
| `STORAGE_ENCRYPTION_KEY` | _(empty = disabled)_ | `src/lib/db/encryption.ts` | AES key for full SQLite database encryption at rest. Generate with `openssl rand -hex 32`. |
| `STORAGE_ENCRYPTION_KEY_VERSION` | `v1` | `scripts/bootstrap-env.mjs`, `electron/main.js` | Version label for the encryption key. Increment when performing key rotation to support decryption of old backups. |
| `DISABLE_SQLITE_AUTO_BACKUP` | `false` | `src/lib/db/backup.ts` | When `true`, skips the automatic database backup that runs before migrations on every startup. |
| `OMNIROUTE_CRYPT_KEY` | _(unset)_ | `src/lib/db/encryption.ts` | **Legacy alias** for `STORAGE_ENCRYPTION_KEY`. Accepted as a fallback when the primary variable is absent. |
| `OMNIROUTE_API_KEY_BASE64` | _(unset)_ | `src/lib/db/encryption.ts` | **Legacy alias** (Base64-encoded form) accepted as a fallback. Decoded automatically before use. |
### Scenarios
| Scenario | Configuration |
| --------------------- | -------------------------------------------------------------------------------- |
| **Local development** | Leave all defaults. DB lives at `~/.omniroute/omniroute.db`. |
| **Docker** | `DATA_DIR=/data` + mount a volume at `/data`. |
| **Encrypted at rest** | Set `STORAGE_ENCRYPTION_KEY` + keep backups of the key! Losing it = losing data. |
| **CI/Testing** | `DATA_DIR=/tmp/omniroute-test` — ephemeral, no encryption needed. |
---
## 3. Network & Ports
| Variable | Default | Source File | Description |
| --------------------- | ------------ | -------------------------- | -------------------------------------------------------------------------------------- |
| `PORT` | `20128` | `src/lib/runtime/ports.ts` | Primary port for both Dashboard UI and API endpoints (single-port mode). |
| `API_PORT` | _(unset)_ | `src/lib/runtime/ports.ts` | When set, serves the `/v1/*` proxy API on this separate port. |
| `API_HOST` | `0.0.0.0` | `src/lib/runtime/ports.ts` | Bind address for the API port. |
| `DASHBOARD_PORT` | _(unset)_ | `src/lib/runtime/ports.ts` | When set, serves the Dashboard UI on this separate port. |
| `PROD_DASHBOARD_PORT` | `20130` | `docker-compose.prod.yml` | Host-side published port for the Dashboard in Docker production mode. |
| `PROD_API_PORT` | `20131` | `docker-compose.prod.yml` | Host-side published port for the API in Docker production mode. |
| `OMNIROUTE_PORT` | _(unset)_ | `src/lib/runtime/ports.ts` | Takes precedence over `PORT` when running inside Electron or other wrappers. |
| `NODE_ENV` | `production` | Next.js core | Controls logging verbosity, caching, error detail exposure, and Next.js optimizations. |
### Port Modes
```
┌─────────────────────────── Single Port (default) ──────────────────────────┐
│ PORT=20128 │
│ → Dashboard: http://localhost:20128 │
│ → API: http://localhost:20128/v1/chat/completions │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────── Split Ports ─────────────────────────────────────┐
│ DASHBOARD_PORT=20128 │
│ API_PORT=20129 │
│ API_HOST=0.0.0.0 │
│ → Dashboard: http://localhost:20128 │
│ → API: http://0.0.0.0:20129/v1/chat/completions │
│ Use case: Expose API to LAN while restricting Dashboard to localhost. │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────── Docker Production ──────────────────────────────┐
│ PROD_DASHBOARD_PORT=443 PROD_API_PORT=8443 │
│ → Maps container ports to host ports in docker-compose.prod.yml. │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## 4. Security & Authentication
| Variable | Default | Source File | Description |
| ----------------------------- | --------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `MACHINE_ID_SALT` | `endpoint-proxy-salt` | `src/lib/auth` | Salt combined with hardware identifiers for machine fingerprinting. Change per-deployment for isolation. |
| `AUTH_COOKIE_SECURE` | `false` | `src/lib/auth` | Sets the `Secure` flag on session cookies. **Must be `true`** when running behind HTTPS. |
| `REQUIRE_API_KEY` | `false` | API middleware | When `true`, all `/v1/*` proxy requests must include a valid API key. |
| `ALLOW_API_KEY_REVEAL` | `false` | Dashboard providers page | Allows revealing full API key values in the Dashboard UI. Security risk on shared instances. |
| `NO_LOG_API_KEY_IDS` | _(empty)_ | `src/lib/compliance/index.ts` | Comma-separated API key IDs that bypass request logging (GDPR compliance). |
| `MAX_BODY_SIZE_BYTES` | `10485760` (10 MB) | `src/shared/middleware/bodySizeGuard.ts` | Maximum allowed request body size. Rejects payloads exceeding this limit. |
| `CORS_ORIGIN` | `*` | Next.js middleware | CORS `Access-Control-Allow-Origin` value. Restrict for production. |
| `OUTBOUND_SSRF_GUARD_ENABLED` | `true` | `src/shared/network/outboundUrlGuard.ts` | Block provider calls targeting private/loopback/link-local IP ranges. Disable only in isolated test envs. |
### Hardening Checklist
```bash
# Production security minimum:
AUTH_COOKIE_SECURE=true # Requires HTTPS
REQUIRE_API_KEY=true # Authenticate all proxy calls
ALLOW_API_KEY_REVEAL=false # Never expose keys in UI
CORS_ORIGIN=https://your.domain.com
MAX_BODY_SIZE_BYTES=5242880 # 5 MB limit
```
---
## 5. Input Sanitization & PII Protection
OmniRoute provides a two-layer defense: request-side injection scanning and response-side PII stripping.
### Request-Side: Prompt Injection Guard
| Variable | Default | Source File | Description |
| ------------------------- | --------- | ---------------------------------------- | ------------------------------------------------------------------------------------------- |
| `INPUT_SANITIZER_ENABLED` | `false` | `src/middleware/promptInjectionGuard.ts` | Enable scanning of incoming messages for prompt injection patterns. |
| `INPUT_SANITIZER_MODE` | `warn` | `src/middleware/promptInjectionGuard.ts` | `warn` = log only, `block` = reject request with 400, `redact` = strip suspicious patterns. |
| `INJECTION_GUARD_MODE` | _(unset)_ | `src/middleware/promptInjectionGuard.ts` | Legacy alias for `INPUT_SANITIZER_MODE` — same behavior. |
| `PII_REDACTION_ENABLED` | `false` | `src/middleware/promptInjectionGuard.ts` | Detect PII (emails, phones, SSNs) in incoming requests. |
### Response-Side: PII Sanitizer
| Variable | Default | Source File | Description |
| -------------------------------- | -------- | ------------------------- | ----------------------------------------------------------------------- |
| `PII_RESPONSE_SANITIZATION` | `false` | `src/lib/piiSanitizer.ts` | Scan LLM responses for leaked PII before returning to client. |
| `PII_RESPONSE_SANITIZATION_MODE` | `redact` | `src/lib/piiSanitizer.ts` | `redact` = mask PII, `warn` = log only, `block` = drop entire response. |
### Scenarios
| Scenario | Configuration |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **Enterprise compliance** | `INPUT_SANITIZER_ENABLED=true`, `INPUT_SANITIZER_MODE=block`, `PII_REDACTION_ENABLED=true`, `PII_RESPONSE_SANITIZATION=true` |
| **Monitoring only** | `INPUT_SANITIZER_ENABLED=true`, `INPUT_SANITIZER_MODE=warn` — logs but never blocks |
| **Personal use** | Leave all disabled — zero overhead |
---
## 6. Tool & Routing Policies
| Variable | Default | Source File | Description |
| ------------------ | ---------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `TOOL_POLICY_MODE` | `disabled` | `src/lib/toolPolicy.ts` | Controls LLM tool/function-calling access. `allowlist` = only listed tools, `denylist` = all except listed, `disabled` = no restrictions. |
---
## 7. URLs & Cloud Sync
| Variable | Default | Source File | Description |
| ----------------------- | ------------------------ | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `BASE_URL` | `http://localhost:20128` | `src/lib/cloudSync.ts` | Server-side URL for internal sync jobs to call `/api/sync/cloud`. |
| `CLOUD_URL` | _(empty)_ | `src/lib/cloudSync.ts` | Cloud relay endpoint URL (premium feature). |
| `CLOUD_SYNC_TIMEOUT_MS` | `12000` | `src/lib/cloudSync.ts` | HTTP timeout for cloud sync requests. |
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | OAuth, Dashboard, sync | Public-facing URL for OAuth redirect_uri, Dashboard links. **Must match your public URL behind reverse proxy.** |
| `NEXT_PUBLIC_CLOUD_URL` | _(empty)_ | Client-side | Client-side mirror of `CLOUD_URL`. |
| `NEXT_PUBLIC_APP_URL` | _(unset)_ | `src/shared/services/cloudSyncScheduler.ts` | Legacy fallback for `NEXT_PUBLIC_BASE_URL`. |
> [!IMPORTANT]
> When deploying behind a reverse proxy (nginx, Caddy), `NEXT_PUBLIC_BASE_URL` **must** be set to your public URL (e.g., `https://omniroute.example.com`). Without this, OAuth callbacks will fail because the redirect_uri won't match.
---
## 8. Outbound Proxy
Route upstream LLM provider calls through an HTTP or SOCKS5 proxy for egress control, geo-routing, or IP masking.
| Variable | Default | Source File | Description |
| --------------------------------- | --------- | -------------------- | ----------------------------------------------------------------------------------- |
| `ENABLE_SOCKS5_PROXY` | `true` | `open-sse/executors` | Enable SOCKS5 proxy agent for upstream calls. |
| `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY` | `true` | Client-side | Client-side awareness of SOCKS5 availability. |
| `HTTP_PROXY` | _(unset)_ | Node.js standard | HTTP proxy for upstream calls. |
| `HTTPS_PROXY` | _(unset)_ | Node.js standard | HTTPS proxy for upstream calls. |
| `ALL_PROXY` | _(unset)_ | Node.js standard | Universal proxy (supports `socks5://`). |
| `NO_PROXY` | _(unset)_ | Node.js standard | Comma-separated hostnames/IPs to bypass the proxy. |
| `ENABLE_TLS_FINGERPRINT` | `false` | `open-sse/executors` | Spoof TLS fingerprint using wreq-js (mimics Chrome 124). Counters JA3/JA4 blocking. |
### Scenarios
| Scenario | Configuration |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| **SOCKS5 through SSH tunnel** | `ALL_PROXY=socks5://127.0.0.1:7890`, `ENABLE_SOCKS5_PROXY=true` |
| **Corporate HTTP proxy** | `HTTP_PROXY=http://proxy.corp.com:3128`, `HTTPS_PROXY=http://proxy.corp.com:3128`, `NO_PROXY=localhost,internal.corp.com` |
| **Anti-fingerprint** | `ENABLE_TLS_FINGERPRINT=true` — requires `wreq-js` (included) |
---
## 9. CLI Tool Integration
Controls how OmniRoute discovers and launches CLI sidecars (Claude Code, Codex, etc.).
| Variable | Default | Source File | Description |
| ------------------------- | ---------- | ----------------------------------- | -------------------------------------------------------------------------- |
| `CLI_MODE` | `auto` | `src/shared/services/cliRuntime.ts` | `auto` = search system PATH; `manual` = use explicit paths only. |
| `CLI_EXTRA_PATHS` | _(unset)_ | `src/shared/services/cliRuntime.ts` | Additional PATH entries for CLI binary discovery (colon-separated). |
| `CLI_CONFIG_HOME` | _(unset)_ | `src/shared/services/cliRuntime.ts` | Override home directory for reading CLI configs (`~/.claude`, `~/.codex`). |
| `CLI_ALLOW_CONFIG_WRITES` | `false` | `src/shared/services/cliRuntime.ts` | Allow OmniRoute to write CLI config files (token refresh, session data). |
| `CLI_CLAUDE_BIN` | `claude` | `src/shared/services/cliRuntime.ts` | Custom path to Claude CLI binary. |
| `CLI_CODEX_BIN` | `codex` | `src/shared/services/cliRuntime.ts` | Custom path to Codex CLI binary. |
| `CLI_DROID_BIN` | `droid` | `src/shared/services/cliRuntime.ts` | Custom path to Droid CLI binary. |
| `CLI_OPENCLAW_BIN` | `openclaw` | `src/shared/services/cliRuntime.ts` | Custom path to OpenClaw CLI binary. |
| `CLI_CURSOR_BIN` | `agent` | `src/shared/services/cliRuntime.ts` | Custom path to Cursor agent binary. |
| `CLI_CLINE_BIN` | `cline` | `src/shared/services/cliRuntime.ts` | Custom path to Cline CLI binary. |
| `CLI_CONTINUE_BIN` | `cn` | `src/shared/services/cliRuntime.ts` | Custom path to Continue CLI binary. |
| `CLI_QODER_BIN` | `qoder` | `src/shared/services/cliRuntime.ts` | Custom path to Qoder CLI binary. |
### Docker Example
```bash
# Mount host binaries into the container and tell OmniRoute where they are:
CLI_EXTRA_PATHS=/host-cli/bin
CLI_CONFIG_HOME=/root
CLI_ALLOW_CONFIG_WRITES=true
CLI_CLAUDE_BIN=/host-cli/bin/claude
```
---
## 10. Internal Agent & MCP Integrations
| Variable | Default | Source File | Description |
| --------------------------------------- | ----------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `OMNIROUTE_BASE_URL` | auto-detect | `open-sse/mcp-server/server.ts` | Explicit URL for MCP/A2A tools to reach OmniRoute. Overrides localhost auto-detection. |
| `OMNIROUTE_API_KEY` | _(unset)_ | MCP/A2A modules | API key for internal MCP tool and A2A skill calls. |
| `OMNIROUTE_API_KEY_ID` | _(unset)_ | `open-sse/mcp-server/audit.ts` | Key ID for MCP audit log attribution. |
| `ROUTER_API_KEY` | _(unset)_ | Legacy | Legacy alias for `OMNIROUTE_API_KEY`. |
| `OMNIROUTE_MCP_ENFORCE_SCOPES` | `false` | `open-sse/mcp-server/server.ts` | Enforce scope-based access control on MCP tool calls. |
| `OMNIROUTE_MCP_SCOPES` | _(all)_ | `open-sse/mcp-server/server.ts` | Comma-separated scopes: `admin`, `combos`, `health`, `models`, `routing`, `budget`, `metrics`, `pricing`, `memory`, `skills`. |
| `MODEL_SYNC_INTERVAL_HOURS` | `24` | `src/shared/services/modelSyncScheduler.ts` | Model catalog sync interval in hours. |
| `PROVIDER_LIMITS_SYNC_INTERVAL_MINUTES` | `70` | `src/server-init.ts` | Provider rate-limit and quota polling interval. |
| `OMNIROUTE_DISABLE_BACKGROUND_SERVICES` | `false` | `src/instrumentation-node.ts` | Disable all background services (sync, pricing, model refresh). Useful for CI/test. |
| `OMNIROUTE_BOOTSTRAPPED` | `false` | `src/app/(dashboard)/dashboard/page.tsx` | Set `true` by bootstrap script after initial setup. Controls setup wizard visibility. |
| `OMNIROUTE_ALLOW_BODY_PROJECT_OVERRIDE` | `0` | `open-sse/executors/antigravity.ts` | Escape hatch: allow request body to override the Antigravity project field. |
### OAuth CLI Bridge (Internal)
| Variable | Default | Source File | Description |
| ------------------- | ----------- | ------------------------------- | ----------------------------------------- |
| `OMNIROUTE_SERVER` | auto-detect | `src/lib/oauth/config/index.ts` | Server URL for CLI↔OmniRoute auth bridge. |
| `OMNIROUTE_TOKEN` | _(unset)_ | `src/lib/oauth/config/index.ts` | Auth token for CLI bridge. |
| `OMNIROUTE_USER_ID` | `cli` | `src/lib/oauth/config/index.ts` | User ID for CLI bridge sessions. |
| `SERVER_URL` | _(unset)_ | `src/lib/oauth/config/index.ts` | Legacy alias for `OMNIROUTE_SERVER`. |
| `CLI_TOKEN` | _(unset)_ | `src/lib/oauth/config/index.ts` | Legacy alias for `OMNIROUTE_TOKEN`. |
| `CLI_USER_ID` | _(unset)_ | `src/lib/oauth/config/index.ts` | Legacy alias for `OMNIROUTE_USER_ID`. |
---
## 11. OAuth Provider Credentials
Built-in credentials for **localhost development**. For remote deployments, register your own at each provider's developer console.
| Variable | Provider | Notes |
| --------------------------------- | ----------------------- | --------------------------------------------------------------------------------- |
| `CLAUDE_OAUTH_CLIENT_ID` | Claude Code (Anthropic) | Public client — no secret needed. |
| `CLAUDE_CODE_REDIRECT_URI` | Claude Code | Override redirect URI. Default: `https://platform.claude.com/oauth/code/callback` |
| `CODEX_OAUTH_CLIENT_ID` | Codex / OpenAI | Public client. |
| `GEMINI_OAUTH_CLIENT_ID` | Gemini (Google) | Requires matching `_SECRET`. |
| `GEMINI_OAUTH_CLIENT_SECRET` | Gemini (Google) | — |
| `GEMINI_CLI_OAUTH_CLIENT_ID` | Gemini CLI | Usually same as Gemini. |
| `GEMINI_CLI_OAUTH_CLIENT_SECRET` | Gemini CLI | — |
| `QWEN_OAUTH_CLIENT_ID` | Qwen (Alibaba) | Public client. |
| `KIMI_CODING_OAUTH_CLIENT_ID` | Kimi Coding (Moonshot) | Public client. |
| `ANTIGRAVITY_OAUTH_CLIENT_ID` | Antigravity (Google) | Requires matching `_SECRET`. |
| `ANTIGRAVITY_OAUTH_CLIENT_SECRET` | Antigravity (Google) | — |
| `GITHUB_OAUTH_CLIENT_ID` | GitHub Copilot | Public client. |
| `QODER_OAUTH_CLIENT_SECRET` | Qoder | — |
| `QODER_OAUTH_AUTHORIZE_URL` | Qoder | Set to enable Qoder OAuth. |
| `QODER_OAUTH_TOKEN_URL` | Qoder | — |
| `QODER_OAUTH_USERINFO_URL` | Qoder | — |
| `QODER_OAUTH_CLIENT_ID` | Qoder | — |
| `QODER_PERSONAL_ACCESS_TOKEN` | Qoder | Direct API key fallback (bypasses OAuth). |
| `QODER_CLI_WORKSPACE` | Qoder | Workspace ID for Qoder CLI. |
| `OMNIROUTE_QODER_WORKSPACE` | Qoder | Alias for `QODER_CLI_WORKSPACE`. |
> [!WARNING]
> **Google OAuth** (Antigravity, Gemini CLI) credentials **only work on localhost**. For remote servers:
>
> 1. Go to [Google Cloud Console → Credentials](https://console.cloud.google.com/apis/credentials)
> 2. Create an OAuth 2.0 Client ID (type: "Web application")
> 3. Add your server URL as Authorized redirect URI
> 4. Replace the credential values in `.env`.
---
## 12. Provider User-Agent Overrides
Override the `User-Agent` header sent to each upstream provider. This is dynamically resolved at runtime by the executor base class:
```
process.env[`${PROVIDER_ID}_USER_AGENT`]
```
> **Source:** `open-sse/executors/base.ts` → `buildHeaders()`
| Variable | Default Value | When to Update |
| ------------------------ | -------------------------------------------- | ------------------------------------------------------------- |
| `CLAUDE_USER_AGENT` | `claude-cli/1.0.83 (external, cli)` | When Anthropic releases a new CLI version |
| `CODEX_USER_AGENT` | `codex-cli/0.92.0 (Windows 10.0.26100; x64)` | When OpenAI updates the Codex CLI |
| `CODEX_CLIENT_VERSION` | `0.92.0` | Override Codex client version independently of full UA string |
| `GITHUB_USER_AGENT` | `GitHubCopilotChat/0.26.7` | When GitHub Copilot Chat updates |
| `ANTIGRAVITY_USER_AGENT` | `antigravity/1.104.0 darwin/arm64` | When Antigravity IDE updates |
| `KIRO_USER_AGENT` | `AWS-SDK-JS/3.0.0 kiro-ide/1.0.0` | When Kiro IDE updates |
| `QODER_USER_AGENT` | `Qoder-Cli` | When Qoder CLI updates |
| `QWEN_USER_AGENT` | `QwenCode/0.12.3 (linux; x64)` | When Qwen Code updates |
| `CURSOR_USER_AGENT` | `connect-es/1.6.1` | When Cursor updates |
| `GEMINI_CLI_USER_AGENT` | `google-api-nodejs-client/9.15.1` | When Google API client updates |
> [!TIP]
> You can add User-Agent overrides for **any** provider using the pattern `{PROVIDER_ID}_USER_AGENT`. The executor dynamically constructs the env var name.
---
## 13. CLI Fingerprint Compatibility
When enabled, OmniRoute reorders HTTP headers and JSON body fields to match the exact signature of official CLI tools. This reduces the risk of account flagging while preserving your proxy IP.
**Source:** `open-sse/config/cliFingerprints.ts`, `open-sse/executors/base.ts`
### Per-Provider
| Variable | Effect |
| -------------------------- | --------------------------------------- |
| `CLI_COMPAT_CODEX=1` | Mimics Codex CLI request signature |
| `CLI_COMPAT_CLAUDE=1` | Mimics Claude Code request signature |
| `CLI_COMPAT_GITHUB=1` | Mimics GitHub Copilot request signature |
| `CLI_COMPAT_ANTIGRAVITY=1` | Mimics Antigravity request signature |
| `CLI_COMPAT_KIRO=1` | Mimics Kiro IDE request signature |
| `CLI_COMPAT_CURSOR=1` | Mimics Cursor request signature |
| `CLI_COMPAT_KIMI_CODING=1` | Mimics Kimi Coding request signature |
| `CLI_COMPAT_KILOCODE=1` | Mimics Kilo Code request signature |
| `CLI_COMPAT_CLINE=1` | Mimics Cline request signature |
| `CLI_COMPAT_QWEN=1` | Mimics Qwen Code request signature |
### Global
| Variable | Effect |
| ------------------ | --------------------------------------------------------------- |
| `CLI_COMPAT_ALL=1` | Enable fingerprint compatibility for **all** providers at once. |
> [!NOTE]
> This feature works alongside the User-Agent overrides (§12). The fingerprint system handles header ordering and body field ordering, while User-Agent overrides handle the specific UA string. Both can be enabled independently.
---
## 14. API Key Providers
API keys for providers that use direct authentication. **Preferred setup:** Dashboard → Providers → Add API Key.
Setting via environment variables is an alternative for Docker or headless deployments.
Recognized pattern: `{PROVIDER_ID}_API_KEY`
| Variable | Provider |
| -------------------- | ------------------- |
| `DEEPSEEK_API_KEY` | DeepSeek |
| `GROQ_API_KEY` | Groq |
| `XAI_API_KEY` | xAI (Grok) |
| `MISTRAL_API_KEY` | Mistral AI |
| `PERPLEXITY_API_KEY` | Perplexity |
| `TOGETHER_API_KEY` | Together AI |
| `FIREWORKS_API_KEY` | Fireworks AI |
| `CEREBRAS_API_KEY` | Cerebras |
| `COHERE_API_KEY` | Cohere |
| `NVIDIA_API_KEY` | NVIDIA NIM |
| `NEBIUS_API_KEY` | Nebius (embeddings) |
> [!TIP]
> Keys set via the Dashboard are stored encrypted in SQLite and take precedence over environment variables.
---
## 15. Timeout Settings
All values are in **milliseconds**. Centralized resolution in `src/shared/utils/runtimeTimeouts.ts`.
### Timeout Hierarchy
```
REQUEST_TIMEOUT_MS (global override)
├─→ FETCH_TIMEOUT_MS (upstream provider calls, default: 600000)
│ ├─→ FETCH_HEADERS_TIMEOUT_MS (inherits from FETCH_TIMEOUT_MS)
│ ├─→ FETCH_BODY_TIMEOUT_MS (inherits from FETCH_TIMEOUT_MS)
│ ├─→ TLS_CLIENT_TIMEOUT_MS (inherits from FETCH_TIMEOUT_MS)
│ ├── FETCH_CONNECT_TIMEOUT_MS (independent, default: 30000)
│ └── FETCH_KEEPALIVE_TIMEOUT_MS (independent, default: 4000)
├─→ STREAM_IDLE_TIMEOUT_MS (inherits from REQUEST_TIMEOUT_MS, default: 600000)
└─→ API_BRIDGE_PROXY_TIMEOUT_MS (inherits from REQUEST_TIMEOUT_MS, default: 30000)
├─→ API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS (derived, default: 300000)
├── API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS (default: 60000)
├── API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS (default: 5000)
└── API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS (default: 0 = disabled)
```
| Variable | Default | Description |
| ---------------------------------------- | -------------------- | ------------------------------------------------------------------------------------------- |
| `REQUEST_TIMEOUT_MS` | _(unset)_ | Global shortcut — overrides both `FETCH_TIMEOUT_MS` and `STREAM_IDLE_TIMEOUT_MS` defaults. |
| `FETCH_TIMEOUT_MS` | `600000` | Total HTTP request timeout for upstream provider calls. |
| `STREAM_IDLE_TIMEOUT_MS` | `600000` | Max silence between SSE chunks before aborting. Extended-thinking models rarely pause >90s. |
| `FETCH_HEADERS_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Time to receive response headers. |
| `FETCH_BODY_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | Time to receive the full response body. |
| `FETCH_CONNECT_TIMEOUT_MS` | `30000` | TCP connection establishment timeout. |
| `FETCH_KEEPALIVE_TIMEOUT_MS` | `4000` | Keep-alive socket idle timeout. |
| `TLS_CLIENT_TIMEOUT_MS` | = `FETCH_TIMEOUT_MS` | TLS fingerprint proxy (wreq-js) timeout. |
| `API_BRIDGE_PROXY_TIMEOUT_MS` | `30000` | Proxy hop timeout for `/v1` bridge requests. |
| `API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS` | `300000` | Overall server request timeout for the bridge. |
| `API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS` | `60000` | Time to send response headers via the bridge. |
| `API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS` | `5000` | Bridge keep-alive idle timeout. |
| `API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS` | `0` | Raw socket timeout (0 = disabled). |
| `SHUTDOWN_TIMEOUT_MS` | `30000` | Grace period on SIGTERM/SIGINT before force-exit. |
### Scenarios
| Scenario | Configuration |
| -------------------------------- | ------------------------------------------------------ |
| **Long-running code generation** | `REQUEST_TIMEOUT_MS=900000` (15 min) |
| **Fast-fail for production API** | `API_BRIDGE_PROXY_TIMEOUT_MS=10000` |
| **Extended thinking models** | `STREAM_IDLE_TIMEOUT_MS=300000` (5 min between chunks) |
---
## 16. Logging
The logging system writes to both stdout and rotated log files. All configuration is read by `src/lib/logEnv.ts`.
| Variable | Default | Description |
| --------------------------- | -------------------------- | ---------------------------------------------------------------------------- |
| `APP_LOG_LEVEL` | `info` | Minimum log level: `debug`, `info`, `warn`, `error`. |
| `APP_LOG_FORMAT` | `text` | Output format: `text` (human-readable) or `json` (structured). |
| `APP_LOG_TO_FILE` | `true` | Write logs to file alongside stdout. |
| `APP_LOG_FILE_PATH` | `logs/application/app.log` | Log file path (relative to project root or `DATA_DIR`). |
| `APP_LOG_MAX_FILE_SIZE` | `50M` | Max file size before rotation. Accepts: `50M`, `1G`, `512K`, or plain bytes. |
| `APP_LOG_RETENTION_DAYS` | `7` | Days to keep rotated application log files. |
| `APP_LOG_MAX_FILES` | `20` | Maximum rotated log file backups. |
| `CALL_LOG_RETENTION_DAYS` | `7` | Days to keep request/call log entries in the database. |
| `CALL_LOG_MAX_ENTRIES` | `10000` | Max call log entries in the in-memory buffer. |
| `CALL_LOGS_TABLE_MAX_ROWS` | `100000` | Max rows in the `call_logs` SQLite table before pruning. |
| `PROXY_LOGS_TABLE_MAX_ROWS` | `100000` | Max rows in the `proxy_logs` SQLite table before pruning. |
---
## 17. Memory Optimization
| Variable | Default | Description |
| -------------------------- | ------------------------------- | ---------------------------------------------------------------------- |
| `OMNIROUTE_MEMORY_MB` | `256` (Docker) / system default | V8 heap limit. Sets `--max-old-space-size`. |
| `PROMPT_CACHE_MAX_SIZE` | `50` | Max cached system prompt entries. |
| `PROMPT_CACHE_MAX_BYTES` | `2097152` (2 MB) | Max total prompt cache size. |
| `PROMPT_CACHE_TTL_MS` | `300000` (5 min) | Prompt cache entry TTL. |
| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Max cached temperature=0 responses. |
| `SEMANTIC_CACHE_MAX_BYTES` | `4194304` (4 MB) | Max total semantic cache size. |
| `SEMANTIC_CACHE_TTL_MS` | `1800000` (30 min) | Semantic cache entry TTL. |
| `STREAM_HISTORY_MAX` | `50` | Max recent stream events in the Dashboard live view buffer. |
| `CONTEXT_LENGTH_DEFAULT` | `128000` | Global fallback max context length for models without explicit config. |
| `USAGE_TOKEN_BUFFER` | `100` | Extra token headroom reserved when tracking usage quotas. |
### Low-RAM Docker Example
```bash
OMNIROUTE_MEMORY_MB=128
PROMPT_CACHE_MAX_SIZE=20
PROMPT_CACHE_MAX_BYTES=524288 # 512 KB
SEMANTIC_CACHE_MAX_SIZE=25
SEMANTIC_CACHE_MAX_BYTES=1048576 # 1 MB
STREAM_HISTORY_MAX=10
```
---
## 18. Pricing Sync
Automatic model pricing data synchronization from external sources.
| Variable | Default | Source File | Description |
| ----------------------- | ------------- | ------------------------ | ----------------------------- |
| `PRICING_SYNC_ENABLED` | `false` | `src/lib/pricingSync.ts` | Opt-in periodic pricing sync. |
| `PRICING_SYNC_INTERVAL` | `86400` (24h) | `src/lib/pricingSync.ts` | Sync interval in seconds. |
| `PRICING_SYNC_SOURCES` | `litellm` | `src/lib/pricingSync.ts` | Comma-separated data sources. |
---
## 19. Model Sync (Dev)
| Variable | Default | Source File | Description |
| -------------------------- | ------------- | -------------------------- | -------------------------------------------------------- |
| `MODELS_DEV_SYNC_INTERVAL` | `86400` (24h) | `src/lib/modelsDevSync.ts` | Development-time model catalog sync interval in seconds. |
---
## 20. Provider-Specific Settings
| Variable | Default | Source File | Description |
| ----------------------------------------- | ------------------ | ------------------------------------------ | ------------------------------------------------------------------------------------- |
| `OPENROUTER_CATALOG_TTL_MS` | `86400000` (24h) | `src/lib/catalog/openrouterCatalog.ts` | OpenRouter model catalog cache TTL. |
| `NANOBANANA_POLL_TIMEOUT_MS` | `120000` | `open-sse/handlers/imageGeneration.ts` | Max wait for NanoBanana image generation jobs. |
| `NANOBANANA_POLL_INTERVAL_MS` | `2500` | `open-sse/handlers/imageGeneration.ts` | NanoBanana job polling frequency. |
| `CLOUDFLARE_ACCOUNT_ID` | _(unset)_ | `open-sse/executors/cloudflare-ai.ts` | Account ID for Cloudflare Workers AI. |
| `CLOUDFLARED_BIN` | auto-detect | `src/lib/cloudflaredTunnel.ts` | Custom path to `cloudflared` binary. |
| `SEARCH_CACHE_TTL_MS` | `300000` (5 min) | `open-sse/services/searchCache.ts` | TTL for search API (Perplexity, Brave, etc.) response caching. |
| `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE` | `false` | `src/app/api/providers/route.ts` | Allow multiple simultaneous connections per OpenAI-compatible provider. |
| `ENABLE_CC_COMPATIBLE_PROVIDER` | `false` | `src/shared/utils/featureFlags.ts` | Enable experimental Claude Code compatible provider endpoint. |
| `CLIPROXYAPI_HOST` | `127.0.0.1` | `open-sse/executors/cliproxyapi.ts` | CLIProxyAPI bridge host (legacy integration). |
| `CLIPROXYAPI_PORT` | `5544` | `open-sse/executors/cliproxyapi.ts` | CLIProxyAPI bridge port. |
| `CLIPROXYAPI_CONFIG_DIR` | `~/.cli-proxy-api` | `src/lib/versionManager/processManager.ts` | CLIProxyAPI config directory. |
| `LOCAL_HOSTNAMES` | _(empty)_ | `open-sse/config/providerRegistry.ts` | Comma-separated additional hostnames treated as "local" (Docker service names, etc.). |
---
## 21. Proxy Health
| Variable | Default | Source File | Description |
| ---------------------------- | ---------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `PROXY_FAST_FAIL_TIMEOUT_MS` | `2000` | `src/lib/proxyHealth.ts` | Fast-fail health check timeout. |
| `PROXY_HEALTH_CACHE_TTL_MS` | `30000` | `src/lib/proxyHealth.ts` | Health check result cache TTL. |
| `RATE_LIMIT_MAX_WAIT_MS` | `120000` (2 min) | `open-sse/services/rateLimitManager.ts` | Max time to wait on a 429 before failing the request. |
| `REQUEST_RETRY` | `2` | `src/sse/services/cooldownAwareRetry.ts` | Number of automatic retries on model-scoped cooldown responses before returning error to client. |
| `MAX_RETRY_INTERVAL_SEC` | `30` | `src/sse/services/cooldownAwareRetry.ts` | Max backoff interval (seconds) between cooldown retries. Capped by this value regardless of upstream `Retry-After`. |
---
## 22. Debugging
> [!CAUTION]
> These variables produce **verbose output** and may leak sensitive data. **Never enable in production.**
| Variable | Default | Source File | Description |
| -------------------------------- | --------- | ----------------------------------------- | -------------------------------------------------------------- |
| `CURSOR_PROTOBUF_DEBUG` | _(unset)_ | `open-sse/utils/cursorProtobuf.ts` | Set `1` to dump Cursor protobuf decode/encode details. |
| `CURSOR_STREAM_DEBUG` | _(unset)_ | `open-sse/executors/cursor.ts` | Set `1` to dump raw Cursor SSE stream data. |
| `DEBUG_RESPONSES_SSE_TO_JSON` | _(unset)_ | `open-sse/handlers/responseTranslator.ts` | Set `true` to log Responses API SSE→JSON translation details. |
| `NEXT_PUBLIC_OMNIROUTE_E2E_MODE` | _(unset)_ | E2E test harness | Set `true` to enable E2E test mode (relaxed auth, test hooks). |
---
## 23. GitHub Integration
Allow users to report issues directly from the Dashboard.
| Variable | Default | Source File | Description |
| --------------------- | --------- | --------------------------------------- | ------------------------------------------------------- |
| `GITHUB_ISSUES_REPO` | _(unset)_ | `src/app/api/v1/issues/report/route.ts` | Repository in `owner/repo` format. |
| `GITHUB_ISSUES_TOKEN` | _(unset)_ | `src/app/api/v1/issues/report/route.ts` | GitHub Personal Access Token with `issues:write` scope. |
---
## Deployment Scenarios
### Minimal Local Development
```bash
JWT_SECRET=$(openssl rand -base64 48)
API_KEY_SECRET=$(openssl rand -hex 32)
INITIAL_PASSWORD=dev123
PORT=20128
NODE_ENV=development
```
### Docker Production
```bash
JWT_SECRET=<generated>
API_KEY_SECRET=<generated>
INITIAL_PASSWORD=<generated>
STORAGE_ENCRYPTION_KEY=<generated>
DATA_DIR=/data
PORT=20128
API_PORT=20129
NODE_ENV=production
AUTH_COOKIE_SECURE=true
REQUIRE_API_KEY=true
NEXT_PUBLIC_BASE_URL=https://omniroute.example.com
BASE_URL=http://localhost:20128
OMNIROUTE_MEMORY_MB=512
CORS_ORIGIN=https://your-frontend.example.com
```
### Air-Gapped / CI
```bash
JWT_SECRET=test-jwt-secret-for-ci
API_KEY_SECRET=test-api-key-secret-for-ci
INITIAL_PASSWORD=testpass
NODE_ENV=production
OMNIROUTE_DISABLE_BACKGROUND_SERVICES=true
APP_LOG_TO_FILE=false
```
### VPS with Reverse Proxy (nginx + Cloudflare)
```bash
JWT_SECRET=<generated>
API_KEY_SECRET=<generated>
STORAGE_ENCRYPTION_KEY=<generated>
PORT=20128
AUTH_COOKIE_SECURE=true
REQUIRE_API_KEY=true
NEXT_PUBLIC_BASE_URL=https://omniroute.example.com
BASE_URL=http://127.0.0.1:20128
CORS_ORIGIN=https://omniroute.example.com
ENABLE_TLS_FINGERPRINT=true
CLI_COMPAT_ALL=1
```
---
## Audit: Removed / Dead Variables
The following variables appeared in previous versions of `.env.example` but have **no runtime references** in the current codebase. They have been removed:
| Variable | Reason |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `STORAGE_DRIVER=sqlite` | Never read by any source file. SQLite is the only supported driver — no selection needed. |
| `INSTANCE_NAME=omniroute` | Present in old docs/env templates but unused at runtime. May return in a future multi-instance feature. |
| `SQLITE_MAX_SIZE_MB=2048` | Not referenced in source code. Database size is not artificially limited. |
| `SQLITE_CLEAN_LEGACY_FILES=true` | Not referenced in source code. Legacy cleanup was likely removed. |
| `CLI_ROO_BIN` | Not registered in `src/shared/services/cliRuntime.ts`. |
| `CLI_KIMI_CODING_BIN` | Not registered in `src/shared/services/cliRuntime.ts` (Kimi Coding uses OAuth, not a CLI binary). |
| `IFLOW_OAUTH_CLIENT_ID` / `IFLOW_OAUTH_CLIENT_SECRET` | Not referenced anywhere in source code. |
### Default Value Corrections
| Variable | Old `.env.example` Value | Actual Code Default | Fixed |
| ------------------------- | ------------------------ | ------------------- | ------------------------------------------------------ |
| `APP_LOG_RETENTION_DAYS` | `90` | `7` | ✅ Removed misleading value; documented `7` as default |
| `CALL_LOG_RETENTION_DAYS` | `90` | `7` | ✅ Removed misleading value; documented `7` as default |

View File

@@ -4,8 +4,6 @@
---
Visual guide to every section of the OmniRoute dashboard.
---
@@ -22,6 +20,13 @@ Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI)
Create model routing combos with 13 strategies: priority, weighted, round-robin, random, least-used, cost-optimized, strict-random, auto, fill-first, p2c, lkgp, context-optimized, and **context-relay**. Each combo chains multiple models with automatic fallback and includes quick templates and readiness checks.
Recent combo improvements:
- **Structured combo builder** — create each step by selecting provider, model, and exact account/connection
- **Repeated provider support** — reuse the same provider many times in one combo as long as the `(provider, model, connection)` tuple is unique
- **Combo target health** — analytics and health surfaces now distinguish individual combo targets/steps instead of collapsing everything into model strings
- **Composite tier ordering** — `defaultTier -> fallbackTier` now influences runtime execution/fallback order for top-level combo steps
![Combos Dashboard](screenshots/02-combos.png)
---
@@ -36,7 +41,7 @@ Comprehensive usage analytics with token consumption, cost estimates, activity h
## 🏥 System Health
Real-time monitoring: uptime, memory, version, latency percentiles (p50/p95/p99), cache statistics, and provider circuit breaker states.
Real-time monitoring: uptime, memory, version, latency percentiles (p50/p95/p99), cache statistics, provider circuit breaker states, active quota-monitored sessions, and combo target health.
![Health Dashboard](screenshots/04-health.png)
@@ -101,6 +106,7 @@ Dashboard for discovering and managing CLI agents. Shows a grid of 14 built-in a
A combo strategy that preserves session continuity when account rotation happens mid-conversation. Before the active account is exhausted, OmniRoute generates a structured handoff summary in the background. After the next request resolves to a different account, the summary is injected as a system message so the new account continues with full context.
Configurable via combo-level or global settings:
- **Handoff Threshold** — Quota usage percentage that triggers summary generation (default 85%)
- **Max Messages For Summary** — How much recent history to condense
- **Summary Model** — Optional override model for generating the handoff summary
@@ -120,6 +126,43 @@ Comprehensive proxy configuration enforcement across the entire request pipeline
---
## 📧 Email Privacy Masking _(v3.5.6+)_
OAuth account emails are now masked in the provider dashboard (e.g. `di*****@g****.com`) to prevent accidental exposure when sharing screenshots or recording demos. The full email address remains accessible via hover tooltip (`title` attribute).
---
## 👁️ Model Visibility Toggle _(v3.5.6+)_
The provider page model list now includes:
- **Real-time search/filter bar** — Quickly find specific models
- **Per-model visibility toggle** (👁 icon) — Hidden models are grayed out and excluded from the `/v1/models` catalog
- **Active-count badge** (`N/M active`) — Shows at a glance how many models are enabled vs total
---
## 🔧 OAuth Env Repair _(v3.6.1+)_
One-click "Repair env" action for OAuth providers that restores missing environment variables and fixes broken auth state. Accessible from `Dashboard → Providers → [OAuth Provider] → Repair env`. Automatically detects and repairs:
- Missing OAuth client credentials
- Corrupted env file entries
- Backup path sanitization
---
## 🗑️ Uninstall / Full Uninstall _(v3.6.2+)_
Clean removal scripts for all installation methods:
| Command | Action |
| ------------------------ | ----------------------------------------------------------------------------------- |
| `npm run uninstall` | Removes the system app but **keeps your DB and configurations** in `~/.omniroute`. |
| `npm run uninstall:full` | Removes the app AND permanently **erases all configurations, keys, and databases**. |
---
## 🖼️ Media _(v2.0.3+)_
Generate images, videos, and music from the dashboard. Supports OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI, AnimateDiff, Stable Audio Open, and MusicGen.
@@ -167,5 +210,61 @@ Key features:
- Auto-update on restart
- Platform-conditional UI (macOS traffic lights, Windows/Linux default titlebar)
- Hardened Electron build packaging — symlinked `node_modules` in the standalone bundle is detected and rejected before packaging, preventing runtime dependency on the build machine (v2.5.5+)
- **Graceful shutdown** — Electron `before-quit` shuts down Next.js cleanly, preventing SQLite WAL database locks (v3.6.2+)
📖 See [`electron/README.md`](../electron/README.md) for full documentation.
---
## 🌐 V1 WebSocket Bridge _(v3.6.6+)_
OmniRoute now supports **OpenAI-compatible WebSocket clients** via the `/v1/ws` upgrade endpoint. The custom `scripts/v1-ws-bridge.mjs` server wraps Next.js and upgrades WS connections to full bidirectional streaming sessions. Authentication uses the same API key or session cookie as HTTP requests.
Key behaviours:
- WS upgrade validated by `src/lib/ws/handshake.ts` before the connection is established
- Streams terminated cleanly on session close or upstream error
- Works alongside the existing HTTP+SSE streaming path simultaneously
---
## 🔑 Sync Tokens & Config Bundle _(v3.6.6+)_
Multi-device and external operator access is now possible via **scoped sync tokens**:
- **`POST /api/sync/tokens`** — Issue a new sync token (scoped, with optional expiry)
- **`DELETE /api/sync/tokens/:id`** — Revoke a token
- **`GET /api/sync/bundle`** — Download a versioned, ETag-keyed JSON snapshot of all non-sensitive settings (passwords redacted)
The config bundle is built by `src/lib/sync/bundle.ts`. Consumers compare the `ETag` response header to detect changes without re-downloading the full payload.
---
## 🧠 GLM Thinking Preset _(v3.6.6+)_
**GLM Thinking (`glmt`)** is now a registered first-class provider: 65 536 max output tokens, 24 576 thinking budget, 900 s default timeout, Claude-compatible API format, and shared usage sync with the GLM family.
**Hybrid token counting** also lands in v3.6.6: when a Claude-compatible provider exposes `/messages/count_tokens`, OmniRoute calls it before large requests with graceful estimation fallback.
---
## 🛡️ Safe Outbound Fetch & SSRF Guard _(v3.6.6+)_
All provider validation and model discovery calls now go through a two-layer outbound guard:
1. **URL guard** (`src/shared/network/outboundUrlGuard.ts`) — Blocks private/loopback/link-local IP ranges before the socket is opened.
2. **Safe fetch wrapper** (`src/shared/network/safeOutboundFetch.ts`) — Applies the URL guard, normalises timeouts, and retries transient errors with exponential backoff.
Guard violations surface as HTTP 422 (`URL_GUARD_BLOCKED`) and are written to the compliance audit log via `providerAudit.ts`.
---
## 🔄 Cooldown-Aware Retries _(v3.6.6+)_
Chat requests now **automatically retry** when an upstream provider returns a model-scoped cooldown. Configurable via `REQUEST_RETRY` (default: 2) and `MAX_RETRY_INTERVAL_SEC` (default: 30 s). Rate-limit header learning improved across `x-ratelimit-reset-requests`, `x-ratelimit-reset-tokens`, and `Retry-After` — per-model cooldown state is visible in the Resilience dashboard.
---
## 📋 Compliance Audit v2 _(v3.6.6+)_
The audit log has been expanded with cursor-based pagination, request context enrichment (request ID, user agent, IP), structured auth events, provider CRUD events with diff context, and SSRF-blocked validation logging. New events emitted by `src/lib/compliance/providerAudit.ts`.

View File

@@ -4,58 +4,76 @@
---
تم إنشاء OmniRoute في Fly.io من خلال الرابط التالي:
本文档记录 OmniRoute Fly.io 上的实际部署方法,适用于两类场景:
- تم تطويره بواسطة Fly.io
- 首次把当前项目部署到 Fly.io
- 后续代码更新后继续发布
- 新项目参考同样流程部署
من المحتمل أن هذا هو السبب في أن كل ما عليك فعله هو ` Omniroute`.---## 1. 部署目标
本文基于当前项目已经验证通过的配置整理,应用名为 `omniroute`
- الاسم: Fly.io
- 部署方式: تم إنشاء `flyctl` 直接接发布
- قم بتنزيل الرابط: قم بتنزيل الملف `Dockerfile` و`fly.toml`.
- الاسم الأصلي: Fly Volume موجود في `/data`
- الرابط:`https://omniroute.fly.dev/`---## 2. 当前项目关键配置
---
قم بزيارة الرابط التالي `fly.toml` من خلال الرابط التالي:```toml
التطبيق = "الطريق الشامل"
Primary_region = 'الخطيئة'
## 1. 部署目标
[[يتصاعد]]
المصدر = "البيانات"
الوجهة = '/ البيانات'
- 平台Fly.io
- 部署方式:本地 `flyctl` 直接发布
- 运行方式:使用仓库内现有 `Dockerfile``fly.toml`
- 数据持久化Fly Volume 挂载到 `/data`
- 访问地址:`https://omniroute.fly.dev/`
[العمليات]
التطبيق = 'عقدة تشغيل Standalone.mjs'
---
## 2. 当前项目关键配置
当前仓库中的 `fly.toml` 已确认包含以下关键项:
```toml
app = 'omniroute'
primary_region = 'sin'
[[mounts]]
source = 'data'
destination = '/data'
[processes]
app = 'node run-standalone.mjs'
[http_service]
منفذ داخلي = 20128
internal_port = 20128
[بيئة]
TZ = "آسيا/شنغهاي"
المضيف = "0.0.0.0"
اسم المضيف = "0.0.0.0"
ربط = "0.0.0.0"```
[env]
TZ = "Asia/Shanghai"
HOST = "0.0.0.0"
HOSTNAME = "0.0.0.0"
BIND = "0.0.0.0"
```
الاسم:
说明:
- `app = 'omniroute'' تطبيق Fly 应用
- `الوجهة = '/ البيانات''
- قم بإلغاء تحديد `DATA_DIR=/data`، وقم بإلغاء تحديد موقع الويب الخاص بك---
- `app = 'omniroute'` 决定实际部署到哪个 Fly 应用
- `destination = '/data'` 决定持久卷挂载目录
- 本项目必须让 `DATA_DIR=/data`,否则数据库和密钥会写到容器临时目录
---
## 3. 必备工具
### 3.1 安装 Fly CLI
ويندوز بوويرشيل:```powershell
Windows PowerShell
```powershell
pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"
```
````
如果安装脚本在当前环境失败,也可以手动下载 `flyctl` 二进制并放到 `PATH` 中。
يمكن أن يكون هذا هو الحال بالنسبة لـ "flyctl" أو "PATH" أو "PATH".### 3.2 登录 Fly 账号```powershell
### 3.2 登录 Fly 账号
```powershell
flyctl auth login
````
```
### 3.3 检查登录状态
@@ -77,86 +95,110 @@ cd OmniRoute
### 4.2 确认应用名
قم بزيارة `fly.toml`، باستخدام الرابط التالي:`toml
التطبيق = "الطريق الشامل"`
打开 `fly.toml`,重点看这一行:
يجب أن تكون قادرًا على التعامل مع هذه المشكلة على النحو التالي:```toml
```toml
app = 'omniroute'
```
如果你准备部署到自己的新应用,可改成全局唯一名称,例如:
```toml
app = 'omniroute-yourname'
```
````
注意:
الاسم:
- 控制台里要看的是与 `fly.toml``app` 一致的应用
- 以前如果用过别的名字,例如 `oroute`,不要和 `omniroute` 混淆
- قم بالنقر على زر "fly.toml" من خلال "التطبيق" الموجود على الرابط
- 以前如果用过别的名字، 例如 `الطريق`، 不要 و``الطريق الشامل` 混淆### 4.3 创建应用
### 4.3 创建应用
اسم المنتج:```powershell
تقوم تطبيقات flyctl بإنشاء طريق شامل```
من المؤكد أن هذا يعني أن "الطريق الشامل" هو الطريق الصحيح.### 4.4 首次部署
如果该应用尚不存在:
```powershell
نشر flyctl```
flyctl apps create omniroute
```
如果你已经改成别的应用名,把 `omniroute` 替换成你的名字。
### 4.4 首次部署
```powershell
flyctl deploy
```
---
## 5. 必配参数
تم إطلاق لعبة Fly.io على جهاز الكمبيوتر الخاص بك.### 5.1 已验证使用的参数
本项目在 Fly.io 上建议至少配置以下参数。
أفضل الطرق للوصول إلى الطريق الشامل هي:
### 5.1 已验证使用的参数
这些参数已经在当前 `omniroute` 应用上实际部署:
- `API_KEY_SECRET`
- `DATA_DIR`
- `JWT_SECRET`
- `MACHINE_ID_SALT`
- `NEXT_PUBLIC_BASE_URL`
- `STORAGE_ENCRYPTION_KEY`### 5.2 关于 `INITIAL_PASSWORD`
- `STORAGE_ENCRYPTION_KEY`
اختر كلمة مرور `INITIAL_PASSWORD`، وقم بإلغاء تحديدها.
### 5.2 关于 `INITIAL_PASSWORD`
العنوان:
当前项目没有设置 `INITIAL_PASSWORD`,因为本次部署按需求不使用它。
- 启动日志会提示默认密码是 `CHANGEME'
- ماكينات غسيل الملابس
如果不设置:
يجب أن تكون قادرًا على التعامل مع هذه المشكلة:
- 启动日志会提示默认密码是 `CHANGEME`
- 部署后应尽快在系统设置中修改登录密码
- `INITIAL_PASSWORD`---
如果你希望无人值守初始化后台密码,也可以后续补:
- `INITIAL_PASSWORD`
---
## 6. 推荐参数说明
### 6.1 Secrets 中设置
أسرار الطيران:
建议放入 Fly Secrets
| 变量名 | 是否推荐 | 说明 |
| 变量名 | 是否推荐 | 说明 |
| ------------------------ | -------- | ------------------------------ |
| `API_KEY_SECRET` | 必需 | مفتاح API 生成与校验使用 |
| `JWT_SECRET` | 必需 | 登录态和 JWT 签名使用 |
| `STORAGE_ENCRYPTION_KEY` | 强烈推荐 | 加密存储敏感连接信息 |
| `MACHINE_ID_SALT` | جديد | 生成稳定机器标识 |
| `INITIAL_PASSWORD` | 可选 | ماكينات غسيل الملابس في الصين |
| OAuth/API 私密凭证 | الصفحة الرئيسية | 各类外部平台鉴权配置 |### 6.2 当前项目推荐值
| `API_KEY_SECRET` | 必需 | API Key 生成与校验使用 |
| `JWT_SECRET` | 必需 | 登录态和 JWT 签名使用 |
| `STORAGE_ENCRYPTION_KEY` | 强烈推荐 | 加密存储敏感连接信息 |
| `MACHINE_ID_SALT` | 推荐 | 生成稳定机器标识 |
| `INITIAL_PASSWORD` | 可选 | 首次部署时直接指定后台初始密码 |
| OAuth/API 私密凭证 | 按需 | 各类外部平台鉴权配置 |
| 变量名 | جديد |
### 6.2 当前项目推荐值
| 变量名 | 推荐值 |
| ---------------------- | --------------------------- |
| `DATA_DIR` | `/ البيانات` |
| `DATA_DIR` | `/data` |
| `NEXT_PUBLIC_BASE_URL` | `https://omniroute.fly.dev` |
الاسم:
说明:
- `DATA_DIR=/data` 非常关键،تحديد حجم الطيران
- `NEXT_PUBLIC_BASE_URL' عنوان البريد الإلكتروني الخاص بنا---
- `DATA_DIR=/data` 非常关键,必须与 Fly Volume 挂载点一致
- `NEXT_PUBLIC_BASE_URL` 用于调度器和前端回调等场景
---
## 7. 一键设置参数
تم إنشاء هذا الرابط من قبل شركة Fly Secrets.
下面命令会生成安全随机值,并把当前项目需要的参数一次性写入 Fly Secrets
الاسم:
说明:
- اختر "INITIAL_PASSWORD".
- 适用于当前项目 "شامل"```powershell
- 不包含 `INITIAL_PASSWORD`
- 适用于当前项目 `omniroute`
```powershell
$apiKeySecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
$jwtSecret = [Convert]::ToHexString((1..64 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
$machineIdSalt = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
@@ -170,187 +212,244 @@ flyctl secrets set `
DATA_DIR=/data `
NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev `
-a omniroute
````
```
ما هي أفضل الطرق التي يجب اتباعها:`powershell
مجموعة أسرار flyctl INITIAL_PASSWORD=你的强密码 - طريق شامل`
如果你还要加初始密码:
```powershell
flyctl secrets set INITIAL_PASSWORD=你的强密码 -a omniroute
```
---
## 8. 查看当前参数
````powershell
قائمة أسرار flyctl - طريق شامل```
```powershell
flyctl secrets list -a omniroute
```
如果控制台 ``الأسرار`` 页面没有显示你期待的变量،先检查:
如果控制台 `Secrets` 页面没有显示你期待的变量先检查
- omniroute omniroute
- `fly.toml'`app` 是否和控制台应用一致---
- 看的应用是不是 `omniroute`
- `fly.toml``app` 是否和控制台应用一致
---
## 9. 后续更新发布
أفضل ما في الأمر:```powershell
代码有更新后,发布步骤很简单:
```powershell
git pull
flyctl deploy
````
```
أفضل ما في الأمر:`powershell
تعيين أسرار flyctl KEY=value -a omniroute`
如果只更新参数,不改代码:
يطير هنا.### 9.1 跟踪原仓库更新并保留 fork 的 `fly.toml`
```powershell
flyctl secrets set KEY=value -a omniroute
```
شوكة 如果当前仓库是، 并且你要同步上游 `https://github.com/diegosouzapw/OmniRoute` 的更新، 推荐按下面流程执行.
Fly 会自动滚动更新机器。
العنوان:```powershell
### 9.1 跟踪原仓库更新并保留 fork 的 `fly.toml`
如果当前仓库是 fork并且你要同步上游 `https://github.com/diegosouzapw/OmniRoute` 的更新,推荐按下面流程执行。
先确认远程:
```powershell
git remote -v
```
````
应至少包含:
اسم المنتج:
- `origin` 指向你自己的 fork
- `upstream` 指向原仓库
- "الأصل" 指向你自己的
- `المنبع` 指向原仓库
如果没有 `upstream`,先添加:
المنبع ``المنبع``:```powershell
git عن بعد إضافة المنبع https://github.com/diegosouzapw/OmniRoute.git```
```powershell
git remote add upstream https://github.com/diegosouzapw/OmniRoute.git
```
أفضل ما في الأمر:```powershell
同步上游前,先抓取最新提交和标签:
```powershell
git fetch upstream --tags
````
```
أفضل ما في الأمر:`powershell
وصف git --tags --دائما
عرض git --no-patch --oneline v3.4.7`
查看当前版本和上游标签:
如果你想合并上游最新 `main`، 并强制保留 fork 当前的 `fly.toml`، 可按下面流程执行:```powershell
```powershell
git describe --tags --always
git show --no-patch --oneline v3.4.7
```
如果你想合并上游最新 `main`,并强制保留 fork 当前的 `fly.toml`,可按下面流程执行:
```powershell
git merge upstream/main
git checkout HEAD~1 -- fly.toml
git add -- fly.toml
git commit -m "chore(deploy): keep fork fly.toml"
git push origin main
```
````
说明:
الاسم:
- ``دمج بوابة المنبع/الرئيسية''
- `git merge upstream/main` 用于同步原仓库最新代码
- `git checkout HEAD~1 -- fly.toml` 用于恢复合并前你 fork 自己的 `fly.toml`
- 如果上游没有改 `fly.toml这一步不会带来额外差异
- اضغط على `fly.toml`، واستخدام حماية Fly لملفات تعريف الارتباط، والملفات، وشوكة شوكة.
- 如果上游没有改 `fly.toml`这一步不会带来额外差异
- 如果上游改了 `fly.toml`,这一步能确保 Fly 应用名、挂载卷、区域等 fork 自定义部署配置不被覆盖
تم إنشاء الإصدار 3.4.7 من الإصدار 3.4.7، وقد تم تصميمه بواسطة ``المنبع/الرئيسي``:```powershell
git merge-base --is-ancestor v3.4.7 upstream/main```
如果你明确只想对齐某个发布标签,例如 `v3.4.7`,也可以先确认标签是否已经包含在 `upstream/main`
يتم تحديد المنبع/الرئيسي بواسطة المنبع/الرئيسي.### 9.2 同步上游后的标准发布顺序
```powershell
git merge-base --is-ancestor v3.4.7 upstream/main
```
أفضل ما في الأمر هو الحصول على أفضل الأسعار:
返回成功表示 `upstream/main` 已经包含该版本,直接合并 `upstream/main` 即可。
1. جلب git المنبع --tags
2. "دمج بوابة المنبع/الرئيسية".
3. شوكة شوكة "fly.toml".
4. `جيت دفع الأصل الرئيسي`
5. "نشر flyctl".
6. ``حالة flyctl - طريق شامل``
7. ``flyctl logs --no-tail -a omniroute`
### 9.2 同步上游后的标准发布顺序
تم تحديث الإصدار `v3.4.7` من الإصدار الجديد.---
同步原仓库完成后,推荐按下面顺序发布:
1. `git fetch upstream --tags`
2. `git merge upstream/main`
3. 恢复 fork 的 `fly.toml`
4. `git push origin main`
5. `flyctl deploy`
6. `flyctl status -a omniroute`
7. `flyctl logs --no-tail -a omniroute`
这就是当前项目升级到 `v3.4.7` 时使用的实际流程。
---
## 10. 发布后检查
### 10.1 查看应用状态
```powershell
حالة flyctl - طريق شامل```
flyctl status -a omniroute
```
### 10.2 查看启动日志
```powershell
سجلات flyctl - بدون ذيل - طريق شامل```
flyctl logs --no-tail -a omniroute
```
### 10.3 检查网站可访问
```powershell
حاول {
(استدعاء WebRequest -Uri "https://omniroute.fly.dev" -MaximumRedirection 5 -UseBasicParsing).رمز الحالة
} أمسك {
إذا ($_.Exception.Response) {
try {
(Invoke-WebRequest -Uri "https://omniroute.fly.dev" -MaximumRedirection 5 -UseBasicParsing).StatusCode
} catch {
if ($_.Exception.Response) {
$_.Exception.Response.StatusCode.value__
} آخر {
رمي
} else {
throw
}
}```
}
```
`200` 说明站点已正常响应.---
返回 `200` 说明站点已正常响应
---
## 11. 成功标志
أفضل ما في الأمر:```text
部署成功后,日志里应看到类似内容:
```text
[bootstrap] Secrets persisted to: /data/server.env
[DB] SQLite database ready: /data/storage.sqlite
````
```
هذا هو الحل:
这两个点很关键:
- `/data/server.env`
- `/data/storage.sqlite` تم تخزين البيانات فيه
- `/data/server.env` 说明运行时密钥落到了持久卷
- `/data/storage.sqlite` 说明数据库写入持久卷
تم إلغاء الطلب `/app/data/...``DATA_DIR` إلغاء الطلب، 需要立即修正.---## 12. 常见问题
如果你看到的是 `/app/data/...`,说明 `DATA_DIR` 没配对,需要立即修正。
---
## 12. 常见问题
### 12.1 `Secrets` 页面是空的
اسم المنتج:
通常有两种原因:
- 你还没执行 "مجموعة أسرار flyctl".
- تم إلغاء التثبيت، `الطريق`، `الطريق الشامل`### 12.2 `flyctlploy` `لم يتم العثور على التطبيق`
- 你还没执行 `flyctl secrets set`
- 你打开的是另一个应用,例如 `oroute`,不是 `omniroute`
اسم المنتج:`powershell
تقوم تطبيقات flyctl بإنشاء طريق شامل`
### 12.2 `flyctl deploy` 报 `app not found`
先创建应用:
```powershell
flyctl apps create omniroute
```
### 12.3 `fly.toml` 解析失败
اسم المنتج:
重点检查:
- 注释里是否有乱码字符
- TOML 引号和缩进是否正确### 12.4 数据没有持久化
- TOML 引号和缩进是否正确
检查以下两点:
### 12.4 数据没有持久化
- `fly.toml` `الوجهة = '/ البيانات''
- `DATA_DIR` 是否设置为 `/data`### 12.5 不设置 `INITIAL_PASSWORD` 是否能跑
检查以下两点:
هذا هو السبب في أن هذا هو السبب وراء `CHANGEME`.---
- `fly.toml` 中是否存在 `destination = '/data'`
- `DATA_DIR` 是否设置为 `/data`
### 12.5 不设置 `INITIAL_PASSWORD` 是否能跑
可以运行,但会回退到默认 `CHANGEME`。生产环境建议尽快修改后台密码。
---
## 13. 新项目复用建议
لا داعي للقلق بشأن هذه المشكلة:
如果以后是新项目照着这份文档部署,最少改这几项:
1. قم بتنزيل "fly.toml" على "التطبيق"
2. قم بزيارة `NEXT_PUBLIC_BASE_URL`
3. اختر "DATA_DIR=/data".
4. قم بالضغط على `API_KEY_SECRET``JWT_SECRET``MACHINE_ID_SALT``STORAGE_ENCRYPTION_KEY`
5. قم بإنشاء بيانات جديدة `/data`
1. 修改 `fly.toml` 里的 `app`
2. 修改 `NEXT_PUBLIC_BASE_URL`
3. 保持 `DATA_DIR=/data`
4. 重新生成 `API_KEY_SECRET``JWT_SECRET``MACHINE_ID_SALT``STORAGE_ENCRYPTION_KEY`
5. 首次部署后检查日志是否写入 `/data`
لا داعي للقلق بشأن هذا الأمر.---
不要直接复用旧项目的密钥。
---
## 14. 当前项目的最小发布清单
أفضل ما في الأمر هو الحصول على أفضل النتائج:```powershell
当前项目后续最常用的命令如下:
```powershell
flyctl auth whoami
flyctl status -a omniroute
flyctl secrets list -a omniroute
flyctl deploy
flyctl logs --no-tail -a omniroute
```
````
如果只是正常发版,核心就是:
أفضل ما في الأمر:```powershell
نشر flyctl```
```powershell
flyctl deploy
```
أفضل ما في الأمر:
如果是新环境首次部署,核心就是:
1. "تسجيل الدخول بمصادقة flyctl".
2. `تطبيقات flyctl تنشئ طريقًا شاملاً`
3. ``مجموعة أسرار flyctl ... -طريق شامل``
4. "نشر flyctl".
5. `سجلات flyctl --no-tail -a omniroute`
````
1. `flyctl auth login`
2. `flyctl apps create omniroute`
3. `flyctl secrets set ... -a omniroute`
4. `flyctl deploy`
5. `flyctl logs --no-tail -a omniroute`

View File

@@ -4,181 +4,229 @@
---
يدعم OmniRoute**30 لغة**مع ترجمة كاملة لواجهة مستخدم لوحة المعلومات، والوثائق المترجمة، ودعم RTL للغة العربية والعبرية.## مرجع سريع
OmniRoute supports **30 languages** with full dashboard UI translation, translated documentation, and RTL support for Arabic and Hebrew.
| مهمة | الأمر |
| ------------------------------------ | --------------------------------------------------------------------------------------- | ---------------------------- |
| توليد الترجمات | `نصوص المؤتمرة/i18n/generate-multilang.mjs messages` |
| ترجمة المستندات (ماجستير في القانون) | `python3 scripts/i18n_autotranslate.py --api-url <url> --api-key <key> --model <model>` |
| التحقق من صحة اللغة | `python3 scripts/validate_translation.py fast -l cs` |
| تحقق من المفاتيح التعليمات | `python3 scripts/check_translations.py` |
| إنشاء تقرير ضمان الجودة | `العقدة النصية/i18n/generate-qa-checklist.mjs` |
| ضمان الجودة المرئية (كاتب مسرحي) | `العقدة النصية/i18n/run-visual-qa.mjs` | ##الهندسة### Source of Truth |
## Quick Reference
-**سلاسل واجهة المستخدم**: `src/i18n/messages/en.json` (المصدر باللغة الإنجليزية، ~2800 مفتاح) -**ملفات اللغة**: `src/i18n/messages/{locale}.json` (30 ترجمة) -**Framework**: `next-intl` مع الاعتماد التلقائي المستندة إلى ملفات تعريف الارتباط -**التكوين**: `src/i18n/config.ts` — يحدد جميع اللغات الثلاثين وأسماء اللغات والأعلام### Runtime Flow
| Task | Command |
| ---------------------- | --------------------------------------------------------------------------------------- |
| Generate translations | `node scripts/i18n/generate-multilang.mjs messages` |
| Translate docs (LLM) | `python3 scripts/i18n_autotranslate.py --api-url <url> --api-key <key> --model <model>` |
| Validate a locale | `python3 scripts/validate_translation.py quick -l cs` |
| Check code keys | `python3 scripts/check_translations.py` |
| Generate QA report | `node scripts/i18n/generate-qa-checklist.mjs` |
| Visual QA (Playwright) | `node scripts/i18n/run-visual-qa.mjs` |
1. يقوم المستخدم باختيار اللغة → مجموعة ملفات تعريف الارتباط `NEXT_LOCALE`
2. `src/i18n/request.ts` يحل اللغة: ملف تعريف الارتباط → رأس `قبول اللغة` → محايد `ar`
3. يقوم باستيراد الرسائل الالكترونية/{locale}.json
4.استخدام المكونات `useTranslations("namespace")` و`t("key")`### اللغات المدعومة
## الهندسة
| الكود | اللغة | من الإنجليزية إلى فارس | كود ترجمة جوجل |
| -------------------- | --------------------- | ---------------------- | ----------------- | -------------------------------------------- |
| `ع` | العربية | نعم | `ع` |
| `بج` | البلغارية | لا | `بج` |
| `CS` | تشيستينا | لا | `CS` |
| `دا` | دانسك | لا | `دا` |
| `دي` | الألمانية | لا | `دي` |
| `es` | الاسبانية | لا | `es` |
| `في` | سومي | لا | `في` |
| `الاب` | الفرنسية | لا | `الاب` |
| `هو` | عبرية | نعم | `iw` |
| `مرحبا` | الهندية | لا | `مرحبا` |
| `هو` | المجرية | لا | `هو` |
| "معرف" | البهاسا الإندونيسية | لا | "معرف" |
| "إنه" | إيطالينو | لا | "إنه" |
| `جا` | 日本語 | لا | `جا` |
| `كو` | 한국어 | لا | `كو` |
| `مس` | البهاسا ملايو | لا | `مس` |
| `نل` | هولندا | لا | `نل` |
| `لا` | نورسك | لا | `لا` |
| `فاي` | فلبينية | لا | `ل` |
| `ر` | بولسكي | لا | `ر` |
| `نقطة` | البرتغالية (البرتغال) | لا | `نقطة` |
| `pt-BR` | إسبانيا (البرازيل) | لا | `نقطة` |
| `رو` | رومانا | لا | `رو` |
| `رو` | Русский | لا | `رو` |
| `سك` | سلوفينيا | لا | `سك` |
| `sv` | سفينسكا | لا | `sv` |
| `ال` | ไทย | لا | `ال` |
| `تر` | تركي | لا | `تر` |
| `المملكة المتحدة-UA` | أوكرانيا | لا | `المملكة المتحدة` |
| `السادس` | تينغ فيت | لا | `السادس` |
| `zh-CN` | 中文 (简体) | لا | `zh-CN` | ## إضافة لغة جديدة### 1. Register the Locale |
### Source of Truth
تحرير `src/i18n/config.ts`:`ts
// أضف إلى مجموعة LOCALES
"س س"،
// أضف إلى مصفوفة اللغات
{ الكود: "xx"، التصنيف: "XX"، الاسم: "اسم اللغة"، العلم: "🏳️" },`
- **UI strings**: `src/i18n/messages/en.json` (English source, ~2800 keys)
- **Locale files**: `src/i18n/messages/{locale}.json` (30 translations)
- **Framework**: `next-intl` with cookie-based locale resolution
- **Config**: `src/i18n/config.ts` — defines all 30 locales, language names, flags
### Runtime Flow
1. User selects language → `NEXT_LOCALE` cookie set
2. `src/i18n/request.ts` resolves locale: cookie → `Accept-Language` header → fallback `en`
3. Dynamic import loads `messages/{locale}.json`
4. Components use `useTranslations("namespace")` and `t("key")`
### Supported Locales
| Code | Language | RTL | Google Translate Code |
| ------- | -------------------- | --- | --------------------- |
| `ar` | العربية | Yes | `ar` |
| `bg` | Български | No | `bg` |
| `cs` | Čeština | No | `cs` |
| `da` | Dansk | No | `da` |
| `de` | Deutsch | No | `de` |
| `es` | Español | No | `es` |
| `fi` | Suomi | No | `fi` |
| `fr` | Français | No | `fr` |
| `he` | עברית | Yes | `iw` |
| `hi` | हिन्दी | No | `hi` |
| `hu` | Magyar | No | `hu` |
| `id` | Bahasa Indonesia | No | `id` |
| `it` | Italiano | No | `it` |
| `ja` | 日本語 | No | `ja` |
| `ko` | 한국어 | No | `ko` |
| `ms` | Bahasa Melayu | No | `ms` |
| `nl` | Nederlands | No | `nl` |
| `no` | Norsk | No | `no` |
| `phi` | Filipino | No | `tl` |
| `pl` | Polski | No | `pl` |
| `pt` | Português (Portugal) | No | `pt` |
| `pt-BR` | Português (Brasil) | No | `pt` |
| `ro` | Română | No | `ro` |
| `ru` | Русский | No | `ru` |
| `sk` | Slovenčina | No | `sk` |
| `sv` | Svenska | No | `sv` |
| `th` | ไทย | No | `th` |
| `tr` | Türkçe | No | `tr` |
| `uk-UA` | Українська | No | `uk` |
| `vi` | Tiếng Việt | No | `vi` |
| `zh-CN` | 中文 (简体) | No | `zh-CN` |
## Adding a New Language
### 1. Register the Locale
Edit `src/i18n/config.ts`:
```ts
// Add to LOCALES array
"xx",
// Add to LANGUAGES array
{ code: "xx", label: "XX", name: "Language Name", flag: "🏳️" },
```
### 2. Add to Generator
تحرير "scripts/i18n/generate-multilang.mjs" - إضافة إدخال إلى "LOCALE_SPECS":```js
{
code: "xx",
googleTl: "xx",
label: "XX",
flag: "🏳️",
languageName: "Language Name",
readmeName: "Language Name",
docsName: "Language Name",
},
Edit `scripts/i18n/generate-multilang.mjs` — add entry to `LOCALE_SPECS`:
````
```js
{
code: "xx",
googleTl: "xx",
label: "XX",
flag: "🏳️",
languageName: "Language Name",
readmeName: "Language Name",
docsName: "Language Name",
},
```
### 3. Generate Initial Translation
```bash
node scripts/i18n/generate-multilang.mjs messages
````
```
يؤدي هذا إلى إنشاء src/i18n/messages/xx.json مترجمًا آليًا من `en.json` عبر الترجمة خدمة من Google.### 4. مراجعة الترجمات التلقائية وإصلاحها
This creates `src/i18n/messages/xx.json` auto-translated from `en.json` via Google Translate.
الترجمات التلقائية هي نقطة البداية. التعديل اليدوي لـ:
### 4. Review & Fix Auto-Translations
- الدقة الفنية
- المصطلحات الصحيحة للسياق
- التعامل مع العناصر النائبة (`{count}`، `{value}`، وما إلى ذلك)### 5. التحقق من صحة```bash
python3 scripts/validate_translation.py quick -l xx
python3 scripts/validate_translation.py diff common -l xx
Auto-translations are a starting point. Review manually for:
````
- Technical accuracy
- Context-appropriate terminology
- Proper handling of placeholders (`{count}`, `{value}`, etc.)
### 5. Validate
```bash
python3 scripts/validate_translation.py quick -l xx
python3 scripts/validate_translation.py diff common -l xx
```
### 6. Generate Translated Documentation
```bash
node scripts/i18n/generate-multilang.mjs docs
````
```
## Auto-Translation Pipeline
### generate-multilang.mjs (Google Translate)
**محرك الترجمة التلقائي الأساسي**— يستخدم برمجة برمجة تطبيقات لترجمة Google إنشاء ترجمات لسلاسل واجهة المستخدم والملفات البرمجة والوثائق.`bash
البرامج النصية للعقدة/i18n/generate-multilang.mjs [الرسائل|الملف التمهيدي|المستندات|الكل]`
**Primary auto-translation engine** — uses Google Translate free API to generate translations for UI strings, READMEs, and documentation.
| الوضع | ماذا يفعل |
| ---------------- | ------------------------------------------------------------------------- |
| `الرسائل` | يترجم المفاتيح المفقودة في `src/i18n/messages/{locale}.json` من `en.json` |
| "الملف التمهيدي" | يترجم `README.md` إلى كافة اللغات كـ `README.{code}.md` في جذر المشروع |
| `المستندات` | يترجم `DOC_SOURCE_FILES` إلى `docs/i18n/{locale}/{docName}` |
| `الكل` | يعمل على جميع الأوضاع الثلاثة |
```bash
node scripts/i18n/generate-multilang.mjs [messages|readme|docs|all]
```
**الميزات:**
| Mode | What it does |
| ---------- | ----------------------------------------------------------------------------- |
| `messages` | Translates missing keys in `src/i18n/messages/{locale}.json` from `en.json` |
| `readme` | Translates `README.md` into all locales as `README.{code}.md` in project root |
| `docs` | Translates `DOC_SOURCE_FILES` into `docs/i18n/{locale}/{docName}` |
| `all` | Runs all three modes |
-**حماية النص**: كتل التعليمات البرمجية للأقنعة (```)، والتعليمات البرمجية المضمنة (`` `)، وروابط/صور تخفيض السعر (`[نص](url)`)، وعلامات HTML، والجداول، والعناصر النائبة لـ ICU (`{count}`، `{value}`، `{total}`، وما إلى ذلك) قبل الترجمة، ثم استعادتها -**التجميع المقسم**: ربط سلاسل متعددة باستخدام محددات `__OMNIROUTE_I18N_SEPARATOR__` لتقليل استدعاءات واجهة برمجة التطبيقات (بحد أقصى 1800 حرف لكل طلب) -**ذاكرة التخزين المؤقت في الذاكرة**: تتجنب استدعاءات واجهة برمجة التطبيقات المتكررة للسلاسل المتكررة خلال الجلسة -**منطق إعادة المحاولة**: التراجع الأسي (حتى 5 محاولات مع 300 مللي ثانية × تأخير المحاولة) للأخطاء 429/5xx -**المهلة**: 20 ثانية لكل طلب -**تخطي الملف الموجود**: إذا كان الملف الهدف موجودًا بالفعل، فلن تتم الكتابة فوقه
**Features:**
**سلوكيات مهمة:**
- **Text protection**: Masks code blocks (` ``` `), inline code (`` ` ``), markdown links/images (`[text](url)`), HTML tags, tables, and ICU placeholders (`{count}`, `{value}`, `{total}`, etc.) before translation, then restores them
- **Chunked batching**: Joins multiple strings with `__OMNIROUTE_I18N_SEPARATOR__` delimiters to minimize API calls (max 1800 chars per request)
- **In-memory cache**: Avoids redundant API calls for repeated strings within a session
- **Retry logic**: Exponential backoff (up to 5 attempts with 300ms × attempt delay) for 429/5xx errors
- **Timeout**: 20 seconds per request
- **Skip existing**: If target file already exists, it is NOT overwritten
- `docs/i18n/README.md` يتم**إعادة إنشائه**كل مرة — وهو عبارة عن فهرس يتم إنشاؤه تلقائيًا لجميع المستندات
- يتم إنشاء ملفات `README.{code}.md` الجذر فقط في حالة عدم وجودها (يتخطى اللغات المحلية في `EXISTING_README_CODES`)
- يتم إدراج/تحديث أشرطة اللغة (`🌐**اللغات:**...`) تلقائيًا في جميع المستندات المترجمة### i18n_autotranslate.py (LLM-based)
**Important behaviors:**
**مترجم ثانوي**— يستخدم أي LLM API متوافق مع OpenAI (بما في ذلك OmniRoute نفسه) لترجمة ملفات تخفيض السعر الموجودة `docs/i18n/`. الأفضل لتلميع المستندات أو إعادة ترجمتها بجودة أفضل من ترجمة Google.```bash
- `docs/i18n/README.md` is **regenerated** each run — it's an auto-generated index of all docs
- Root `README.{code}.md` files are only created if they don't exist (skips locales in `EXISTING_README_CODES`)
- Language bars (`🌐 **Languages:** ...`) are automatically inserted/updated in all translated docs
### i18n_autotranslate.py (LLM-based)
**Secondary translator** — uses any OpenAI-compatible LLM API (including OmniRoute itself) to translate existing `docs/i18n/` markdown files. Best for polishing or re-translating docs with better quality than Google Translate.
```bash
python3 scripts/i18n_autotranslate.py \
--api-url http://localhost:20128/v1 \
--api-key sk-your-key \
--model gpt-4o
--api-url http://localhost:20128/v1 \
--api-key sk-your-key \
--model gpt-4o
```
````
**Features:**
**الميزات:**
- Scans `docs/i18n/` markdown files for English paragraphs
- Skips code blocks, tables, and already-translated content
- Sends paragraphs to LLM with technical translation system prompt
- Supports all 30 languages
- يقوم بمسح الملفات المشهورة بسعر رخيص `docs/i18n/` بحثًا عن الفقرات الإنجليزية
- تخطي كتل التعليمات البرمجية والبرمجيات والمحتوى المترجم بالفعل
- يرسلون الفقرات إلى LLM مع نظام الترجمة الفوري
- يدعم جميع اللغات الثلاثين## Validation & QA### validate_translation.py
## Validation & QA
**أداة التحقق من صحة الترجمة**— مقارنة أي لغة JSON مع `en.json` وإبلاغ المشكلات.```bash
# فحص سريع (التهم فقط)
python3 scripts/validate_translation.py fast -l cs
# الإخراج:
#مفقود: 0
# غير مترجم: 0
# تم التجاهل (UNTRANSLATABLE_KEYS): 236
### validate_translation.py
# الفرق التفصيلي حسب الفئة
**Translation validator** — compares any locale JSON against `en.json` and reports issues.
```bash
# Quick check (counts only)
python3 scripts/validate_translation.py quick -l cs
# Output:
# Missing: 0
# Untranslated: 0
# Ignored (UNTRANSLATABLE_KEYS): 236
# Detailed diff by category
python3 scripts/validate_translation.py diff common -l cs
python3 scripts/validate_translation.py إعدادات الفرق -l cs
python3 scripts/validate_translation.py diff settings -l cs
# تصدير إلى CSV
# Export to CSV
python3 scripts/validate_translation.py csv -l cs > report.csv
# تصدير إلى تخفيض السعر
# Export to Markdown
python3 scripts/validate_translation.py md -l cs > report.md
# التقرير الكامل (الافتراضي)
python3 scripts/validate_translation.py -l cs```
# Full report (default)
python3 scripts/validate_translation.py -l cs
```
**يكتشف:**
**Detects:**
-**المفاتيح المفقودة**— المفاتيح الموجودة في `en.json` ولكن ليست في الملف المحلي
-**مفاتيح إضافية**— مفاتيح في ملف الإعدادات المحلية ولكن ليس في `en.json`
-**المفاتيح غير المترجمة**— المفاتيح التي تساوي فيها قيمة اللغة المصدر باللغة الإنجليزية (باستثناء القائمة المسموح بها)
-**عدم تطابق العناصر النائبة**— العناصر النائبة لـ ICU غير متطابقة بين المصدر والترجمة
- **Missing keys** keys in `en.json` but not in locale file
- **Extra keys** keys in locale file but not in `en.json`
- **Untranslated keys** — keys where locale value equals English source (excluding allowlist)
- **Placeholder mismatches** ICU placeholders that don't match between source and translation
**رموز الخروج:**
| الكود | معنى |
**Exit codes:**
| Code | Meaning |
|------|---------|
| 0 | موافق |
| 1 | خطأ عام |
| 2 | سلاسل مفقودة (خطأ فادح) |
| 3 | تحذير غير مترجم (ناعم) |
| 0 | OK |
| 1 | Generic error |
| 2 | Missing strings (hard error) |
| 3 | Untranslated warning (soft) |
**البيئة:**قم بتعيين `TRANSLATION_LANG=cs` أو استخدم علامة `-l cs`.### check_translations.py
**Environment:** Set `TRANSLATION_LANG=cs` or use `-l cs` flag.
**مدقق المفاتيح Code-to-JSON**— يفحص `src/**/*.tsx` و`src/**/*.ts` لاستدعاءات `useTranslations()` ويتحقق من وجود جميع المفاتيح المشار إليها في `en.json`.```bash
### check_translations.py
**Code-to-JSON key checker** — scans `src/**/*.tsx` and `src/**/*.ts` for `useTranslations()` calls and verifies all referenced keys exist in `en.json`.
```bash
# Basic check
python3 scripts/check_translations.py
@@ -187,175 +235,207 @@ python3 scripts/check_translations.py --verbose
# Auto-fix (adds missing keys to en.json)
python3 scripts/check_translations.py --fix
````
```
### generate-qa-checklist.mjs
**تحليل ثابت وجودة**— يقوم بفحص الملفات صفحة Next.js بحثًا عن مقاييس ألمانية i18n منشئ ويتقرير Markdown.`bash
العقدة النصية/i18n/generate-qa-checklist.mjs`
**Static analysis QA** — scans Next.js page files for i18n risk metrics and generates a Markdown report.
**الفحوصات:**
```bash
node scripts/i18n/generate-qa-checklist.mjs
```
- استخدام فئة العرض الثابت (خطر التجاوز)
- فئات الاتجاه لليسار/اليمين (خطر RTL)
- الأنماط المعرضة للتقطيع
- التكافؤ المحلي (مفاتيح مفقودة/إضافية مقابل `en.json`)
- أشرطة تحديد اللغة README في اللغات المحلية ذات الأولوية (`es`، `fr`، `de`، `ja`، `ar`)
**Checks:**
**الإخراج:**`docs/reports/i18n-qa-checklist-{date}.md`### run-visual-qa.mjs
- Fixed-width class usage (overflow risk)
- Directional left/right classes (RTL risk)
- Clipping-prone patterns
- Locale parity (missing/extra keys vs `en.json`)
- README language selector bars in priority locales (`es`, `fr`, `de`, `ja`, `ar`)
**Visual QA عبر Playwright**— يلتقط لقطات شاشة لجميع مسارات لوحة المعلومات في مناطق ومنافذ عرض متعددة، ثم يقوم بتقييم صحة الصفحة.```bash
**Output:** `docs/reports/i18n-qa-checklist-{date}.md`
### run-visual-qa.mjs
**Visual QA via Playwright** — takes screenshots of all dashboard routes in multiple locales and viewports, then evaluates page health.
```bash
# Default: es, fr, de, ja, ar on localhost:20128
node scripts/i18n/run-visual-qa.mjs
# Custom base URL and locales
QA_BASE_URL=http://staging.example.com QA_LOCALES=de,fr node scripts/i18n/run-visual-qa.mjs
# Custom routes
QA_ROUTES=/dashboard/settings,/dashboard/providers node scripts/i18n/run-visual-qa.mjs
```
````
**Detects:**
**اكتشف:**
- Text overflow
- Element clipping
- RTL layout mismatches
- تجاوز النص
- قطع العناصر
- عدم تطابق تخطيط RTL
**Output:** `docs/reports/i18n-visual-qa-{date}.md` + JSON report
**الإخراج:**`docs/reports/i18n-visual-qa-{date}.md` + تقرير JSON## إدارة المفاتيح غير القابلة للترجمة### untranslatable-keys.json
## Managing Untranslatable Keys
**الملف:**`scripts/i18n/untranslatable-keys.json`
### untranslatable-keys.json
"""""""""""للمفاتيح التي يجب أن تستعين بها للمصدر باللغة الإنجليزية. انتبه بواسطة `validate_translation.py` للإشعارات المسببة لأسباب "غير الترجمة".```json
**File:** `scripts/i18n/untranslatable-keys.json`
Allowlist of keys that should remain identical to English source. Used by `validate_translation.py` to avoid false-positive "untranslated" warnings.
```json
{
"description": "المفاتيح التي يجب أن تظل غير مترجمة..."،
"مفاتيح": [
"النموذج المشترك"،
"common.oauth"،
"health.cpu"،
"description": "Keys that should remain untranslated...",
"keys": [
"common.model",
"common.oauth",
"health.cpu",
...
]
}```
}
```
**ما ينتمي هنا:**
**What belongs here:**
- أسماء العلامات التجارية/المنتجات: `landing.brandName`common.social-github`
- المصطلحات/المختصرات الفنية: `health.cpu`mcpDashboard.pid`settings.ai`
- سلاسل ICU/تنسيق: `apiManager.modelsCount`health.millithansShort`
- قيم العنصر النائب: `providers.openaiBaseUrlPlaceholder`cliTools.baseUrlPlaceholder`
- أسماء البروتوكولات: `common.http`common.oauth`providers.oauth2Label`
- أقسام التنقل: `sidebar.primarySection`sidebar.cliSection`
- Brand/product names: `landing.brandName`, `common.social-github`
- Technical terms/acronyms: `health.cpu`, `mcpDashboard.pid`, `settings.ai`
- ICU/format strings: `apiManager.modelsCount`, `health.millisecondsShort`
- Placeholder values: `providers.openaiBaseUrlPlaceholder`, `cliTools.baseUrlPlaceholder`
- Protocol names: `common.http`, `common.oauth`, `providers.oauth2Label`
- Navigation sections: `sidebar.primarySection`, `sidebar.cliSection`
**لإضافة مفتاح:**قم بتحرير مصفوفة `المفاتيح` في `scripts/i18n/untranslatable-keys.json` وأعد تشغيل التحقق من الصحة.## CI Integration
**To add a key:** Edit the `keys` array in `scripts/i18n/untranslatable-keys.json` and re-run validation.
## CI Integration
### GitHub Actions (`.github/workflows/ci.yml`)
يتحقق خط أنابيب CI من صحة جميع اللغات في كل دفعة وPR:
The CI pipeline validates all locales on every push and PR:
1.**`i18n-matrix` job**— يكتشف بشكل ديناميكي جميع الملفات المحلية (باستثناء `en.json`)
2.**`i18n` job**— يتم تشغيل `validate_translation.py Quick -l '<lang>'` لكل لغة بالتوازي
3.**`ci-summary` job**— تجميع النتائج في ملخص لوحة المعلومات```yaml
1. **`i18n-matrix` job** dynamically discovers all locale files (excluding `en.json`)
2. **`i18n` job** runs `validate_translation.py quick -l '<lang>'` for each locale in parallel
3. **`ci-summary` job** aggregates results into a dashboard summary
```yaml
# i18n-matrix: discovers languages
LANGS=$(ls src/i18n/messages/*.json | xargs -n1 basename | sed 's/.json$//' | grep -v '^en$')
# i18n: validates each language
python3 scripts/validate_translation.py quick -l '${{ matrix.lang }}'
````
```
**إخراج لوحة التحكم:**```
**Dashboard output:**
## 🌍 الترجمات
```
## 🌍 Translations
| Metric | Value |
|--------|------|
| Languages checked | 30 |
| Total untranslated | 0 |
| متري | القيمة |
| ----------------- | ------ |
| تم فحص اللغات | 30 |
| المجموع غير مترجم | 0 |
✅جميع الترجمات كاملة```
✅ All translations complete
```
## File Structure
````
سرك/i18n/
├── config.ts # تعريفات الإعدادات المحلية (30 لغة، تكوين RTL)
├── request.ts # دقة لغة وقت التشغيل
└── الرسائل/
├── ar.json # مصدر الحقيقة (~2800 مفتاح)
├── cs.json # الترجمة التشيكية
├── de.json # ترجمة ألمانية
└── ... إجمالي # 30 ملفًا محليًا
```
src/i18n/
├── config.ts # Locale definitions (30 locales, RTL config)
├── request.ts # Runtime locale resolution
└── messages/
├── en.json # Source of truth (~2800 keys)
├── cs.json # Czech translation
├── de.json # German translation
└── ... # 30 locale files total
البرامج النصية/
├──i18n/
│ ├── generator-multilang.mjs # محرك الترجمة التلقائية (ترجمة جوجل، 888 سطرًا)
│ ├── create-qa-checklist.mjs # التحليل الثابت ضمان الجودة
│ ├── run-visual-qa.mjs # Playwright visual QA
│ └── untranslatable-keys.json # القائمة المسموح بها للتحقق (236 مفتاحًا)
├── validate_translation.py # مدقق الترجمة
├── check_translations.py # مدقق مفتاح Code-to-JSON
└── i18n_autotranslate.py # مترجم مستندات مستند إلى LLM
scripts/
├── i18n/
├── generate-multilang.mjs # Auto-translation engine (Google Translate, 888 lines)
├── generate-qa-checklist.mjs # Static analysis QA
├── run-visual-qa.mjs # Playwright visual QA
└── untranslatable-keys.json # Allowlist for validation (236 keys)
├── validate_translation.py # Translation validator
├── check_translations.py # Code-to-JSON key checker
└── i18n_autotranslate.py # LLM-based doc translator
.جيثب/سير العمل/
└── التحقق من صحة ci.yml # i18n في مصفوفة CI
.github/workflows/
└── ci.yml # i18n validation in CI matrix
المستندات/
├── I18N.md # هذا الملف — وثائق سلسلة أدوات i18n
├──i18n/
│ ├── README.md # فهرس اللغة الذي تم إنشاؤه تلقائيًا
│ ├── cs/ # مستندات تشيكية
│ │ └── المستندات /
│ ├── I18N.md # الترجمة التشيكية لهذا الملف
│ └── ...
│ ├── de/ # المستندات الألمانية
│ └── ... # 30 دليل محلي
└── التقارير/
├── i18n-qa-checklist-*.md # تقارير التحليل الثابت
└── i18n-visual-qa-*.md # تقارير ضمان الجودة المرئية```
docs/
├── I18N.md # This file — i18n toolchain documentation
├── i18n/
├── README.md # Auto-generated language index
├── cs/ # Czech docs
│ │ └── docs/
├── I18N.md # Czech translation of this file
└── ...
├── de/ # German docs
└── ... # 30 locale directories
└── reports/
├── i18n-qa-checklist-*.md # Static analysis reports
└── i18n-visual-qa-*.md # Visual QA reports
```
## Best Practices
### When Editing Translations
1.**قم دائمًا بتحرير `en.json` أولاً**— فهو مصدر الحقيقة
2.**قم بتشغيل رسائل generator-multilang.mjs**لنشر مفاتيح جديدة لجميع اللغات
3.**مراجعة الترجمات التلقائية**— ترجمة Google هي نقطة البداية، وليست نهائية
4.**التحقق قبل الالتزام**— `python3 scripts/validate_translation.py Quick -l <lang>`
5.**قم بتحديث `untranslatable-keys.json`**إذا كان ينبغي أن يظل المفتاح باللغة الإنجليزية### Placeholder Safety
1. **Always edit `en.json` first** — it's the source of truth
2. **Run `generate-multilang.mjs messages`** to propagate new keys to all locales
3. **Review auto-translations** — Google Translate is a starting point, not final
4. **Validate before committing**`python3 scripts/validate_translation.py quick -l <lang>`
5. **Update `untranslatable-keys.json`** if a key should remain in English
- يجب الحفاظ على العناصر النائبة لـ ICU (`{count}`، `{value}`، `{total}`، `{secions}`) تمامًا
- يجب أن تحافظ صيغ الجمع (`{count, plural, one {# model} الأخرى {#models}}`) على البنية
- يكتشف المدقق عدم تطابق العناصر النائبة تلقائيًا### Adding New Translation Keys in Code
### Placeholder Safety
- ICU placeholders (`{count}`, `{value}`, `{total}`, `{seconds}`) must be preserved exactly
- Plural formats (`{count, plural, one {# model} other {# models}}`) must maintain structure
- The validator detects placeholder mismatches automatically
### Adding New Translation Keys in Code
```tsx
// استخدم مفاتيح مساحة الاسم
const t = useTranslations("الإعدادات");
t("إعدادات ذاكرة التخزين المؤقت"); // يتم تعيينه إلى settings.cacheSettings في JSON
// Use namespaced keys
const t = useTranslations("settings");
t("cacheSettings"); // maps to settings.cacheSettings in JSON
// قم بتشغيل check_translations.py للتحقق من وجود المفاتيح
python3 scripts/check_translations.py --verbose```
// Run check_translations.py to verify keys exist
python3 scripts/check_translations.py --verbose
```
### RTL Considerations
- العربية (`ar`) والعبرية (`he`) هي لغات RTL
- تجنب استخدام لغة CSS ذات الترميز الثابت `left`/`right` - استخدم الخصائص المنطقية `start`/`end`
- تكتشف Visual QA عدم تطابق تخطيط RTL عبر "run-visual-qa.mjs".## Known Issues & History
- Arabic (`ar`) and Hebrew (`he`) are RTL locales
- Avoid hardcoded `left`/`right` CSS — use `start`/`end` logical properties
- Visual QA catches RTL layout mismatches via `run-visual-qa.mjs`
## Known Issues & History
### `in.json` → `hi.json` Fix
استخدم المولد في الأصل `الكود: "in"` (كود ترجمة Google المهجور) للغة الهندية بدلاً من ISO 639-1 الصحيح `hi`. أدى هذا إلى إنشاء نسخة معزولة `in.json` من `hi.json`. تم الإصلاح عن طريق تغيير `code: "in"` إلى `code: "hi"` في `generate-multilang.mjs` وإزالة الملف المعزول.### `docs/i18n/README.md` Is Auto-Generated
The generator originally used `code: "in"` (deprecated Google Translate code) for Hindi instead of the correct ISO 639-1 `hi`. This created an orphaned `in.json` duplicate of `hi.json`. Fixed by changing `code: "in"` to `code: "hi"` in `generate-multilang.mjs` and removing the orphaned file.
تمت إعادة إنشاء الملف "docs/i18n/README.md" بالكامل بواسطة "generate-multilang.mjs docs". سيتم فقدان أي تعديلات يدوية. استخدم `docs/I18N.md` (هذا الملف) للوثائق المكتوبة بخط اليد والتي يجب أن تستمر.### External Untranslatable Keys List
### `docs/i18n/README.md` Is Auto-Generated
تم نقل القائمة المسموح بها `untranslatable-keys.json` من مجموعة Python المضمنة في `validate_translation.py` إلى ملف JSON خارجي لتسهيل الصيانة. يقوم المدقق بتحميله في وقت التشغيل.### `generate-multilang.mjs` Hindi Code Fix
The `docs/i18n/README.md` file is completely regenerated by `generate-multilang.mjs docs`. Any manual edits will be lost. Use `docs/I18N.md` (this file) for hand-written documentation that should persist.
استخدم المولد في الأصل `الكود: "in"` (كود ترجمة Google المهجور) للغة الهندية بدلاً من ISO 639-1 الصحيح `hi`. تم تقديم هذا في الالتزام الأولي `952b0b22c` بواسطة diegosouzapw. تم الإصلاح عن طريق تغيير `code: "in"` إلى `code: "hi"` في مصفوفة `LOCALE_SPECS` وإزالة الملف اليتيم `in.json`.### `validate_translation.py` Ignored Count Output
### External Untranslatable Keys List
يعرض الفحص "السريع" الآن عدد المفاتيح التي تم تجاهلها من "untranslatable-keys.json":```
The `untranslatable-keys.json` allowlist was moved from an inline Python set in `validate_translation.py` to an external JSON file for easier maintenance. The validator loads it at runtime.
### `generate-multilang.mjs` Hindi Code Fix
The generator originally used `code: "in"` (deprecated Google Translate code) for Hindi instead of the correct ISO 639-1 `hi`. This was introduced in upstream commit `952b0b22c` by `diegosouzapw`. Fixed by changing `code: "in"` to `code: "hi"` in the `LOCALE_SPECS` array and removing the orphaned `in.json` file.
### `validate_translation.py` Ignored Count Output
The `quick` check now displays the count of ignored keys from `untranslatable-keys.json`:
```
Missing: 0
Untranslated: 0
Ignored (UNTRANSLATABLE_KEYS): 236
````
```

View File

@@ -4,69 +4,84 @@
---
> المدرسة التمهيدية النموذجية المزود بـ 16 أداة ذكية## تثبيت
> Model Context Protocol server with 16 intelligent tools
OmniRoute MCP المدمج. ابدأ بـ:`bash
الطريق الشامل --mcp`
## تثبيت
أو عبر النقل المفتوح:```bash
OmniRoute MCP is built-in. Start it with:
```bash
omniroute --mcp
```
Or via the open-sse transport:
```bash
# HTTP streamable transport (port 20130)
omniroute --dev # MCP auto-starts on /mcp endpoint
omniroute --dev # MCP auto-starts on /mcp endpoint
```
## IDE Configuration
مراجعة تكوينات IDE](integrations/ide-configs.md) التوجه إلى إعداد Antigravity وCursor وCopilot وClaude Desktop.---## Essential Tools (8)
See [IDE Configs](integrations/ide-configs.md) for Antigravity, Cursor, Copilot, and Claude Desktop setup.
| أداة | الوصف |
---
## Essential Tools (8)
| Tool | Description |
| :------------------------------ | :--------------------------------------- |
| `omniroute_get_health` | صحة البوابة، قواطع الضوء، الجهوزية |
| `omniroute_list_combos` | جميع المجموعات التي تم اختيارها مع الارتباطات |
| `omniroute_get_combo_metrics` | مقاييس محددة |
| `omniroute_switch_combo` | تعديل التحرير والسرد فقط حسب المعرف/الاسم |
| `omniroute_check_quota` | حالة الحصة لكل ما يتعلق أو الكل |
| `omniroute_route_request` | استكمال الدردشة من خلال OmniRoute |
| `تقرير رحلة_الطريق الشامل` | تحليلات التكلفة لوقت طويل |
| `omniroute_list_models_catalog` | كتالوج نموذجي كامل مع رموزيات |## أدوات متقدمة (8)
| `omniroute_get_health` | Gateway health, circuit breakers, uptime |
| `omniroute_list_combos` | All configured combos with models |
| `omniroute_get_combo_metrics` | Performance metrics for a specific combo |
| `omniroute_switch_combo` | Switch active combo by ID/name |
| `omniroute_check_quota` | Quota status per provider or all |
| `omniroute_route_request` | Send a chat completion through OmniRoute |
| `omniroute_cost_report` | Cost analytics for a time period |
| `omniroute_list_models_catalog` | Full model catalog with capabilities |
| أداة | الوصف |
## Advanced Tools (8)
| Tool | Description |
| :--------------------------------- | :---------------------------------------------------------- |
| `omniroute_simulate_route` | المحاكاة الجافة باستخدام الشجرة التقليدية |
| `omniroute_set_budget_guard` | ضبط إجراءات مع التخفيض/الحظر/التنبيه |
| `omniroute_set_resilience_profile` | التقدم نحو التقدم/المتوازن/العدواني |
| `omniroute_test_combo` | تم اختباره بشكل مباشر لجميع الاتجاهات في مجموعة من خلال طلب حقيقي للمنبع |
| `omniroute_get_provider_metrics` | معايير محددة لمزود واحد |
| `omniroute_best_combo_for_task` | وصفة بملاءة المهام مع البدائل |
| `omniroute_explain_route` | شرح الوضع السابق |
| `omniroute_get_session_snapshot` | ملحوظة: التكاليف والرموز والأخطاء |## Authentication
| `omniroute_simulate_route` | Dry-run routing simulation with fallback tree |
| `omniroute_set_budget_guard` | Session budget with degrade/block/alert actions |
| `omniroute_set_resilience_profile` | Apply conservative/balanced/aggressive preset |
| `omniroute_test_combo` | Live-test all models in a combo via a real upstream request |
| `omniroute_get_provider_metrics` | Detailed metrics for one provider |
| `omniroute_best_combo_for_task` | Task-fitness recommendation with alternatives |
| `omniroute_explain_route` | Explain a past routing decision |
| `omniroute_get_session_snapshot` | Full session state: costs, tokens, errors |
تم مصادقة أدوات MCP عبر نطاقات المفاتيح API. متطلبات كل أدوات النطاقات المحددة:
## Authentication
| النطاق | أدوات |
MCP tools are authenticated via API key scopes. Each tool requires specific scopes:
| Scope | Tools |
| :------------- | :----------------------------------------------- |
| `اقرأ:الصحة` | get_health، get_provider_metrics |
| `اقرأ: المجموعات` | list_combos، get_combo_metrics |
| `اكتب: المجموعات` | Switch_combo |
| `اقرأ: الحصة` | check_quota |
| `اكتب: الطريق` | طلب_الطريق، محاكاة_الطريق، اختبار_كومبو |
| `قراءة:استخدام` | إقرار التكلفة، الحصول على لقطة_الجلسة، شرح_الطريق |
| `الكتابة: إستبدل` | set_budget_guard، set_resilience_profile |
| `اقرأ:النماذج` | list_models_catalog، best_combo_for_task |## تسجيل التدقيق
| `read:health` | get_health, get_provider_metrics |
| `read:combos` | list_combos, get_combo_metrics |
| `write:combos` | switch_combo |
| `read:quota` | check_quota |
| `write:route` | route_request, simulate_route, test_combo |
| `read:usage` | cost_report, get_session_snapshot, explain_route |
| `write:config` | set_budget_guard, set_resilience_profile |
| `read:models` | list_models_catalog, best_combo_for_task |
يتم تسجيل كل الاتصال للأداة في `mcp_tool_audit` باستخدام:
## Audit Logging
- اسم الأداة، والوسائط، والنتيجة
- المدة (مللي ثانية)، النجاح/الفشل
- تجزئة مفتاح API، الأثر العمري## Files
Every tool call is logged to `mcp_tool_audit` with:
| ملف | الحصاد |
- Tool name, arguments, result
- Duration (ms), success/failure
- API key hash, timestamp
## Files
| File | Purpose |
| :------------------------------------------- | :------------------------------------------ |
| `open-sse/mcp-server/server.ts` | إنشاء خادم MCP + تسجيل 16 أداة |
| `open-sse/mcp-server/transport.ts` | نقل Stdio + HTTP |
| `open-sse/mcp-server/auth.ts` | مفتاح API + التحقق من صحة النطاق |
| `open-sse/mcp-server/audit.ts` | تسجيل تدقيق الاتصال بالأداة |
| `open-sse/mcp-server/tools/advancedTools.ts` | 8 معالجات وأدوات متقدمة |
```
| `open-sse/mcp-server/server.ts` | MCP server creation + 16 tool registrations |
| `open-sse/mcp-server/transport.ts` | Stdio + HTTP transport |
| `open-sse/mcp-server/auth.ts` | API key + scope validation |
| `open-sse/mcp-server/audit.ts` | Tool call audit logging |
| `open-sse/mcp-server/tools/advancedTools.ts` | 8 advanced tool handlers |

View File

@@ -4,23 +4,41 @@
---
استخدم قائمة التحقق هذه قبل وضع علامة على إصدار OmniRoute الجديد أو نشره.## الإصدار وسجل التغيير
Use this checklist before tagging or publishing a new OmniRoute release.
1. قم بتثبيت الإصدار `package.json` (`x.y.z`) في فرع الإصدار.
2. انقل نسخة التعليقات من `## [Unreleased]` في `CHANGELOG.md` إلى قسم المؤرخ:
## Version and Changelog
1. Bump `package.json` version (`x.y.z`) in the release branch.
2. Move release notes from `## [Unreleased]` in `CHANGELOG.md` to a dated section:
- `## [x.y.z] — YYYY-MM-DD`
3. يستخدم بـ `## [Unreleased]` كقسم جديد للعمل القادم القادم.
4. تأكد من أن أحدث قسم في `CHANGELOG.md` يساوي الإصدار `package.json`.## API Docs
3. Keep `## [Unreleased]` as the first changelog section for upcoming work.
4. Ensure the latest semver section in `CHANGELOG.md` equals `package.json` version.
5. قم بزيارة "docs/openapi.yaml":
- يجب أن يكون `info.version` مساويًا لإصدار `package.json`.
6. التحقق من صحة الأمثلة على نقاط نهائية في حالة عدة عقود API.## Runtime Docs
## API Docs
7. قم بمراجعة docs/ARCHITECTURE.md للتخزين/وقت التشغيل.
8. راجع `docs/TROUBLESHOOTING.md` بحثًا عن env var والانجراف التشغيلي.
9. قم بزيارة الموقع بشكل غير المترجم إذا تغيرت مصدر العشب ملحوظة.## الفحص الآلي
1. Update `docs/openapi.yaml`:
- `info.version` must equal `package.json` version.
2. Validate endpoint examples if API contracts changed.
يُسمح له بالسيطرة المحلية قبل فتح العلاقات العامة:`bash
التحقق من تشغيل npm:docs-sync`
## Runtime Docs
يقوم CI أيضًا بتشغيل هذا الفحص في `.github/workflows/ci.yml` (مهمة الوبر).
1. Review `docs/ARCHITECTURE.md` for storage/runtime drift.
2. Review `docs/TROUBLESHOOTING.md` for env var and operational drift.
3. Verify the release/runtime Node.js version still satisfies the supported secure floor:
- `>=20.20.2 <21` or `>=22.22.2 <23`
- `npm run check:node-runtime`
4. Validate the npm publish artifact after building the standalone package:
- `npm run build:cli`
- `npm run check:pack-artifact`
- confirm no `app.__qa_backup`, `scripts/scratch`, `package-lock.json`, or other local residue
5. Update localized docs if source docs changed significantly.
## Automated Check
Run the sync guard locally before opening PR:
```bash
npm run check:docs-sync
```
CI also runs this check in `.github/workflows/ci.yml` (lint job).

View File

@@ -10,15 +10,16 @@ Common problems and solutions for OmniRoute.
## 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 v1.4.11+ (Zod schema fix for settings persistence) |
| Login crash / blank page | You may be on Node.js 24+ — see [Node.js Compatibility](#nodejs-compatibility) below |
| Proxy "fetch failed" | Ensure proxy config is set at the correct level — see [Proxy Issues](#proxy-issues) below |
| 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 v1.4.11+ (Zod schema fix for settings persistence) |
| 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 |
---
@@ -28,26 +29,52 @@ Common problems and solutions for OmniRoute.
### Login page crashes or shows "Module self-registration" error
**Cause:** You are running Node.js 24+. The `better-sqlite3` native binary is not compatible with Node.js 24, which causes a fatal crash when the server tries to initialize the database.
**Cause:** You are running a Node.js version outside OmniRoute's approved secure runtime floor. The most common case is running an older Node 20, 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
- Starting with v3.5.5, the login page shows an **orange warning banner** with your Node version if incompatibility is detected
- The login page shows an **orange warning banner** with your Node version if the runtime is outside the supported secure policy
**Fix:**
1. Install Node.js 22 LTS (recommended):
1. Install a supported Node.js LTS release (recommended: Node.js 24.x):
```bash
nvm install 22
nvm use 22
nvm install 24
nvm use 24
```
2. Verify your version: `node --version` should show `v22.x.x`
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 versions:** Node.js 18, 20, or 22 LTS. Node.js 24+ is **not supported**.
> **Supported secure versions:** `>=20.20.2 <21`, `>=22.22.2 <23`, or `>=24.0.0 <25`. Node.js 24.x LTS (Krypton) is fully supported.
### macOS: `dlopen` / "slice is not valid mach-o file"
<a name="macos-native-module-rebuild"></a>
**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/<user>/.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 range is **`>=20.20.2 <21`, `>=22.22.2 <23`, or `>=24.0.0 <25`** (`engines` field in `package.json`). Node.js 24.x LTS (Krypton) is fully supported with `better-sqlite3` v12.x.
---

View File

@@ -0,0 +1,157 @@
# OmniRoute — Uninstall Guide (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/UNINSTALL.md) · 🇪🇸 [es](../../es/docs/UNINSTALL.md) · 🇫🇷 [fr](../../fr/docs/UNINSTALL.md) · 🇩🇪 [de](../../de/docs/UNINSTALL.md) · 🇮🇹 [it](../../it/docs/UNINSTALL.md) · 🇷🇺 [ru](../../ru/docs/UNINSTALL.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/UNINSTALL.md) · 🇯🇵 [ja](../../ja/docs/UNINSTALL.md) · 🇰🇷 [ko](../../ko/docs/UNINSTALL.md) · 🇸🇦 [ar](../../ar/docs/UNINSTALL.md) · 🇮🇳 [hi](../../hi/docs/UNINSTALL.md) · 🇮🇳 [in](../../in/docs/UNINSTALL.md) · 🇹🇭 [th](../../th/docs/UNINSTALL.md) · 🇻🇳 [vi](../../vi/docs/UNINSTALL.md) · 🇮🇩 [id](../../id/docs/UNINSTALL.md) · 🇲🇾 [ms](../../ms/docs/UNINSTALL.md) · 🇳🇱 [nl](../../nl/docs/UNINSTALL.md) · 🇵🇱 [pl](../../pl/docs/UNINSTALL.md) · 🇸🇪 [sv](../../sv/docs/UNINSTALL.md) · 🇳🇴 [no](../../no/docs/UNINSTALL.md) · 🇩🇰 [da](../../da/docs/UNINSTALL.md) · 🇫🇮 [fi](../../fi/docs/UNINSTALL.md) · 🇵🇹 [pt](../../pt/docs/UNINSTALL.md) · 🇷🇴 [ro](../../ro/docs/UNINSTALL.md) · 🇭🇺 [hu](../../hu/docs/UNINSTALL.md) · 🇧🇬 [bg](../../bg/docs/UNINSTALL.md) · 🇸🇰 [sk](../../sk/docs/UNINSTALL.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/UNINSTALL.md) · 🇮🇱 [he](../../he/docs/UNINSTALL.md) · 🇵🇭 [phi](../../phi/docs/UNINSTALL.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/UNINSTALL.md) · 🇨🇿 [cs](../../cs/docs/UNINSTALL.md) · 🇹🇷 [tr](../../tr/docs/UNINSTALL.md)
---
This guide covers how to cleanly remove OmniRoute from your system.
---
## Quick Uninstall (v3.6.2+)
OmniRoute provides two built-in scripts for clean removal:
### Keep Your Data
```bash
npm run uninstall
```
This removes the OmniRoute application but **preserves** your database, configurations, API keys, and provider settings in `~/.omniroute/`. Use this if you plan to reinstall later and want to keep your setup.
### Full Removal
```bash
npm run uninstall:full
```
This removes the application **and permanently erases** all data:
- Database (`storage.sqlite`)
- Provider configurations and API keys
- Backup files
- Log files
- All files in the `~/.omniroute/` directory
> ⚠️ **Warning:** `npm run uninstall:full` is irreversible. All your provider connections, combos, API keys, and usage history will be permanently deleted.
---
## Manual Uninstall
### NPM Global Install
```bash
# Remove the global package
npm uninstall -g omniroute
# (Optional) Remove data directory
rm -rf ~/.omniroute
```
### pnpm Global Install
```bash
pnpm uninstall -g omniroute
rm -rf ~/.omniroute
```
### Docker
```bash
# Stop and remove the container
docker stop omniroute
docker rm omniroute
# Remove the volume (deletes all data)
docker volume rm omniroute-data
# (Optional) Remove the image
docker rmi diegosouzapw/omniroute:latest
```
### Docker Compose
```bash
# Stop and remove containers
docker compose down
# Also remove volumes (deletes all data)
docker compose down -v
```
### Electron Desktop App
**Windows:**
- Open `Settings → Apps → OmniRoute → Uninstall`
- Or run the NSIS uninstaller from the install directory
**macOS:**
- Drag `OmniRoute.app` from `/Applications` to Trash
- Remove data: `rm -rf ~/Library/Application Support/omniroute`
**Linux:**
- Remove the AppImage file
- Remove data: `rm -rf ~/.omniroute`
### Source Install (git clone)
```bash
# Remove the cloned directory
rm -rf /path/to/omniroute
# (Optional) Remove data directory
rm -rf ~/.omniroute
```
---
## Data Directories
OmniRoute stores data in the following locations by default:
| Platform | Default Path | Override |
| ------------- | ----------------------------- | ------------------------- |
| Linux | `~/.omniroute/` | `DATA_DIR` env var |
| macOS | `~/.omniroute/` | `DATA_DIR` env var |
| Windows | `%APPDATA%/omniroute/` | `DATA_DIR` env var |
| Docker | `/app/data/` (mounted volume) | `DATA_DIR` env var |
| XDG-compliant | `$XDG_CONFIG_HOME/omniroute/` | `XDG_CONFIG_HOME` env var |
### Files in the data directory
| File/Directory | Description |
| -------------------- | ------------------------------------------------- |
| `storage.sqlite` | Main database (providers, combos, settings, keys) |
| `storage.sqlite-wal` | SQLite write-ahead log (temporary) |
| `storage.sqlite-shm` | SQLite shared memory (temporary) |
| `call_logs/` | Request payload archives |
| `backups/` | Automatic database backups |
| `log.txt` | Legacy request log (optional) |
---
## Verify Complete Removal
After uninstalling, verify there are no remaining files:
```bash
# Check for global npm package
npm list -g omniroute 2>/dev/null
# Check for data directory
ls -la ~/.omniroute/ 2>/dev/null
# Check for running processes
pgrep -f omniroute
```
If any process is still running, stop it:
```bash
pkill -f omniroute
```

View File

@@ -4,8 +4,6 @@
---
Complete guide for configuring providers, creating combos, integrating CLI tools, and deploying OmniRoute.
---
@@ -59,7 +57,7 @@ Complete guide for configuring providers, creating combos, integrating CLI tools
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
1. cc/claude-opus-4-7 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
@@ -87,7 +85,7 @@ Quality: Production-ready models
```
Combo: "always-on"
1. cc/claude-opus-4-6 (best quality)
1. cc/claude-opus-4-7 (best quality)
2. cx/gpt-5.2-codex (second subscription)
3. glm/glm-4.7 (cheap, resets daily)
4. minimax/MiniMax-M2.1 (cheapest, 5h reset)
@@ -125,7 +123,7 @@ Dashboard → Providers → Connect Claude Code
→ 5-hour + weekly quota tracking
Models:
cc/claude-opus-4-6
cc/claude-opus-4-7
cc/claude-sonnet-4-5-20250929
cc/claude-haiku-4-5-20251001
```
@@ -234,7 +232,7 @@ Dashboard → Combos → Create New
Name: premium-coding
Models:
1. cc/claude-opus-4-6 (Subscription primary)
1. cc/claude-opus-4-7 (Subscription primary)
2. glm/glm-4.7 (Cheap backup, $0.6/1M)
3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M)
@@ -263,7 +261,7 @@ Cost: $0 forever!
Settings → Models → Advanced:
OpenAI API Base URL: http://localhost:20128/v1
OpenAI API Key: [from omniroute dashboard]
Model: cc/claude-opus-4-6
Model: cc/claude-opus-4-7
```
### Claude Code
@@ -317,7 +315,7 @@ Edit `~/.openclaw/openclaw.json`:
Provider: OpenAI Compatible
Base URL: http://localhost:20128/v1
API Key: [from dashboard]
Model: cc/claude-opus-4-6
Model: cc/claude-opus-4-7
```
---
@@ -347,9 +345,9 @@ The CLI automatically loads `.env` from `~/.omniroute/.env` or `./.env`.
When you no longer need OmniRoute, we provide two quick scripts for a clean removal:
| Command | Action |
| --- | --- |
| `npm run uninstall` | Removes the system app but **keeps your DB and configurations** in `~/.omniroute`. |
| Command | Action |
| ------------------------ | ----------------------------------------------------------------------------------- |
| `npm run uninstall` | Removes the system app but **keeps your DB and configurations** in `~/.omniroute`. |
| `npm run uninstall:full` | Removes the app AND permanently **erases all configurations, keys, and databases**. |
> Note: To run these commands, navigate to the OmniRoute project folder (if you cloned it) and run them. Alternatively, if globally installed, you can simply run `npm uninstall -g omniroute`.
@@ -556,7 +554,7 @@ For the full environment variable reference, see the [README](../README.md).
<details>
<summary><b>View all available models</b></summary>
**Claude Code (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001`
**Claude Code (`cc/`)** — Pro/Max: `cc/claude-opus-4-7`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001`
**Codex (`cx/`)** — Plus/Pro: `cx/gpt-5.2-codex`, `cx/gpt-5.1-codex-max`
@@ -749,7 +747,7 @@ Define global fallback chains that apply across all requests:
```
Chain: production-fallback
1. cc/claude-opus-4-6
1. cc/claude-opus-4-7
2. gh/gpt-5.1-codex
3. glm/glm-4.7
```
@@ -763,10 +761,11 @@ Configure via **Dashboard → Settings → Resilience**.
OmniRoute implements provider-level resilience with four components:
1. **Provider Profiles** — Per-provider configuration for:
- Failure threshold (how many failures before opening)
- Cooldown duration
- Rate limit detection sensitivity
- Exponential backoff parameters
- **Transient Cooldown** — Base cooldown for transient upstream failures
- **Rate Limit Cooldown** — Base cooldown for `429`-driven lockouts
- **Max Backoff Level** — Maximum exponential backoff level for repeated failures
- **CB Threshold** — Failure count before model quarantine / provider circuit breaker escalates
- **CB Reset Time** — Failure counting window and breaker reset timer
2. **Editable Rate Limits** — System-level defaults configurable in the dashboard:
- **Requests Per Minute (RPM)** — Maximum requests per minute per account
@@ -774,14 +773,18 @@ OmniRoute implements provider-level resilience with four components:
- **Max Concurrent Requests** — Maximum simultaneous requests per account
- Click **Edit** to modify, then **Save** or **Cancel**. Values persist via the resilience API.
3. **Circuit Breaker** — Tracks failures per provider and automatically opens the circuit when a threshold is reached:
3. **Circuit Breaker** — Tracks failures per provider and automatically opens the circuit when the configured threshold is reached:
- **CLOSED** (Healthy) — Requests flow normally
- **OPEN** — Provider is temporarily blocked after repeated failures
- **HALF_OPEN** — Testing if provider has recovered
The same provider profile also drives model-scoped lockouts:
- Account/model lockouts react immediately to authoritative `429` / `404` signals and use the configured cooldown + backoff values
- Global provider/model quarantine only activates after repeated exhaustion hits the configured **CB Threshold** within **CB Reset Time**
4. **Policies & Locked Identifiers** — Shows circuit breaker status and locked identifiers with force-unlock capability.
5. **Rate Limit Auto-Detection** — Monitors `429` and `Retry-After` headers to proactively avoid hitting provider rate limits.
5. **Rate Limit Auto-Detection** — Monitors `429` and `Retry-After` headers to proactively avoid hitting provider rate limits. When an upstream provider returns an explicit wait window, that authoritative `Retry-After` value overrides the base cooldown from the provider profile.
**Pro Tip:** Use **Reset All** button to clear all circuit breakers and cooldowns when a provider recovers from an outage.

View File

@@ -4,36 +4,47 @@
---
الدليل الكامل لـ OmniRoute وتكوينه على VM (VPS) مع المجال المُدار عبر Cloudflare.---## Prerequisites
Complete guide to install and configure OmniRoute on a VM (VPS) with domain managed via Cloudflare.
| حرق | الحد | موصى به |
| -------------------------- | -------------------------------- | -------------------------------- |
| **وحدة المعالجة المركزية** | 1 وحدة المعالجة المركزية الرقمية | 2 وحدة المعالجة المركزية الرقمية |
| **ذاكرة الوصول العشوائي** | 1 جيجا | 2 جيجا |
| **القرص** | 10 جيجا اس اس دي | 25 جيجا اس دي |
| **نظام التشغيل** | أوبونتو 22.04 LTS | أوبونتو 24.04 LTS |
| **المجال** | مسجل في Cloudflare | — |
| **عامل ميناء** | محرك دوكر 24+ | عامل ميناء 27+ |
---
**المزودون الذين تم اختبارهم**: Akamai (Linode)، DigitalOcean، Vultr، Hetzner، AWS Lightsail.---## 1. Configure the VM
## Prerequisites
| Item | Minimum | Recommended |
| ---------- | ------------------------ | ---------------- |
| **CPU** | 1 vCPU | 2 vCPU |
| **RAM** | 1 GB | 2 GB |
| **Disk** | 10 GB SSD | 25 GB SSD |
| **OS** | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS |
| **Domain** | Registered on Cloudflare | — |
| **Docker** | Docker Engine 24+ | Docker 27+ |
**Tested providers**: Akamai (Linode), DigitalOcean, Vultr, Hetzner, AWS Lightsail.
---
## 1. Configure the VM
### 1.1 Create the instance
على موفر VPS المفضل لديك:
On your preferred VPS provider:
- اختر Ubuntu 24.04 LTS
-تحديد الحد الأدنى للخطة (1 vCPU / 1 جيجابايت من ذاكرة الوصول العشوائي)
- قم بتواجد كلمة مرور جذر قوية أو قم بتكوين مفتاح SSH
- ملحوظة**عنوان IP العام**(على سبيل المثال، `203.0.113.10`)### 1.2 الاتصال عبر SSH```bash
ssh root@203.0.113.10
- Choose Ubuntu 24.04 LTS
- Select the minimum plan (1 vCPU / 1 GB RAM)
- Set a strong root password or configure SSH key
- Note the **public IP** (e.g., `203.0.113.10`)
````
### 1.2 Connect via SSH
```bash
ssh root@203.0.113.10
```
### 1.3 Update the system
```bash
apt update && apt upgrade -y
````
```
### 1.4 Install Docker
@@ -67,7 +78,11 @@ ufw allow 443/tcp # HTTPS
ufw enable
```
> **نصيحة**: للحصول على الحد الأقصى من الأمان، يجب بتقييد المنفذين 80 و443 بناوين Cloudflare IP فقط. راجع قسم [الأمان المتقدم](#الأمن المتقدم).---## 2. Install OmniRoute
> **Tip**: For maximum security, restrict ports 80 and 443 to Cloudflare IPs only. See the [Advanced Security](#advanced-security) section.
---
## 2. Install OmniRoute
### 2.1 Create configuration directory
@@ -107,118 +122,130 @@ NEXT_PUBLIC_BASE_URL=https://llms.seudominio.com
EOF
```
> ⚠️**هام**: أنشئ مفاتيح سرية فريدة! استخدم "openssl rand -hex 32" لكل مفتاح.### 2.3 ابدأ الحاوية```bash
> docker pull diegosouzapw/omniroute:latest
> ⚠️ **IMPORTANT**: Generate unique secret keys! Use `openssl rand -hex 32` for each key.
### 2.3 Start the container
```bash
docker pull diegosouzapw/omniroute:latest
docker run -d \
--name omniroute \
--restart unless-stopped \
--env-file /opt/omniroute/.env \
-p 20128:20128 \
-v omniroute-data:/app/data \
diegosouzapw/omniroute:latest
````
--name omniroute \
--restart unless-stopped \
--env-file /opt/omniroute/.env \
-p 20128:20128 \
-v omniroute-data:/app/data \
diegosouzapw/omniroute:latest
```
### 2.4 Verify that it is running
```bash
docker ps | grep omniroute
docker logs omniroute --tail 20
````
```
يجب أن يتم تعرض: "قاعدة بيانات SQLite [DB] جاهزة" و"الاشتراك في منفذ 20128".---## 3. Configure nginx (Reverse Proxy)
It should display: `[DB] SQLite database ready` and `listening on port 20128`.
---
## 3. Configure nginx (Reverse Proxy)
### 3.1 Generate SSL certificate (Cloudflare Origin)
في لوحة معلومات Cloudflare:
In the Cloudflare dashboard:
1. انتقل إلى**SSL/TLS → الخادم الأصلي**
2.نقر**إنشاء شهادة**
2. استخدم الإعدادات الافتراضية (15 عامًا، \*.yourdomain.com)
4.انسخ**شهادة المنشأ**و**المفتاح الخاص**```bash
mkdir -p /etc/nginx/ssl
1. Go to **SSL/TLS → Origin Server**
2. Click **Create Certificate**
3. Keep the defaults (15 years, \*.yourdomain.com)
4. Copy the **Origin Certificate** and the **Private Key**
# لصق الشهادة
```bash
mkdir -p /etc/nginx/ssl
نانو /etc/nginx/ssl/origin.crt
# Paste the certificate
nano /etc/nginx/ssl/origin.crt
# الصق المفتاح الخاص
# Paste the private key
nano /etc/nginx/ssl/origin.key
نانو /etc/nginx/ssl/origin.key
chmod 600 /etc/nginx/ssl/origin.key```
chmod 600 /etc/nginx/ssl/origin.key
```
### 3.2 Nginx Configuration
````bash
cat > /etc/nginx/sites-available/omniroute << 'NGINX'
# الخادم الافتراضي - يمنع الوصول المباشر عبر IP
الخادم {
الاستماع 80 default_server؛
الاستماع [::]:80 default_server؛
الاستماع 443 SSL default_server؛
استمع [::]:443 ssl default_server؛
ssl_certificate /etc/nginx/ssl/origin.crt;
```bash
cat > /etc/nginx/sites-available/omniroute << NGINX
# Default server — blocks direct access via IP
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /etc/nginx/ssl/origin.crt;
ssl_certificate_key /etc/nginx/ssl/origin.key;
اسم الخادم _;
العودة 444؛
server_name _;
return 444;
}
# OmniRoute - HTTPS
الخادم {
الاستماع 443 SSL؛
استمع [::]:443 ssl;
اسم الخادم llms.yourdomain.com; # التغيير إلى المجال الخاص بك
# OmniRoute HTTPS
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name llms.yourdomain.com; # Change to your domain
ssl_certificate /etc/nginx/ssl/origin.crt;
ssl_certificate /etc/nginx/ssl/origin.crt;
ssl_certificate_key /etc/nginx/ssl/origin.key;
ssl_protocols TLSv1.2 TLSv1.3;
Client_max_body_size 100M؛
client_max_body_size 100M;
الموقع / {
location / {
proxy_pass http://127.0.0.1:20128;
proxy_set_header المضيف $host;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header مخطط X-Forwarded-Proto $;
proxy_set_header X-Forwarded-Proto $scheme;
# دعم ويبسوكيت
# WebSocket support
proxy_http_version 1.1;
ترقية proxy_set_header $http_upgrade;
اتصال proxy_set_header "ترقية"؛
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
# SSE (الأحداث المرسلة من الخادم) - تدفق استجابات الذكاء الاصطناعي
proxy_buffering معطل؛
proxy_cache معطل؛
proxy_read_timeout 600s؛
# SSE (Server-Sent Events) — streaming AI responses
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
}
}
# HTTP → إعادة توجيه HTTPS
الخادم {
استمع 80؛
استمع [::]:80;
اسم الخادم llms.yourdomain.com;
إرجاع 301 https://$server_name$request_uri;
# HTTP → HTTPS redirect
server {
listen 80;
listen [::]:80;
server_name llms.yourdomain.com;
return 301 https://$server_name$request_uri;
}
نجينكس```
NGINX
```
حافظ على توافق مهلات دفق الوكيل العكسي مع vars env لمهلة OmniRoute. إذا رفعت
`FETCH_TIMEOUT_MS` / `STREAM_IDLE_TIMEOUT_MS`، ارفع `proxy_read_timeout` / `proxy_send_timeout`
فوق نفس العتبة.### 3.3 Enable and Test
Keep reverse-proxy stream timeouts aligned with your OmniRoute timeout env vars. If you raise
`FETCH_TIMEOUT_MS` / `STREAM_IDLE_TIMEOUT_MS`, raise `proxy_read_timeout` / `proxy_send_timeout`
above the same threshold.
### 3.3 Enable and Test
```bash
# إزالة التكوين الافتراضي
# Remove default configuration
rm -f /etc/nginx/sites-enabled/default
# تمكين OmniRoute
# Enable OmniRoute
ln -sf /etc/nginx/sites-available/omniroute /etc/nginx/sites-enabled/omniroute
# اختبار وإعادة تحميل
nginx -t && systemctl إعادة تحميل nginx```
# Test and reload
nginx -t && systemctl reload nginx
```
---
@@ -226,25 +253,30 @@ nginx -t && systemctl إعادة تحميل nginx```
### 4.1 Add DNS record
في لوحة معلومات Cloudflare → DNS:
In the Cloudflare dashboard → DNS:
| اكتب | الاسم | المحتوى | الوكيل |
| Type | Name | Content | Proxy |
| ---- | ------ | ---------------------- | ---------- |
| أ | ``للم`` | `203.0.113.10` (VM IP) | ✅ توكيل |### 4.2 Configure SSL
| A | `llms` | `203.0.113.10` (VM IP) | ✅ Proxied |
ضمن**SSL/TLS → نظرة عامة**:
### 4.2 Configure SSL
- الوضع:**كامل (صارم)**
Under **SSL/TLS → Overview**:
ضمن**SSL/TLS → شهادات الحافة**:
- Mode: **Full (Strict)**
- استخدم HTTPS دائمًا: ✅ قيد التشغيل
- الحد الأدنى لإصدار TLS: TLS 1.2
- إعادة كتابة HTTPS تلقائيًا: ✅ تشغيل### 4.3 Testing
Under **SSL/TLS → Edge Certificates**:
- Always Use HTTPS: ✅ On
- Minimum TLS Version: TLS 1.2
- Automatic HTTPS Rewrites: ✅ On
### 4.3 Testing
```bash
حليقة -sI https://llms.seudominio.com/health
# يجب أن يُرجع HTTP/2 200```
curl -sI https://llms.seudominio.com/health
# Should return HTTP/2 200
```
---
@@ -253,37 +285,41 @@ nginx -t && systemctl إعادة تحميل nginx```
### Upgrade to a new version
```bash
عامل ميناء سحب diegosouzapw/omniroute:latest
عامل ميناء توقف omniroute && docker rm omniroute
تشغيل عامل الإرساء -d --اسم المسار الشامل --إعادة التشغيل ما لم يتم إيقافه \
--env-ملف /opt/omniroute/.env \
-ص20128:20128\
-v بيانات المسار الشامل:/app/data \
diegosouzapw/omniroute:latest```
docker pull diegosouzapw/omniroute:latest
docker stop omniroute && docker rm omniroute
docker run -d --name omniroute --restart unless-stopped \
--env-file /opt/omniroute/.env \
-p 20128:20128 \
-v omniroute-data:/app/data \
diegosouzapw/omniroute:latest
```
### View logs
```bash
سجلات عامل الإرساء -f omniroute # البث في الوقت الفعلي
سجلات عامل الإرساء في كل الاتجاهات --tail 50 # آخر 50 سطرًا```
docker logs -f omniroute # Real-time stream
docker logs omniroute --tail 50 # Last 50 lines
```
### Manual database backup
```bash
# انسخ البيانات من المجلد إلى المضيف
# Copy data from the volume to the host
docker cp omniroute:/app/data ./backup-$(date +%F)
# أو ضغط الحجم بأكمله
تشغيل عامل الميناء --rm -v omniroute-data:/data -v $(pwd):/backup \
جبال الألب القطران czf /backup/omniroute-data-$(date +%F).tar.gz /data```
# Or compress the entire volume
docker run --rm -v omniroute-data:/data -v $(pwd):/backup \
alpine tar czf /backup/omniroute-data-$(date +%F).tar.gz /data
```
### Restore from backup
```bash
توقف عامل الإرساء في كل اتجاه
تشغيل عامل الميناء --rm -v omniroute-data:/data -v $(pwd):/backup \
جبال الألب sh -c “rm -rf /data/* && tar xzf /backup/omniroute-data-YYYY-MM-DD.tar.gz -C /”
عامل الإرساء يبدأ في كل اتجاه```
docker stop omniroute
docker run --rm -v omniroute-data:/data -v $(pwd):/backup \
alpine sh -c “rm -rf /data/* && tar xzf /backup/omniroute-data-YYYY-MM-DD.tar.gz -C /”
docker start omniroute
```
---
@@ -292,8 +328,8 @@ docker cp omniroute:/app/data ./backup-$(date +%F)
### Restrict nginx to Cloudflare IPs
```bash
cat > /etc/nginx/cloudflare-ips.conf << 'CF'
# نطاقات Cloudflare IPv4 - يتم تحديثها بشكل دوري
cat > /etc/nginx/cloudflare-ips.conf << CF
# Cloudflare IPv4 ranges — update periodically
# https://www.cloudflare.com/ips-v4/
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
@@ -311,11 +347,14 @@ set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
real_ip_header CF-Connecting-IP;
قوات التحالف```
CF
```
أضف ما يلي إلى `nginx.conf` داخل الكتلة `http {}`:```nginx
Add the following to `nginx.conf` inside the `http {}` block:
```nginx
include /etc/nginx/cloudflare-ips.conf;
````
```
### Install fail2ban
@@ -344,22 +383,25 @@ netfilter-persistent save
## 7. Deploy to Cloudflare Workers (Optional)
للوصول بعد عبر Cloudflare Workers (دون الكشف عن الجهاز الافتراضي مباشرة):```bash
# في المستودع المحلي
For remote access via Cloudflare Workers (without exposing the VM directly):
```bash
# In the local repository
cd omnirouteCloud
تثبيت npm
تسجيل دخول رانجلر npx
نشر رانجلر npx```
npm install
npx wrangler login
npx wrangler deploy
```
راجع الوثائق الكاملة على [omnirouteCloud/README.md](../omnirouteCloud/README.md).---
See the full documentation at [omnirouteCloud/README.md](../omnirouteCloud/README.md).
---
## Port Summary
| ميناء | الخدمة | الوصول |
| ----- | ------------- | ----------------------------- |
| 22 | سش | عام (مع Fail2ban) |
| 80 | إنجينكس HTTP | إعادة التوجيه → HTTPS |
| 443 | إنجينكس HTTPS | عبر وكيل Cloudflare |
| 20128 | أومنيروتي | المضيف المحلي فقط (عبر nginx) |
| Port | Service | Access |
| ----- | ----------- | -------------------------- |
| 22 | SSH | Public (with fail2ban) |
| 80 | nginx HTTP | Redirect → HTTPS |
| 443 | nginx HTTPS | Via Cloudflare Proxy |
| 20128 | OmniRoute | Localhost only (via nginx) |

View File

@@ -0,0 +1,106 @@
# Guia Completo: Cloudflare Tunnel & Zero Trust (Split-Port) (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../docs/cloudflare-zero-trust-guide.md) · 🇪🇸 [es](../../es/docs/cloudflare-zero-trust-guide.md) · 🇫🇷 [fr](../../fr/docs/cloudflare-zero-trust-guide.md) · 🇩🇪 [de](../../de/docs/cloudflare-zero-trust-guide.md) · 🇮🇹 [it](../../it/docs/cloudflare-zero-trust-guide.md) · 🇷🇺 [ru](../../ru/docs/cloudflare-zero-trust-guide.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/cloudflare-zero-trust-guide.md) · 🇯🇵 [ja](../../ja/docs/cloudflare-zero-trust-guide.md) · 🇰🇷 [ko](../../ko/docs/cloudflare-zero-trust-guide.md) · 🇸🇦 [ar](../../ar/docs/cloudflare-zero-trust-guide.md) · 🇮🇳 [hi](../../hi/docs/cloudflare-zero-trust-guide.md) · 🇮🇳 [in](../../in/docs/cloudflare-zero-trust-guide.md) · 🇹🇭 [th](../../th/docs/cloudflare-zero-trust-guide.md) · 🇻🇳 [vi](../../vi/docs/cloudflare-zero-trust-guide.md) · 🇮🇩 [id](../../id/docs/cloudflare-zero-trust-guide.md) · 🇲🇾 [ms](../../ms/docs/cloudflare-zero-trust-guide.md) · 🇳🇱 [nl](../../nl/docs/cloudflare-zero-trust-guide.md) · 🇵🇱 [pl](../../pl/docs/cloudflare-zero-trust-guide.md) · 🇸🇪 [sv](../../sv/docs/cloudflare-zero-trust-guide.md) · 🇳🇴 [no](../../no/docs/cloudflare-zero-trust-guide.md) · 🇩🇰 [da](../../da/docs/cloudflare-zero-trust-guide.md) · 🇫🇮 [fi](../../fi/docs/cloudflare-zero-trust-guide.md) · 🇵🇹 [pt](../../pt/docs/cloudflare-zero-trust-guide.md) · 🇷🇴 [ro](../../ro/docs/cloudflare-zero-trust-guide.md) · 🇭🇺 [hu](../../hu/docs/cloudflare-zero-trust-guide.md) · 🇧🇬 [bg](../../bg/docs/cloudflare-zero-trust-guide.md) · 🇸🇰 [sk](../../sk/docs/cloudflare-zero-trust-guide.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/cloudflare-zero-trust-guide.md) · 🇮🇱 [he](../../he/docs/cloudflare-zero-trust-guide.md) · 🇵🇭 [phi](../../phi/docs/cloudflare-zero-trust-guide.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/cloudflare-zero-trust-guide.md) · 🇨🇿 [cs](../../cs/docs/cloudflare-zero-trust-guide.md) · 🇹🇷 [tr](../../tr/docs/cloudflare-zero-trust-guide.md)
---
Este guia documenta o padrão ouro de infraestrutura de rede para proteger o **OmniRoute** e expor sua aplicação de forma segura para a internet, **sem abrir nenhuma porta (Zero Inbound)**.
## O que foi feito na sua VM?
Nós ativamos o OmniRoute em modo **Split-Port** através do PM2:
- **Porta \`20128\`:** Roda **apenas a API** `/v1`.
- **Porta \`20129\`:** Roda **apenas o Dashboard** Administrativo visual.
Além disso, o serviço interno exige \`REQUIRE_API_KEY=true\`, o que significa que nenhum agente pode consumir os endpoints da API sem enviar um "Bearer Token" legítimo gerado na aba API Keys do Painel.
Isso nos permite criar duas regras completamente independentes na rede. É aqui que entra o **Cloudflare Tunnel (cloudflared)**.
---
## 1. Como Criar o Túnel na Cloudflare
O utilitário \`cloudflared\` já está instalado na sua máquina. Siga os passos na nuvem:
1. Acesse seu painel **Cloudflare Zero Trust** (One.dash.cloudflare.com).
2. No menu à esquerda, vá em **Networks > Tunnels**.
3. Clique em **Add a Tunnel**, escolha **Cloudflared** e dê o nome \`OmniRoute-VM\`.
4. Ele vai gerar um comando na tela chamado "Install and run a connector". **Você só precisa copiar o Token (a string longa após `--token`)**.
5. Logue via SSH na sua máquina virtual (ou Terminal do Proxmox) e execute:
\`\`\`bash
# Inicia e amarra o túnel permanentemente à sua conta
cloudflared service install SEU_TOKEN_GIGANTE_AQUI
\`\`\`
---
## 2. Configurando o Roteamento (Public Hostnames)
Ainda na tela do Tunnel recém-criado, vá para a aba **Public Hostnames** e adicione as **duas** rotas, aproveitando a separação que fizemos:
### Rota 1: API Segura (Limitada)
- **Subdomain:** \`api\`
- **Domain:** \`seuglobal.com.br\` (escolha seu domínio real)
- **Service Type:** \`HTTP\`
- **URL:** \`127.0.0.1:20128\` _(Porta interna da API)_
### Rota 2: Painel Zero Trust (Fechado)
- **Subdomain:** \`omniroute\` ou \`painel\`
- **Domain:** \`seuglobal.com.br\`
- **Service Type:** \`HTTP\`
- **URL:** \`127.0.0.1:20129\` _(Porta interna do App/Visual)_
Neste momento, a conectividade "Física" está resolvida. Agora vamos blindar de verdade.
---
## 3. Blindando o Painel com Zero Trust (Access)
Nenhuma senha local protege melhor o seu painel do que remover totalmente o acesso a ele da internet aberta.
1. No painel Zero Trust, vá em **Access > Applications > Add an application**.
2. Selecione **Self-hosted**.
3. Em **Application name**, coloque \`Painel OmniRoute\`.
4. Em **Application domain**, coloque \`omniroute.seuglobal.com.br\` (O mesmo que você fez na "Rota 2").
5. Clique em **Next**.
6. Em **Rule action**, escolha \`Allow\`. Em nome da Rule coloque \`Admin Apenas\`.
7. Em **Include**, no seletor de "Selector" escolha \`Emails\` e digite o seu email, por exemplo \`admin@spgeo.com.br\`.
8. Salve (`Add application`).
> **O que isso fez:** Se você tentar abrir \`omniroute.seuglobal.com.br\`, não cai mais na sua aplicação OmniRoute! Cai numa tela elegante da Cloudflare pedindo para digitar seu email. Somente se você (ou o email que você botou) for digitado lá, ele recebe no Outlook/Gmail um código de 6 dígitos temporário que libera o túnel até a porta \`20129\`.
---
## 4. Limitando e Protegendo a API com Rate Limit (WAF)
O Dashboard do Zero Trust não se aplica à rota da API (\`api.seuglobal.com.br\`), porque é um acesso programático via ferramentas automatizadas (agentes) sem navegador. Para ele, usaremos o Firewall principal (WAF) da Cloudflare.
1. Acesse o **Painel Normal** da Cloudflare (dash.cloudflare.com) e entre no seu Domínio.
2. No menu esquerdo, vá em **Security > WAF > Rate limiting rules**.
3. Clique em **Create rule**.
4. **Name:** \`Anti-Abuso OmniRoute API\`
5. **If incoming requests match...**
- Escolha em Field: \`Hostname\`
- Operator: \`equals\`
- Value: \`api.seuglobal.com.br\`
6. Em **With the same characteristics:** Mantenha \`IP\`.
7. Nos limites (Limit):
- **When requests exceed:** \`50\`
- **Period:** \`1 minute\`
8. No final, em **Action**: \`Block\` (Bloquear) e decida se o bloqueio dura por 1 minuto ou 1 hora.
9. **Deploy**.
> **O que isso fez:** Ninguém pode mandar mais de 50 requisições num período de 60 segundos na sua URL de API. Como você roda vários agentes e os consumos por trás já batem rate limit e já rastreiam tokens, isso é apenas uma medida na Borda da Internet (Edge Layer) que protege sua Instância On-Premises de cair por estresse térmico antes mesmo do tráfego descer pelo túnel.
---
## Finalização
1. A sua VM **não possui nenhuma porta exposta** em `/etc/ufw`.
2. O OmniRoute só conversa HTTPS saindo (\`cloudflared\`) e não recebendo TCP direto do mundo.
3. Seus requets pro OpenAI são ofuscados porque configuramos eles globalmente pra passar em um Proxy SOCKS5 (A nuvem não liga pro SOCKS5 porque ela vem Inbound).
4. Seu painel web tem 2-Factor com Email.
5. Sua API está ratelimitada na borda pela Cloudflare e só trafega Bearer Tokens.

View File

@@ -0,0 +1,130 @@
# Context Relay (العربية)
🌐 **Languages:** 🇺🇸 [English](../../../../../docs/features/context-relay.md) · 🇪🇸 [es](../../../es/docs/features/context-relay.md) · 🇫🇷 [fr](../../../fr/docs/features/context-relay.md) · 🇩🇪 [de](../../../de/docs/features/context-relay.md) · 🇮🇹 [it](../../../it/docs/features/context-relay.md) · 🇷🇺 [ru](../../../ru/docs/features/context-relay.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/features/context-relay.md) · 🇯🇵 [ja](../../../ja/docs/features/context-relay.md) · 🇰🇷 [ko](../../../ko/docs/features/context-relay.md) · 🇸🇦 [ar](../../../ar/docs/features/context-relay.md) · 🇮🇳 [hi](../../../hi/docs/features/context-relay.md) · 🇮🇳 [in](../../../in/docs/features/context-relay.md) · 🇹🇭 [th](../../../th/docs/features/context-relay.md) · 🇻🇳 [vi](../../../vi/docs/features/context-relay.md) · 🇮🇩 [id](../../../id/docs/features/context-relay.md) · 🇲🇾 [ms](../../../ms/docs/features/context-relay.md) · 🇳🇱 [nl](../../../nl/docs/features/context-relay.md) · 🇵🇱 [pl](../../../pl/docs/features/context-relay.md) · 🇸🇪 [sv](../../../sv/docs/features/context-relay.md) · 🇳🇴 [no](../../../no/docs/features/context-relay.md) · 🇩🇰 [da](../../../da/docs/features/context-relay.md) · 🇫🇮 [fi](../../../fi/docs/features/context-relay.md) · 🇵🇹 [pt](../../../pt/docs/features/context-relay.md) · 🇷🇴 [ro](../../../ro/docs/features/context-relay.md) · 🇭🇺 [hu](../../../hu/docs/features/context-relay.md) · 🇧🇬 [bg](../../../bg/docs/features/context-relay.md) · 🇸🇰 [sk](../../../sk/docs/features/context-relay.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/features/context-relay.md) · 🇮🇱 [he](../../../he/docs/features/context-relay.md) · 🇵🇭 [phi](../../../phi/docs/features/context-relay.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/features/context-relay.md) · 🇨🇿 [cs](../../../cs/docs/features/context-relay.md) · 🇹🇷 [tr](../../../tr/docs/features/context-relay.md)
---
`context-relay` is a combo strategy that keeps session continuity when the active account
rotates before the conversation is finished.
The current runtime behaves like priority routing for model selection, then adds a
handoff layer on top:
- before the active account is exhausted, OmniRoute generates a compact structured summary
- after authentication selects a different account for the same session, OmniRoute injects
that summary as a system message into the next request
- once the handoff is consumed successfully, it is removed from storage
## When To Use It
Use `context-relay` when all of the following are true:
- the combo is expected to rotate between multiple accounts of the same provider
- losing short-term conversational continuity would hurt task quality
- the provider exposes enough quota information to predict an approaching account limit
This is most useful for long-running coding or research sessions that may outlive a single
account window.
## Runtime Flow
The current behavior is intentionally split across two runtime layers.
### 0% to 84% quota used
No handoff is generated. Requests behave like normal priority routing.
### 85% to 94% quota used
If the active provider is enabled in `handoffProviders`, OmniRoute generates a structured
handoff summary in the background before the account is fully exhausted.
Important details:
- the default warning threshold is `0.85`
- the hard stop for generation is `0.95`
- only one in-flight handoff generation is allowed per `sessionId + comboName`
- if an active handoff already exists for that session/combo, no duplicate summary is generated
### 95% or more quota used
No new handoff is generated. At this point the system is already in or near exhaustion and
the runtime avoids scheduling another summary request.
### After account rotation
When the next request for the same session resolves to a different authenticated account,
OmniRoute prepends the stored handoff as a system message. Injection happens only after the
real account switch is known.
## Handoff Payload
The persisted handoff payload is stored in `context_handoffs` and includes:
- `sessionId`
- `comboName`
- `fromAccount`
- `summary`
- `keyDecisions`
- `taskProgress`
- `activeEntities`
- `messageCount`
- `model`
- `warningThresholdPct`
- `generatedAt`
- `expiresAt`
The summary model is instructed to return a JSON object with this structure:
```json
{
"summary": "Dense summary of what matters for continuity",
"keyDecisions": ["Decision 1", "Decision 2"],
"taskProgress": "What is done, what is pending, and the next step",
"activeEntities": ["fileA.ts", "feature X", "provider Y"]
}
```
At injection time, OmniRoute converts that payload into a `<context_handoff>` system
message so the next account can continue with the correct local context.
## الإعداد
`context-relay` supports these config fields:
- `handoffThreshold`: warning threshold for summary generation, default `0.85`
- `handoffModel`: optional model override used only for summary generation
- `handoffProviders`: allowlist of providers allowed to trigger handoff generation
Global defaults can be configured in Settings, and combo-specific values can override them
in the Combos page.
## Architectural Note
The current implementation does not use a standalone `handleContextRelayCombo` handler.
Instead:
- `open-sse/services/combo.ts` decides whether a successful turn should generate a handoff
- `src/sse/handlers/chat.ts` injects the handoff only after authentication resolves the
actual account used for the request
This split is intentional in the current codebase because the combo loop alone does not know
whether the request stayed on the same account or actually switched accounts.
## Limitations
- Effective runtime support is currently centered on `codex` quota rotation.
- `handoffProviders` is already modeled as a config surface, but real handoff generation
still depends on provider-specific quota plumbing.
- The summary is intentionally compact and recent-history based; it is not a full transcript
replay mechanism.
- Handoffs are scoped by `sessionId + comboName` and expire automatically.
- If the session does not switch accounts, the stored handoff is not injected.
## Recommended Usage Pattern
- use multiple accounts from the same provider
- keep stable `sessionId` values across the session
- set `handoffThreshold` early enough to leave room for the background summary request
- treat the feature as continuity assistance, not as a replacement for persistent memory

View File

@@ -4,9 +4,13 @@
---
> **Agent-to-Agent Protocol v0.3**— يتزايد أي وكيل AI من استخدام OmniRoute كوكيل توجيه ذكي عبر JSON-RPC 2.0.
> **Agent-to-Agent Protocol v0.3** Enables any AI agent to use OmniRoute as an intelligent routing agent via JSON-RPC 2.0.
يعرض مضيف A2A OmniRoute**وكيلًا من الدرجة الأولى**يمكن لوكلاء الاكتشافات الأخرى وطلب الاتصال به باستخدام [بروتوكول A2A](https://google.github.io/A2A/).---## الهندسة
The A2A Server exposes OmniRoute as a **first-class agent** that other agents can discover, delegate tasks to, and collaborate with using the [A2A Protocol](https://google.github.io/A2A/).
---
## الهندسة
```
┌──────────────────────────────────────────────────────────────────┐
@@ -39,48 +43,52 @@
### Agent Discovery
يعرض كل وكيل متوافق مع A2A**بطاقة الوكيل**على `/.well-known/agent.json`:`bash
حليقة http://localhost:20128/.well-known/agent.json`
Every A2A-compatible agent exposes an **Agent Card** at `/.well-known/agent.json`:
**إجابة:**```json
{
"name": "OmniRoute",
"description": "Intelligent AI gateway with auto-routing across 50+ providers",
"url": "http://localhost:20128/a2a",
"version": "1.8.1",
"capabilities": {
"streaming": true,
"pushNotifications": false
},
"skills": [
{
"id": "smart-routing",
"name": "Smart Routing",
"description": "Routes prompts through OmniRoute intelligent pipeline",
"tags": ["routing", "llm", "multi-provider", "cost-optimization"],
"examples": [
"Write a hello world in Python",
"Explain quantum computing using the cheapest provider"
]
},
{
"id": "quota-management",
"name": "Quota Management",
"description": "Natural-language queries about provider quotas",
"tags": ["quota", "analytics", "cost"],
"examples": [
"Which provider has the most quota remaining?",
"Suggest a free combo for coding"
]
}
],
"authentication": {
"schemes": ["bearer"],
"apiKeyHeader": "Authorization"
}
}
```bash
curl http://localhost:20128/.well-known/agent.json
```
````
**Response:**
```json
{
"name": "OmniRoute",
"description": "Intelligent AI gateway with auto-routing across 50+ providers",
"url": "http://localhost:20128/a2a",
"version": "1.8.1",
"capabilities": {
"streaming": true,
"pushNotifications": false
},
"skills": [
{
"id": "smart-routing",
"name": "Smart Routing",
"description": "Routes prompts through OmniRoute intelligent pipeline",
"tags": ["routing", "llm", "multi-provider", "cost-optimization"],
"examples": [
"Write a hello world in Python",
"Explain quantum computing using the cheapest provider"
]
},
{
"id": "quota-management",
"name": "Quota Management",
"description": "Natural-language queries about provider quotas",
"tags": ["quota", "analytics", "cost"],
"examples": [
"Which provider has the most quota remaining?",
"Suggest a free combo for coding"
]
}
],
"authentication": {
"schemes": ["bearer"],
"apiKeyHeader": "Authorization"
}
}
```
---
@@ -88,22 +96,27 @@
### `message/send` — Synchronous Execution
أرسل رسالة إلى إحدى المهارات واحصل على الرد الكامل.```bash
حليقة -X POST http://localhost:20128/a2a \
-H "نوع المحتوى: application/json" \
-H "التفويض: حامل YOUR_KEY" \
-د '{
"jsonrpc": "2.0",
"المعرف": "1"،
"الطريقة": "رسالة/إرسال"،
"المعلمات": {
"المهارة": "التوجيه الذكي"،
"messages": [{"role": "user", "content": "اكتب عالم بايثون المرحب"}],
"بيانات التعريف": {"model": "auto"، "combo": "الترميز السريع"}
}
}'```
Send a message to a skill and receive the complete response.
**إجابة:**```json
```bash
curl -X POST http://localhost:20128/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{
"jsonrpc": "2.0",
"id": "1",
"method": "message/send",
"params": {
"skill": "smart-routing",
"messages": [{"role": "user", "content": "Write a Python hello world"}],
"metadata": {"model": "auto", "combo": "fast-coding"}
}
}'
```
**Response:**
```json
{
"jsonrpc": "2.0",
"id": "1",
@@ -120,32 +133,36 @@
}
}
}
````
```
### `message/stream` — SSE Streaming
نفس `الرسالة/الإرسال` ولكنها تُرجع الأحداث المرسلة من العميل للبث في الوقت الحقيقي.`bash
حليقة -N -X POST http://localhost:20128/a2a \
-H "نوع المحتوى: application/json" \
-H "التفويض: حامل YOUR_KEY" \
-د '{
"jsonrpc": "2.0",
"المعرف": "1"،
"الطريقة": "رسالة/دفق"،
"المعلمات": {
"المهارة": "التوجيه الذكي"،
"messages": [{"role": "user", "content": "شرح الحوسبة الكمومية"}]
}
}'`
Same as `message/send` but returns Server-Sent Events for real-time streaming.
**أحداث SSE:**```
```bash
curl -N -X POST http://localhost:20128/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{
"jsonrpc": "2.0",
"id": "1",
"method": "message/stream",
"params": {
"skill": "smart-routing",
"messages": [{"role": "user", "content": "Explain quantum computing"}]
}
}'
```
**SSE Events:**
```
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"working"},"chunk":{"type":"text","content":"Quantum computing..."}}}
: heartbeat 2026-03-04T21:00:00Z
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"completed"},"metadata":{...}}}
````
```
### `tasks/get` — Query Task Status
@@ -154,7 +171,7 @@ curl -X POST http://localhost:20128/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_KEY" \
-d '{"jsonrpc":"2.0","id":"2","method":"tasks/get","params":{"taskId":"TASK_UUID"}}'
````
```
### `tasks/cancel` — Cancel a Running Task
@@ -171,36 +188,42 @@ curl -X POST http://localhost:20128/a2a \
### `smart-routing`
تطالب المسارات عبر خط الأنابيب OmniRoute الذكي مع إمكانية المراقبة الكاملة.
Routes prompts through OmniRoute's intelligent pipeline with full observability.
**المعلمات (في `البيانات الوصفية`):**
**Parameters (in `metadata`):**
| المعلمة | اكتب | افتراضي | الوصف |
| ---------------- | --------- | ------------------ | ----------------------------------------------------------------------------- |
| `نموذج` | "السلسلة" | `"تلقائي"` | النموذج المستهدف (على سبيل المثال، `clude-sonnet-4`، `gpt-4o`، `auto`) |
| `التحرير والسرد` | "السلسلة" | التحرير والسرد لكم | التحرير والسرد للتوجيه من خلال |
| `الميزانية` | `الرقم` | لا شيء | الحد الأقصى للتكلفة بالدولار الأمريكي هذا الطلب |
| `دور` | "السلسلة" | لا شيء | تلميح مهم: `التميز`، `المراجعة`، `التخطيط`، `التحليل`، `تصحيح سبب`، `التوثيق` |
| Parameter | Type | Default | Description |
| --------- | -------- | ------------ | ---------------------------------------------------------------------------------------- |
| `model` | `string` | `"auto"` | Target model (e.g., `claude-sonnet-4`, `gpt-4o`, `auto`) |
| `combo` | `string` | active combo | Specific combo to route through |
| `budget` | `number` | none | Maximum cost in USD for this request |
| `role` | `string` | none | Task role hint: `coding`, `review`, `planning`, `analysis`, `debugging`, `documentation` |
**المرتجعات:**
**Returns:**
| | الوصف |
| ------------------------------ | ------------------------------------------------------------------------ | ----------------- |
| `المصنوعات[].content` | نصرد LLM |
| `metadata.routing_explanation` | شرح مفهوم لقرار التوجيه |
| `metadata.cost_envelope` | التكلفة المقدرة مقابل تكلفة التكلفة للعملة |
| `metadata.resilience_trace` | مصفوفة من الأحداث (تم تحديدها بشكل أساسي، والمطلوبة بديلاً، وما إلى ذلك) |
| `metadata.policy_verdict` | ما إذا كان ائداً لها لسبب | ### `إدارة الحصص` |
| Field | Description |
| ------------------------------ | --------------------------------------------------------- |
| `artifacts[].content` | The LLM response text |
| `metadata.routing_explanation` | Human-readable explanation of routing decision |
| `metadata.cost_envelope` | Estimated vs actual cost with currency |
| `metadata.resilience_trace` | Array of events (primary_selected, fallback_needed, etc.) |
| `metadata.policy_verdict` | Whether the request was allowed and why |
يجيب على استفسارات اللغة الطبيعية حول حصص الموفرين.
### `quota-management`
**أنواع اتفق (المنتهية من محتوى الرسالة):**
Answers natural-language queries about provider quotas.
| نمط | نوع المصدر |
| ------------------------------------------------- | ----------------------------------------- | -------------------- |
| يحتوي على `"التصنيف"`، `"الأكثر حصة"`، `"الأفضل"` | تم ترتيب مقدمي الخدمة حسب الحصص النهائية |
| يحتوي على `"مجاني"`، `"اقتراح"` | يسرد المهرجانات أو المهرجانات المجانية |
| افتراضي | ملخص كامل للحصص مع تحذيرات للحصص المنخفضة | ---## Task Lifecycle |
**Query types (inferred from message content):**
| Query Pattern | Response Type |
| ---------------------------------------------- | -------------------------------------------------------- |
| Contains `"ranking"`, `"most quota"`, `"best"` | Providers ranked by remaining quota |
| Contains `"free"`, `"suggest"` | Lists free combos or suggests free-tier providers |
| Default | Full quota summary with warnings for low-quota providers |
---
## Task Lifecycle
```
submitted ──→ working ──→ completed
@@ -208,17 +231,21 @@ submitted ──→ working ──→ completed
──────────→ cancelled
```
| الدولة | الوصف |
| -------- | ------------------------------------------------------------ |
| `مُقدم` | تم إنشاء المهمة، في قائمة الانتظار للتنفيذ |
| `العمل` | معالج المهارة ينفذ |
| `مكتملة` | البدء في التنفيذ، القطع الأثرية الصعبة |
| `فشل` | فشل التنفيذ أو النهاية إلى النهاية (TTL: 5 بالضغط الافتراضي) |
| `ملغاة` | تم الإلغاء من قبل العميل عبر `المهام/الإلغاء` |
| State | Description |
| ----------- | ----------------------------------------------------- |
| `submitted` | Task created, queued for execution |
| `working` | Skill handler is executing |
| `completed` | Execution succeeded, artifacts available |
| `failed` | Execution failed or task expired (TTL: 5 min default) |
| `cancelled` | Cancelled by client via `tasks/cancel` |
- حالات الوحدة الطرفية: `مكتملة`، `فشل`، `ملغى` (لم تحدث عمليات انتقال أخرى)
- يتم وضع العلامة التجارية الجديدة على انتهاء الصلاحية في "المقدمة" أو "الجاري" على أنها "فاشلة".
- يتم جمع المهام المهمة بعد 2 × TTL---## Client Examples
- Terminal states: `completed`, `failed`, `cancelled` (no further transitions)
- Expired tasks in `submitted` or `working` are auto-marked as `failed`
- Tasks are garbage-collected after 2× TTL
---
## Client Examples
### Python — Orchestrator Agent
@@ -514,33 +541,40 @@ func main() {
### 🤖 Use Case 1: Multi-Agent Coding Pipeline
يقوم وكيل منسق بتفويض إنشاء تعليمات الحظر إلى OmniRoute، ثم يقوم بتمرير الترخيص لوكيل التعديل.```python
تعريف coding_pipeline (المهمة: str): # الخطوة 1: قم بإنشاء الكود عبر OmniRoute A2A
code_result = a2a_send("التوجيه الذكي"، [
{"role": "user"، "content": f"اكتب كود جودة الإنتاج: {task}"}
]، البيانات الوصفية={"model": "auto"، "role": "coding"})
كود = code_result["artifacts"][0]["content"]
An orchestrator agent delegates code generation to OmniRoute, then passes the output to a review agent.
# الخطوة الثانية: قم بمراجعة الكود عبر OmniRoute A2A (نموذج مختلف)
review_result = a2a_send("التوجيه الذكي"، [
{"role": "user"، "content": f"راجع هذا الرمز بحثًا عن الأخطاء والتحسينات:\n\n{code}"}
]، البيانات الوصفية={"model": "auto"، "role": "review"})
المراجعة = review_result["artifacts"][0]["content"]
```python
def coding_pipeline(task: str):
# Step 1: Generate code via OmniRoute A2A
code_result = a2a_send("smart-routing", [
{"role": "user", "content": f"Write production-quality code: {task}"}
], metadata={"model": "auto", "role": "coding"})
code = code_result["artifacts"][0]["content"]
# الخطوة 3: التحقق من التكاليف
print(f"تكلفة الكود: ${code_result['metadata']['cost_envelope']['actual']}")
print(f"تكلفة المراجعة: ${review_result['metadata']['cost_envelope']['actual']}")
# Step 2: Review the code via OmniRoute A2A (different model)
review_result = a2a_send("smart-routing", [
{"role": "user", "content": f"Review this code for bugs and improvements:\n\n{code}"}
], metadata={"model": "auto", "role": "review"})
review = review_result["artifacts"][0]["content"]
إرجاع {"كود": كود، "مراجعة": مراجعة}```
# Step 3: Check costs
print(f"Code cost: ${code_result['metadata']['cost_envelope']['actual']}")
print(f"Review cost: ${review_result['metadata']['cost_envelope']['actual']}")
return {"code": code, "review": review}
```
### 💡 Use Case 2: Quota-Aware Agent Swarm
يقوم العديد من الوكلاء بمشاركة الحصص من خلال OmniRoute، وذلك باستخدام مهارة الحصص للتنسيق.```python
async def quota_aware_agent(agent_name: str, task: str): # Check quota before starting
quota = a2a_send("quota-management", [
{"role": "user", "content": "Which provider has the most quota remaining?"}
])
print(f"[{agent_name}] {quota['artifacts'][0]['content']}")
Multiple agents share quota through OmniRoute, using the quota skill to coordinate.
```python
async def quota_aware_agent(agent_name: str, task: str):
# Check quota before starting
quota = a2a_send("quota-management", [
{"role": "user", "content": "Which provider has the most quota remaining?"}
])
print(f"[{agent_name}] {quota['artifacts'][0]['content']}")
# Send request with budget constraint
result = a2a_send("smart-routing", [
@@ -557,60 +591,64 @@ print(f"[{agent_name}] {quota['artifacts'][0]['content']}")
print(f"[{agent_name}] Free alternatives: {quota['artifacts'][0]['content']}")
return result
````
```
### 📊 Use Case 3: Real-Time Streaming Dashboard
يقوم بالمراقبة ببث الاستجابات ويعرض التقدم في الوقت الفعلي.```typescript
وظيفة غير متزامنة StreamDashboard(prompt: string) {
استجابة ثابتة = انتظار الجلب(`${BASE_URL}/a2a`, {
الطريقة: "POST"،
الرؤوس: { "نوع المحتوى": "application/json"، التفويض: `Bearer ${API_KEY}` }،
الجسم: JSON.stringify({
جسونربك: "2.0"،
المعرف: "داش-1"،
الطريقة: "رسالة/دفق"،
المعلمات: { المهارة: "التوجيه الذكي"، الرسائل: [{ الدور: "المستخدم"، المحتوى: موجه }] }،
A monitoring agent streams responses and displays progress in real-time.
```typescript
async function streamingDashboard(prompt: string) {
const response = await fetch(`${BASE_URL}/a2a`, {
method: "POST",
headers: { "Content-Type": "application/json", Authorization: `Bearer ${API_KEY}` },
body: JSON.stringify({
jsonrpc: "2.0",
id: "dash-1",
method: "message/stream",
params: { skill: "smart-routing", messages: [{ role: "user", content: prompt }] },
}),
});
دع مجموع القطع = 0؛
قارئ ثابت = استجابة. الجسم!.getReader();
let totalChunks = 0;
const reader = response.body!.getReader();
const decoder = new TextDecoder();
بينما (صحيح) {
const { تم، القيمة } = انتظار Reader.read();
إذا (تم) كسر؛
while (true) {
const { done, value } = await reader.read();
if (done) break;
for (سطر ثابت من decoder.decode(value).split("\n")) {
إذا (line.startsWith("البيانات:")) {
حدث const = JSON.parse(line.slice(6));
حالة ثابتة = Event.params.task.state;
for (const line of decoder.decode(value).split("\n")) {
if (line.startsWith("data: ")) {
const event = JSON.parse(line.slice(6));
const state = event.params.task.state;
إذا (الحالة === "العمل" && events.params.chunk) {
TotalChunks++;
عملية.stdout.write(
`\r[قطعة ${totalChunks}] ${event.params.chunk.content.slice(0, 50)}...`
if (state === "working" && event.params.chunk) {
totalChunks++;
process.stdout.write(
`\r[Chunk ${totalChunks}] ${event.params.chunk.content.slice(0, 50)}...`
);
}
إذا (الحالة === "مكتملة") {
const meta = events.params.metadata;
if (state === "completed") {
const meta = event.params.metadata;
console.log(
`\n ✅ تم | التكلفة: $${meta?.cost_envelope?.actual || 0} | الطريق: ${meta?.routing_explanation || "غير متوفر"}`
`\n✅ Done | Cost: $${meta?.cost_envelope?.actual || 0} | Route: ${meta?.routing_explanation || "N/A"}`
);
}
إذا (الحالة === "فشل") {
if (state === "failed") {
console.error(`\n❌ Failed: ${event.params.metadata?.error}`);
}
}
}
}
}```
}
```
### 🔁 Use Case 4: Task Polling Pattern
بالنسبة للمهام طويلة الأمد، قم باستقصاء حالة المهمة بدلاً من الانتظار بشكل متزامن.```python
For long-running tasks, poll the task status instead of waiting synchronously.
```python
import time
def poll_task(task_id: str, timeout: int = 60):
@@ -640,64 +678,75 @@ def poll_task(task_id: str, timeout: int = 60):
"params": {"taskId": task_id},
})
raise TimeoutError(f"Task {task_id} timed out after {timeout}s")
````
```
---
## Error Codes
| الكود | ثابت | معنى |
| ------ | -------------------------- | --------------------------------- | -------------------- |
| -32700 | — | خطأ في التحليل (JSON غير صالح) |
| -32600 | `طلب_غير صالح` | طلب JSON-RPC غير صالح أو | غير مصرح به |
| -32601 | `METHOD_NOT_FOUND` | طريقة أو مهارة غير معروفة |
| -32602 | `INVALID_PARAMS` | معلمات مفقودة أو غير صالحة |
| -32603 | `خطأ_داخلي` | فشل في تنفيذ المهارة |
| -32001 | `مهمة_لم يتم العثور عليها` | لم يتم العثور على المفتاح الرئيسي |
| -32002 | `المهمة_الجاهزة_مكتملة` | لا يمكن تعديل مهمة مكتملة |
| -32003 | "غير مصرح به" | API الرئيسية غير صالحة أو مفقودة |
| -32004 | `الميزانية_تجاوزت` | التجاوز المدى المكمل |
| -32005 | `PROVIDER_UNAVAILABLE` | لا يوجد مقدمي خيارات الأسهم | ---## Authentication |
| Code | Constant | Meaning |
| ------ | ------------------------ | ---------------------------------------- |
| -32700 | — | Parse error (invalid JSON) |
| -32600 | `INVALID_REQUEST` | Invalid JSON-RPC request or unauthorized |
| -32601 | `METHOD_NOT_FOUND` | Unknown method or skill |
| -32602 | `INVALID_PARAMS` | Missing or invalid parameters |
| -32603 | `INTERNAL_ERROR` | Skill execution failed |
| -32001 | `TASK_NOT_FOUND` | Task ID not found |
| -32002 | `TASK_ALREADY_COMPLETED` | Cannot modify a completed task |
| -32003 | `UNAUTHORIZED` | Invalid or missing API key |
| -32004 | `BUDGET_EXCEEDED` | Request exceeds configured budget |
| -32005 | `PROVIDER_UNAVAILABLE` | No available providers |
تتطلب جميع الطلبات `/a2a` رمزًا مميزًا لحاملها عبر الرأس `الإعلان`:`
التفويض: الحامل YOUR_OMNIROUTE_API_KEY`
---
إذا لم يتم تكوين أي مفتاح API على الخادم (`OMNIROUTE_API_KEY` فارغ)، فسيتم تجاوز المصادقة.---
## Authentication
All `/a2a` requests require a Bearer token via the `Authorization` header:
```
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
```
If no API key is configured on the server (`OMNIROUTE_API_KEY` is empty), authentication is bypassed.
---
## File Structure
````
سرك/ليب/a2a/
├── TaskManager.ts # دورة حياة المهمة (إنشاء/تحديث/إلغاء/قائمة)، TTL، تنظيف
├── TaskExecution.ts # منفذ المهام العامة مع إدارة الحالة
├── Stream.ts # تنسيق دفق SSE، ونبضات القلب، وأحداث القطعة/الإكمال
├── routingLogger.ts # مسجل قرار التوجيه (الإحصائيات والتاريخ والاحتفاظ)
└── المهارات/
├── SmartRouting.ts # مهارة التوجيه الذكي (الطرق عبر /v1/chat/completions)
└── quotaManagement.ts # مهارة إدارة الحصص (استعلامات الحصص باللغة الطبيعية)
```
src/lib/a2a/
├── taskManager.ts # Task lifecycle (create/update/cancel/list), TTL, cleanup
├── taskExecution.ts # Generic task executor with state management
├── streaming.ts # SSE stream formatting, heartbeat, chunk/completion events
├── routingLogger.ts # Routing decision logger (stats, history, retention)
└── skills/
├── smartRouting.ts # Smart routing skill (routes via /v1/chat/completions)
└── quotaManagement.ts # Quota management skill (natural-language quota queries)
سرك/التطبيق/a2a/
└── Route.ts # معالج مسار واجهة برمجة التطبيقات Next.js (إرسال JSON-RPC 2.0)
src/app/a2a/
└── route.ts # Next.js API route handler (JSON-RPC 2.0 dispatch)
مفتوح-SSE/MCP-خادم/
└── schemas/a2a.ts # مخططات Zod (AgentCard، Task، JSON-RPC، أحداث SSE)```
open-sse/mcp-server/
└── schemas/a2a.ts # Zod schemas (AgentCard, Task, JSON-RPC, SSE events)
```
---
## Comparison: MCP vs A2A
| ميزة | خادم MCP | خادم A2A |
| Feature | MCP Server | A2A Server |
| ----------------- | ---------------------------- | ------------------------------------------------- |
|**البروتوكول**| بروتوكول السياق النموذجي | بروتوكول وكيل إلى وكيل v0.3 |
|**النقل**| ستديو / HTTP | HTTP (JSON-RPC 2.0) |
|**الاكتشاف**| قائمة الأدوات عبر MCP | `/.well-known/agent.json` |
|**التفاصيل**| 16 أداة فردية | 2 مهارات عالية المستوى |
|**الأفضل لـ**| وكلاء IDE (المؤشر، كود VS) | أنظمة متعددة الوكلاء (LangChain، CrewAI) |
|**البث**| غير مدعوم | SSE عبر "الرسالة/الدفق" |
|**تتبع المهام**| لا | دورة حياة كاملة (مقدمة → مكتملة) |
|**الملاحظة**| سجل التدقيق لكل استدعاء أداة | مظروف التكلفة + تتبع المرونة + حكم السياسة |---
| **Protocol** | Model Context Protocol | Agent-to-Agent Protocol v0.3 |
| **Transport** | stdio / HTTP | HTTP (JSON-RPC 2.0) |
| **Discovery** | Tool listing via MCP | `/.well-known/agent.json` |
| **Granularity** | 16 individual tools | 2 high-level skills |
| **Best for** | IDE agents (Cursor, VS Code) | Multi-agent systems (LangChain, CrewAI) |
| **Streaming** | Not supported | SSE via `message/stream` |
| **Task tracking** | No | Full lifecycle (submitted → completed) |
| **Observability** | Audit log per tool call | Cost envelope + resilience trace + policy verdict |
---
## الرخصة
جزء من [OmniRoute](https://github.com/diegosouzapw/OmniRoute) - ترخيص معهد ماساتشوستس للتكنولوجيا.
````
Part of [OmniRoute](https://github.com/diegosouzapw/OmniRoute) — MIT License.

File diff suppressed because it is too large Load Diff

229
docs/i18n/bg/CLAUDE.md Normal file
View File

@@ -0,0 +1,229 @@
# CLAUDE.md — AI Agent Session Bootstrap (Български)
🌐 **Languages:** 🇺🇸 [English](../../../CLAUDE.md) · 🇪🇸 [es](../es/CLAUDE.md) · 🇫🇷 [fr](../fr/CLAUDE.md) · 🇩🇪 [de](../de/CLAUDE.md) · 🇮🇹 [it](../it/CLAUDE.md) · 🇷🇺 [ru](../ru/CLAUDE.md) · 🇨🇳 [zh-CN](../zh-CN/CLAUDE.md) · 🇯🇵 [ja](../ja/CLAUDE.md) · 🇰🇷 [ko](../ko/CLAUDE.md) · 🇸🇦 [ar](../ar/CLAUDE.md) · 🇮🇳 [hi](../hi/CLAUDE.md) · 🇮🇳 [in](../in/CLAUDE.md) · 🇹🇭 [th](../th/CLAUDE.md) · 🇻🇳 [vi](../vi/CLAUDE.md) · 🇮🇩 [id](../id/CLAUDE.md) · 🇲🇾 [ms](../ms/CLAUDE.md) · 🇳🇱 [nl](../nl/CLAUDE.md) · 🇵🇱 [pl](../pl/CLAUDE.md) · 🇸🇪 [sv](../sv/CLAUDE.md) · 🇳🇴 [no](../no/CLAUDE.md) · 🇩🇰 [da](../da/CLAUDE.md) · 🇫🇮 [fi](../fi/CLAUDE.md) · 🇵🇹 [pt](../pt/CLAUDE.md) · 🇷🇴 [ro](../ro/CLAUDE.md) · 🇭🇺 [hu](../hu/CLAUDE.md) · 🇧🇬 [bg](../bg/CLAUDE.md) · 🇸🇰 [sk](../sk/CLAUDE.md) · 🇺🇦 [uk-UA](../uk-UA/CLAUDE.md) · 🇮🇱 [he](../he/CLAUDE.md) · 🇵🇭 [phi](../phi/CLAUDE.md) · 🇧🇷 [pt-BR](../pt-BR/CLAUDE.md) · 🇨🇿 [cs](../cs/CLAUDE.md) · 🇹🇷 [tr](../tr/CLAUDE.md)
---
> Quick-start context for AI coding agents. For deep architecture details, see `AGENTS.md`.
> For contribution workflow, see `CONTRIBUTING.md`.
## Бърз старт
```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 test:coverage # Unit tests + coverage gate (60% min)
npm run check # lint + test combined
```
### Running a Single Test
```bash
# Node.js native test runner (most tests)
node --import tsx/esm --test tests/unit/your-file.test.mjs
# Vitest (MCP server, autoCombo, cache)
npm run test:vitest
```
---
## Преглед
**OmniRoute** — unified AI proxy/router. One endpoint, 100+ LLM providers, auto-fallback.
| 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 |
### 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
```
---
## Request Pipeline (Abbreviated)
```
Client → /v1/chat/completions (Next.js route)
→ CORS → Zod validation → auth? → policy check → prompt injection guard
→ handleChatCore() [open-sse/handlers/chatCore.ts]
→ cache check → rate limit → combo routing?
→ resolveComboTargets() → handleSingleModel() per target
→ translateRequest() → getExecutor() → executor.execute()
→ fetch() upstream → retry w/ backoff
→ response translation → SSE stream or JSON
```
---
## Key Conventions
### Code Style
- **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
### Database Access
- **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
### Error Handling
- 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)
### Сигурност
- **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)
---
## Common Modification Scenarios
### Adding a New Provider
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)
### Adding a New API Route
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
### Adding a New DB Module
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
### Adding a New MCP Tool
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)
### Adding a New A2A Skill
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
---
## Testing Cheat Sheet
| 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` |
**PR rule**: If you change production code in `src/`, `open-sse/`, `electron/`, or `bin/`,
you must include or update tests in the same PR.
---
## Git Workflow
```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
```
**Branch prefixes**: `feat/`, `fix/`, `refactor/`, `docs/`, `test/`, `chore/`
**Commit format** ([Conventional Commits](https://www.conventionalcommits.org/)):
```
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
```
**Scopes**: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`,
`memory`, `skills`.
---
## Environment
- **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`
---
## Hard Rules (Never Violate)
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)

View File

@@ -0,0 +1,132 @@
# Contributor Covenant Code of Conduct (Български)
🌐 **Languages:** 🇺🇸 [English](../../../CODE_OF_CONDUCT.md) · 🇪🇸 [es](../es/CODE_OF_CONDUCT.md) · 🇫🇷 [fr](../fr/CODE_OF_CONDUCT.md) · 🇩🇪 [de](../de/CODE_OF_CONDUCT.md) · 🇮🇹 [it](../it/CODE_OF_CONDUCT.md) · 🇷🇺 [ru](../ru/CODE_OF_CONDUCT.md) · 🇨🇳 [zh-CN](../zh-CN/CODE_OF_CONDUCT.md) · 🇯🇵 [ja](../ja/CODE_OF_CONDUCT.md) · 🇰🇷 [ko](../ko/CODE_OF_CONDUCT.md) · 🇸🇦 [ar](../ar/CODE_OF_CONDUCT.md) · 🇮🇳 [hi](../hi/CODE_OF_CONDUCT.md) · 🇮🇳 [in](../in/CODE_OF_CONDUCT.md) · 🇹🇭 [th](../th/CODE_OF_CONDUCT.md) · 🇻🇳 [vi](../vi/CODE_OF_CONDUCT.md) · 🇮🇩 [id](../id/CODE_OF_CONDUCT.md) · 🇲🇾 [ms](../ms/CODE_OF_CONDUCT.md) · 🇳🇱 [nl](../nl/CODE_OF_CONDUCT.md) · 🇵🇱 [pl](../pl/CODE_OF_CONDUCT.md) · 🇸🇪 [sv](../sv/CODE_OF_CONDUCT.md) · 🇳🇴 [no](../no/CODE_OF_CONDUCT.md) · 🇩🇰 [da](../da/CODE_OF_CONDUCT.md) · 🇫🇮 [fi](../fi/CODE_OF_CONDUCT.md) · 🇵🇹 [pt](../pt/CODE_OF_CONDUCT.md) · 🇷🇴 [ro](../ro/CODE_OF_CONDUCT.md) · 🇭🇺 [hu](../hu/CODE_OF_CONDUCT.md) · 🇧🇬 [bg](../bg/CODE_OF_CONDUCT.md) · 🇸🇰 [sk](../sk/CODE_OF_CONDUCT.md) · 🇺🇦 [uk-UA](../uk-UA/CODE_OF_CONDUCT.md) · 🇮🇱 [he](../he/CODE_OF_CONDUCT.md) · 🇵🇭 [phi](../phi/CODE_OF_CONDUCT.md) · 🇧🇷 [pt-BR](../pt-BR/CODE_OF_CONDUCT.md) · 🇨🇿 [cs](../cs/CODE_OF_CONDUCT.md) · 🇹🇷 [tr](../tr/CODE_OF_CONDUCT.md)
---
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@@ -4,16 +4,25 @@
---
Благодарим ви за интереса да допринесете! Това ръководство обхваща всичко необходимо, за да работи.---## Development Setup
Thank you for your interest in contributing! This guide covers everything you need to get started.
---
## Development Setup
### Prerequisites
-**Node.js**>= 18 < 24 (препоръчително: 22 LTS) -**npm**10+ -**Git**### Клониране и инсталиране```bash
- **Node.js** >= 18 < 24 (recommended: 22 LTS)
- **npm** 10+
- **Git**
### Clone & Install
```bash
git clone https://github.com/diegosouzapw/OmniRoute.git
cd OmniRoute
npm install
````
```
### Environment Variables
@@ -24,81 +33,97 @@ cp .env.example .env
# Generate required secrets
echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env
echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env
````
```
Ключови променливи за развитие:
Key variables for development:
| Променлива | Разработка по подразбиране | Описание |
| ---------------------- | -------------------------- | ------------------------------------------ | ---------------------- |
| `ПОРТ` | 20128 | Порт на сървъра |
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | Основен URL адрес за интерфейс |
| `JWT_SECRET` | (генериране по-горе) | Тайна за подписване на JWT |
| `ПЪРВОНАЧАЛНААРОЛА` | `CHANGEME` | Първа парола за влизане |
| `APP_LOG_LEVEL` | `информация` | Ниво на подробност на регистрационния файл | ### Dashboard Settings |
| Variable | Development Default | Description |
| ---------------------- | ------------------------ | --------------------- |
| `PORT` | `20128` | Server port |
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | Base URL for frontend |
| `JWT_SECRET` | (generate above) | JWT signing secret |
| `INITIAL_PASSWORD` | `CHANGEME` | First login password |
| `APP_LOG_LEVEL` | `info` | Log verbosity level |
Таблото за управление предоставя UI превключватели за функции, които също могат да бъдат конфигурирани чрез променливи на средата:
### Dashboard Settings
| Задаване на местоположение | Превключване | Описание |
| -------------------------- | ------------------------------- | --------------------------------------------------------------------------------- |
| Настройки → Разширени | Режим на отстраняване на грешки | Активиране на регистрационните файлове на заявките за отстраняване на грешки (UI) |
| Настройки → Общи | Видимост на страничната лента | Показване/скриване на секциите на страничната лента |
The dashboard provides UI toggles for features that can also be configured via environment variables:
Тези настройки се запазват в базата данни и се запазват при рестартиране, като заменят настройките по подразбиране env var, когато са претърпени.### Running Locally```bash
| Setting Location | Toggle | Description |
| ------------------- | ------------------ | ------------------------------ |
| Settings → Advanced | Debug Mode | Enable debug request logs (UI) |
| Settings → General | Sidebar Visibility | Show/hide sidebar sections |
These settings are stored in the database and persist across restarts, overriding env var defaults when set.
### Running Locally
```bash
# Development mode (hot reload)
npm run dev
# Production build
npm run build
npm run start
# Common port configuration
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
````
Default URLs:
URL адреси по подразбиране:
- **Dashboard**: `http://localhost:20128/dashboard`
- **API**: `http://localhost:20128/v1`
-**Табло за управление**: `http://localhost:20128/табло за управление`
-**API**: `http://localhost:20128/v1`---## Git Workflow
---
> ⚠️**НИКОГА не се включва директно с `main`.**Винаги използват разклонения на функции.```bash
## Git Workflow
> ⚠️ **NEVER commit directly to `main`.** Always use feature branches.
```bash
git checkout -b feat/your-feature-name
# ... направи промени ...
git commit -m "feat: опишете вашата промяна"
# ... make changes ...
git commit -m "feat: describe your change"
git push -u origin feat/your-feature-name
# Отворете заявка за изтегляне в GitHub```
# Open a Pull Request on GitHub
```
### Branch Naming
| Префикс | Цел |
| ----------- | ------------------------ |
| `подвиг/` | Нови функции |
| `поправи/` | Поправки на грешки |
| `рефактор/` | Преструктуриране на код |
| `документи/` | Промени в документацията |
| `тест/` | Тестови допълнения/поправки |
| `скучна работа/` | Инструментална екипировка, CI, зависимости |### Commit Messages
| Prefix | Purpose |
| ----------- | ------------------------- |
| `feat/` | New features |
| `fix/` | Bug fixes |
| `refactor/` | Code restructuring |
| `docs/` | Documentation changes |
| `test/` | Test additions/fixes |
| `chore/` | Tooling, CI, dependencies |
Следвайте [Конвенционални ангажименти](https://www.conventionalcommits.org/):```
### Commit Messages
Follow [Conventional Commits](https://www.conventionalcommits.org/):
```
feat: add circuit breaker for provider calls
fix: resolve JWT secret validation edge case
docs: update SECURITY.md with PII protection
test: add observability unit tests
refactor(db): consolidate rate limit tables
````
```
Обхвати: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`.---## Running Tests
Scopes: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`.
---
## Running Tests
```bash
# All tests (unit + vitest + ecosystem + e2e)
npm run test:all
# Single test file (Node.js native test runner — most tests use this)
node --import tsx/esm --test tests/unit/your-file.test.mjs
node --import tsx/esm --test tests/unit/your-file.test.ts
# Vitest (MCP server, autoCombo, cache)
npm run test:vitest
@@ -121,35 +146,50 @@ npm run lint
npm run check
```
Бележки за покритието:
Coverage notes:
- `npm run test:coverage` измерва покритието на източника за тестови пакети на основната единица, изключвайки `tests/**` и включва `open-sse/**`
- Заявките за изтегляне трябва да поддържат общата врата за покритие на**60% или по-висока**за отчети, линии, функции и клонове
- Ако PR промени производствения код в `src/`, `open-sse/`, `electron/` или `bin/`, той трябва да добави или актуализира автоматизирани тестове в същия PR
- `npm run coverage:report` отпечатва подробния отчетен файл по файл от последното изпълнение на покритието
- `npm run test:coverage:legacy` запазва по-старата метрика за историческо сравнение
- Вижте `docs/COVERAGE_PLAN.md` за поетапна пътна карта за подобряване на покритието### Pull Request Requirements
- `npm run test:coverage` measures source coverage for the main unit test suite, excludes `tests/**`, and includes `open-sse/**`
- Pull requests must keep the overall coverage gate at **60% or higher** for statements, lines, functions, and branches
- If a PR changes production code in `src/`, `open-sse/`, `electron/`, or `bin/`, it must add or update automated tests in the same PR
- `npm run coverage:report` prints the detailed file-by-file report from the latest coverage run
- `npm run test:coverage:legacy` preserves the older metric for historical comparison
- See `docs/COVERAGE_PLAN.md` for the phased coverage improvement roadmap
Преди да отворите или обедините PR:
### Pull Request Requirements
- Стартирайте `npm run test:unit`
- Стартирайте `npm run test:coverage`
- Уверете се, че вратата за покритие остава на**60%+**за всички показатели
- Включете променените или добавени тестови файлове в PR описанието при промяна на производствения код
- Проверете резултатите от SonarQube на PR, когато тайните на проекта са конфигурирани в CI
Before opening or merging a PR:
Текущо състояние на теста:**122 файла за единичен тест**, обхващащи:
- Run `npm run test:unit`
- Run `npm run test:coverage`
- Ensure the coverage gate stays at **60%+** for all metrics
- Include the changed or added test files in the PR description when production code changed
- Check the SonarQube result on the PR when the project secrets are configured in CI
- Преводачи на доставчици и конвертиране на формати
- Ограничаване на скоростта, прекъсвач и устойчивост
- Семантичен кеш, идемпотентност, проследяване на напредъка
- Операции с база данни и схема (21 DB модула)
- OAuth потоци и удостоверяване
- API валиден за крайни точки (Zod v4)
- MCP сървърни инструменти и прилагане на обхват
- Системи за памет и умения---## Code Style
Current test status: **122 unit test files** covering:
-**ESLint**— Стартирайте `npm run lint` преди извършване -**Prettier**— Автоматично форматирано чрез `lint-staged` при ангажиране (2 интервала, точка и запетая, двойни кавички, ширина 100 знака, es5 запетая в края) -**TypeScript**— Всички `src/` кодове се използват `.ts`/`.tsx`; `open-sse/` използва `.ts`/`.js`; документ с TSDoc (`@param`, `@returns`, `@throws`) -**Без `eval()`**— ESLint налага `no-eval`, `no-implied-eval`, `no-new-func` -**Zod валидиране**— Използвайте Zod v4 схеми за всички входни валидации на API -**Именуване**: Файлове = camelCase/kebab-case, компоненти = PascalCase, константи = UPPER_SNAKE---## Project Structure
- Provider translators and format conversion
- Rate limiting, circuit breaker, and resilience
- Semantic cache, idempotency, progress tracking
- Database operations and schema (21 DB modules)
- OAuth flows and authentication
- API endpoint validation (Zod v4)
- MCP server tools and scope enforcement
- Memory and Skills systems
---
## Code Style
- **ESLint** — Run `npm run lint` before committing
- **Prettier** — Auto-formatted via `lint-staged` on commit (2 spaces, semicolons, double quotes, 100 char width, es5 trailing commas)
- **TypeScript** — All `src/` code uses `.ts`/`.tsx`; `open-sse/` uses `.ts`/`.js`; document with TSDoc (`@param`, `@returns`, `@throws`)
- **No `eval()`** — ESLint enforces `no-eval`, `no-implied-eval`, `no-new-func`
- **Zod validation** — Use Zod v4 schemas for all API input validation
- **Naming**: Files = camelCase/kebab-case, components = PascalCase, constants = UPPER_SNAKE
---
## Project Structure
```
src/ # TypeScript (.ts / .tsx)
@@ -216,31 +256,56 @@ docs/ # Documentation
### Step 1: Register Provider Constants
Добавете към `src/shared/constants/providers.ts` — Zod-валидирано при зареждане на модула.### Стъпка 2: Добавяне на изпълнител (ако е необходима персонализирана логика)
Add to `src/shared/constants/providers.ts` — Zod-validated at module load.
Създайте изпълнител в `open-sse/executors/your-provider.ts`, като разширите базовия изпълнител.### Стъпка 3: Добавете преводач (ако форматът не е OpenAI)
### Step 2: Add Executor (if custom logic needed)
Създайте преводачи на заявка/отговор в `open-sse/translator/`.### Стъпка 4: Добавете OAuth Config (ако е базиран на OAuth)
Create executor in `open-sse/executors/your-provider.ts` extending the base executor.
Добавете идентификационни данни за OAuth в `src/lib/oauth/constants/oauth.ts` и услуга в `src/lib/oauth/services/`.### Стъпка 5: Регистрирайте модели
### Step 3: Add Translator (if non-OpenAI format)
Добавете дефиниции на модели в `open-sse/config/providerRegistry.ts`.### Стъпка 6: Добавете тестове
Create request/response translators in `open-sse/translator/`.
Напишете модулни тестове в `tests/unit/`, покривайки минимум:
### Step 4: Add OAuth Config (if OAuth-based)
- Регистрация при доставчик
- Превод на заявка/отговор
- Обработка на грешки---## Pull Request Checklist
Add OAuth credentials in `src/lib/oauth/constants/oauth.ts` and service in `src/lib/oauth/services/`.
- [ ] Тестовете преминават („npm тест“)
- [ ] Linting преминава (`npm run lint`)
- [ ] Компилацията е успешна (`npm run build`)
- [] TypeScript типове, добавени за нови публични функции и интерфейси
- [ ] Няма твърдо кодирани тайни или резервни стойности
- [ ] Всички входове, валидирани със схеми на Zod
- [ ] CHANGELOG актуализиран (ако промяната е пред потребителя)
- [ ] Актуализирана документация (ако е приложимо)---## Releasing
### Step 5: Register Models
Изданията се управляват чрез работен процес `/generate-release`. Когато се създаде ново издание на GitHub, пакетът се**автоматично публикува в npm**чрез GitHub Actions.---## Getting Help
Add model definitions in `open-sse/config/providerRegistry.ts`.
-**Архитектура**: Вижте [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) -**API справка**: Вижте [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md) -**Проблеми**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -**ADRs**: Вижте `docs/adr/` за записи на архитектурни решения
### Step 6: Add Tests
Write unit tests in `tests/unit/` covering at minimum:
- Provider registration
- Request/response translation
- Error handling
---
## Pull Request Checklist
- [ ] Tests pass (`npm test`)
- [ ] Linting passes (`npm run lint`)
- [ ] Build succeeds (`npm run build`)
- [ ] TypeScript types added for new public functions and interfaces
- [ ] No hardcoded secrets or fallback values
- [ ] All inputs validated with Zod schemas
- [ ] CHANGELOG updated (if user-facing change)
- [ ] Documentation updated (if applicable)
---
## Releasing
Releases are managed via the `/generate-release` workflow. When a new GitHub Release is created, the package is **automatically published to npm** via GitHub Actions.
---
## Getting Help
- **Architecture**: See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
- **API Reference**: See [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md)
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
- **ADRs**: See `docs/adr/` for architectural decision records

19
docs/i18n/bg/GEMINI.md Normal file
View File

@@ -0,0 +1,19 @@
# Security and Cleanliness Rules for AI Assistants (Български)
🌐 **Languages:** 🇺🇸 [English](../../../GEMINI.md) · 🇪🇸 [es](../es/GEMINI.md) · 🇫🇷 [fr](../fr/GEMINI.md) · 🇩🇪 [de](../de/GEMINI.md) · 🇮🇹 [it](../it/GEMINI.md) · 🇷🇺 [ru](../ru/GEMINI.md) · 🇨🇳 [zh-CN](../zh-CN/GEMINI.md) · 🇯🇵 [ja](../ja/GEMINI.md) · 🇰🇷 [ko](../ko/GEMINI.md) · 🇸🇦 [ar](../ar/GEMINI.md) · 🇮🇳 [hi](../hi/GEMINI.md) · 🇮🇳 [in](../in/GEMINI.md) · 🇹🇭 [th](../th/GEMINI.md) · 🇻🇳 [vi](../vi/GEMINI.md) · 🇮🇩 [id](../id/GEMINI.md) · 🇲🇾 [ms](../ms/GEMINI.md) · 🇳🇱 [nl](../nl/GEMINI.md) · 🇵🇱 [pl](../pl/GEMINI.md) · 🇸🇪 [sv](../sv/GEMINI.md) · 🇳🇴 [no](../no/GEMINI.md) · 🇩🇰 [da](../da/GEMINI.md) · 🇫🇮 [fi](../fi/GEMINI.md) · 🇵🇹 [pt](../pt/GEMINI.md) · 🇷🇴 [ro](../ro/GEMINI.md) · 🇭🇺 [hu](../hu/GEMINI.md) · 🇧🇬 [bg](../bg/GEMINI.md) · 🇸🇰 [sk](../sk/GEMINI.md) · 🇺🇦 [uk-UA](../uk-UA/GEMINI.md) · 🇮🇱 [he](../he/GEMINI.md) · 🇵🇭 [phi](../phi/GEMINI.md) · 🇧🇷 [pt-BR](../pt-BR/GEMINI.md) · 🇨🇿 [cs](../cs/GEMINI.md) · 🇹🇷 [tr](../tr/GEMINI.md)
---
## 1. File Placement & Organization
- **Test Files**: ALL unit tests, integration tests, ecosystem tests, or Vitest files MUST strictly be placed within the `tests/` directory (e.g., `tests/unit/`, `tests/integration/`). NEVER create test files in the project root (`/`).
- **Scripts and Utilities**: ALL maintenance, debugging, generation, or experimental scripts (`.cjs`, `.mjs`, `.js`, `.ts`) MUST be placed strictly inside the `scripts/` directory or `scripts/scratch/` for temporary one-offs. NEVER dump loose scripts in the project root (`/`).
**The Project Root MUST ONLY CONTAIN:**
- Configuration files (`vitest.config.ts`, `next.config.mjs`, `eslint.config.mjs`, etc.)
- Dependency files (`package.json`, `package-lock.json`)
- Documentation files (`README.md`, `CHANGELOG.md`, `AGENTS.md`)
- CI/CD files and ignore definitions (`.gitignore`, `.dockerignore`)
When creating _any_ validation tests or one-off logic scripts, default to using `scripts/scratch/` or the `tests/unit/` directories according to your goals. Do not pollute the `/` root context.

View File

@@ -391,10 +391,10 @@ When a call fails, the dev doesn't know if it was a rate limit, expired token, w
- **Unified Logs Dashboard** — 4 tabs: Request Logs, Proxy Logs, Audit Logs, Console
- **Console Log Viewer** — Real-time terminal-style viewer with color-coded levels, auto-scroll, search, filter
- **SQLite Proxy Logs** — Persistent logs that survive server restarts
- **SQLite Summary Logs** — Request and proxy log indexes stay queryable across restarts without loading large payload blobs into SQLite
- **Translator Playground** — 4 debugging modes: Playground (format translation), Chat Tester (round-trip), Test Bench (batch), Live Monitor (real-time)
- **Request Telemetry** — p50/p95/p99 latency + X-Request-Id tracing
- **File-Based Logging with Rotation** — App logs rotate by size, retention days, and archive count; call log artifacts rotate by retention days and file count
- **File-Based Detail Artifacts** — App logs rotate by size, retention days, and archive count; detailed request/response payloads live in `DATA_DIR/call_logs/` and rotate independently of SQLite summaries
- **System Info Report** — `npm run system-info` generates `system-info.txt` with your full environment (Node version, OmniRoute version, OS, CLI tools, Docker/PM2 status). Attach it when reporting issues for instant triage.
</details>
@@ -699,7 +699,7 @@ During deep debugging, long histories with tool results quickly exceed provider
```txt
Combo: "maximize-claude"
1. cc/claude-opus-4-6
1. cc/claude-opus-4-7
2. glm/glm-4.7
3. if/kimi-k2-thinking
@@ -723,7 +723,7 @@ Outcome: stable free coding workflow
```txt
Combo: "always-on"
1. cc/claude-opus-4-6
1. cc/claude-opus-4-7
2. cx/gpt-5.2-codex
3. glm/glm-4.7
4. minimax/MiniMax-M2.1
@@ -1515,7 +1515,7 @@ OmniRoute v3.6 is built as an operational platform, not just a relay proxy.
```txt
Combo: "my-coding-stack"
1. cc/claude-opus-4-6
1. cc/claude-opus-4-7
2. nvidia/llama-3.3-70b
3. glm/glm-4.7
4. if/kimi-k2-thinking
@@ -1654,7 +1654,7 @@ Dashboard → Providers → Connect Claude Code
→ 5-hour + weekly quota tracking
Models:
cc/claude-opus-4-6
cc/claude-opus-4-7
cc/claude-sonnet-4-5-20250929
cc/claude-haiku-4-5-20251001
```
@@ -1854,7 +1854,7 @@ Dashboard → Combos → Create New
Name: premium-coding
Models:
1. cc/claude-opus-4-6 (Subscription primary)
1. cc/claude-opus-4-7 (Subscription primary)
2. glm/glm-4.7 (Cheap backup, $0.6/1M)
3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M)
@@ -1884,7 +1884,7 @@ Cost: $0 forever!
Settings → Models → Advanced:
OpenAI API Base URL: http://localhost:20128/v1
OpenAI API Key: [from OmniRoute dashboard]
Model: cc/claude-opus-4-6
Model: cc/claude-opus-4-7
```
### Claude Code
@@ -1994,7 +1994,7 @@ opencode
**Rate limiting**
- Subscription quota out → Fallback to GLM/MiniMax
- Add combo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
- Add combo: `cc/claude-opus-4-7 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth token expired**
@@ -2027,8 +2027,10 @@ opencode
**No request logs**
- Request artifacts are written to `DATA_DIR/call_logs/` as one JSON file per request
- `call_logs` in SQLite stores summary metadata for the Request Logs table and analytics views
- Detailed request/response payloads are written to `DATA_DIR/call_logs/` as one JSON artifact per request
- Enable pipeline capture from Dashboard → Logs → Request Logs if you need detailed per-stage payloads
- `Export Logs` reads the artifact files on demand, while `Export All` includes the `call_logs/` directory alongside `storage.sqlite`
- Set `APP_LOG_TO_FILE=true` if you also want application console logs in `logs/application/app.log`
- Adjust `APP_LOG_MAX_FILE_SIZE`, `APP_LOG_RETENTION_DAYS`, `APP_LOG_MAX_FILES`, and `CALL_LOG_MAX_ENTRIES` as needed
@@ -2324,9 +2326,23 @@ gh release create v2.0.0 --title "v2.0.0" --generate-notes
## 📊 Star History
## Stargazers over time
<a href="https://www.star-history.com/?repos=diegosouzapw%2Fomniroute&type=date&legend=top-left">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=diegosouzapw/omniroute&type=date&theme=dark&legend=top-left" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=diegosouzapw/omniroute&type=date&legend=top-left" />
<img alt="Star History Chart" src="https://api.star-history.com/chart?repos=diegosouzapw/omniroute&type=date&legend=top-left" />
</picture>
</a>
## [![Stargazers over time](https://starchart.cc/diegosouzapw/OmniRoute.svg?variant=adaptive)](https://starchart.cc/diegosouzapw/OmniRoute)
## 🌍 StarMapper
<a href="https://starmapper.bruniaux.com/diegosouzapw/omniroute">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://starmapper.bruniaux.com/api/map-image/diegosouzapw/omniroute?theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://starmapper.bruniaux.com/api/map-image/diegosouzapw/omniroute?theme=light" />
<img alt="StarMapper" src="https://starmapper.bruniaux.com/api/map-image/diegosouzapw/omniroute" />
</picture>
</a>
## 🙏 Acknowledgments

View File

@@ -6,145 +6,174 @@
## Reporting Vulnerabilities
Ако откриете уязвимост на сигурността в OmniRoute, моля, докладвайте отговорно:
If you discover a security vulnerability in OmniRoute, please report it responsibly:
1.**НЕ**отваряйте публичен проблем на GitHub 2. Използвайте [Съвети за сигурност на GitHub](https://github.com/diegosouzapw/OmniRoute/security/advisories/new) 3. Включете: описание, стъпки за възпроизвеждане и потенциално действие## Response Timeline
1. **DO NOT** open a public GitHub issue
2. Use [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new)
3. Include: description, reproduction steps, and potential impact
| Етап | Цел |
| -------------------- | ------------------------- | -------------------- |
| Признание | 48 часа |
| Сортиране и оценка | 5 работни дни |
| Издаване на корекция | 14 работни дни (критично) | ## Поддържани версии |
## Response Timeline
| Версия | Състояние на поддръжка |
| ------- | ---------------------- | --------------------------- |
| 3.4.x | ✅ Активен |
| 3.0.x | ✅ Сигурност |
| < 3.0.0 | ❌ Не се поддържа | ---## Security Architecture |
| Stage | Target |
| ------------------- | --------------------------- |
| Acknowledgment | 48 hours |
| Triage & Assessment | 5 business days |
| Patch Release | 14 business days (critical) |
OmniRoute прилага многослоен модел за сигурност:`
Заявка → CORS → API Key Auth → Prompt Injection Guard → Input Sanitizer → Rate Limiter → Circuit Breaker → Provider`
## Supported Versions
| Version | Support Status |
| ------- | -------------- |
| 3.6.x | ✅ Active |
| 3.5.x | ✅ Security |
| < 3.5.0 | ❌ Unsupported |
---
## Security Architecture
OmniRoute implements a multi-layered security model:
```
Request → CORS → API Key Auth → Prompt Injection Guard → Input Sanitizer → Rate Limiter → Circuit Breaker → Provider
```
### 🔐 Authentication & Authorization
| Характеристика | Изпълнение |
| ----------------------------------- | ------------------------------------------------------------------------- | ------------------------- |
| **Влизане в таблото за управление** | Базирано на парола удостоверяване с JWT токени (HttpOnly бисквитки) |
| **API Key Auth** | HMAC-подписани ключове с CRC валидиране |
| **OAuth 2.0 + PKCE** | Сигурно удостоверяване на доставчик (Claude, Codex, Gemini, Cursor и др.) |
| **Token Refresh** | Автоматично опресняване на OAuth токена преди изтичане |
| **Защитени бисквитки** | `AUTH_COOKIE_SECURE=true` за HTTPS среди |
| **MCP обхвати** | 10 подробни обхвата за контрол на достъпа до MCP инструмент | ### 🛡️ Encryption at Rest |
| Feature | Implementation |
| -------------------- | ---------------------------------------------------------- |
| **Dashboard Login** | Password-based auth with JWT tokens (HttpOnly cookies) |
| **API Key Auth** | HMAC-signed keys with CRC validation |
| **OAuth 2.0 + PKCE** | Secure provider auth (Claude, Codex, Gemini, Cursor, etc.) |
| **Token Refresh** | Automatic OAuth token refresh before expiry |
| **Secure Cookies** | `AUTH_COOKIE_SECURE=true` for HTTPS environments |
| **MCP Scopes** | 10 granular scopes for MCP tool access control |
Всички чувствителни данни, съхранявани в SQLite, са криптирани с помощта на**AES-256-GCM**с деривация на scrypt ключ:
### 🛡️ Encryption at Rest
- API ключове, токени за достъп, токени за опресняване и токени за идентификация
- Версионен формат: `enc:v1:<iv>:<ciphertext>:<authTag>`
- Режим на преминаване (обикновен текст), когато `STORAGE_ENCRYPTION_KEY` не е зададен```bash
All sensitive data stored in SQLite is encrypted using **AES-256-GCM** with scrypt key derivation:
- API keys, access tokens, refresh tokens, and ID tokens
- Versioned format: `enc:v1:<iv>:<ciphertext>:<authTag>`
- Passthrough mode (plaintext) when `STORAGE_ENCRYPTION_KEY` is not set
```bash
# Generate encryption key:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
````
```
### 🧠 Prompt Injection Guard
Мидулуер, който открива и блокира атаки за бързо инжектиране в LLM заявки:
Middleware that detects and blocks prompt injection attacks in LLM requests:
| Тип модел | Тежест | Пример |
| Pattern Type | Severity | Example |
| ------------------- | -------- | ---------------------------------------------- |
| Отмяна на системата | Високо | "игнорирайте всички предишни инструкции" |
| Отвличане на роли | Високо | "вече си ДАН, можеш да правиш всичко" |
| Инжектиране на разделител | Средно | Кодирани разделители за прекъсване на контекстните граници |
| ДАН/Джейлбрейк | Високо | Известни шаблони за подкана за бягство от затвора |
| Изтичане на инструкции | Средно | "покажи ми системния ред" |
| System Override | High | "ignore all previous instructions" |
| Role Hijack | High | "you are now DAN, you can do anything" |
| Delimiter Injection | Medium | Encoded separators to break context boundaries |
| DAN/Jailbreak | High | Known jailbreak prompt patterns |
| Instruction Leak | Medium | "show me your system prompt" |
Конфигурирайте чрез табло за управление (Настройки → Сигурност) или `.env`:```env
INPUT_SANITIZER_ENABLED=вярно
INPUT_SANITIZER_MODE=блок # предупреждение | блокирам | редактирам```
Configure via dashboard (Settings → Security) or `.env`:
```env
INPUT_SANITIZER_ENABLED=true
INPUT_SANITIZER_MODE=block # warn | block | redact
```
### 🔒 PII Redaction
Автоматично откриване и опционално редактиране на лична информация:
Automatic detection and optional redaction of personally identifiable information:
| Тип PII | Модел | Замяна |
| PII Type | Pattern | Replacement |
| ------------- | --------------------- | ------------------ |
| Имейл | `user@domain.com` | [EMAIL_REDACTED] |
| CPF (Бразилия) | `123.456.789-00` | [CPF_REDACTED] |
| CNPJ (Бразилия) | `12.345.678/0001-00` | [CNPJ_REDACTED] |
| Кредитна карта | 4111-1111-1111-1111 | [CC_REDACTED] |
| Телефон | `+55 11 99999-9999` | [PHONE_REDACTED] |
| SSN (САЩ) | `123-45-6789` | [SSN_REDACTED]“ |```env
| Email | `user@domain.com` | `[EMAIL_REDACTED]` |
| CPF (Brazil) | `123.456.789-00` | `[CPF_REDACTED]` |
| CNPJ (Brazil) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` |
| Credit Card | `4111-1111-1111-1111` | `[CC_REDACTED]` |
| Phone | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
| SSN (US) | `123-45-6789` | `[SSN_REDACTED]` |
```env
PII_REDACTION_ENABLED=true
````
```
### 🌐 Network Security
| Характеристика | Описание |
| ----------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------ |
| **CORS** | Конфигурираме начален контрол (`CORS_ORIGIN` env var, по подразбиране `*`) |
| **IP филтриране** | Списък с разрешени/блокирани IP диапазони в таблото |
| **Ограничаване на скоростта** | Ограничения на скоростта за всеки доставчик с автоматично заплащане |
| **Anti-Thundering Herd** | Mutex + затваряне на връзката предотвратява каскадно 502s |
| **TLS пръстов отпечатък** | Подобно на браузъра TLS фалшифициране на пръстови отпечатъци за намаляване на откриването на бот |
| **CLI пръстов отпечатък** | Подреждане на заглавка/тяло на доставчика, за да съответства на собствените CLI подписи | ### 🔌 Устойчивост и наличност |
| Feature | Description |
| ------------------------ | ---------------------------------------------------------------- |
| **CORS** | Configurable origin control (`CORS_ORIGIN` env var, default `*`) |
| **IP Filtering** | Allowlist/blocklist IP ranges in dashboard |
| **Rate Limiting** | Per-provider rate limits with automatic backoff |
| **Anti-Thundering Herd** | Mutex + per-connection locking prevents cascading 502s |
| **TLS Fingerprint** | Browser-like TLS fingerprint spoofing to reduce bot detection |
| **CLI Fingerprint** | Per-provider header/body ordering to match native CLI signatures |
| Характеристика | Описание |
| ------------------------------ | ------------------------------------------------------------------------------------- | ----------------- |
| **Прекъсвач** | 3 състояния (Затворено → Отворено → Полуотворено) на доставчика, поддържано от SQLite |
| **Искане на идемпотентност** | 5-секунден прозорец за дедупиране за дублирани заявки |
| **Експоненциално отстъпление** | Автоматичен повторен опит с нарастващи закъснения |
| **Здравно табло** | Мониторинг на здравето на доставчика в реално време | ### 📋 Compliance |
### 🔌 Resilience & Availability
| Характеристика | Описание |
| --------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------ |
| **Запазване на регистрационни файлове** | Автоматично след почистване `CALL_LOG_RETENTION_DAYS` |
| **Отказ без влизане** | Флагът `noLog` за API ключ деактивира регистрацията на заявки |
| **Дневник за проверка** | Административни действия, последвани в таблицата `audit_log` |
| **MCP Одит** | Поддържано от SQLite обикновено регистриране за всички извиквания на MCP инструмент |
| **Проверка на Zod** | Всички API входове, валидирани със схеми на Zod v4 при зареждане на модул | ---## Required Environment Variables |
| Feature | Description |
| ----------------------- | ------------------------------------------------------------------ |
| **Circuit Breaker** | 3-state (Closed → Open → Half-Open) per provider, SQLite-persisted |
| **Request Idempotency** | 5-second dedup window for duplicate requests |
| **Exponential Backoff** | Automatic retry with increasing delays |
| **Health Dashboard** | Real-time provider health monitoring |
Всички тайни трябва да бъдат лоши преди стартиране на сървъра. Сървърът ще**откаже бързо**, ако те липсва или са слаби.```bash
### 📋 Compliance
# ЗАДЪЛЖИТЕЛНО — сървърът няма да стартира без тези:
| Feature | Description |
| ------------------ | ----------------------------------------------------------- |
| **Log Retention** | Automatic cleanup after `CALL_LOG_RETENTION_DAYS` |
| **No-Log Opt-out** | Per API key `noLog` flag disables request logging |
| **Audit Log** | Administrative actions tracked in `audit_log` table |
| **MCP Audit** | SQLite-backed audit logging for all MCP tool calls |
| **Zod Validation** | All API inputs validated with Zod v4 schemas at module load |
JWT_SECRET=$(openssl rand -base64 48) # мин. 32 знака
API_KEY_SECRET=$(openssl rand -hex 32) # мин. 16 знака
---
# ПРЕПОРЪЧИТЕЛНО — разрешава криптиране в покой:
## Required Environment Variables
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)```
All secrets must be set before starting the server. The server will **fail fast** if they are missing or weak.
Сървърът активно отхвърля известни слаби стойности като `changeme`, `secret` или `password`.---
```bash
# REQUIRED — server will not start without these:
JWT_SECRET=$(openssl rand -base64 48) # min 32 chars
API_KEY_SECRET=$(openssl rand -hex 32) # min 16 chars
# RECOMMENDED — enables encryption at rest:
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
```
The server actively rejects known-weak values like `changeme`, `secret`, or `password`.
---
## Docker Security
- Използвайте не-root потребител в производството
- Монтиране на тайни като томове само за четене
- Никога не копирайте `.env` файлове в Docker изображения
- Използвайте `.dockerignore`, за да изключите чувствителни файлове
- Задайте `AUTH_COOKIE_SECURE=true`, когато сте зад HTTPS```bash
docker run -d \
--name omniroute \
--restart unless-stopped \
--read-only \
-p 20128:20128 \
-v omniroute-data:/app/data \
-e JWT_SECRET="$(openssl rand -base64 48)" \
-e API_KEY_SECRET="$(openssl rand -hex 32)" \
-e STORAGE_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
diegosouzapw/omniroute:latest
- Use non-root user in production
- Mount secrets as read-only volumes
- Never copy `.env` files into Docker images
- Use `.dockerignore` to exclude sensitive files
- Set `AUTH_COOKIE_SECURE=true` when behind HTTPS
```bash
docker run -d \
--name omniroute \
--restart unless-stopped \
--read-only \
-p 20128:20128 \
-v omniroute-data:/app/data \
-e JWT_SECRET="$(openssl rand -base64 48)" \
-e API_KEY_SECRET="$(openssl rand -hex 32)" \
-e STORAGE_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
diegosouzapw/omniroute:latest
```
---
## Dependencies
- Редовно изпълнете `npm audit`
- Поддържайте зависимостите от актуализациите
- Проектът използва `husky` + `lint-staged` за проверки преди ангажиране
- CI тръбопроводът изпълнява правила за сигурност ESLint при всяко натискане
- Константа на доставчика, валидирана при зареждане на модул чрез Zod (`src/shared/validation/providerSchema.ts`)
```
- Run `npm audit` regularly
- Keep dependencies updated
- The project uses `husky` + `lint-staged` for pre-commit checks
- CI pipeline runs ESLint security rules on every push
- Provider constants validated at module load via Zod (`src/shared/validation/providerSchema.ts`)

View File

@@ -0,0 +1,63 @@
# Feature: Smart Auto-Combos — Dynamic model composition (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1041-smart-auto-combos.md) · 🇪🇸 [es](../../../es/_ideia/defer/1041-smart-auto-combos.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1041-smart-auto-combos.md) · 🇩🇪 [de](../../../de/_ideia/defer/1041-smart-auto-combos.md) · 🇮🇹 [it](../../../it/_ideia/defer/1041-smart-auto-combos.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1041-smart-auto-combos.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1041-smart-auto-combos.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1041-smart-auto-combos.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1041-smart-auto-combos.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1041-smart-auto-combos.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1041-smart-auto-combos.md) · 🇮🇳 [in](../../../in/_ideia/defer/1041-smart-auto-combos.md) · 🇹🇭 [th](../../../th/_ideia/defer/1041-smart-auto-combos.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1041-smart-auto-combos.md) · 🇮🇩 [id](../../../id/_ideia/defer/1041-smart-auto-combos.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1041-smart-auto-combos.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1041-smart-auto-combos.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1041-smart-auto-combos.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1041-smart-auto-combos.md) · 🇳🇴 [no](../../../no/_ideia/defer/1041-smart-auto-combos.md) · 🇩🇰 [da](../../../da/_ideia/defer/1041-smart-auto-combos.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1041-smart-auto-combos.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1041-smart-auto-combos.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1041-smart-auto-combos.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1041-smart-auto-combos.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1041-smart-auto-combos.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1041-smart-auto-combos.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1041-smart-auto-combos.md) · 🇮🇱 [he](../../../he/_ideia/defer/1041-smart-auto-combos.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1041-smart-auto-combos.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1041-smart-auto-combos.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1041-smart-auto-combos.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1041-smart-auto-combos.md)
---
> GitHub Issue: #1041 — opened by @oyi77 on 2026-04-07
> Status: 📋 Cataloged | Priority: High
## 📝 Original Request
When a user first sets up OmniRoute they manually build an Auto-Combo that reflects current credentials. The combo gets stale immediately when new API keys/providers are added or better models are released.
**Proposed: "Smart Combo" mode** — combo member list is re-evaluated at routing time against all currently active credentials, rather than being a fixed array.
## 💬 Community Discussion
### Participants
- @oyi77 — Original requester (power user, contributor)
- @kilo-code-bot — Flagged similarity to #563 (91%), but author explained distinction
### Key Points
- **#563 (closed)** was about routing an incoming model pattern to a specific combo (routing layer)
- **This issue** is about the combo's own member list being dynamic (composition layer)
- Combo should auto-update when credentials/providers change
- Should respect user-configured constraints (exclude lists, priority overrides)
## 🎯 Refined Feature Description
Add a "Smart" toggle to combo creation that makes the combo's model member list dynamically computed at routing time. Instead of storing fixed model IDs, it evaluates all currently active credentials/models and selects the best options.
### What it solves
- Stale combos when new API keys are added
- Models not being used when newly synced from models.dev
- Disabled credentials still being tried
### How it should work (high level)
1. User creates combo with "Smart" toggle ON
2. Configures filters/constraints (provider whitelist/blacklist, model pattern regex, cost tier limits)
3. At request time, combo engine queries active credentials + model catalog
4. Dynamically computes the member list based on filters + scoring (LKGP, latency, cost)
5. Routes using the dynamically computed list with the selected strategy
### Affected areas
- `open-sse/services/combo.ts` — core routing engine
- `open-sse/services/autoCombo/` — auto-combo scoring
- `src/lib/db/combos.ts` — combo schema changes
- `src/shared/validation/schemas.ts` — new combo type schema
- Dashboard combo creation UI
## 📎 Attachments & References
- Discussion with @kilo-code-bot distinguishing from #563
## 🔗 Related Ideas
- Related to [980-lkgp-routing](./980-lkgp-routing.md) — LKGP could feed scoring
- Related to [785-task-class-routing](./785-task-class-routing.md) — task-aware routing

View File

@@ -0,0 +1,64 @@
# Feature: Providers as dynamic plugins/addons (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1112-providers-dynamic-plugins.md) · 🇪🇸 [es](../../../es/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇩🇪 [de](../../../de/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇮🇹 [it](../../../it/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇮🇳 [in](../../../in/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇹🇭 [th](../../../th/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇮🇩 [id](../../../id/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇳🇴 [no](../../../no/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇩🇰 [da](../../../da/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇮🇱 [he](../../../he/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1112-providers-dynamic-plugins.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1112-providers-dynamic-plugins.md)
---
> GitHub Issue: #1112 — opened by @diegosouzapw on 2026-04-10T09:36:17Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem
Currently, adding new providers requires deep integration across the codebase (`open-sse/executors`, `open-sse/config/providerRegistry.ts`, etc.). It's somewhat modularized but not a true drop-in system, making it harder for the community to contribute new providers as simple add-ons.
### Proposed Solution
Implement a dynamic drop-in plugin system that loads providers at runtime from a dedicated `plugins/` or `addons/` directory, allowing users to just drop a `.js` / `.ts` file or folder into the directory to register a new provider without modifying core code.
### Implementation Ideas
- Expose a stable Plugin API or SDK (`ProviderDefinition` interface).
- Dynamic imports to load files from `addons/providers/` at startup.
- Update the UI to show dynamically loaded providers alongside built-in ones.
### Current Workarounds
Currently, any new provider must be hardcoded into the TypeScript source code and the project needs to be recompiled.
### Additional Context
Source: Discussion #1084
## 💬 Community Discussion
(No comments yet, originated from discussion)
## 🎯 Refined Feature Description
Create a robust standard plugin interface where a self-contained JS/TS bundle can define:
- Metadata (ID, name, auth format)
- `executor` logic (how to request)
- Config schemas
And drop it into a `/addons/` folder. The app loads these dynamically on boot via `import()` or `require()`.
### What it solves
Decouples new provider implementations from the core codebase.
Enables closed-source or specialized community providers.
Simplifies PRs (less modification of core registries).
### Affected areas
- `open-sse/config/providerRegistry.ts` (needs dynamic loading phase)
- Next.js build config (allowing external requires)
## 📎 Attachments & References
N/A
## 🔗 Related Ideas
N/A

View File

@@ -0,0 +1,105 @@
# Feature: [Feature] Add plan-aware GitHub Copilot model filtering and refresh the GitHub model catalog (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇪🇸 [es](../../../es/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇩🇪 [de](../../../de/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇮🇹 [it](../../../it/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇮🇳 [in](../../../in/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇹🇭 [th](../../../th/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇮🇩 [id](../../../id/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇳🇴 [no](../../../no/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇩🇰 [da](../../../da/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇮🇱 [he](../../../he/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1168-feature-add-plan-aware-github-copilot-model-filtering-and-refresh-the-github-model-catalog.md)
---
> GitHub Issue: #1168 — opened by @demiolawunmi on 2026-04-11T23:09:31Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem / Use Case
It would be helpful to improve the GitHub Copilot integration by making model availability plan-aware and updating the listed models to match GitHubs current documentation.
Right now, the available model list appears out of sync with GitHubs latest Copilot docs, and there is no clear way to distinguish which models should be shown for different Copilot entitlements. GitHubs documentation notes that model availability can vary by plan and by client, and that some models may not be available depending on the users plan.
This creates confusion for users on GitHub Copilot Student, because Student does not have the same model access as Pro+. GitHubs plans docs say Copilot Student includes unlimited completions, access to premium models in Copilot Chat, and a monthly premium request allowance, while Copilot Pro+ includes full access to all available models in Copilot Chat. :contentReference[oaicite:1]{index=1}
As a result, the integration can currently expose models that are not actually available for a users GitHub Copilot plan, and the displayed GitHub model list may not reflect the current supported model catalog from GitHubs docs.
Copilot student only has access to these models: Claude Haiku 4.5 Gemini 2.5 Pro Gemini 3 Flash Gemini 3.1 Pro GPT-4.1 GPT-5 mini GPT-5.1 GPT-5.2 GPT-5.2-Codex GPT-5.3-Codex GPT-5.4 mini Grok Code Fast 1 Raptor mini
### Proposed Solution
Add plan-aware handling for the GitHub Copilot provider.
Suggested behavior:
- Allow the GitHub provider to distinguish between Copilot Free, Student, Pro, and Pro+.
- Only show models that are actually available for the selected or detected plan.
- Clearly label models as included vs premium where relevant.
- Refresh the GitHub Copilot model catalog so it stays aligned with GitHubs current supported-model documentation.
- If plan auto-detection is not possible, add a manual setting so users can choose their Copilot entitlement.
This would make the GitHub provider more accurate and would prevent users from selecting models that GitHub does not make available under their current plan. GitHubs docs already distinguish plans and supported models, so reflecting that in OmniRoute would improve correctness and UX. :contentReference[oaicite:3]{index=3}
### Alternatives Considered
Current workarounds are limited:
- Manually ignore models that are not available under the users plan.
- Manually compare OmniRoutes GitHub model list against GitHubs docs.
- Use trial and error to see which models actually work.
These workarounds are inconvenient and easy to get wrong, especially because GitHubs supported model list and plan access can change over time. :contentReference[oaicite:4]{index=4}
### Acceptance Criteria
- GitHub Copilot models are filtered by plan entitlement (at minimum: Free, Student, Pro, Pro+).
- Unsupported GitHub Copilot models are hidden or clearly marked unavailable for the selected plan.
- The GitHub providers model list matches GitHubs current supported-model documentation.
- If plan detection is not automatic, a manual plan selector is available in provider settings.
- Existing non-GitHub providers remain unaffected.
- Tests cover plan-based filtering and GitHub model list updates.
### Area
Provider Support
### Related Provider(s)
Github Copilot
### Additional Context
GitHubs official documentation currently separates Copilot plans and supported AI models. The docs also state that Pro+ has full access to all available models, while other plans have different limits and allowances. GitHub also notes that supported models vary by client and that some models may not be available depending on the plan. :contentReference[oaicite:5]{index=5}
Because of that, plan-aware filtering would make the GitHub provider more accurate and less confusing, especially for Copilot Student users.
### Expected Test Plan
- Add unit tests for GitHub provider plan-based model filtering.
- Add coverage for Student, Pro, and Pro+ model visibility behavior.
- Add or update tests for the GitHub provider model registry / model list sync.
- Verify that unavailable models are hidden or marked correctly.
- Verify that existing provider integrations remain unchanged.
## 💬 Community Discussion
No community comments yet.
## 🎯 Refined Feature Description
(Requires manual/AI refinement)
### What it solves
- TBD
### How it should work (high level)
1. TBD
### Affected areas
- TBD
## 📎 Attachments & References
- TBD
## 🔗 Related Ideas
- TBD

View File

@@ -0,0 +1,63 @@
# Feature: Add TPS (Tokens Per Second) Metric (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1182-tps-metric.md) · 🇪🇸 [es](../../../es/_ideia/defer/1182-tps-metric.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1182-tps-metric.md) · 🇩🇪 [de](../../../de/_ideia/defer/1182-tps-metric.md) · 🇮🇹 [it](../../../it/_ideia/defer/1182-tps-metric.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1182-tps-metric.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1182-tps-metric.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1182-tps-metric.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1182-tps-metric.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1182-tps-metric.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1182-tps-metric.md) · 🇮🇳 [in](../../../in/_ideia/defer/1182-tps-metric.md) · 🇹🇭 [th](../../../th/_ideia/defer/1182-tps-metric.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1182-tps-metric.md) · 🇮🇩 [id](../../../id/_ideia/defer/1182-tps-metric.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1182-tps-metric.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1182-tps-metric.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1182-tps-metric.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1182-tps-metric.md) · 🇳🇴 [no](../../../no/_ideia/defer/1182-tps-metric.md) · 🇩🇰 [da](../../../da/_ideia/defer/1182-tps-metric.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1182-tps-metric.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1182-tps-metric.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1182-tps-metric.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1182-tps-metric.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1182-tps-metric.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1182-tps-metric.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1182-tps-metric.md) · 🇮🇱 [he](../../../he/_ideia/defer/1182-tps-metric.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1182-tps-metric.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1182-tps-metric.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1182-tps-metric.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1182-tps-metric.md)
---
> GitHub Issue: #1182 — opened by @uwuclxdy on 2026-04-12
> Status: ⏭️ DEFER | Priority: Medium
## 📝 Original Request
Add a Tokens Per Second (TPS) metric to the OmniRoute dashboard to measure and display the speed of model responses. This would help users compare provider/model performance and make informed routing decisions.
## 💬 Community Discussion
### Participants
- @uwuclxdy — Original requester, active contributor (also opened #1339, #1364)
- 3 comments in discussion thread
### Key Points
- TPS is a key metric for comparing streaming performance across providers
- Would require measuring token output rate during streaming responses
- Useful for both real-time display (per-request) and historical aggregation
- Could feed into routing decisions (e.g., prefer faster providers for interactive use)
## 🎯 Refined Feature Description
Instrument the streaming response pipeline to measure and display Tokens Per Second (TPS) — the rate at which tokens are generated — per request, per model, and per provider.
### What it solves
- No visibility into streaming response speed across providers/models
- Cannot compare provider performance objectively
- Cannot make routing decisions based on throughput
### How it should work (high level)
1. During streaming responses, track the time between the first and last token
2. Count output tokens from the response `usage` field or chunk count
3. Calculate TPS = total_output_tokens / (last_token_time - first_token_time)
4. Display TPS on: individual request logs, provider metrics, combo metrics
5. Optionally expose TPS via the MCP server `get_provider_metrics` tool
6. Store historical TPS data for trend analysis in the dashboard
### Affected areas
- `open-sse/handlers/chatCore.ts` — instrument streaming for timing
- `open-sse/services/usage.ts` — store TPS alongside existing usage metrics
- `src/lib/db/detailedLogs.ts` — add TPS column to detailed logs
- `src/app/(dashboard)/dashboard/logs/` — display TPS in log entries
- `src/app/(dashboard)/dashboard/endpoint/` — display TPS in provider/combo metrics
- DB migrations — new `tps` column in relevant tables
## 📎 Attachments & References
- No external references
## 🔗 Related Ideas
- TPS data could feed into [1041-smart-auto-combos](./1041-smart-auto-combos.md) scoring
- Related to [980-lkgp-routing](./980-lkgp-routing.md) — throughput as routing signal

View File

@@ -0,0 +1,65 @@
# Feature: [Feature] Add GLM 5.1 support and fix tool-calling compatibility (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇪🇸 [es](../../../es/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇩🇪 [de](../../../de/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇮🇹 [it](../../../it/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇮🇳 [in](../../../in/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇹🇭 [th](../../../th/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇮🇩 [id](../../../id/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇳🇴 [no](../../../no/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇩🇰 [da](../../../da/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇮🇱 [he](../../../he/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1199-feature-add-glm-5-1-support-and-fix-tool-calling-compatibility.md)
---
> GitHub Issue: #1199 — opened by @CmetankaJDD on 2026-04-13T07:57:20Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
## Summary
Please add support for GLM 5.1 in OmniRoute.
At the moment, GLM 5.1 appears to have problems with tool usage / tool calling, which makes it hard to use in agent-style workflows.
## Current behavior
- GLM 5.1 is not available or not fully supported as a first-class model option.
- When trying to use tools with GLM 5.1, requests fail / tool usage does not work correctly.
## Expected behavior
- GLM 5.1 should be supported as a selectable model/provider option.
- Tool calling should work correctly with the model, following the same OpenAI-compatible tool schema behavior expected by OmniRoute clients.
## Why this matters
GLM 5.1 is useful for users who want broader model coverage in OmniRoute, and tool-calling support is required for many coding assistants, agents, and structured workflows.
## Suggested scope
- Add GLM 5.1 model support
- Validate request/response compatibility for tools
- Ensure tool call messages are translated correctly if provider-specific mapping is needed
- Add a basic regression test for tool usage with GLM 5.1
## 💬 Community Discussion
No community comments yet.
## 🎯 Refined Feature Description
(Requires manual/AI refinement)
### What it solves
- TBD
### How it should work (high level)
1. TBD
### Affected areas
- TBD
## 📎 Attachments & References
- TBD
## 🔗 Related Ideas
- TBD

View File

@@ -0,0 +1,114 @@
# Feature: [Feature] Native support for Tavily Extract, Crawl, Map, and Research endpoints (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇪🇸 [es](../../../es/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇩🇪 [de](../../../de/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇮🇹 [it](../../../it/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇮🇳 [in](../../../in/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇹🇭 [th](../../../th/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇮🇩 [id](../../../id/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇳🇴 [no](../../../no/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇩🇰 [da](../../../da/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇮🇱 [he](../../../he/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1217-feature-native-support-for-tavily-extract-crawl-map-and-research-endpoints.md)
---
> GitHub Issue: #1217 — opened by @edwardsconnects90 on 2026-04-13T15:57:08Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem / Use Case
OmniRoute registers Tavily as a search provider (`tavily-search` in `searchRegistry.ts`) and successfully proxies `/v1/search` requests. However, the Tavily API exposes four additional endpoints that are widely used by MCP integrations and AI agents:
- `POST /extract` — extract structured content from URLs
- `POST /crawl` — crawl websites with configurable depth/breadth
- `POST /map` — map website structure (URL discovery)
- `POST /research` — deep multi-source research with async polling (`GET /research/:id`)
When a client (e.g., Tavily MCP server) is configured with `TAVILY_BASE_URL` pointing to OmniRoute, only `/v1/search` works. The other four endpoints return **HTTP 404**, forcing users to either bypass OmniRoute entirely or maintain a separate proxy layer.
This breaks the value proposition of OmniRoute as a unified gateway — Tavily credentials must be managed in two places, and usage of extract/crawl/map/research cannot be tracked or logged through OmniRoute's analytics.
### Proposed Solution
Add four new API routes that proxy requests to the corresponding Tavily API endpoints, reusing the existing `tavily-search` provider credentials from `provider_connections`:
1. `POST /v1/extract``https://api.tavily.com/extract`
2. `POST /v1/crawl``https://api.tavily.com/crawl`
3. `POST /v1/map``https://api.tavily.com/map`
4. `POST /v1/research``https://api.tavily.com/research`
5. `GET /v1/research/:id``https://api.tavily.com/research/:id` (polling for async results)
The routes should:
- Resolve the Tavily API key from the existing `tavily-search` provider connection (same decryption path as `/v1/search`)
- Inject `api_key` into the request body and `Authorization: Bearer` header before forwarding
- Forward the request body as-is (passthrough) — no transformation needed
- Stream the response back to the client
- Record usage in call logs for analytics/cost tracking
- Respect the existing API key policy (`enforceApiKeyPolicy`) if enabled
### Alternatives Considered
1. **Client-side direct connection** — configure the MCP server to hit `api.tavily.com` directly. This works but defeats the purpose of OmniRoute as a centralized gateway, duplicates credential management, and loses visibility into usage analytics.
2. **Separate reverse proxy** — run a lightweight proxy (nginx or Node.js) alongside OmniRoute that routes Tavily-specific endpoints directly while sending `/v1/search` through OmniRoute. Adds operational complexity and splits configuration.
3. **Runtime hotfix** — monkey-patch `http.createServer` via `NODE_OPTIONS --require` to intercept the four routes before Next.js handles them. This is the current workaround and functions correctly, but it is fragile (bypasses OmniRoute's auth, logging, and cost tracking) and adds maintenance burden with each OmniRoute upgrade.
### Acceptance Criteria
- `POST /v1/extract` returns 200 with Tavily's response when given valid `urls` in the body
- `POST /v1/crawl` returns 200 with crawled page content
- `POST /v1/map` returns 200 with discovered URL list
- `POST /v1/research` returns 200 with `request_id` and `status: pending`
- `GET /v1/research/:id` returns the research result or current polling status
- All five endpoints resolve credentials from the existing `tavily-search` provider connection — no additional configuration required
- Requests are logged in OmniRoute's call log and visible in the dashboard analytics
- API key policy enforcement works consistently across all Tavily endpoints
- Existing `/v1/search` behavior (multi-provider selection, caching, cost tracking) is not affected
### Area
Proxy / Routing
### Related Provider(s)
Tavily (`tavily-search`)
### Additional Context
The Tavily MCP server (v0.2.18, official package `tavily-mcp` from `github.com/tavily-ai/tavily-mcp`) is commonly used with Claude Code, Cursor, and other AI coding tools. It supports the `TAVILY_BASE_URL` environment variable, making it straightforward to route through OmniRoute. The server registers all five tools (`tavily_search`, `tavily_extract`, `tavily_crawl`, `tavily_map`, `tavily_research`) and expects all endpoints to be available at the configured base URL.
The `research` endpoint is asynchronous — it returns a `request_id` on POST, and the client polls `GET /research/:id` until `status` changes to `completed` or `failed`. The MCP server implements exponential backoff polling (2s initial, 1.5x factor, 10s max interval) with a timeout of 5 minutes (mini) or 15 minutes (pro/auto).
Architecturally, these routes are simpler than `/v1/search` — they do not require multi-provider selection, response normalization, or request coalescing. A straightforward passthrough with credential injection and call logging would be sufficient.
### Expected Test Plan
- Add unit tests for each new route handler (extract, crawl, map, research, research polling)
- Add integration test verifying credential resolution from `provider_connections`
- Verify that call logs are recorded for each endpoint
- Verify that API key policy enforcement applies
- Keep `npm run test:coverage` at 60%+
## 💬 Community Discussion
No community comments yet.
## 🎯 Refined Feature Description
(Requires manual/AI refinement)
### What it solves
- TBD
### How it should work (high level)
1. TBD
### Affected areas
- TBD
## 📎 Attachments & References
- TBD
## 🔗 Related Ideas
- TBD

View File

@@ -0,0 +1,60 @@
# Feature: Add MiniMax OAuth Provider (Device-Code + PKCE) (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1251-minimax-oauth-provider.md) · 🇪🇸 [es](../../../es/_ideia/defer/1251-minimax-oauth-provider.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1251-minimax-oauth-provider.md) · 🇩🇪 [de](../../../de/_ideia/defer/1251-minimax-oauth-provider.md) · 🇮🇹 [it](../../../it/_ideia/defer/1251-minimax-oauth-provider.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1251-minimax-oauth-provider.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1251-minimax-oauth-provider.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1251-minimax-oauth-provider.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1251-minimax-oauth-provider.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1251-minimax-oauth-provider.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1251-minimax-oauth-provider.md) · 🇮🇳 [in](../../../in/_ideia/defer/1251-minimax-oauth-provider.md) · 🇹🇭 [th](../../../th/_ideia/defer/1251-minimax-oauth-provider.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1251-minimax-oauth-provider.md) · 🇮🇩 [id](../../../id/_ideia/defer/1251-minimax-oauth-provider.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1251-minimax-oauth-provider.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1251-minimax-oauth-provider.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1251-minimax-oauth-provider.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1251-minimax-oauth-provider.md) · 🇳🇴 [no](../../../no/_ideia/defer/1251-minimax-oauth-provider.md) · 🇩🇰 [da](../../../da/_ideia/defer/1251-minimax-oauth-provider.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1251-minimax-oauth-provider.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1251-minimax-oauth-provider.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1251-minimax-oauth-provider.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1251-minimax-oauth-provider.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1251-minimax-oauth-provider.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1251-minimax-oauth-provider.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1251-minimax-oauth-provider.md) · 🇮🇱 [he](../../../he/_ideia/defer/1251-minimax-oauth-provider.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1251-minimax-oauth-provider.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1251-minimax-oauth-provider.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1251-minimax-oauth-provider.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1251-minimax-oauth-provider.md)
---
> GitHub Issue: #1251 — opened by @Tasogarre on 2026-04-14
> Status: ⏭️ DEFER | Priority: Low
## 📝 Original Request
Add MiniMax as an OAuth-based provider using the device-code + PKCE flow. MiniMax is an AI model provider that offers models accessible through their API, and the author proposes using a device-code OAuth flow (similar to GitHub CLI's auth flow) combined with PKCE for security.
## 💬 Community Discussion
### Participants
- @Tasogarre — Original requester, provided detailed OAuth flow specification
### Key Points
- Device-code + PKCE is a different OAuth pattern from OmniRoute's existing OAuth flows (browser redirect-based)
- Existing OAuth providers (Claude Code, Antigravity, Codex, GitHub Copilot, Cursor, etc.) use standard redirect flows
- Implementing device-code flow would require new OAuth infrastructure in `src/lib/oauth/`
- No community discussion beyond the initial proposal
## 🎯 Refined Feature Description
Add MiniMax as an OAuth provider using the device-code grant type with PKCE, enabling users to authenticate via a displayed code + URL (like `gh auth login`) rather than browser redirects.
### What it solves
- Adds MiniMax model provider access to OmniRoute
- Introduces device-code OAuth flow type for headless/terminal environments
- Could benefit other future providers that use device-code authentication
### How it should work (high level)
1. User clicks "Connect MiniMax" in the dashboard
2. Dashboard displays a device code and URL (e.g., "Go to minimax.chat/device and enter code: ABCD-1234")
3. User visits URL, enters code, authorizes the application
4. OmniRoute polls the token endpoint until authorization is complete
5. Stores OAuth tokens and refreshes automatically
### Affected areas
- `src/lib/oauth/constants/oauth.ts` — new OAuth config for MiniMax
- `src/lib/oauth/` — new device-code flow handler (distinct from existing redirect flows)
- `open-sse/executors/` — new or default executor for MiniMax API
- `src/shared/constants/providers.ts` — register in `OAUTH_PROVIDERS`
- `open-sse/config/providerRegistry.ts` — model registration
- Dashboard OAuth modal — new device-code UI variant
## 📎 Attachments & References
- Author provided detailed OAuth flow specification in the issue body (2795 chars)
## 🔗 Related Ideas
- Related to existing OAuth providers architecture in `src/lib/oauth/`

View File

@@ -0,0 +1,58 @@
# Feature: Add Freepik Pikaso Image Generation Provider (Cookie/Subscription-Based) (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1276-freepik-pikaso-provider.md) · 🇪🇸 [es](../../../es/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇩🇪 [de](../../../de/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇮🇹 [it](../../../it/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇮🇳 [in](../../../in/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇹🇭 [th](../../../th/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇮🇩 [id](../../../id/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇳🇴 [no](../../../no/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇩🇰 [da](../../../da/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇮🇱 [he](../../../he/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1276-freepik-pikaso-provider.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1276-freepik-pikaso-provider.md)
---
> GitHub Issue: #1276 — opened by @RaviTharuma on 2026-04-15
> Status: ⏭️ DEFER | Priority: Low
## 📝 Original Request
Add Freepik Pikaso as a cookie/subscription-based image generation provider. Pikaso is Freepik's AI image generation tool that uses a session cookie for authentication and can be accessed through their web API.
The author (@RaviTharuma) is a known contributor who built the Perplexity Web and Grok Web executors.
## 💬 Community Discussion
### Participants
- @RaviTharuma — Original requester, contributor (built Perplexity Web + Grok Web executors)
### Key Points
- Would follow the same cookie-based executor pattern as Grok Web and Perplexity Web
- Freepik Pikaso uses subscription-based access (cookie auth)
- Needs reverse-engineering of the Pikaso API endpoints and response format
- No community discussion beyond the initial proposal
## 🎯 Refined Feature Description
Add a new cookie-based image generation executor for Freepik Pikaso, following the established pattern of web-subscription providers (Grok Web, Perplexity Web).
### What it solves
- Enables Freepik Pikaso subscribers to route image generation through OmniRoute
- Extends image generation provider coverage alongside existing DALL-E, SD WebUI, ComfyUI
### How it should work (high level)
1. User provides their Freepik session cookie in the dashboard
2. OmniRoute sends image generation requests to Pikaso's internal API
3. Responses are translated to the standard OmniRoute image generation format
4. Supports text-to-image generation with style/model parameters
### Affected areas
- `open-sse/executors/` — new `freepik-pikaso.ts` executor
- `src/shared/constants/providers.ts` — register in `WEB_COOKIE_PROVIDERS` or image-specific catalog
- `open-sse/handlers/imageGeneration.ts` — add Pikaso routing support
- `open-sse/config/providerRegistry.ts` — model registration
## 📎 Attachments & References
- No external references provided yet; needs API traffic capture
## 🔗 Related Ideas
- Same pattern as Grok Web and Perplexity Web cookie-based executors

View File

@@ -0,0 +1,75 @@
# Feature: Per-Key Token Rate Limiting (TPM/TPD) (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇪🇸 [es](../../../es/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇩🇪 [de](../../../de/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇮🇹 [it](../../../it/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇮🇳 [in](../../../in/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇹🇭 [th](../../../th/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇮🇩 [id](../../../id/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇳🇴 [no](../../../no/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇩🇰 [da](../../../da/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇮🇱 [he](../../../he/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1305-per-key-token-rate-limiting.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1305-per-key-token-rate-limiting.md)
---
> GitHub Issue: #1305 — opened by @kaccang on 2026-04-16
> Status: ⏭️ DEFER | Priority: Medium
## 📝 Original Request
OmniRoute already supports per-key request-based limits, but subscription-based API operators also need token-based limits to control upstream cost exposure. A single request to a large-context model can consume far more compute and cost than a normal request while still counting as only one request.
**Use case examples (from author):**
- Lite plan: 32K tokens/minute, 5M tokens/day
- Pro plan: 64K tokens/minute, 15M tokens/day
**Proposed fields:**
- `max_tokens_per_minute` (TPM)
- `max_tokens_per_day` (TPD)
Returns HTTP 429 with `token_limit_exceeded` reason when exceeded.
## 💬 Community Discussion
### Participants
- @kaccang — Original requester, detailed operator-focused use case
### Key Points
- Addresses operators selling subscription-based AI API products through OmniRoute
- Request-only limits are insufficient for long-context or high-output models
- Token accounting should use actual usage from upstream response `usage` fields
- Must handle both streaming and non-streaming accounting paths
- Backward compatible — keys without token limits keep existing behavior
## 🎯 Refined Feature Description
Add optional per-API-key token-based rate limiting alongside existing request-based limits, enabling operators to enforce fair-use policies based on actual token consumption.
### What it solves
- Disproportionate cost exposure from large-context requests that count as single requests
- Inability to sell token-based subscription plans through OmniRoute
- Lack of per-customer cost protection for mixed model catalogs with varying context windows
### How it should work (high level)
1. Add `max_tokens_per_minute` and `max_tokens_per_day` optional fields to API key configuration
2. After each response, extract `usage.total_tokens` from the upstream response
3. Account consumed tokens to the authenticated key using sliding window counters
4. Before each request, check if the key has remaining token budget for the current window
5. If budget exceeded, return 429 with `token_limit_exceeded` error code and `Retry-After` header
6. For streaming responses, account tokens from the final usage chunk (`stream_options.include_usage`)
7. Dashboard UI: display TPM/TPD fields in the API key creation/edit modal
### Affected areas
- `src/lib/db/apiKeys.ts` — new columns for TPM/TPD limits
- `open-sse/services/rateLimitManager.ts` — token-based window tracking
- `open-sse/handlers/chatCore.ts` — post-response token accounting
- `src/app/api/v1/` routes — pre-request token budget check
- `src/app/(dashboard)/dashboard/settings/` — API key modal UI extension
- DB migrations — new columns on `api_keys` table
## 📎 Attachments & References
- Author's detailed acceptance criteria and test plan in issue body
## 🔗 Related Ideas
- Directly related to [1320-rate-limit-headers](./1320-rate-limit-headers.md) — expose token limits via standard headers

View File

@@ -0,0 +1,71 @@
# Feature: Standard Rate Limit Headers for Requests, Tokens, Resets, and Retry-After (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1320-rate-limit-headers.md) · 🇪🇸 [es](../../../es/_ideia/defer/1320-rate-limit-headers.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1320-rate-limit-headers.md) · 🇩🇪 [de](../../../de/_ideia/defer/1320-rate-limit-headers.md) · 🇮🇹 [it](../../../it/_ideia/defer/1320-rate-limit-headers.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1320-rate-limit-headers.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1320-rate-limit-headers.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1320-rate-limit-headers.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1320-rate-limit-headers.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1320-rate-limit-headers.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1320-rate-limit-headers.md) · 🇮🇳 [in](../../../in/_ideia/defer/1320-rate-limit-headers.md) · 🇹🇭 [th](../../../th/_ideia/defer/1320-rate-limit-headers.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1320-rate-limit-headers.md) · 🇮🇩 [id](../../../id/_ideia/defer/1320-rate-limit-headers.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1320-rate-limit-headers.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1320-rate-limit-headers.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1320-rate-limit-headers.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1320-rate-limit-headers.md) · 🇳🇴 [no](../../../no/_ideia/defer/1320-rate-limit-headers.md) · 🇩🇰 [da](../../../da/_ideia/defer/1320-rate-limit-headers.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1320-rate-limit-headers.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1320-rate-limit-headers.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1320-rate-limit-headers.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1320-rate-limit-headers.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1320-rate-limit-headers.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1320-rate-limit-headers.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1320-rate-limit-headers.md) · 🇮🇱 [he](../../../he/_ideia/defer/1320-rate-limit-headers.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1320-rate-limit-headers.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1320-rate-limit-headers.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1320-rate-limit-headers.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1320-rate-limit-headers.md)
---
> GitHub Issue: #1320 — opened by @kaccang on 2026-04-16
> Status: ⏭️ DEFER | Priority: Medium
## 📝 Original Request
When a client is throttled, it should receive machine-readable rate-limit information via standard HTTP headers so it can back off correctly. Without explicit response headers, clients guess retry timing, producing unnecessary retry loops that increase pressure on the gateway.
**Proposed headers (from author):**
Request-based:
- `X-RateLimit-Limit-Requests-Minute` / `X-RateLimit-Remaining-Requests-Minute` / `X-RateLimit-Reset-Requests-Minute`
- `X-RateLimit-Limit-Requests-Day` / `X-RateLimit-Remaining-Requests-Day` / `X-RateLimit-Reset-Requests-Day`
Token-based (if configured):
- `X-RateLimit-Limit-Tokens-Minute` / `X-RateLimit-Remaining-Tokens-Minute` / `X-RateLimit-Reset-Tokens-Minute`
- `X-RateLimit-Limit-Tokens-Day` / `X-RateLimit-Remaining-Tokens-Day` / `X-RateLimit-Reset-Tokens-Day`
On 429: `Retry-After` header.
## 💬 Community Discussion
### Participants
- @kaccang — Original requester, also opened #1305 (per-key token rate limiting)
### Key Points
- Aligns with OpenAI's rate-limit header convention
- Useful for SDKs, automation tools, and customer dashboards
- Backward compatible — clients that don't consume headers are unaffected
- Author provided detailed acceptance criteria and test plan
## 🎯 Refined Feature Description
Expose current rate-limit state via standard HTTP response headers on all API responses, and include `Retry-After` on 429 responses.
### What it solves
- Clients cannot determine remaining quota without trial-and-error
- SDKs and automation tools lack machine-readable throttling signals
- Unnecessary retry loops when clients guess retry timing
### How it should work (high level)
1. On every successful response, inject rate-limit headers reflecting the authenticated key's current state
2. On 429 responses, include `Retry-After` with the number of seconds until the next window
3. Request-based and token-based headers are independent — only include what is configured
4. Headers are derived from the existing `rateLimitManager` state, no new persistence needed
### Affected areas
- `open-sse/services/rateLimitManager.ts` — expose current window state
- `open-sse/handlers/chatCore.ts` — inject headers into response
- `src/app/api/v1/` routes — inject headers at route level
- `src/middleware/` — potential centralized header injection
## 📎 Attachments & References
- Author's test plan included in the issue body
## 🔗 Related Ideas
- Directly related to [1305-per-key-token-rate-limiting](./1305-per-key-token-rate-limiting.md) — both address rate-limit observability

View File

@@ -0,0 +1,59 @@
# Feature: API Key Routing Rules for Custom Endpoints (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/1339-api-key-routing-rules.md) · 🇪🇸 [es](../../../es/_ideia/defer/1339-api-key-routing-rules.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/1339-api-key-routing-rules.md) · 🇩🇪 [de](../../../de/_ideia/defer/1339-api-key-routing-rules.md) · 🇮🇹 [it](../../../it/_ideia/defer/1339-api-key-routing-rules.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/1339-api-key-routing-rules.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/1339-api-key-routing-rules.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/1339-api-key-routing-rules.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/1339-api-key-routing-rules.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/1339-api-key-routing-rules.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/1339-api-key-routing-rules.md) · 🇮🇳 [in](../../../in/_ideia/defer/1339-api-key-routing-rules.md) · 🇹🇭 [th](../../../th/_ideia/defer/1339-api-key-routing-rules.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/1339-api-key-routing-rules.md) · 🇮🇩 [id](../../../id/_ideia/defer/1339-api-key-routing-rules.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/1339-api-key-routing-rules.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/1339-api-key-routing-rules.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/1339-api-key-routing-rules.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/1339-api-key-routing-rules.md) · 🇳🇴 [no](../../../no/_ideia/defer/1339-api-key-routing-rules.md) · 🇩🇰 [da](../../../da/_ideia/defer/1339-api-key-routing-rules.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/1339-api-key-routing-rules.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/1339-api-key-routing-rules.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/1339-api-key-routing-rules.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/1339-api-key-routing-rules.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/1339-api-key-routing-rules.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/1339-api-key-routing-rules.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/1339-api-key-routing-rules.md) · 🇮🇱 [he](../../../he/_ideia/defer/1339-api-key-routing-rules.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/1339-api-key-routing-rules.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/1339-api-key-routing-rules.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/1339-api-key-routing-rules.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/1339-api-key-routing-rules.md)
---
> GitHub Issue: #1339 — opened by @uwuclxdy on 2026-04-16
> Status: ⏭️ DEFER | Priority: Medium
## 📝 Original Request
When using a custom OpenAI endpoint with multiple API keys, the only available routing option is "round-robin". The user wants the ability to configure routing strategies per-provider (e.g., "exhaust first key before using second"), similar to how combo-level strategies already work.
The user included a screenshot of the API key popup in the dashboard, highlighting that there's no strategy selector available at the provider/connection level.
## 💬 Community Discussion
### Participants
- @uwuclxdy — Original requester, active contributor (also opened #1364, #1182)
### Key Points
- Currently, routing strategies (priority, weighted, fill-first, round-robin, etc.) are only configurable at the combo level
- Provider-level multi-key rotation is hardcoded to round-robin
- User wants "fill-first" (exhaust first key before next) for cost optimization
- Affects custom OpenAI-compatible and Anthropic-compatible providers
## 🎯 Refined Feature Description
Extend the provider connection management to allow per-provider API key routing strategy selection, mirroring the 13 strategies already available at the combo level.
### What it solves
- Users with multiple API keys for the same provider cannot control which key is used first
- Round-robin wastes quota evenly across keys instead of exhausting free/cheaper tiers first
- No parity between combo-level routing flexibility and provider-level key management
### How it should work (high level)
1. Add a "Key Routing Strategy" dropdown to the provider detail page's connection/key management popup
2. Support at minimum: `round-robin`, `priority`, `fill-first`, `random`
3. Store the per-provider strategy in the `provider_connections` table or a new column
4. The combo routing engine respects per-provider key strategy when dispatching requests
### Affected areas
- `open-sse/services/combo.ts` — key selection within a provider target
- `src/lib/db/providers.ts` — store per-provider key strategy
- `src/app/(dashboard)/dashboard/providers/[id]/page.tsx` — UI for strategy selection
- `src/shared/validation/schemas.ts` — new schema for provider key strategy
## 📎 Attachments & References
- Screenshot of API key popup: https://github.com/user-attachments/assets/d26049ba-0dba-4c64-8ed4-8f68e8c00252
## 🔗 Related Ideas
- Related to combo routing engine strategies in `open-sse/services/combo.ts`

View File

@@ -0,0 +1,41 @@
# Feature: Task-Class Routing with Escalation/De-escalation (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/785-task-class-routing.md) · 🇪🇸 [es](../../../es/_ideia/defer/785-task-class-routing.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/785-task-class-routing.md) · 🇩🇪 [de](../../../de/_ideia/defer/785-task-class-routing.md) · 🇮🇹 [it](../../../it/_ideia/defer/785-task-class-routing.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/785-task-class-routing.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/785-task-class-routing.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/785-task-class-routing.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/785-task-class-routing.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/785-task-class-routing.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/785-task-class-routing.md) · 🇮🇳 [in](../../../in/_ideia/defer/785-task-class-routing.md) · 🇹🇭 [th](../../../th/_ideia/defer/785-task-class-routing.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/785-task-class-routing.md) · 🇮🇩 [id](../../../id/_ideia/defer/785-task-class-routing.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/785-task-class-routing.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/785-task-class-routing.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/785-task-class-routing.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/785-task-class-routing.md) · 🇳🇴 [no](../../../no/_ideia/defer/785-task-class-routing.md) · 🇩🇰 [da](../../../da/_ideia/defer/785-task-class-routing.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/785-task-class-routing.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/785-task-class-routing.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/785-task-class-routing.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/785-task-class-routing.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/785-task-class-routing.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/785-task-class-routing.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/785-task-class-routing.md) · 🇮🇱 [he](../../../he/_ideia/defer/785-task-class-routing.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/785-task-class-routing.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/785-task-class-routing.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/785-task-class-routing.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/785-task-class-routing.md)
---
> GitHub Issue: #785 — opened by @igormorais123 on 2026-03-30
> Status: 📋 Cataloged | Priority: Medium
## 📝 Original Request
Map incoming requests to specialized combos based on 7 task classes (bulk_low_risk, code_generation, security_critical, etc.) with automatic escalation to premium models for complex tasks and de-escalation to economy for simple ones.
## 🎯 Refined Feature Description
OmniRoute already has `taskAwareRouter.ts` and `intentClassifier.ts` that provide basic task-aware routing. This request expands that with a formal escalation/de-escalation engine based on task classification.
### What it solves
- Same combo used for trivial and critical tasks
- No automatic quality scaling based on difficulty
### How it should work
1. Classify incoming request into a task class (using existing `intentClassifier`)
2. Map task class → combo selection rules (which combo, which strategy)
3. Apply escalation rules (complex request → premium model)
4. Apply de-escalation (trivial → cheap model)
### Affected areas
- `open-sse/services/taskAwareRouter.ts` — extend classification
- `open-sse/services/intentClassifier.ts` — more task classes
- `open-sse/services/combo.ts` — task-class routing integration
- Settings UI — task-class configuration
## 🔗 Related Ideas
- Related to [980-lkgp-routing](./980-lkgp-routing.md) — LKGP scoring
- Related to [1041-smart-auto-combos](./1041-smart-auto-combos.md) — dynamic combos
- Part of @igormorais123's series

View File

@@ -0,0 +1,20 @@
# Feature: AutoResearch — Recursive Self-Improvement Loop (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/787-auto-research.md) · 🇪🇸 [es](../../../es/_ideia/defer/787-auto-research.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/787-auto-research.md) · 🇩🇪 [de](../../../de/_ideia/defer/787-auto-research.md) · 🇮🇹 [it](../../../it/_ideia/defer/787-auto-research.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/787-auto-research.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/787-auto-research.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/787-auto-research.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/787-auto-research.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/787-auto-research.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/787-auto-research.md) · 🇮🇳 [in](../../../in/_ideia/defer/787-auto-research.md) · 🇹🇭 [th](../../../th/_ideia/defer/787-auto-research.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/787-auto-research.md) · 🇮🇩 [id](../../../id/_ideia/defer/787-auto-research.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/787-auto-research.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/787-auto-research.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/787-auto-research.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/787-auto-research.md) · 🇳🇴 [no](../../../no/_ideia/defer/787-auto-research.md) · 🇩🇰 [da](../../../da/_ideia/defer/787-auto-research.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/787-auto-research.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/787-auto-research.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/787-auto-research.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/787-auto-research.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/787-auto-research.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/787-auto-research.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/787-auto-research.md) · 🇮🇱 [he](../../../he/_ideia/defer/787-auto-research.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/787-auto-research.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/787-auto-research.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/787-auto-research.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/787-auto-research.md)
---
> GitHub Issue: #787 — opened by @igormorais123 on 2026-03-30
> Status: 📋 Cataloged | Priority: Low
## 📝 Original Request
Implement an autonomous optimization loop where an AI agent iterates hundreds of routing configurations against evaluation datasets, inspired by Karpathy's AutoResearch paradigm.
## 🎯 Refined Feature Description
An ambitious research-grade feature that would require significant infrastructure (evaluation datasets, automated benchmarking, config mutation engine). Beyond current scope but catalogs a valid long-term vision.
## 🔗 Related Ideas
- Part of @igormorais123's series: [792](./792-team-of-rivals.md), [797](./797-hierarchical-router.md), [801](./801-cross-provider-diversity.md), [785](./785-task-class-routing.md)

View File

@@ -0,0 +1,20 @@
# Feature: Multi-Provider Code Review Pipeline (Team of Rivals) (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/792-team-of-rivals.md) · 🇪🇸 [es](../../../es/_ideia/defer/792-team-of-rivals.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/792-team-of-rivals.md) · 🇩🇪 [de](../../../de/_ideia/defer/792-team-of-rivals.md) · 🇮🇹 [it](../../../it/_ideia/defer/792-team-of-rivals.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/792-team-of-rivals.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/792-team-of-rivals.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/792-team-of-rivals.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/792-team-of-rivals.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/792-team-of-rivals.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/792-team-of-rivals.md) · 🇮🇳 [in](../../../in/_ideia/defer/792-team-of-rivals.md) · 🇹🇭 [th](../../../th/_ideia/defer/792-team-of-rivals.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/792-team-of-rivals.md) · 🇮🇩 [id](../../../id/_ideia/defer/792-team-of-rivals.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/792-team-of-rivals.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/792-team-of-rivals.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/792-team-of-rivals.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/792-team-of-rivals.md) · 🇳🇴 [no](../../../no/_ideia/defer/792-team-of-rivals.md) · 🇩🇰 [da](../../../da/_ideia/defer/792-team-of-rivals.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/792-team-of-rivals.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/792-team-of-rivals.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/792-team-of-rivals.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/792-team-of-rivals.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/792-team-of-rivals.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/792-team-of-rivals.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/792-team-of-rivals.md) · 🇮🇱 [he](../../../he/_ideia/defer/792-team-of-rivals.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/792-team-of-rivals.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/792-team-of-rivals.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/792-team-of-rivals.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/792-team-of-rivals.md)
---
> GitHub Issue: #792 — opened by @igormorais123 on 2026-03-30
> Status: 📋 Cataloged | Priority: Low
## 📝 Original Request
Send critical tasks to 2-3 providers in parallel (Planner, Critic, Executor, Quality Reviewer), each from different providers for cognitive diversity.
## 🎯 Refined Feature Description
Advanced multi-agent orchestration pattern outside OmniRoute's core scope as a proxy/router. Better suited for an orchestration framework built on top of OmniRoute.
## 🔗 Related Ideas
- Part of @igormorais123's series: [797](./797-hierarchical-router.md), [801](./801-cross-provider-diversity.md), [785](./785-task-class-routing.md), [787](./787-auto-research.md)

View File

@@ -0,0 +1,20 @@
# Feature: Hierarchical Router — Direct vs Multi-Agent orchestration (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/797-hierarchical-router.md) · 🇪🇸 [es](../../../es/_ideia/defer/797-hierarchical-router.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/797-hierarchical-router.md) · 🇩🇪 [de](../../../de/_ideia/defer/797-hierarchical-router.md) · 🇮🇹 [it](../../../it/_ideia/defer/797-hierarchical-router.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/797-hierarchical-router.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/797-hierarchical-router.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/797-hierarchical-router.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/797-hierarchical-router.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/797-hierarchical-router.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/797-hierarchical-router.md) · 🇮🇳 [in](../../../in/_ideia/defer/797-hierarchical-router.md) · 🇹🇭 [th](../../../th/_ideia/defer/797-hierarchical-router.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/797-hierarchical-router.md) · 🇮🇩 [id](../../../id/_ideia/defer/797-hierarchical-router.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/797-hierarchical-router.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/797-hierarchical-router.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/797-hierarchical-router.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/797-hierarchical-router.md) · 🇳🇴 [no](../../../no/_ideia/defer/797-hierarchical-router.md) · 🇩🇰 [da](../../../da/_ideia/defer/797-hierarchical-router.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/797-hierarchical-router.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/797-hierarchical-router.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/797-hierarchical-router.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/797-hierarchical-router.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/797-hierarchical-router.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/797-hierarchical-router.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/797-hierarchical-router.md) · 🇮🇱 [he](../../../he/_ideia/defer/797-hierarchical-router.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/797-hierarchical-router.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/797-hierarchical-router.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/797-hierarchical-router.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/797-hierarchical-router.md)
---
> GitHub Issue: #797 — opened by @igormorais123 on 2026-03-30
> Status: 📋 Cataloged | Priority: Low
## 📝 Original Request
Two-tier routing layer classifying requests into fast direct path (single model) or multi-agent orchestration (planner → critic → executor).
## 🎯 Refined Feature Description
This is an advanced orchestration concept that goes well beyond OmniRoute's scope as a proxy/router. OmniRoute already has `taskAwareRouter.ts` and `intentClassifier.ts` which provide basic task-aware routing, but full multi-agent orchestration is an application-layer concern.
## 🔗 Related Ideas
- Part of @igormorais123's series: [792](./792-team-of-rivals.md), [801](./801-cross-provider-diversity.md), [785](./785-task-class-routing.md), [787](./787-auto-research.md)

View File

@@ -0,0 +1,27 @@
# Feature: Cross-Provider Cognitive Diversity (Role-to-Provider Mapping) (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/801-cross-provider-diversity.md) · 🇪🇸 [es](../../../es/_ideia/defer/801-cross-provider-diversity.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/801-cross-provider-diversity.md) · 🇩🇪 [de](../../../de/_ideia/defer/801-cross-provider-diversity.md) · 🇮🇹 [it](../../../it/_ideia/defer/801-cross-provider-diversity.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/801-cross-provider-diversity.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/801-cross-provider-diversity.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/801-cross-provider-diversity.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/801-cross-provider-diversity.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/801-cross-provider-diversity.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/801-cross-provider-diversity.md) · 🇮🇳 [in](../../../in/_ideia/defer/801-cross-provider-diversity.md) · 🇹🇭 [th](../../../th/_ideia/defer/801-cross-provider-diversity.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/801-cross-provider-diversity.md) · 🇮🇩 [id](../../../id/_ideia/defer/801-cross-provider-diversity.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/801-cross-provider-diversity.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/801-cross-provider-diversity.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/801-cross-provider-diversity.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/801-cross-provider-diversity.md) · 🇳🇴 [no](../../../no/_ideia/defer/801-cross-provider-diversity.md) · 🇩🇰 [da](../../../da/_ideia/defer/801-cross-provider-diversity.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/801-cross-provider-diversity.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/801-cross-provider-diversity.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/801-cross-provider-diversity.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/801-cross-provider-diversity.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/801-cross-provider-diversity.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/801-cross-provider-diversity.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/801-cross-provider-diversity.md) · 🇮🇱 [he](../../../he/_ideia/defer/801-cross-provider-diversity.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/801-cross-provider-diversity.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/801-cross-provider-diversity.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/801-cross-provider-diversity.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/801-cross-provider-diversity.md)
---
> GitHub Issue: #801 — opened by @igormorais123 on 2026-03-30
> Status: 📋 Cataloged | Priority: Low
## 📝 Original Request
Enforce that different roles in multi-model review pipelines use different providers to maximize failure diversity. A planner and its critic should never be the same provider.
## 🎯 Refined Feature Description
This is an advanced orchestration pattern. OmniRoute already supports multi-provider combos but doesn't enforce cognitive diversity between roles. This would require significant architectural changes to add role-based routing.
### Affected areas
- Would require a new orchestration layer above combo routing
- Significant scope for a routing proxy
## 🔗 Related Ideas
- Related to [792-team-of-rivals](./792-team-of-rivals.md)
- Related to [797-hierarchical-router](./797-hierarchical-router.md)
- Part of @igormorais123's 5-issue series (#785, #787, #792, #797, #801)

View File

@@ -0,0 +1,47 @@
# Feature: LKGP (Last Known Good Providers) Routing (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/defer/980-lkgp-routing.md) · 🇪🇸 [es](../../../es/_ideia/defer/980-lkgp-routing.md) · 🇫🇷 [fr](../../../fr/_ideia/defer/980-lkgp-routing.md) · 🇩🇪 [de](../../../de/_ideia/defer/980-lkgp-routing.md) · 🇮🇹 [it](../../../it/_ideia/defer/980-lkgp-routing.md) · 🇷🇺 [ru](../../../ru/_ideia/defer/980-lkgp-routing.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/defer/980-lkgp-routing.md) · 🇯🇵 [ja](../../../ja/_ideia/defer/980-lkgp-routing.md) · 🇰🇷 [ko](../../../ko/_ideia/defer/980-lkgp-routing.md) · 🇸🇦 [ar](../../../ar/_ideia/defer/980-lkgp-routing.md) · 🇮🇳 [hi](../../../hi/_ideia/defer/980-lkgp-routing.md) · 🇮🇳 [in](../../../in/_ideia/defer/980-lkgp-routing.md) · 🇹🇭 [th](../../../th/_ideia/defer/980-lkgp-routing.md) · 🇻🇳 [vi](../../../vi/_ideia/defer/980-lkgp-routing.md) · 🇮🇩 [id](../../../id/_ideia/defer/980-lkgp-routing.md) · 🇲🇾 [ms](../../../ms/_ideia/defer/980-lkgp-routing.md) · 🇳🇱 [nl](../../../nl/_ideia/defer/980-lkgp-routing.md) · 🇵🇱 [pl](../../../pl/_ideia/defer/980-lkgp-routing.md) · 🇸🇪 [sv](../../../sv/_ideia/defer/980-lkgp-routing.md) · 🇳🇴 [no](../../../no/_ideia/defer/980-lkgp-routing.md) · 🇩🇰 [da](../../../da/_ideia/defer/980-lkgp-routing.md) · 🇫🇮 [fi](../../../fi/_ideia/defer/980-lkgp-routing.md) · 🇵🇹 [pt](../../../pt/_ideia/defer/980-lkgp-routing.md) · 🇷🇴 [ro](../../../ro/_ideia/defer/980-lkgp-routing.md) · 🇭🇺 [hu](../../../hu/_ideia/defer/980-lkgp-routing.md) · 🇧🇬 [bg](../../../bg/_ideia/defer/980-lkgp-routing.md) · 🇸🇰 [sk](../../../sk/_ideia/defer/980-lkgp-routing.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/defer/980-lkgp-routing.md) · 🇮🇱 [he](../../../he/_ideia/defer/980-lkgp-routing.md) · 🇵🇭 [phi](../../../phi/_ideia/defer/980-lkgp-routing.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/defer/980-lkgp-routing.md) · 🇨🇿 [cs](../../../cs/_ideia/defer/980-lkgp-routing.md) · 🇹🇷 [tr](../../../tr/_ideia/defer/980-lkgp-routing.md)
---
> GitHub Issue: #980 — opened by @diegosouzapw on 2026-04-04
> Status: 📋 Cataloged | Priority: Medium
> Source: Discussion 919 by @oyi77
## 📝 Original Request
Implement a dynamic weighting algorithm in the combo routing engine that uses latency and recent success rate (LKGP) alongside healthchecks.
## 💬 Community Discussion
### Participants
- @diegosouzapw — Issue creator
- @oyi77 — Original discussion author
## 🎯 Refined Feature Description
LKGP routing tracks which provider connections have been performing well recently (low latency, high success rate) and dynamically adjusts routing weights to prefer them. Unlike static priority, this adapts in real-time.
### What it solves
- Static priority can't adapt to transient provider degradation
- Healthchecks are periodic — LKGP uses real request metrics
### How it should work
1. Track last N request outcomes per connection (success/fail, latency)
2. Compute a LKGP score = f(success_rate, avg_latency, recency)
3. Use LKGP scores as dynamic weights in combo routing
4. Decay old metrics over time
### Affected areas
- `open-sse/services/combo.ts` — routing weight calculation
- `src/lib/db/domainState.ts` — LKGP metric storage
- Dashboard — LKGP score visualization
## 🔗 Related Ideas
- Related to [1041-smart-auto-combos](./1041-smart-auto-combos.md)
- Related to [785-task-class-routing](./785-task-class-routing.md)

View File

@@ -0,0 +1,43 @@
# Feature: Providers-independent approach (Universal Model IDs) (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1023-providers-independent.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1023-providers-independent.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1023-providers-independent.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1023-providers-independent.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1023-providers-independent.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1023-providers-independent.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1023-providers-independent.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1023-providers-independent.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1023-providers-independent.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1023-providers-independent.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1023-providers-independent.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1023-providers-independent.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1023-providers-independent.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1023-providers-independent.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1023-providers-independent.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1023-providers-independent.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1023-providers-independent.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1023-providers-independent.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1023-providers-independent.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1023-providers-independent.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1023-providers-independent.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1023-providers-independent.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1023-providers-independent.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1023-providers-independent.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1023-providers-independent.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1023-providers-independent.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1023-providers-independent.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1023-providers-independent.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1023-providers-independent.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1023-providers-independent.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1023-providers-independent.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1023-providers-independent.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1023-providers-independent.md)
---
> GitHub Issue: #1023 — opened by @ralphilius on 2026-04-06
> Status: 📋 Cataloged | Priority: Medium
## 📝 Original Request
When connecting to multiple providers that serve the same models, users need to switch prefixes in coding tool configs. Proposes universal constant model IDs that work regardless of provider, making OmniRoute appear as a single provider.
## 💬 Community Discussion
### Participants
- @ralphilius — Original requester
### Key Points
- Pain point: switching provider prefixes in client configs when rotating providers
- Wants "set and forget" configuration
## 🎯 Refined Feature Description
This is essentially the model alias system that already exists. Users can create aliases like `claude-sonnet``anthropic/claude-sonnet-4` so their clients always use the same model name regardless of which provider serves it.
### What it solves
- Already solved by existing Model Aliases feature (`/dashboard/settings` → Model Aliases)
### Affected areas
- May need better documentation/discoverability of existing aliases feature
## 📎 Attachments & References
- Existing feature: Model Aliases in dashboard settings
## 🔗 Related Ideas
- This overlaps with existing Model Aliases functionality — may just need documentation/UI improvements

View File

@@ -0,0 +1,80 @@
# Feature: Native Playground LLM Dashboard - Built-in testing page (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1046-native-playground.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1046-native-playground.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1046-native-playground.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1046-native-playground.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1046-native-playground.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1046-native-playground.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1046-native-playground.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1046-native-playground.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1046-native-playground.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1046-native-playground.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1046-native-playground.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1046-native-playground.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1046-native-playground.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1046-native-playground.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1046-native-playground.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1046-native-playground.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1046-native-playground.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1046-native-playground.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1046-native-playground.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1046-native-playground.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1046-native-playground.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1046-native-playground.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1046-native-playground.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1046-native-playground.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1046-native-playground.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1046-native-playground.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1046-native-playground.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1046-native-playground.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1046-native-playground.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1046-native-playground.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1046-native-playground.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1046-native-playground.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1046-native-playground.md)
---
> GitHub Issue: #1046 — opened by @diegosouzapw on 2026-04-07
> Status: 📋 Cataloged | Priority: High
> Duplicate of: #234 (92% similarity per Kilo)
## 📝 Original Request
**Source:** Discussion #1035 by @rilham97
Add a built-in playground or test page in the OmniRoute dashboard where users can easily test their configured LLMs, verify model names, and check the response body formatting directly.
### Implementation Ideas
- A lightweight React component in the `/dashboard` route.
- A simple chat or raw completion interface to send test requests to the OmniRoute proxy endpoint.
### Current Workarounds
Users can use lightweight local clients like OpenClaw, or standard terminal/browser curl requests to test the API.
## 💬 Community Discussion
### Participants
- @diegosouzapw — Issue creator (from discussion)
- @rilham97 — Original requester, provided design references
- @kilo-code-bot — Auto-triage (duplicate of #234, 92%)
### Key Points
- This is a highly requested feature with a prior duplicate (#234)
- @rilham97 provided concrete UI references:
- https://app.fireworks.ai/playground
- https://ai.nahcrof.com/
## 🎯 Refined Feature Description
A built-in playground page at `/dashboard/playground` that allows users to:
1. Select any configured combo or provider+model
2. Send chat completion requests with customizable parameters (temperature, max_tokens, system prompt)
3. View full response including metadata (tokens used, latency, cost)
4. Toggle between streaming and non-streaming modes
5. View raw request/response JSON for debugging
### What it solves
- Eliminates need for external tools to test model configuration
- Provides instant feedback on whether a combo/provider is working
- Helps debug response format issues without leaving the dashboard
### How it should work (high level)
1. User navigates to `/dashboard/playground`
2. Selects a combo or specific provider/model from dropdown
3. Types a message in a chat interface
4. Clicks Send → sees streaming response
5. Can inspect raw JSON, token usage, and latency metrics
### Affected areas
- `src/app/(dashboard)/dashboard/playground/` — new page
- `src/app/api/` — may use existing `/v1/chat/completions` internally
- i18n — new translation keys across 30 languages
- Sidebar navigation — add new menu item
## 📎 Attachments & References
- Fireworks AI Playground: https://app.fireworks.ai/playground
- AI Nahcrof playground: https://ai.nahcrof.com/
- Original discussion: #1035
## 🔗 Related Ideas
- Related to #234 (original playground request, 92% similarity)

View File

@@ -0,0 +1,61 @@
# Feature: [Feature] Headroom support (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1100-headroom-support.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1100-headroom-support.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1100-headroom-support.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1100-headroom-support.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1100-headroom-support.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1100-headroom-support.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1100-headroom-support.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1100-headroom-support.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1100-headroom-support.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1100-headroom-support.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1100-headroom-support.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1100-headroom-support.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1100-headroom-support.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1100-headroom-support.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1100-headroom-support.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1100-headroom-support.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1100-headroom-support.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1100-headroom-support.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1100-headroom-support.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1100-headroom-support.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1100-headroom-support.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1100-headroom-support.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1100-headroom-support.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1100-headroom-support.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1100-headroom-support.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1100-headroom-support.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1100-headroom-support.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1100-headroom-support.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1100-headroom-support.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1100-headroom-support.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1100-headroom-support.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1100-headroom-support.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1100-headroom-support.md)
---
> GitHub Issue: #1100 — opened by @mkizilov on 2026-04-10T00:15:46Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem / Use Case
Right now there is problematic to running Headroom because it needs to be routed via omniroute. Maybe implement some easier way to do it?
https://github.com/chopratejas/headroom
### Proposed Solution
https://github.com/chopratejas/headroom
### Acceptance Criteria
some turn on\off switch to use headroom right in the UI
### Area
Proxy / Routing
## 💬 Community Discussion
(No comments yet)
## 🎯 Refined Feature Description
Headroom is an open-source UI for interacting with LLMs. The user wants to integrate/run Headroom directly through OmniRoute's UI with a simple switch, rather than having to separately deploy and configure Headroom to route traffic through OmniRoute.
### What it solves
- Removes the deployment friction for using a chat UI (Headroom) with our local API endpoints.
- Unifies the experience within our dashboard.
### How it should work (high level)
1. Add an internal proxy or embedding layer for Headroom's static UI.
2. In the OmniRoute dashboard, provide a switch or dedicated "Chat UI" route to launch headroom.
3. Auto-configure the Headroom UI to use `http://localhost:20128/v1` and the user's OmniRoute APIs automatically.
### Affected areas
- `src/app/(dashboard)/`
- `open-sse/services/`
- Next.js rewrite/proxy configs or Docker compose templates.
## 📎 Attachments & References
- https://github.com/chopratejas/headroom
## 🔗 Related Ideas
- 1046-native-playground (already implemented a native playground, which might solve their primary need)

View File

@@ -0,0 +1,65 @@
# Feature: [Feature] whitelist models for specific API KEY (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1110-whitelist-models-api-key.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1110-whitelist-models-api-key.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1110-whitelist-models-api-key.md)
---
> GitHub Issue: #1110 — opened by @0xtbug on 2026-04-10T09:26:02Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem / Use Case
For better API KEY management, the system needs to support a customized model list (whitelist) for specific API KEYs. This is crucial for access control, cost limitation, and offering tiered services.
For example:
- api_key_1 (Admin/Pro): can access all models (\*).
- api_key_2 (Basic): can only access specific, perhaps cheaper, models like gpt-3.5-turbo, claude-3-haiku.
- api_key_3 (Vendor): can access all models from a specific provider alongside specific extra models (e.g., anthropic/\*, model_extra_1).
### Proposed Solution
1. Data Schema Update: Add a new optional property (e.g., allowed_models as an array of strings) to the API Key database/schema. Support wildcards or provider namespaces (e.g., _, openai/_, gpt-4).
2. Middleware / Validation Logic: Modify the authentication middleware. After validating the API Key, intercept the request payload to check if the requested model is within the key's allowed list.
3. Interception: If the requested model is not in the API Key's whitelist, reject the request with a 403 Forbidden status and a clear error message (e.g., "Model not allowed for this API key").
4. Admin Dashboard (If UI exists): Add a multi-select dropdown in the API Key creation interface so admins can easily configure permitted models for the new key.
### Alternatives Considered
- Using a Separate Reverse Proxy (API Gateway). Drawback: Adds infrastructure complexity.
- Deploying Different Instances. Drawback: Highly resource-intensive.
### Acceptance Criteria
- API keys with \* access (or no restrictions) can successfully call all available models (200 OK).
- API keys attempting to call unsupported models are rejected with 403 Forbidden.
- Support wildcard parsing logic (`openai/*`).
- No significant performance latency.
## 💬 Community Discussion
- @kilo-code-bot — Triaged this issue as a duplicate of #781 (Similarity score: 90%). Tagged `kilo-duplicate`.
## 🎯 Refined Feature Description
Allow administrators to restrict which specific models/combos an OmniRoute API Key can invoke. Currently, an OmniRoute key grants access to all configured combos. This feature would restrict that access at the routing layer (`chatCore.ts` or auth middleware).
### What it solves
Allows the creation of "cheap" keys for casual tools and "expensive" keys for priority workflows.
### Affected areas
- `src/lib/db/apiKeys.ts`
- `open-sse/handlers/chatCore.ts` (or the Auth plugin)
- Dashboard `ApiKeysView.tsx`
## 📎 Attachments & References
N/A
## 🔗 Related Ideas
> This feature is a duplicate of #781. Consider marking it as ALREADY EXISTS or NOT FIT depending on #781 status.

View File

@@ -0,0 +1,42 @@
# Feature: Automated installation for Hermes (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1129-automated-hermes.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1129-automated-hermes.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1129-automated-hermes.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1129-automated-hermes.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1129-automated-hermes.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1129-automated-hermes.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1129-automated-hermes.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1129-automated-hermes.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1129-automated-hermes.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1129-automated-hermes.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1129-automated-hermes.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1129-automated-hermes.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1129-automated-hermes.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1129-automated-hermes.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1129-automated-hermes.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1129-automated-hermes.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1129-automated-hermes.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1129-automated-hermes.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1129-automated-hermes.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1129-automated-hermes.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1129-automated-hermes.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1129-automated-hermes.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1129-automated-hermes.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1129-automated-hermes.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1129-automated-hermes.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1129-automated-hermes.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1129-automated-hermes.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1129-automated-hermes.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1129-automated-hermes.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1129-automated-hermes.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1129-automated-hermes.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1129-automated-hermes.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1129-automated-hermes.md)
---
> GitHub Issue: #1129 — opened by @Snodgrass-Wilkerschnoz on 2026-04-10
> Status: ❌ NOT FIT | Priority: TBD
## 📝 Original Request
### Problem / Use Case
Id like to simply configure Hermes to work with OmniRoute with an Hermes-led step-through configuration to simplify onboarding and avoid manual config.
### Proposed Solution
Step-though initial config for Hermes.
### Acceptance Criteria
-Direct Hermes to install OmniRoute
-After installation, Hermes walks through config
-Configuration is written to OmniRoute and can be controlled successfully by Hermes
## 💬 Community Discussion
### Participants
- @Snodgrass-Wilkerschnoz — Original requester
## 🎯 Refined Feature Description
Create an automated deployment script inside the Hermes Agent configuration wizard to download, install, and interface with OmniRoute.
### Why it does not fit
Hermes Agent is a completely separate application that utilizes APIs. Any installer logic dictating "Hermes walks through config" would technically reside exclusively inside the Hermes Agent repository's source code, not inside the OmniRoute proxy itself. Expanding the OmniRoute proxy engine to package installation routines for external autonomous agents violates OmniRoute's architectural boundaries as a headless unified proxy wrapper.
## 🔗 Related Ideas
- N/A

View File

@@ -0,0 +1,40 @@
# Feature: [Feature] venice.ai inference provider (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1132-venice-ai-provider.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1132-venice-ai-provider.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1132-venice-ai-provider.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1132-venice-ai-provider.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1132-venice-ai-provider.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1132-venice-ai-provider.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1132-venice-ai-provider.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1132-venice-ai-provider.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1132-venice-ai-provider.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1132-venice-ai-provider.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1132-venice-ai-provider.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1132-venice-ai-provider.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1132-venice-ai-provider.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1132-venice-ai-provider.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1132-venice-ai-provider.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1132-venice-ai-provider.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1132-venice-ai-provider.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1132-venice-ai-provider.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1132-venice-ai-provider.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1132-venice-ai-provider.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1132-venice-ai-provider.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1132-venice-ai-provider.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1132-venice-ai-provider.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1132-venice-ai-provider.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1132-venice-ai-provider.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1132-venice-ai-provider.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1132-venice-ai-provider.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1132-venice-ai-provider.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1132-venice-ai-provider.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1132-venice-ai-provider.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1132-venice-ai-provider.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1132-venice-ai-provider.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1132-venice-ai-provider.md)
---
> GitHub Issue: #1132 — opened by @neurocis on 2026-04-11
> Status: 🔁 EXISTS | Priority: None
## 📝 Original Request
### Problem / Use Case
Please add an OpenAI compatible Inference provider as 1st class citizen (venice.ai)
### Proposed Solution
Please add venice.ai as a 1st class AI Inference provider.
### Acceptance Criteria
API endpoint: https://api.venice.ai/api/v1
## 💬 Community Discussion
### Participants
- @neurocis — Original requester
## 🎯 Refined Feature Description
Add native proxy support and UI configuration mapping for the Venice AI inference network.
### Why it already exists
This specific provider endpoint implementation `https://api.venice.ai/api/v1` and configuration was completely fulfilled in an earlier version cycle during our ecosystem adoption of 60+ upstream target definitions. Venice AI is already registered and can be configured normally through the Provider Dashboard.
## 🔗 Related Ideas
- N/A

View File

@@ -0,0 +1,39 @@
# Feature: Filter for Custom Model (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1191-filter-custom-model.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1191-filter-custom-model.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1191-filter-custom-model.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1191-filter-custom-model.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1191-filter-custom-model.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1191-filter-custom-model.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1191-filter-custom-model.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1191-filter-custom-model.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1191-filter-custom-model.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1191-filter-custom-model.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1191-filter-custom-model.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1191-filter-custom-model.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1191-filter-custom-model.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1191-filter-custom-model.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1191-filter-custom-model.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1191-filter-custom-model.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1191-filter-custom-model.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1191-filter-custom-model.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1191-filter-custom-model.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1191-filter-custom-model.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1191-filter-custom-model.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1191-filter-custom-model.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1191-filter-custom-model.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1191-filter-custom-model.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1191-filter-custom-model.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1191-filter-custom-model.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1191-filter-custom-model.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1191-filter-custom-model.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1191-filter-custom-model.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1191-filter-custom-model.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1191-filter-custom-model.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1191-filter-custom-model.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1191-filter-custom-model.md)
---
> GitHub Issue: #1191 — opened by @tjengbudi on 2026-04-13
> Status: 🔁 ALREADY EXISTS
## 📝 Original Request
The user requests a filter/search functionality for custom models in the provider detail page, to help find specific models in large catalogs.
## 💬 Community Discussion
### Participants
- @tjengbudi — Original requester
- 2 comments in discussion thread
### Key Points
- User may not have discovered the existing filter functionality
- The model filter bar may not be sufficiently visible on the page
## 🎯 Resolution
This functionality **already exists** in OmniRoute:
**Location:** Provider Detail Page (`/dashboard/providers/<id>`) → Models section
**How it works:**
1. Navigate to Dashboard → Providers → click on any provider
2. Scroll down to the Models section
3. The search/filter input at the top of the model list filters by name, ID, and aliases
4. Implementation: `modelFilter` state (line 989 in `page.tsx`) with `matchesModelCatalogQuery()` function
The filter supports searching by model name, model ID, and configured aliases. It works for both built-in and custom models.

View File

@@ -0,0 +1,75 @@
# Feature: [Feature] gpt-image-1 and gpt-iamge-1.5 support (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1195-feature-gpt-image-1-and-gpt-iamge-1-5-support.md)
---
> GitHub Issue: #1195 — opened by @cryptiklemur on 2026-04-13T04:51:30Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem / Use Case
Image generation should support gpt-image-x models
### Proposed Solution
Image generation should support gpt-image-x models
### Alternatives Considered
_No response_
### Acceptance Criteria
Can select gpt-image-1 or 1.5
### Area
Provider Support
### Related Provider(s)
OpenAI
### Additional Context
_No response_
### Expected Test Plan
_No response_
## 💬 Community Discussion
- @kilo-code-bot: This issue appears to be a duplicate of https://github.com/diegosouzapw/OmniRoute/issues/973.
> **Support for Image Generation with Custom OpenAI-Compatible Providers** (#973)
Similarity score: 91%
...
## 🎯 Refined Feature Description
(Requires manual/AI refinement)
### What it solves
- TBD
### How it should work (high level)
1. TBD
### Affected areas
- TBD
## 📎 Attachments & References
- TBD
## 🔗 Related Ideas
- TBD

View File

@@ -0,0 +1,93 @@
# Feature: [Feature] Add configurable stagger delay between token health check sweep iterations (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1220-feature-add-configurable-stagger-delay-between-token-health-check-sweep-iterations.md)
---
> GitHub Issue: #1220 — opened by @edwardsconnects90 on 2026-04-13T16:43:19Z
> Status: 📋 Cataloged | Priority: TBD
## 📝 Original Request
### Problem / Use Case
The proactive token health check sweep iterates all OAuth connections sequentially but with **no delay** between iterations. When running with multiple SOCKS5 proxies (one per account), all proxy connections are initiated in rapid succession — effectively simultaneously from the proxy perspective. This causes proxy overload, connection timeouts, and failed token refreshes across all accounts in the same sweep cycle.
With multiple dedicated SOCKS5 proxies, the sweep fires all connections within milliseconds. Logs show all "Refreshing ..." entries appearing in a burst (<100ms total for all accounts).
### Proposed Solution
Add a configurable stagger delay after each iteration of the sweep loop in `tokenHealthCheck.ts`, controlled by a `HEALTHCHECK_STAGGER_MS` environment variable (default: `3000` ms). When set to `0`, staggering is disabled.
The implementation is a single `await new Promise(resolve => setTimeout(resolve, STAGGER_MS))` at the end of each loop iteration inside the sweep function.
| Variable | Default | Description |
| ------------------------ | ------- | ----------------------------------------------------------------------------------------------- |
| `HEALTHCHECK_STAGGER_MS` | `3000` | Delay in milliseconds between consecutive token health check iterations. Set to `0` to disable. |
With the stagger in place, inter-iteration gaps become ~3-7s (configured stagger + proxy round-trip time), confirming that connections no longer pile up simultaneously.
### Alternatives Considered
- **Client-side rate limiting per proxy:** More complex, requires tracking per-proxy concurrency. The stagger approach is simpler and sufficient for the sequential sweep loop.
- **Parallel sweep with concurrency limit:** Would require rewriting the sweep loop to use a worker pool. Overkill for the current use case where sequential + stagger is adequate.
### Acceptance Criteria
- Health check sweep has a configurable delay between iterations via `HEALTHCHECK_STAGGER_MS` env variable
- Default delay is 3000ms
- Setting to 0 disables the stagger
- Consecutive "Refreshing ..." log entries are spaced by at least `HEALTHCHECK_STAGGER_MS` milliseconds
- All existing health check functionality remains unchanged
### Area
Proxy / Routing
### Related Provider(s)
Codex (OpenAI) — affects all OAuth providers when multiple connections use dedicated SOCKS5 proxies
### Additional Context
- **Impact without fix:** All proxy connections open simultaneously → proxy overload → universal token refresh failure each sweep cycle
- **Impact with fix:** Connections spread over `N x STAGGER_MS` total sweep duration → each proxy gets exclusive window → reliable token refreshes
- Total sweep duration increases proportionally (e.g. 10 connections x 3s = ~30s minimum), which is acceptable given sweeps run on intervals of minutes to hours
- **Optional UI enhancement:** Settings panel could expose `HEALTHCHECK_STAGGER_MS` as a numeric input under Provider Health Check settings
- Current workaround: build-time patch (`patch-stagger-healthcheck.cjs`) injects `setTimeout` delay into compiled webpack chunks
### Expected Test Plan
- Add unit test for sweep loop verifying inter-iteration delay when `HEALTHCHECK_STAGGER_MS > 0`
- Add unit test verifying no delay when `HEALTHCHECK_STAGGER_MS=0`
- Integration test: run sweep with multiple connections, verify log timestamps show expected stagger spacing
## 💬 Community Discussion
- @diegosouzapw: Thanks for the well-thought-out proposal, @edwardsconnects90. The stagger logic is sound.
We're accepting this as an enhancement. The implementation is straightforward — a configurable `HEALTHCHECK_S...
## 🎯 Refined Feature Description
(Requires manual/AI refinement)
### What it solves
- TBD
### How it should work (high level)
1. TBD
### Affected areas
- TBD
## 📎 Attachments & References
- TBD
## 🔗 Related Ideas
- TBD

View File

@@ -0,0 +1,35 @@
# Feature: Enforce Passing All Tests / Workflows Before Release (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/1364-enforce-tests-before-release.md) · 🇪🇸 [es](../../../es/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇩🇪 [de](../../../de/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇮🇹 [it](../../../it/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇮🇳 [in](../../../in/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇹🇭 [th](../../../th/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇮🇩 [id](../../../id/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇳🇴 [no](../../../no/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇩🇰 [da](../../../da/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇮🇱 [he](../../../he/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/1364-enforce-tests-before-release.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/1364-enforce-tests-before-release.md)
---
> GitHub Issue: #1364 — opened by @uwuclxdy on 2026-04-17
> Status: 🔁 ALREADY EXISTS
## 📝 Original Request
The user is trying to use the latest version but reports the last two releases (v3.6.6, v3.6.7) were broken. Proposes creating a release workflow or gate that prevents creating a new release until all tests and workflows pass.
## 💬 Community Discussion
### Participants
- @uwuclxdy — Original requester
- @chalitbkb — Linked to #1355 (same CLI issue)
### Key Points
- The specific breakage was the CLI entry point shipping as raw TypeScript (`.ts` instead of compiled `.mjs`)
- The test suite itself was passing — the issue was a missing build step in the publishing pipeline
- Community identified this as related to #1355
## 🎯 Resolution
This functionality **already exists** in OmniRoute:
1. **`/generate-release` workflow** — runs full test suite (`npm run test:all`) before creating any release
2. **Pre-push git hooks** — block pushes if tests fail
3. **lint-staged** — runs prettier + eslint on every commit
The v3.6.6/v3.6.7 breakage was specifically caused by a missing CLI build step (not a test failure), which has been fixed in v3.6.8 with `bin/omniroute.mjs`. The release pipeline gap has been closed.

View File

@@ -0,0 +1,24 @@
# Feature: 9router to OmniRoute migration tool (Български)
🌐 **Languages:** 🇺🇸 [English](../../../../../_ideia/notfit/804-9router-migration.md) · 🇪🇸 [es](../../../es/_ideia/notfit/804-9router-migration.md) · 🇫🇷 [fr](../../../fr/_ideia/notfit/804-9router-migration.md) · 🇩🇪 [de](../../../de/_ideia/notfit/804-9router-migration.md) · 🇮🇹 [it](../../../it/_ideia/notfit/804-9router-migration.md) · 🇷🇺 [ru](../../../ru/_ideia/notfit/804-9router-migration.md) · 🇨🇳 [zh-CN](../../../zh-CN/_ideia/notfit/804-9router-migration.md) · 🇯🇵 [ja](../../../ja/_ideia/notfit/804-9router-migration.md) · 🇰🇷 [ko](../../../ko/_ideia/notfit/804-9router-migration.md) · 🇸🇦 [ar](../../../ar/_ideia/notfit/804-9router-migration.md) · 🇮🇳 [hi](../../../hi/_ideia/notfit/804-9router-migration.md) · 🇮🇳 [in](../../../in/_ideia/notfit/804-9router-migration.md) · 🇹🇭 [th](../../../th/_ideia/notfit/804-9router-migration.md) · 🇻🇳 [vi](../../../vi/_ideia/notfit/804-9router-migration.md) · 🇮🇩 [id](../../../id/_ideia/notfit/804-9router-migration.md) · 🇲🇾 [ms](../../../ms/_ideia/notfit/804-9router-migration.md) · 🇳🇱 [nl](../../../nl/_ideia/notfit/804-9router-migration.md) · 🇵🇱 [pl](../../../pl/_ideia/notfit/804-9router-migration.md) · 🇸🇪 [sv](../../../sv/_ideia/notfit/804-9router-migration.md) · 🇳🇴 [no](../../../no/_ideia/notfit/804-9router-migration.md) · 🇩🇰 [da](../../../da/_ideia/notfit/804-9router-migration.md) · 🇫🇮 [fi](../../../fi/_ideia/notfit/804-9router-migration.md) · 🇵🇹 [pt](../../../pt/_ideia/notfit/804-9router-migration.md) · 🇷🇴 [ro](../../../ro/_ideia/notfit/804-9router-migration.md) · 🇭🇺 [hu](../../../hu/_ideia/notfit/804-9router-migration.md) · 🇧🇬 [bg](../../../bg/_ideia/notfit/804-9router-migration.md) · 🇸🇰 [sk](../../../sk/_ideia/notfit/804-9router-migration.md) · 🇺🇦 [uk-UA](../../../uk-UA/_ideia/notfit/804-9router-migration.md) · 🇮🇱 [he](../../../he/_ideia/notfit/804-9router-migration.md) · 🇵🇭 [phi](../../../phi/_ideia/notfit/804-9router-migration.md) · 🇧🇷 [pt-BR](../../../pt-BR/_ideia/notfit/804-9router-migration.md) · 🇨🇿 [cs](../../../cs/_ideia/notfit/804-9router-migration.md) · 🇹🇷 [tr](../../../tr/_ideia/notfit/804-9router-migration.md)
---
> GitHub Issue: #804 — opened by @md-riaz on 2026-03-30
> Status: 📋 Cataloged | Priority: Low
## 📝 Original Request
User trying OmniRoute but can't migrate existing 9router setup. Starting OmniRoute replaces 9router directly.
## 🎯 Refined Feature Description
A migration utility was **already implemented in v3.5.4** — JSON-based settings import/export for legacy 9router configurations, with security-hardened redaction.
### What it solves
- Already solved in v3.5.4
## 🔗 Related Ideas
- None — already implemented

Some files were not shown because too many files have changed in this diff Show More