Compare commits

..

36 Commits

Author SHA1 Message Date
diegosouzapw 6dce45505c chore(release): v1.6.9
Build Electron Desktop App / Validate version (push) Failing after 40s
Build Electron Desktop App / Build Electron (macos-arm64) (push) Has been skipped
Build Electron Desktop App / Build Electron (linux) (push) Has been skipped
Build Electron Desktop App / Build Electron (macos-intel) (push) Has been skipped
Build Electron Desktop App / Build Electron (windows) (push) Has been skipped
Build Electron Desktop App / Create Release (push) Has been skipped
- PR #160: CopilotToolCard URL fix + chat model filter (alpgul)
- PR #161: Proxy port preservation, credential encoding, cache invalidation (ken2190)
- CHANGELOG: v1.6.9 entry
- Version bump: 1.6.8 → 1.6.9
2026-02-28 16:29:25 -03:00
Diego Rodrigues de Sa e Souza 014732788c Merge pull request #161 from ken2190/fix/proxy-logic-and-docker-build
fix: preserve explicit proxy port and fix Docker build
2026-02-28 16:28:28 -03:00
Diego Rodrigues de Sa e Souza 0e75d838ab Merge pull request #160 from alpgul/fix/base-url-and-chat-filter
fix: improve API base URL handling and filter for chat models in CopilotToolCard
2026-02-28 16:28:26 -03:00
Alptekin Gülcan 8383da8a50 fix: improve API base URL handling and filter for chat models in CopilotToolCard 2026-02-28 19:10:17 +00:00
duongvdo 199d173816 fix: preserve explicit proxy port (80/443) instead of defaulting to 8080
The URL parser silently strips default ports (80 for HTTP, 443 for HTTPS)
when constructing URL objects. This caused proxy connections to use port
8080 instead of the user-specified port 80, resulting in connection
timeouts. Fix by extracting the port from the raw URL string before
parsing and building the normalized URL manually to avoid the serializer
stripping it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 01:41:07 +07:00
diegosouzapw f2829441f0 chore(release): v1.6.8
Build Electron Desktop App / Validate version (push) Failing after 36s
Build Electron Desktop App / Build Electron (macos-arm64) (push) Has been skipped
Build Electron Desktop App / Build Electron (linux) (push) Has been skipped
Build Electron Desktop App / Build Electron (macos-intel) (push) Has been skipped
Build Electron Desktop App / Build Electron (windows) (push) Has been skipped
Build Electron Desktop App / Create Release (push) Has been skipped
- Merged PR #159: Electron release workflow refactor (benzntech)
- Added app/ to .gitignore (Next.js App Router conflict fix)
- CHANGELOG: v1.6.8 entry
- Version bump: 1.6.7 → 1.6.8
2026-02-28 15:33:16 -03:00
diegosouzapw 21137bd84a fix: add app/ to .gitignore — prevents Next.js App Router conflict
The production standalone build directory (app/) created by scripts/prepublish.mjs
was conflicting with Next.js App Router detection. Next.js prioritizes root app/
over src/app/, causing all routes to return 404 in dev mode.

The package.json 'files' field still includes app/, so npm publish is unaffected.
2026-02-28 15:32:24 -03:00
Diego Rodrigues de Sa e Souza a05e51a577 Merge pull request #159 from benzntech/fix/electron-release-filter
fix: filter Electron release assets to installers only
2026-02-28 15:30:59 -03:00
benzntech 09a094629c fix: include arm64 dmg in release assets
- Add explicit pattern for *-arm64.dmg files
- Fixes Kilo bot review: *.dmg doesn't match -arm64.dmg
2026-02-28 23:34:37 +05:30
benzntech 90de0fbf68 docs: add installation instructions with macOS Gatekeeper workaround 2026-02-28 23:21:39 +05:30
benzntech c9cdd5109b feat: add Windows portable standalone exe
- NSIS installer: OmniRoute.Setup.X.Y.Z.exe (install to Program Files)
- Portable: OmniRoute.exe (run anywhere, no installation)
2026-02-28 23:19:20 +05:30
duongvdo 0e207dc5d2 fix: proxy logic bugs and Docker build failure
- URL-encode proxy credentials to handle special characters in passwords
- Decode URL-encoded credentials during legacy proxy migration
- Fix HTTPS proxy default port (443 instead of 8080) in frontend and migration
- Add dispatcher cache invalidation when proxy config changes
- Cast proxy port to number for SQLite INTEGER column in proxy logger
- Fix redundant .replace("//", "") in migration protocol parsing
- Copy postinstall script in Dockerfile before npm install

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 00:48:27 +07:00
benzntech 876a5a98f4 feat: add source code archives to releases
- Include .tar.gz and .zip of source code
- Uses git archive for clean export (excludes node_modules, build artifacts)
- Named: OmniRoute-vX.Y.Z.source.tar.gz / .zip
2026-02-28 23:16:43 +05:30
benzntech 8e82350d66 refactor: improve Electron release workflow
- Trigger on git tags (v*) instead of release.published
- Add manual workflow_dispatch for re-runs
- Add version validation step
- Use artifact upload/download pattern
- Single release job ensures all platforms complete first
- Prevents partial releases if one platform fails
2026-02-28 23:14:53 +05:30
benzntech de75ed1551 fix: upload only installer files to releases
- Filter to *.dmg, *.exe, *.AppImage, *.blockmap only
- Prevents uploading unpacked app contents (DLLs, JS files, images)
2026-02-28 21:52:52 +05:30
benzntech 87266104a3 Merge origin/main - sync with v1.6.7 release 2026-02-28 21:52:38 +05:30
benzntech fed8140404 chore: ignore electron build artifacts 2026-02-28 21:44:42 +05:30
diegosouzapw e4d83e91bb chore(release): prepare release v1.6.7
- CHANGELOG: add v1.6.7 entry (Copilot Config Generator #142)
- FEATURES.md: add Copilot to CLI Tools section
- Version bump: 1.6.6 → 1.6.7 (package.json + electron/package.json)
2026-02-28 11:53:39 -03:00
diegosouzapw a3153d893a feat: GitHub Copilot config generator for CLI Tools (#142)
Adds a Copilot configuration generator to the CLI Tools dashboard page.
Users can select models and generate the chatLanguageModels.json config
block for VS Code GitHub Copilot with the Azure vendor pattern.

Features:
- Bulk model selection from /v1/models (includes combos, custom, aliased)
- Search/filter for large model lists
- Configurable maxInputTokens, maxOutputTokens, toolCalling, vision
- One-click copy to clipboard
- Persistent model selection via localStorage
- Version compatibility warning (VS Code >= 1.109, Copilot >= v0.37)

Feedback from @alpgul applied:
- Use /v1/models instead of /api/models/alias (includes combo definitions)
- Use window.location.origin for URL (no port duplication in Docker)

Also: added electron/dist-electron/ to .gitignore (build artifact)
2026-02-28 11:31:55 -03:00
diegosouzapw be219449f9 chore(release): bump version to v1.6.6 2026-02-28 11:17:26 -03:00
diegosouzapw 06d193f0d9 fix: prevent auth bypass after onboarding (#151)
The 'no password' auth bypass check was meant for fresh installs only,
but it also fired after onboarding was complete if the password row
was missing from the database (e.g. after DB migration in v1.6.3).

Fix: Added !settings.setupComplete guard so the bypass only applies
before onboarding is done. Once setupComplete=true, auth is always
required regardless of whether the password key exists in the DB.

Files changed:
- src/proxy.ts (dashboard middleware)
- src/shared/utils/apiAuth.ts (isAuthRequired)
2026-02-28 11:16:23 -03:00
diegosouzapw 4f413615d9 chore(release): prepare release v1.6.5
- Merge PR #154: official Electron icons and release workflow
- Fix electron-release.yml: npm ci → npm install (no package-lock.json)
- CHANGELOG: add v1.6.5 entry
- Version bump: 1.6.4 → 1.6.5
2026-02-28 10:27:58 -03:00
Benson 2a79b833fb feat(electron): add official icons and release workflow (#154)
* feat(electron): add app icons for Windows, macOS, and Linux releases

- icon.ico: Windows application icon (256x256 with multiple resolutions)
- icon.icns: macOS application icon bundle (16px to 1024px)
- icon.png: Linux/general purpose icon (512x512)
- tray-icon.png: System tray icon (32x32)

Icons generated from images/omniroute.png source logo.
Enables branded Electron desktop app builds for all platforms.

* chore: sync package-lock.json

* feat(electron): use official SVG logo and add release workflow

- Regenerated app icons from public/icon-192.svg (official OmniRoute logo)
- Added .github/workflows/electron-release.yml for automated builds
- Icons: icon.icns (macOS), icon.ico (Windows), icon.png (Linux), tray-icon.png
- Build workflow creates DMG (mac), EXE (win), AppImage (linux) on release

* ci: add npm cache to electron-release workflow
2026-02-28 10:26:46 -03:00
Diego Rodrigues de Sa e Souza 52e3d4b37b Merge pull request #153 from diegosouzapw/dependabot/npm_and_yarn/electron/npm_and_yarn-c9b74b4f42
chore(deps-dev): bump electron from 33.4.11 to 40.6.1 in /electron in the npm_and_yarn group across 1 directory
2026-02-28 10:21:25 -03:00
diegosouzapw d9b393a308 docs: restructure all 30 READMEs — reorder sections, remove duplicates
Changes across README.md + 29 translations:
- Remove 🌐 English | Português (BR) language switcher from top
- Move Free AI Provider agents table below badges/links
- Move 📧 Support section right after agents table
- Move 💡 Key Features before 🎯 Use Cases
- Remove 📊 Available Models section
- Move 🔐 OAuth section inside Troubleshooting
- Remove entire 🇧🇷 Portuguese duplicate section at bottom
2026-02-28 09:56:32 -03:00
diegosouzapw 9a3d72c6a2 docs: update electron/README.md, USER_GUIDE.md, FEATURES.md with desktop app docs 2026-02-28 08:33:55 -03:00
dependabot[bot] 5b9b1cdd44 chore(deps-dev): bump electron
Bumps the npm_and_yarn group with 1 update in the /electron directory: [electron](https://github.com/electron/electron).


Updates `electron` from 33.4.11 to 40.6.1
- [Release notes](https://github.com/electron/electron/releases)
- [Commits](https://github.com/electron/electron/compare/v33.4.11...v40.6.1)

---
updated-dependencies:
- dependency-name: electron
  dependency-version: 40.6.1
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-28 11:16:30 +00:00
diegosouzapw d624ddde03 fix(electron): code review hardening — 16 fixes for security, performance, robustness
## Critical Fixes
- #1: Server readiness — waitForServer() polls before loading window
- #2: Restart timeout — 5s + SIGKILL prevents IPC handler from hanging
- #3: changePort — now stops/restarts server on new port

## Important Fixes
- #4: Tray cleanup — destroy old Tray before recreating
- #5: IPC emission — server-status & port-changed events
- #6: Disposer pattern — replaces removeAllListeners
- #7: useSyncExternalStore — eliminates 5x re-renders

## Minor: #8-#16 (dead code, CSP, platform titlebar, types, errors, version)

Tests: 76 / 15 suites (was 64/9)
2026-02-28 08:15:04 -03:00
diegosouzapw d3ace8d611 fix: security hardening, tests, docs for Electron desktop & memory optimization
## Security Fixes
- Sanitize OMNIROUTE_MEMORY_MB with parseInt + range validation (64-16384)
  to prevent command injection via spawn() args
- Validate URL protocol in shell.openExternal (http/https only)
  to prevent RCE in Electron renderer compromise
- Bump default memory from 256MB to 512MB

## Electron package-lock.json
- Added to .gitignore (5278 lines removed from tracking)

## Test Suite (64 tests, 9 suites)
- electron-main.test.mjs: URL validation, IPC channels, window handler
- electron-preload.test.mjs: channel whitelist, API surface, open-external
- cli-memory.test.mjs: injection prevention, boundary values, .env parsing

## Documentation
- Desktop App section added to all 30 READMEs (9 fully translated)
- USER_GUIDE.md updated with 512MB default
- .env.example reflects new defaults
2026-02-28 07:59:38 -03:00
Diego Rodrigues de Sa e Souza 177507bbc8 Merge pull request #150 from benzntech/feat/electron-desktop-app
feat: Electron desktop application
2026-02-28 07:52:31 -03:00
Diego Rodrigues de Sa e Souza d915e2a868 Merge pull request #148 from benzntech/feat/memory-optimization-v2
feat: memory optimization for low-RAM configurations
2026-02-28 07:52:08 -03:00
benzntech a3d15cf971 fix: address PR review comments
- Fix server restart logic to use event-based termination
- Use app.getPath('userData') for cross-platform data directory
- Implement VALID_CHANNELS validation in preload script
- Fix incorrect copy command in user guide
- Fix broken markdown table formatting

Refs: #150
2026-02-28 11:54:41 +05:30
benzntech 5e72cd34f0 fix: improve Electron security and functionality
- Add window control IPC handlers (minimize, maximize, close)
- Add URL validation for open-external to prevent security issues
- Add single instance lock to prevent multiple app instances
- Add deep link protocol support (omniroute://)

Refs: #149
2026-02-28 11:23:27 +05:30
benzntech b004d0472b feat: add Electron desktop application support
- Add electron/ directory with main process, preload script, and types
- Add system tray integration and window management
- Add IPC communication for app info, external links, server controls
- Add useElectron React hooks for Next.js integration
- Add build scripts for Windows, macOS, and Linux
- Add development scripts for running Electron with Next.js

Ref: #149
2026-02-28 10:40:25 +05:30
benzntech 6ed98fb21c Merge branch 'main' of https://github.com/diegosouzapw/OmniRoute into feat/memory-optimization 2026-02-28 09:52:39 +05:30
benzntech 5a2fdacebe feat(memory): optimize RAM usage for low-memory deployments
- Add Node.js heap limit (256MB default) via OMNIROUTE_MEMORY_MB
- Convert LRU caches to byte-based limits (2-4MB)
- Reduce in-memory buffer sizes: 500→200 entries
- Add .env file loading in CLI for global npm installs
- Add PM2 ecosystem.config.js example for deployment
- Document memory tuning env vars in USER_GUIDE.md

Estimated RAM reduction: ~60-70% (from ~512MB+ to ~150-200MB)
2026-02-23 14:16:47 +05:30
68 changed files with 7226 additions and 6820 deletions
+21
View File
@@ -161,3 +161,24 @@ LOG_TO_FILE=true
# LOG_FILE_PATH=logs/application/app.log
# LOG_MAX_FILE_SIZE=50M
# LOG_RETENTION_DAYS=7
# ─────────────────────────────────────────────────────────────────────────────
# Memory Optimization (Low-RAM configurations)
# ─────────────────────────────────────────────────────────────────────────────
# Node.js heap limit in MB (default: 256 for Docker, system default for npm)
# OMNIROUTE_MEMORY_MB=256
# Prompt cache settings
# PROMPT_CACHE_MAX_SIZE=50
# PROMPT_CACHE_MAX_BYTES=2097152
# PROMPT_CACHE_TTL_MS=300000
# Semantic cache settings (temperature=0 responses)
# SEMANTIC_CACHE_MAX_SIZE=100
# SEMANTIC_CACHE_MAX_BYTES=4194304
# SEMANTIC_CACHE_TTL_MS=1800000
# In-memory log buffers
# PROXY_LOG_MAX_ENTRIES=200
# CALL_LOGS_MAX=200
# STREAM_HISTORY_MAX=50
+170
View File
@@ -0,0 +1,170 @@
name: Build Electron Desktop App
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version:
description: 'Release version (e.g., v1.6.8)'
required: true
type: string
permissions:
contents: write
jobs:
validate:
name: Validate version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.validate.outputs.version }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Validate version format
id: validate
run: |
if [[ "${{ github.event_name }}" == "push" ]]; then
VERSION="${GITHUB_REF#refs/tags/}"
else
VERSION="${{ inputs.version }}"
fi
if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Invalid version format. Expected: v1.6.8"
exit 1
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "✓ Valid version: $VERSION"
build:
name: Build Electron (${{ matrix.platform }})
needs: validate
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- platform: windows
runner: windows-latest
target: win
ext: .exe
- platform: macos-intel
runner: macos-latest
target: mac
ext: .dmg
- platform: macos-arm64
runner: macos-latest
target: mac
ext: -arm64.dmg
- platform: linux
runner: ubuntu-latest
target: linux
ext: .AppImage
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
- name: Cache node_modules
uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
run: npm ci
- name: Build Next.js standalone
run: npm run build
- name: Install Electron dependencies
working-directory: electron
run: npm install --no-audit --no-fund
- name: Build Electron for ${{ matrix.platform }}
working-directory: electron
run: npm run build:${{ matrix.target }}
- name: Collect installers
run: |
mkdir -p release-assets
cd electron/dist-electron
# Copy only installer files for this platform
for file in *${{ matrix.ext }}; do
[ -f "$file" ] && cp "$file" ../../release-assets/
done
# Windows: also copy portable standalone exe
if [ "${{ matrix.platform }}" = "windows" ]; then
[ -f "OmniRoute.exe" ] && cp OmniRoute.exe ../../release-assets/
fi
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: electron-${{ matrix.platform }}
path: release-assets/
release:
name: Create Release
needs: [validate, build]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: release-assets
merge-multiple: true
- name: Create source archives
run: |
# Create source code archives (excluding dev dependencies and build artifacts)
export TARBALL="OmniRoute-${{ needs.validate.outputs.version }}.source.tar.gz"
export ZIPBALL="OmniRoute-${{ needs.validate.outputs.version }}.source.zip"
# Use git archive for clean source export
git archive --format=tar.gz --prefix=OmniRoute-${{ needs.validate.outputs.version }}/ HEAD -o "release-assets/$TARBALL"
git archive --format=zip --prefix=OmniRoute-${{ needs.validate.outputs.version }}/ HEAD -o "release-assets/$ZIPBALL"
echo "✓ Created source archives:"
ls -lh "release-assets/$TARBALL" "release-assets/$ZIPBALL"
- name: List release files
run: ls -la release-assets/
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.validate.outputs.version }}
draft: false
prerelease: false
generate_release_notes: true
files: |
release-assets/*.dmg
release-assets/*-arm64.dmg
release-assets/*.exe
release-assets/*.AppImage
release-assets/*.blockmap
release-assets/*.source.tar.gz
release-assets/*.source.zip
release-assets/OmniRoute.exe
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+11
View File
@@ -102,3 +102,14 @@ app.log
# Backup directories
app.__qa_backup/
# Production standalone build (created by scripts/prepublish.mjs)
# Conflicts with Next.js App Router detection in dev (root app/ shadows src/app/)
# npm publish still includes it via package.json "files" field
app/
# Electron (subproject dependency lock and build artifacts)
electron/package-lock.json
electron/dist-electron/
electron/node_modules/
icon.iconset/
+105
View File
@@ -7,6 +7,111 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
---
## [1.6.9] — 2026-02-28
### 🐛 Fixed
- **Proxy Port Preservation** — `new URL()` silently strips default ports (80/443); proxy connections now extract the port from the raw URL string before parsing, preventing connection timeouts ([PR #161](https://github.com/diegosouzapw/OmniRoute/pull/161))
- **Proxy Credential Encoding** — URL-encode special characters in proxy username/password; decode during legacy migration ([PR #161](https://github.com/diegosouzapw/OmniRoute/pull/161))
- **HTTPS Proxy Default Port** — Changed from 8080 to 443 in frontend and migration logic ([PR #161](https://github.com/diegosouzapw/OmniRoute/pull/161))
- **Proxy Dispatcher Cache** — Invalidate cached dispatchers when proxy config is updated or deleted ([PR #161](https://github.com/diegosouzapw/OmniRoute/pull/161))
- **Proxy Logger SQLite Type** — Cast `proxyPort` to `Number` for INTEGER column ([PR #161](https://github.com/diegosouzapw/OmniRoute/pull/161))
- **CopilotToolCard URL** — Use `baseUrl` prop directly instead of redundant `window.location.origin`; filter to chat models only (`!m.type && !m.parent`) ([PR #160](https://github.com/diegosouzapw/OmniRoute/pull/160))
---
## [1.6.8] — 2026-02-28
### 🔧 Improved
- **Electron Release Workflow** — Refactored CI to trigger on git tags (`v*`) + manual dispatch, with version validation, artifact upload/download pattern across 3 platforms, and a single release job. Only installer files (`.dmg`, `.exe`, `.AppImage`) are uploaded — no more 5K+ unpacked files ([PR #159](https://github.com/diegosouzapw/OmniRoute/pull/159))
- **Windows Portable Exe** — Added standalone portable `.exe` build alongside the NSIS installer ([PR #159](https://github.com/diegosouzapw/OmniRoute/pull/159))
- **Source Code Archives** — Releases now include `OmniRoute-vX.Y.Z.source.tar.gz` and `.zip` via `git archive` ([PR #159](https://github.com/diegosouzapw/OmniRoute/pull/159))
- **Installation Docs** — Added platform-specific installation instructions with macOS Gatekeeper workaround ([PR #159](https://github.com/diegosouzapw/OmniRoute/pull/159))
### 🐛 Fixed
- **Next.js App Router Conflict** — Added `app/` (production standalone build) to `.gitignore`. This directory was conflicting with Next.js App Router detection in dev mode, causing all routes to return 404
- **Git Tracking** — Added `electron/node_modules/` to `.gitignore`
---
## [1.6.7] — 2026-02-28
### ✨ New Feature
- **GitHub Copilot Configuration Generator** — New tool on the CLI Tools dashboard page. Select models and generate the `chatLanguageModels.json` config block for VS Code GitHub Copilot using the Azure vendor pattern. Features: bulk model selection from `/v1/models` (includes combos/custom), search/filter, configurable tokens/tool-calling/vision, one-click copy, persistent selection via localStorage. Version compatibility warning for VS Code ≥ 1.109 / Copilot Chat ≥ v0.37 ([#142](https://github.com/diegosouzapw/OmniRoute/issues/142))
### 🧹 Housekeeping
- Added `electron/dist-electron/` to `.gitignore` (build artifact)
---
## [1.6.6] — 2026-02-28
### 🔒 Security Fix
- **Auth bypass after onboarding** — Fixed regression where users could access the dashboard without authentication after upgrading from older versions. The "no password" safeguard (for fresh installs) was incorrectly firing after onboarding was complete, allowing unauthenticated access when `setupComplete=true` but the password DB row was missing ([#151](https://github.com/diegosouzapw/OmniRoute/issues/151))
---
## [1.6.5] — 2026-02-28
### 🖥️ Electron Desktop
- **Official app icons** — Added proper platform-specific icons derived from the OmniRoute SVG logo: `.icns` (macOS), `.ico` (Windows), `.png` (Linux), and `tray-icon.png` (32×32) — via PR [#154](https://github.com/diegosouzapw/OmniRoute/pull/154)
- **Automated release workflow** — New GitHub Actions workflow (`electron-release.yml`) builds Electron for Windows/macOS/Linux on every GitHub release publish
- **CI fix** — Changed `npm ci``npm install` in the Electron build step since `electron/package-lock.json` is `.gitignored`
### 📖 Documentation
- **Desktop App section** — Added to all 30 README files (9 fully translated: PT-BR, ES, FR, DE, ZH-CN, JA, RU, KO, AR)
- **Electron Fix Plan** — Published detailed code review and fix documentation at `docs/ELECTRON_FIX_PLAN.md`
### 🐛 Issue Triage
- **#151** — Auth bypass after v1.6.3 upgrade — triaged, requesting more info from reporter
- **#142** — Copilot Config Generator — previously triaged, 5 comments
---
## [1.6.4] — 2026-02-28
### 🖥️ Electron Desktop — Code Review Hardening (16 Fixes)
#### 🔴 Critical
- **Server readiness** — Window now waits for server health check before loading URL; no more blank screens on cold start (#1)
- **Restart timeout** — `restart-server` IPC handler now has 5s timeout + `SIGKILL` to prevent indefinite hangs (#2)
- **Port change lifecycle** — `changePort()` now stops and restarts the server on the new port instead of just reloading the URL (#3)
#### 🟡 Important
- **Tray cleanup** — Old `Tray` instance is now destroyed before recreating, preventing duplicate icons and memory leaks (#4)
- **IPC event emission** — Main process now emits `server-status` and `port-changed` events to renderer, making React hooks functional (#5)
- **Listener accumulation** — Preload now returns disposer functions for precise listener cleanup instead of `removeAllListeners` (#6)
- **useIsElectron performance** — Replaced `useState`+`useEffect` with `useSyncExternalStore` to eliminate 5x unnecessary re-renders (#7)
#### 🔵 Minor
- Removed dead `isProduction` variable (#8)
- Platform-conditional `titleBarStyle``hiddenInset` only on macOS, `default` on Windows/Linux (#9)
- `stdio: pipe` — Server output captured for logging and readiness detection instead of `inherit` (#10)
- Shared `AppInfo` type — `useElectronAppInfo` now uses the shared interface from `types.d.ts` (#11)
- `useDataDir` error state — Now exposes errors instead of swallowing silently (#12)
- Synced `electron/package.json` version to `1.6.4` (#13)
- Removed dead `omniroute://` protocol config — no handler existed (#14)
- **Content Security Policy** — Added CSP via `session.webRequest.onHeadersReceived` (#15)
- Simplified preload validation — Generic `safeInvoke`/`safeSend`/`safeOn` wrappers reduce boilerplate (#16)
### 🧪 Test Suite Expansion
- **76 tests** across 15 suites (up from 64 tests / 9 suites)
- New: server readiness timeout, restart race condition, CSP directives, platform options, disposer pattern, generic IPC wrappers
---
## [1.6.3] — 2026-02-28
### 🐛 Bug Fixes
+2
View File
@@ -2,6 +2,7 @@ FROM node:22-bookworm-slim AS builder
WORKDIR /app
COPY package*.json ./
COPY scripts/postinstall.mjs ./scripts/postinstall.mjs
RUN if [ -f package-lock.json ]; then npm ci --no-audit --no-fund; else npm install --no-audit --no-fund; fi
COPY . ./
@@ -19,6 +20,7 @@ LABEL org.opencontainers.image.title="omniroute" \
ENV NODE_ENV=production
ENV PORT=20128
ENV HOSTNAME=0.0.0.0
ENV NODE_OPTIONS="--max-old-space-size=256"
# Data directory inside Docker — must match the volume mount in docker-compose.yml
ENV DATA_DIR=/app/data
+136 -183
View File
@@ -247,6 +247,29 @@ docker compose --profile cli up -d
---
---
## 🖥️ تطبيق سطح المكتب — غير متصل ومتاح دائمًا
> 🆕 **جديد!** أصبح OmniRoute متاحًا الآن كـ **تطبيق سطح مكتب أصلي** لنظام Windows وmacOS وLinux.
- 🖥️ **نافذة أصلية** — نافذة مخصصة مع تكامل شريط النظام
- 🔄 **بدء تلقائي** — تشغيل OmniRoute عند تسجيل الدخول
- 🔔 **إشعارات أصلية** — تنبيهات عند نفاد الحصة
-**تثبيت بنقرة واحدة** — NSIS (Windows)، DMG (macOS)، AppImage (Linux)
- 🌐 **وضع غير متصل** — يعمل بالكامل بدون إنترنت
```bash
npm run electron:dev # وضع التطوير
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 التوثيق الكامل: [`electron/README.md`](electron/README.md)
---
## 💰 لمحة سريعة عن الأسعار
| الطبقة | مقدم | التكلفة | إعادة ضبط الحصص | الأفضل لـ |
@@ -272,67 +295,6 @@ docker compose --profile cli up -d
---
## 🎯 حالات الاستخدام
### الحالة 1: "لدي اشتراك Claude Pro"
**المشكلة:** تنتهي صلاحية الحصة غير المستخدمة، وحدود المعدل أثناء عملية الترميز المكثف
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### الحالة 2: "أريد تكلفة صفرية"
**المشكلة:** لا أستطيع تحمل تكلفة الاشتراكات، وتحتاج إلى ترميز يعتمد على الذكاء الاصطناعي
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### الحالة 3: "أحتاج إلى تشفير على مدار 24 ساعة طوال أيام الأسبوع، دون انقطاع"
**المشكلة:** المواعيد النهائية، لا أستطيع تحمل فترات التوقف عن العمل
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### الحالة 4: "أريد ذكاءً اصطناعيًا مجانيًا في OpenClaw"
**المشكلة:** تحتاج إلى مساعد الذكاء الاصطناعي في تطبيقات المراسلة، مجانًا تمامًا
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 الميزات الرئيسية
### 🧠 التوجيه الأساسي والذكاء
@@ -493,6 +455,67 @@ Combo: "my-coding-stack"
---
## 🎯 حالات الاستخدام
### الحالة 1: "لدي اشتراك Claude Pro"
**المشكلة:** تنتهي صلاحية الحصة غير المستخدمة، وحدود المعدل أثناء عملية الترميز المكثف
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### الحالة 2: "أريد تكلفة صفرية"
**المشكلة:** لا أستطيع تحمل تكلفة الاشتراكات، وتحتاج إلى ترميز يعتمد على الذكاء الاصطناعي
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### الحالة 3: "أحتاج إلى تشفير على مدار 24 ساعة طوال أيام الأسبوع، دون انقطاع"
**المشكلة:** المواعيد النهائية، لا أستطيع تحمل فترات التوقف عن العمل
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### الحالة 4: "أريد ذكاءً اصطناعيًا مجانيًا في OpenClaw"
**المشكلة:** تحتاج إلى مساعد الذكاء الاصطناعي في تطبيقات المراسلة، مجانًا تمامًا
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 دليل الإعداد
<details>
@@ -773,74 +796,6 @@ Settings → API Configuration:
---
## 📊 الموديلات المتوفرة
<details>
<summary><b>عرض جميع الموديلات المتاحة</b></summary>
**كود كلود (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `cc/claude-sonnet-4-5-20250929`
- `cc/claude-haiku-4-5-20251001`
**المخطوطة (`cx/`)** - Plus/Pro:
- `cx/gpt-5.2-codex`
- `cx/gpt-5.1-codex-max`
**Gemini CLI (`gc/`)** - مجانًا:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**مساعد جيثب (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - أرصدة مجانية:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- أكثر من 50 طرازًا آخر على [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - 0.6 دولار/مليون:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - 0.2 دولار/1 مليون:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - مجانًا:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**كوين (`qw/`)** - مجانًا:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**كيرو (`kr/`)** - مجانًا:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - أكثر من 100 طراز:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- أي موديل من [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 التقييمات (التقييمات)
يشتمل OmniRoute على إطار تقييم مدمج لاختبار جودة استجابة LLM مقابل المجموعة الذهبية. يمكنك الوصول إليه عبر **Analytics → Evals** في لوحة التحكم.
@@ -864,7 +819,58 @@ Settings → API Configuration:
---
## 🔐 OAuth em Servidor Remoto (إعداد OAuth عن بعد)
## 🐛 استكشاف الأخطاء وإصلاحها
<details>
<summary><b>انقر لتوسيع دليل استكشاف الأخطاء وإصلاحها</b></summary>
**"نموذج اللغة لم يقدم رسائل"**
- استنفدت حصة الموفر → تحقق من تعقب حصة الموفر في لوحة المعلومات
- الحل: استخدم خيار التحرير والسرد الاحتياطي أو قم بالتبديل إلى مستوى أرخص
** الحد من المعدل **
- حصة الاشتراك المحددة → الرجوع إلى GLM/MiniMax
- إضافة التحرير والسرد: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
** انتهت صلاحية رمز OAuth **
- يتم التحديث تلقائيًا بواسطة OmniRoute
- إذا استمرت المشكلات: لوحة المعلومات → الموفر → إعادة الاتصال
**تكاليف مرتفعة**
- التحقق من إحصائيات الاستخدام في لوحة المعلومات → التكاليف
- تبديل النموذج الأساسي إلى GLM/MiniMax
- استخدم الطبقة المجانية (Gemini CLI، iFlow) للمهام غير الحرجة
** لوحة المعلومات تفتح على منفذ خاطئ **
- اضبط `PORT=20128` و`NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**أخطاء المزامنة السحابية**
- تحقق من نقاط `BASE_URL` لمثيلك قيد التشغيل
- تحقق من نقاط `CLOUD_URL` إلى نقطة نهاية السحابة المتوقعة
- احتفظ بقيم `NEXT_PUBLIC_*` متوافقة مع القيم من جانب الخادم
**تسجيل الدخول الأول لا يعمل**
- تحقق من `INITIAL_PASSWORD` في `.env`
- في حالة عدم تعيينها، تكون كلمة المرور الاحتياطية هي `123456`
** لا توجد سجلات الطلب **
- اضبط `ENABLE_REQUEST_LOGS=true` في `.env`
**يظهر اختبار الاتصال "غير صالح" لمقدمي الخدمات المتوافقين مع OpenAI**
- لا يكشف العديد من مقدمي الخدمة عن نقطة النهاية `/models`
- يتضمن OmniRoute v1.0.6+ التحقق الاحتياطي من خلال إكمال الدردشة
- تأكد من أن عنوان URL الأساسي يتضمن اللاحقة `/v1`
### 🔐 OAuth em Servidor Remoto (إعداد OAuth عن بعد)
<a name="oauth-em-servidor-remoto"></a>
@@ -955,59 +961,6 @@ Agora o Google redirecionará corretamente para `https://seu-servidor.com/callba
> يعمل هذا الحل البديل لأن رمز التفويض الموجود على عنوان URL يكون صالحًا بشكل مستقل لإعادة التوجيه حيث يتم تحميله أو لا.
---
## 🐛 استكشاف الأخطاء وإصلاحها
<details>
<summary><b>انقر لتوسيع دليل استكشاف الأخطاء وإصلاحها</b></summary>
**"نموذج اللغة لم يقدم رسائل"**
- استنفدت حصة الموفر → تحقق من تعقب حصة الموفر في لوحة المعلومات
- الحل: استخدم خيار التحرير والسرد الاحتياطي أو قم بالتبديل إلى مستوى أرخص
** الحد من المعدل **
- حصة الاشتراك المحددة → الرجوع إلى GLM/MiniMax
- إضافة التحرير والسرد: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
** انتهت صلاحية رمز OAuth **
- يتم التحديث تلقائيًا بواسطة OmniRoute
- إذا استمرت المشكلات: لوحة المعلومات → الموفر → إعادة الاتصال
**تكاليف مرتفعة**
- التحقق من إحصائيات الاستخدام في لوحة المعلومات → التكاليف
- تبديل النموذج الأساسي إلى GLM/MiniMax
- استخدم الطبقة المجانية (Gemini CLI، iFlow) للمهام غير الحرجة
** لوحة المعلومات تفتح على منفذ خاطئ **
- اضبط `PORT=20128` و`NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**أخطاء المزامنة السحابية**
- تحقق من نقاط `BASE_URL` لمثيلك قيد التشغيل
- تحقق من نقاط `CLOUD_URL` إلى نقطة نهاية السحابة المتوقعة
- احتفظ بقيم `NEXT_PUBLIC_*` متوافقة مع القيم من جانب الخادم
**تسجيل الدخول الأول لا يعمل**
- تحقق من `INITIAL_PASSWORD` في `.env`
- في حالة عدم تعيينها، تكون كلمة المرور الاحتياطية هي `123456`
** لا توجد سجلات الطلب **
- اضبط `ENABLE_REQUEST_LOGS=true` في `.env`
**يظهر اختبار الاتصال "غير صالح" لمقدمي الخدمات المتوافقين مع OpenAI**
- لا يكشف العديد من مقدمي الخدمة عن نقطة النهاية `/models`
- يتضمن OmniRoute v1.0.6+ التحقق الاحتياطي من خلال إكمال الدردشة
- تأكد من أن عنوان URL الأساسي يتضمن اللاحقة `/v1`
</details>
---
+137 -264
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — Безплатният AI Gateway
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Никога не спирайте да кодирате. Интелигентно маршрутизиране към **БЕЗПЛАТНИ и евтини AI модели** с автоматичен резервен вариант.
_Вашият универсален API прокси — една крайна точка, 36+ доставчици, нулев престой._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
-**One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Ценообразуването с един поглед
| Ниво | Доставчик | Цена | Нулиране на квота | Най-добро за |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Случаи на употреба
### Случай 1: „Имам абонамент за Claude Pro“
**Проблем:** Квотата изтича неизползвана, ограничения на скоростта по време на тежко кодиране
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Случай 2: „Искам нулеви разходи“
**Проблем:** Не мога да си позволя абонаменти, имам нужда от надеждно AI кодиране
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Случай 3: „Имам нужда от кодиране 24/7, без прекъсвания“
**Проблем:** Крайни срокове, не мога да си позволя престой
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Случай 4: „Искам БЕЗПЛАТЕН AI в OpenClaw“
**Проблем:** Имате нужда от AI асистент в приложенията за съобщения, напълно безплатно
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Основни характеристики
### 🧠 Основно маршрутизиране и разузнаване
@@ -495,6 +456,67 @@ OmniRoute включва мощна вградена игра за превод
---
## 🎯 Случаи на употреба
### Случай 1: „Имам абонамент за Claude Pro“
**Проблем:** Квотата изтича неизползвана, ограничения на скоростта по време на тежко кодиране
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Случай 2: „Искам нулеви разходи“
**Проблем:** Не мога да си позволя абонаменти, имам нужда от надеждно AI кодиране
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Случай 3: „Имам нужда от кодиране 24/7, без прекъсвания“
**Проблем:** Крайни срокове, не мога да си позволя престой
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Случай 4: „Искам БЕЗПЛАТЕН AI в OpenClaw“
**Проблем:** Имате нужда от AI асистент в приложенията за съобщения, напълно безплатно
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Ръководство за настройка
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Налични модели
<details>
<summary><b>Вижте всички налични модели</b></summary>
**Claude Code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - БЕЗПЛАТНО:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - БЕЗПЛАТНИ кредити:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- още 50+ модела на [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0,6/1 млн.:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0,2/1 млн.:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - БЕЗПЛАТНО:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - БЕЗПЛАТНО:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Киро (`kr/`)** - БЕЗПЛАТНО:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ модела:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Всеки модел от [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Оценки (Evals)
OmniRoute включва вградена рамка за оценка за тестване на качеството на отговора на LLM спрямо златен набор. Достъп до него чрез **Analytics → Evals** в таблото за управление.
@@ -866,7 +820,58 @@ OmniRoute включва вградена рамка за оценка за те
---
## 🔐 OAuth em Servidor Remoto (Отдалечена настройка на OAuth)
## 🐛 Отстраняване на неизправности
<details>
<summary><b>Щракнете, за да разширите ръководството за отстраняване на неизправности</b></summary>
**„Езиковият модел не предостави съобщения“**
- Квотата на доставчика е изчерпана → Проверете инструмента за проследяване на квотата на таблото за управление
- Решение: Използвайте комбо резервен вариант или преминете към по-евтино ниво
**Ограничаване на скоростта**
- Изчерпване на квотата за абонамент → Резервно връщане към GLM/MiniMax
- Добавяне на комбинация: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth токенът е изтекъл**
- Автоматично опресняване от OmniRoute
- Ако проблемите продължават: Табло → Доставчик → Повторно свързване
**Високи разходи**
- Проверете статистическите данни за използването в Табло → Разходи
- Превключете основния модел към GLM/MiniMax
- Използвайте безплатно ниво (Gemini CLI, iFlow) за некритични задачи
**Таблото се отваря на грешен порт**
- Задайте `PORT=20128` и `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Грешки при синхронизиране в облак**
- Потвърдете, че `BASE_URL` сочи към вашия работещ екземпляр
- Проверете `CLOUD_URL` точки към вашата очаквана крайна точка в облака
- Поддържайте стойностите на `NEXT_PUBLIC_*` в съответствие със стойностите от страната на сървъра
**Първото влизане не работи**
- Проверете `INITIAL_PASSWORD` в `.env`
- Ако не е зададена, резервната парола е `123456`
**Няма регистрационни файлове за заявки**
- Задайте `ENABLE_REQUEST_LOGS=true` в `.env`
**Тестът за връзка показва „Невалидно“ за OpenAI-съвместими доставчици**
- Много доставчици не излагат `/models` крайна точка
- OmniRoute v1.0.6+ включва резервно валидиране чрез завършвания на чат
- Уверете се, че основният URL адрес включва суфикс `/v1`
### 🔐 OAuth em Servidor Remoto (Отдалечена настройка на OAuth)
<a name="oauth-em-servidor-remoto"></a>
@@ -957,59 +962,6 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
> Това заобиколно решение функционира, ако кодът на авторизацията на URL е валиден независимо от пренасочването към пренасочване или не.
---
## 🐛 Отстраняване на неизправности
<details>
<summary><b>Щракнете, за да разширите ръководството за отстраняване на неизправности</b></summary>
**„Езиковият модел не предостави съобщения“**
- Квотата на доставчика е изчерпана → Проверете инструмента за проследяване на квотата на таблото за управление
- Решение: Използвайте комбо резервен вариант или преминете към по-евтино ниво
**Ограничаване на скоростта**
- Изчерпване на квотата за абонамент → Резервно връщане към GLM/MiniMax
- Добавяне на комбинация: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth токенът е изтекъл**
- Автоматично опресняване от OmniRoute
- Ако проблемите продължават: Табло → Доставчик → Повторно свързване
**Високи разходи**
- Проверете статистическите данни за използването в Табло → Разходи
- Превключете основния модел към GLM/MiniMax
- Използвайте безплатно ниво (Gemini CLI, iFlow) за некритични задачи
**Таблото се отваря на грешен порт**
- Задайте `PORT=20128` и `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Грешки при синхронизиране в облак**
- Потвърдете, че `BASE_URL` сочи към вашия работещ екземпляр
- Проверете `CLOUD_URL` точки към вашата очаквана крайна точка в облака
- Поддържайте стойностите на `NEXT_PUBLIC_*` в съответствие със стойностите от страната на сървъра
**Първото влизане не работи**
- Проверете `INITIAL_PASSWORD` в `.env`
- Ако не е зададена, резервната парола е `123456`
**Няма регистрационни файлове за заявки**
- Задайте `ENABLE_REQUEST_LOGS=true` в `.env`
**Тестът за връзка показва „Невалидно“ за OpenAI-съвместими доставчици**
- Много доставчици не излагат `/models` крайна точка
- OmniRoute v1.0.6+ включва резервно валидиране чрез завършвания на чат
- Уверете се, че основният URL адрес включва суфикс `/v1`
</details>
---
@@ -1152,85 +1104,6 @@ gh release create v1.0.6 --title "v1.0.6" --generate-notes
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento inteligente para **modelos de IA GRATUITOS e de baixo custo** com резервен автоматичен.
_Seu прокси универсален API — um крайна точка, 36+ доставчици, нулев престой._
### 🌐 Internacionalização (i18n)
Таблото за управление на OmniRoute поддържа **múltiplos idiomas**. Актуално налични:
| идиома | Código | Статус |
| ------------------------- | ------- | ------------ |
| 🇺🇸 английски | `en` | ✅ Завършено |
| 🇧🇷 португалски (Бразилия) | `pt-BR` | ✅ Завършено |
**Параметр на трокар или идиома:** Кликнете без избор на идиома (🇺🇸 EN) без заглавка в таблото за управление → избор или избран идиома.
**Para adicionar um new idioma:**
1. Извикайте `src/i18n/messages/{codigo}.json` базирано на `en.json`
2. Добавете кода към `src/i18n/config.ts``LOCALES` и `LANGUAGES`
3. Reinicie или сървър
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Докер
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ доставчици на IA** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek и други
- **Roteamento inteligente** — Резервни автоматични агенти
- **Tradução de formato** — OpenAI ↔ Claude ↔ Gemini automaticamente
- **Multi-conta** — Múltiplas contas por provedor com seleção inteligente
- **Cache semântico** — Reduz custos e latência
- **Автоматичен OAuth** — Автоматично обновяване на токени
- **Combos personalizados** — 6 estratégias de roteamento
- **Пълно табло** — Мониторинг, регистрационни файлове, анализи, конфигуриране
- **CLI инструменти** — Конфигуриране на Claude Code, Codex, Cursor, Cline com um clique
- **100% TypeScript** — Лимпо и тип код
### 📖 Documentação
| Документ | Описание |
| ----------------------------------------------- | --------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Доставчици, комбинации, CLI, внедряване |
| [Referência da API](docs/API_REFERENCE.md) | Всички крайни точки с примери |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Общи проблеми и решения |
| [Arquitetura](docs/ARCHITECTURE.md) | Архитектура и вътрешна система |
| [Contribuição](CONTRIBUTING.md) | Setup de desenvolvimento e guidelines |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Пълна версия: VM + nginx + Cloudflare |
### 📧 Подкрепете
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Двойни гуми, компартилхе дикас и актуализация на фик.
- **Уебсайт**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Проблеми**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Създаден с ❤️ за разработчици, които кодират 24/7</sub>
<br/>
+137 -264
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — Den gratis AI-gateway
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Stop aldrig med at kode. Smart routing til **GRATIS og billige AI-modeller** med automatisk fallback.
_Din universelle API-proxy — ét slutpunkt, 36+ udbydere, ingen nedetid._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
-**One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Prissætning på et øjeblik
| Tier | Udbyder | Omkostninger | Kvote nulstilling | Bedst til |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Use Cases
### Case 1: "Jeg har Claude Pro-abonnement"
**Problem:** Kvoten udløber ubrugt, satsgrænser under tung kodning
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Case 2: "Jeg vil have nul omkostninger"
**Problem:** Har ikke råd til abonnementer, har brug for pålidelig AI-kodning
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Case 3: "Jeg har brug for 24/7 kodning, ingen afbrydelser"
**Problem:** Deadlines, har ikke råd til nedetid
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Case 4: "Jeg vil have GRATIS AI i OpenClaw"
**Problem:** Har brug for AI-assistent i beskedapps, helt gratis
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Nøglefunktioner
### 🧠 Core Routing & Intelligence
@@ -495,6 +456,67 @@ OmniRoute inkluderer en kraftfuld indbygget oversætterlegeplads med **4 tilstan
---
## 🎯 Use Cases
### Case 1: "Jeg har Claude Pro-abonnement"
**Problem:** Kvoten udløber ubrugt, satsgrænser under tung kodning
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Case 2: "Jeg vil have nul omkostninger"
**Problem:** Har ikke råd til abonnementer, har brug for pålidelig AI-kodning
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Case 3: "Jeg har brug for 24/7 kodning, ingen afbrydelser"
**Problem:** Deadlines, har ikke råd til nedetid
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Case 4: "Jeg vil have GRATIS AI i OpenClaw"
**Problem:** Har brug for AI-assistent i beskedapps, helt gratis
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Opsætningsvejledning
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Tilgængelige modeller
<details>
<summary><b>Se alle tilgængelige modeller</b></summary>
**Claude-kode (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - GRATIS:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - GRATIS kreditter:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ flere modeller på [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - 0,6 USD/1 mio.
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - 0,2 USD/1 mio.
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - GRATIS:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - GRATIS:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - GRATIS:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ modeller:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Enhver model fra [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Evalueringer (evalueringer)
OmniRoute inkluderer en indbygget evalueringsramme til at teste LLM-svarkvaliteten mod et gyldent sæt. Få adgang til det via **Analytics → Evals** i dashboardet.
@@ -866,7 +820,58 @@ Det forudindlæste "OmniRoute Golden Set" indeholder 10 testcases, der dækker:
---
## 🔐 OAuth em Servidor Remoto (Remote OAuth Setup)
## 🐛 Fejlfinding
<details>
<summary><b>Klik for at udvide fejlfindingsvejledning</b></summary>
**"Sprogmodellen leverede ikke beskeder"**
- Udbyderkvote opbrugt → Tjek dashboardkvotesporing
- Løsning: Brug combo fallback eller skift til et billigere niveau
**Satsbegrænsende**
- Abonnementskontingent ude → Fallback til GLM/MiniMax
- Tilføj kombination: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth-token er udløbet**
- Automatisk genopfrisket af OmniRoute
- Hvis problemerne fortsætter: Dashboard → Udbyder → Genopret forbindelse
**Høje omkostninger**
- Tjek brugsstatistik i Dashboard → Omkostninger
- Skift primær model til GLM/MiniMax
- Brug gratis niveau (Gemini CLI, iFlow) til ikke-kritiske opgaver
**Dashboard åbner på forkert port**
- Sæt `PORT=20128` og `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Skysynkroniseringsfejl**
- Bekræft `BASE_URL` peger på din løbeforekomst
- Bekræft `CLOUD_URL` point til dit forventede cloud-endepunkt
- Hold `NEXT_PUBLIC_*` værdier på linje med værdier på serversiden
**Første login virker ikke**
- Tjek `INITIAL_PASSWORD` i `.env`
- Hvis den ikke er angivet, er reserveadgangskoden `123456`
**Ingen anmodningslogfiler**
- Indstil `ENABLE_REQUEST_LOGS=true` i `.env`
**Forbindelsestest viser "Ugyldig" for OpenAI-kompatible udbydere**
- Mange udbydere eksponerer ikke et `/models` slutpunkt
- OmniRoute v1.0.6+ inkluderer fallback-validering via chatafslutninger
- Sørg for, at basis-URL'en inkluderer suffikset `/v1`
### 🔐 OAuth em Servidor Remoto (Remote OAuth Setup)
<a name="oauth-em-servidor-remoto"></a>
@@ -957,59 +962,6 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
> Este workaround funciona porque or código de autorização na URL é válido independente do redirect ter carregado or não.
---
## 🐛 Fejlfinding
<details>
<summary><b>Klik for at udvide fejlfindingsvejledning</b></summary>
**"Sprogmodellen leverede ikke beskeder"**
- Udbyderkvote opbrugt → Tjek dashboardkvotesporing
- Løsning: Brug combo fallback eller skift til et billigere niveau
**Satsbegrænsende**
- Abonnementskontingent ude → Fallback til GLM/MiniMax
- Tilføj kombination: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth-token er udløbet**
- Automatisk genopfrisket af OmniRoute
- Hvis problemerne fortsætter: Dashboard → Udbyder → Genopret forbindelse
**Høje omkostninger**
- Tjek brugsstatistik i Dashboard → Omkostninger
- Skift primær model til GLM/MiniMax
- Brug gratis niveau (Gemini CLI, iFlow) til ikke-kritiske opgaver
**Dashboard åbner på forkert port**
- Sæt `PORT=20128` og `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Skysynkroniseringsfejl**
- Bekræft `BASE_URL` peger på din løbeforekomst
- Bekræft `CLOUD_URL` point til dit forventede cloud-endepunkt
- Hold `NEXT_PUBLIC_*` værdier på linje med værdier på serversiden
**Første login virker ikke**
- Tjek `INITIAL_PASSWORD` i `.env`
- Hvis den ikke er angivet, er reserveadgangskoden `123456`
**Ingen anmodningslogfiler**
- Indstil `ENABLE_REQUEST_LOGS=true` i `.env`
**Forbindelsestest viser "Ugyldig" for OpenAI-kompatible udbydere**
- Mange udbydere eksponerer ikke et `/models` slutpunkt
- OmniRoute v1.0.6+ inkluderer fallback-validering via chatafslutninger
- Sørg for, at basis-URL'en inkluderer suffikset `/v1`
</details>
---
@@ -1152,85 +1104,6 @@ MIT-licens - se [LICENSE](LICENSE) for detaljer.
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratis
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento inteligente para **modelos de IA GRATUITOS e de baixo custo** com fallback automático.
_Seu proxy universal de API — et slutpunkt, 36+ tests, nul nedetid._
### 🌐 Internacionalização (i18n)
O dashboard til OmniRoute understøtter **multiplos idiomas**. Atualmente disponível em:
| Idioma | Kode | Status |
| --------------------- | ------- | ---------- |
| 🇺🇸 Engelsk | `en` | ✅ Komplet |
| 🇧🇷 Português (Brasil) | `pt-BR` | ✅ Komplet |
**Para trocar o idioma:** Click no selector de idioma (🇺🇸 EN) no header do dashboard → selection o idioma desejado.
**Sådan tilføjes et nyt formsprog:**
1. Crie `src/i18n/messages/{codigo}.json` baseado em `en.json`
2. Adicione o código em `src/i18n/config.ts``LOCALES` og `LANGUAGES`
3. Reinicie o servidor
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Docker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ provedores de IA** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek, e mais
- **Roteamento inteligente** — Fallback automático entre provedores
- **Tradução de formato** — OpenAI ↔ Claude ↔ Gemini automaticamente
- **Multi-conta** — Múltiplas contas por provedor com seleção inteligente
- **Cache semântico** — Reduz custos e latência
- **OAuth automático** — Tokens renovam automaticamente
- **Combos personalizados** — 6 estratégias de roteamento
- **Dashboard komplet** — Overvågning, logfiler, analyser, konfigurationer
- **CLI Tools** — Konfigurer Claude Code, Codex, Cursor, Cline com um clique
- **100% TypeScript** — Código limpo e tipado
### 📖 Dokumentation
| Dokument | Beskrivelse |
| ----------------------------------------------- | ---------------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, combos, CLI, implementering |
| [Referência da API](docs/API_REFERENCE.md) | Todos os endepunkter com eksempler |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do systema |
| [Contribuição](CONTRIBUTING.md) | Opsætning af desenvolvimento og retningslinjer |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Komplet: VM + nginx + Cloudflare |
### 📧 Støtte
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Træk til, kompartilhe dicas e fique atualizado.
- **Websted**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Problemer**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Bygget med ❤️ for udviklere, der koder 24/7</sub>
<br/>
+85 -129
View File
@@ -247,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop-App — Offline & Immer Aktiv
> 🆕 **NEU!** OmniRoute ist jetzt als **native Desktop-Anwendung** für Windows, macOS und Linux verfügbar.
- 🖥️ **Natives Fenster** — Dediziertes App-Fenster mit System-Tray-Integration
- 🔄 **Autostart** — OmniRoute beim Systemstart starten
- 🔔 **Native Benachrichtigungen** — Warnungen bei Kontingent-Erschöpfung
-**Ein-Klick-Installation** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline-Modus** — Funktioniert vollständig offline mit integriertem Server
```bash
npm run electron:dev # Entwicklungsmodus
npm run electron:build # Aktuelle Plattform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Vollständige Dokumentation: [`electron/README.md`](electron/README.md)
---
## 💰 Preisübersicht
| Tier | Anbieter | Kosten | Kontingent-Reset | Am besten für |
@@ -272,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Anwendungsfälle
### Fall 1: „Ich habe ein Claude Pro Abo"
**Problem:** Kontingent verfällt ungenutzt, Rate-Limits während intensivem Programmieren
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (Abo voll ausnutzen)
2. glm/glm-4.7 (günstiges Backup bei erschöpftem Kontingent)
3. if/kimi-k2-thinking (kostenloser Notfall-Fallback)
Monatliche Kosten: $20 (Abo) + ~$5 (Backup) = $25 gesamt
vs. $20 + an Limits stoßen = Frustration
```
### Fall 2: „Ich will null Kosten"
**Problem:** Kann sich Abos nicht leisten, braucht zuverlässige KI zum Programmieren
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K gratis/Monat)
2. if/kimi-k2-thinking (unbegrenzt gratis)
3. qw/qwen3-coder-plus (unbegrenzt gratis)
Monatliche Kosten: $0
Qualität: Produktionsreife Modelle
```
### Fall 3: „Ich muss 24/7 programmieren, ohne Unterbrechungen"
**Problem:** Enge Deadlines, kann sich keine Ausfallzeit leisten
```
Combo: "always-on"
1. cc/claude-opus-4-6 (beste Qualität)
2. cx/gpt-5.2-codex (zweites Abo)
3. glm/glm-4.7 (günstig, täglicher Reset)
4. minimax/MiniMax-M2.1 (günstigste, 5h Reset)
5. if/kimi-k2-thinking (unbegrenzt kostenlos)
Ergebnis: 5 Fallback-Ebenen = null Ausfallzeit
```
### Fall 4: „Ich will KOSTENLOSE KI in OpenClaw"
**Problem:** Braucht KI-Assistenz in Messaging-Apps, komplett kostenlos
```
Combo: "openclaw-free"
1. if/glm-4.7 (unbegrenzt kostenlos)
2. if/minimax-m2.1 (unbegrenzt kostenlos)
3. if/kimi-k2-thinking (unbegrenzt kostenlos)
Monatliche Kosten: $0
Zugang über: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Hauptfunktionen
### 🧠 Routing & Intelligenz
@@ -474,6 +437,67 @@ Nahtlose Übersetzung zwischen Formaten:
---
## 🎯 Anwendungsfälle
### Fall 1: „Ich habe ein Claude Pro Abo"
**Problem:** Kontingent verfällt ungenutzt, Rate-Limits während intensivem Programmieren
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (Abo voll ausnutzen)
2. glm/glm-4.7 (günstiges Backup bei erschöpftem Kontingent)
3. if/kimi-k2-thinking (kostenloser Notfall-Fallback)
Monatliche Kosten: $20 (Abo) + ~$5 (Backup) = $25 gesamt
vs. $20 + an Limits stoßen = Frustration
```
### Fall 2: „Ich will null Kosten"
**Problem:** Kann sich Abos nicht leisten, braucht zuverlässige KI zum Programmieren
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K gratis/Monat)
2. if/kimi-k2-thinking (unbegrenzt gratis)
3. qw/qwen3-coder-plus (unbegrenzt gratis)
Monatliche Kosten: $0
Qualität: Produktionsreife Modelle
```
### Fall 3: „Ich muss 24/7 programmieren, ohne Unterbrechungen"
**Problem:** Enge Deadlines, kann sich keine Ausfallzeit leisten
```
Combo: "always-on"
1. cc/claude-opus-4-6 (beste Qualität)
2. cx/gpt-5.2-codex (zweites Abo)
3. glm/glm-4.7 (günstig, täglicher Reset)
4. minimax/MiniMax-M2.1 (günstigste, 5h Reset)
5. if/kimi-k2-thinking (unbegrenzt kostenlos)
Ergebnis: 5 Fallback-Ebenen = null Ausfallzeit
```
### Fall 4: „Ich will KOSTENLOSE KI in OpenClaw"
**Problem:** Braucht KI-Assistenz in Messaging-Apps, komplett kostenlos
```
Combo: "openclaw-free"
1. if/glm-4.7 (unbegrenzt kostenlos)
2. if/minimax-m2.1 (unbegrenzt kostenlos)
3. if/kimi-k2-thinking (unbegrenzt kostenlos)
Monatliche Kosten: $0
Zugang über: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Einrichtungsanleitung
<details>
@@ -754,74 +778,6 @@ Einstellungen → API-Konfiguration:
---
## 📊 Verfügbare Modelle
<details>
<summary><b>Alle verfügbaren Modelle anzeigen</b></summary>
**Claude Code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - KOSTENLOS:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - KOSTENLOSE Credits:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ weitere Modelle auf [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0.6/1M:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0.2/1M:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - KOSTENLOS:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - KOSTENLOS:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - KOSTENLOS:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ Modelle:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Jedes Modell von [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Evaluierungen (Evals)
OmniRoute enthält ein integriertes Evaluierungs-Framework zum Testen der LLM-Antwortqualität gegen ein Golden Set. Zugang über **Analytics → Evals** im Dashboard.
+89 -129
View File
@@ -247,6 +247,34 @@ docker compose --profile cli up -d
---
---
## 🖥️ Aplicación de Escritorio — Sin Conexión y Siempre Activo
> 🆕 **¡NUEVO!** OmniRoute ahora está disponible como **aplicación de escritorio nativa** para Windows, macOS y Linux.
Ejecuta OmniRoute como una aplicación de escritorio autónoma — sin terminal, sin navegador, sin internet necesario para modelos locales. La app basada en Electron incluye:
- 🖥️ **Ventana Nativa** — Ventana dedicada con integración en la bandeja del sistema
- 🔄 **Inicio Automático** — Inicia OmniRoute al iniciar sesión
- 🔔 **Notificaciones Nativas** — Recibe alertas sobre cuota o problemas de proveedores
-**Instalación con Un Clic** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Modo Sin Conexión** — Funciona completamente offline con servidor incluido
### Inicio Rápido
```bash
npm run electron:dev # Modo desarrollo
npm run electron:build # Plataforma actual
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Documentación completa: [`electron/README.md`](electron/README.md)
---
## 💰 Precios Resumidos
| Tier | Proveedor | Costo | Reset de Cuota | Mejor Para |
@@ -272,67 +300,6 @@ docker compose --profile cli up -d
---
## 🎯 Casos de Uso
### Caso 1: "Tengo suscripción Claude Pro"
**Problema:** La cuota expira sin usar, límites de tasa durante programación intensa
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (usar suscripción al máximo)
2. glm/glm-4.7 (respaldo barato cuando la cuota se agota)
3. if/kimi-k2-thinking (fallback de emergencia gratuito)
Costo mensual: $20 (suscripción) + ~$5 (respaldo) = $25 total
vs. $20 + chocar con límites = frustración
```
### Caso 2: "Quiero costo cero"
**Problema:** No puede pagar suscripciones, necesita IA confiable para programar
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K gratis/mes)
2. if/kimi-k2-thinking (ilimitado gratis)
3. qw/qwen3-coder-plus (ilimitado gratis)
Costo mensual: $0
Calidad: Modelos listos para producción
```
### Caso 3: "Necesito programar 24/7, sin interrupciones"
**Problema:** Plazos ajustados, no puede permitirse tiempo de inactividad
```
Combo: "always-on"
1. cc/claude-opus-4-6 (mejor calidad)
2. cx/gpt-5.2-codex (segunda suscripción)
3. glm/glm-4.7 (barato, reset diario)
4. minimax/MiniMax-M2.1 (más barato, reset 5h)
5. if/kimi-k2-thinking (gratuito ilimitado)
Resultado: 5 capas de fallback = cero tiempo de inactividad
```
### Caso 4: "Quiero IA GRATUITA en OpenClaw"
**Problema:** Necesita asistente de IA en apps de mensajería, completamente gratuito
```
Combo: "openclaw-free"
1. if/glm-4.7 (ilimitado gratis)
2. if/minimax-m2.1 (ilimitado gratis)
3. if/kimi-k2-thinking (ilimitado gratis)
Costo mensual: $0
Acceso vía: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Características Principales
### 🧠 Enrutamiento e Inteligencia
@@ -474,6 +441,67 @@ Traducción transparente entre formatos:
---
## 🎯 Casos de Uso
### Caso 1: "Tengo suscripción Claude Pro"
**Problema:** La cuota expira sin usar, límites de tasa durante programación intensa
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (usar suscripción al máximo)
2. glm/glm-4.7 (respaldo barato cuando la cuota se agota)
3. if/kimi-k2-thinking (fallback de emergencia gratuito)
Costo mensual: $20 (suscripción) + ~$5 (respaldo) = $25 total
vs. $20 + chocar con límites = frustración
```
### Caso 2: "Quiero costo cero"
**Problema:** No puede pagar suscripciones, necesita IA confiable para programar
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K gratis/mes)
2. if/kimi-k2-thinking (ilimitado gratis)
3. qw/qwen3-coder-plus (ilimitado gratis)
Costo mensual: $0
Calidad: Modelos listos para producción
```
### Caso 3: "Necesito programar 24/7, sin interrupciones"
**Problema:** Plazos ajustados, no puede permitirse tiempo de inactividad
```
Combo: "always-on"
1. cc/claude-opus-4-6 (mejor calidad)
2. cx/gpt-5.2-codex (segunda suscripción)
3. glm/glm-4.7 (barato, reset diario)
4. minimax/MiniMax-M2.1 (más barato, reset 5h)
5. if/kimi-k2-thinking (gratuito ilimitado)
Resultado: 5 capas de fallback = cero tiempo de inactividad
```
### Caso 4: "Quiero IA GRATUITA en OpenClaw"
**Problema:** Necesita asistente de IA en apps de mensajería, completamente gratuito
```
Combo: "openclaw-free"
1. if/glm-4.7 (ilimitado gratis)
2. if/minimax-m2.1 (ilimitado gratis)
3. if/kimi-k2-thinking (ilimitado gratis)
Costo mensual: $0
Acceso vía: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Guía de Configuración
<details>
@@ -754,74 +782,6 @@ Configuración → Configuración de API:
---
## 📊 Modelos Disponibles
<details>
<summary><b>Ver todos los modelos disponibles</b></summary>
**Claude Code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - GRATUITO:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - Créditos GRATUITOS:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ más modelos en [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0.6/1M:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0.2/1M:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - GRATUITO:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - GRATUITO:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - GRATUITO:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ modelos:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Cualquier modelo de [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Evaluaciones (Evals)
OmniRoute incluye un framework de evaluación integrado para probar la calidad de respuestas de LLM contra un conjunto golden. Accede vía **Analytics → Evals** en el dashboard.
+138 -265
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — ilmainen tekoälyyhdyskäytävä
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Älä koskaan lopeta koodaamista. Älykäs reititys **ILMAisiin ja edullisiin tekoälymalleihin** automaattisella varalla.
_Universaali API-välityspalvelin yksi päätepiste, yli 36 palveluntarjoajaa, nolla seisokkia._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
-**One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Hinnoittelu yhdellä silmäyksellä
| Taso | Palveluntarjoaja | Kustannukset | Kiintiön nollaus | Paras |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Käyttökotelot
### Tapaus 1: "Minulla on Claude Pro -tilaus"
**Ongelma:** Kiintiö vanhenee käyttämättä, nopeusrajoitukset raskaan koodauksen aikana
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Tapaus 2: "Haluan ilman kustannuksia"
**Ongelma:** Ei ole varaa tilauksiin, tarvitaan luotettavaa tekoälykoodausta
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Tapaus 3: "Tarvitsen 24/7-koodausta, ei keskeytyksiä"
**Ongelma:** Määräajat, seisokkeihin ei ole varaa
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Tapaus 4: "Haluan ILMAISTA tekoälyä OpenClawissa"
**Ongelma:** Tarvitset AI-avustajan viestisovelluksissa, täysin ilmainen
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Tärkeimmät ominaisuudet
### 🧠 Ydinreititys ja älykkyys
@@ -495,6 +456,67 @@ OmniRoute sisältää tehokkaan sisäänrakennetun Translator Playgroundin, joss
---
## 🎯 Käyttökotelot
### Tapaus 1: "Minulla on Claude Pro -tilaus"
**Ongelma:** Kiintiö vanhenee käyttämättä, nopeusrajoitukset raskaan koodauksen aikana
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Tapaus 2: "Haluan ilman kustannuksia"
**Ongelma:** Ei ole varaa tilauksiin, tarvitaan luotettavaa tekoälykoodausta
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Tapaus 3: "Tarvitsen 24/7-koodausta, ei keskeytyksiä"
**Ongelma:** Määräajat, seisokkeihin ei ole varaa
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Tapaus 4: "Haluan ILMAISTA tekoälyä OpenClawissa"
**Ongelma:** Tarvitset AI-avustajan viestisovelluksissa, täysin ilmainen
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Asennusopas
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Saatavilla olevat mallit
<details>
<summary><b>Näytä kaikki saatavilla olevat mallit</b></summary>
**Claude Code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `cc/claude-sonnet-4-5-20250929`
- `cc/claude-haiku-4-5-20251001`
**Koodi (`cx/`)** - Plus/Pro:
- `cx/gpt-5.2-codex`
- `cx/gpt-5.1-codex-max`
**Gemini CLI (`gc/`)** - ILMAINEN:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - ILMAISIA krediittejä:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- Yli 50 mallia [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - 0,6 $/1 milj.:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - 0,2 $/1 milj.
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - ILMAINEN:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - ILMAINEN:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - ILMAINEN:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ mallia:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Mikä tahansa malli alkaen [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Arvioinnit (Evals)
OmniRoute sisältää sisäänrakennetun arviointikehyksen, jolla testataan LLM-vastauksen laatua kultaiseen joukkoon verrattuna. Käytä sitä kojelaudan **Analytics → Evals** kautta.
@@ -866,7 +820,58 @@ Esiladattu "OmniRoute Golden Set" sisältää 10 testitapausta, jotka kattavat:
---
## 🔐 OAuth em Servidor Remoto (OAuth-etäasetus)
## 🐛 Vianetsintä
<details>
<summary><b>Laajenna vianetsintäopas napsauttamalla</b></summary>
**"Kielimalli ei antanut viestejä"**
- Palveluntarjoajan kiintiö käytetty loppuun → Tarkista kojelaudan kiintiön seuranta
- Ratkaisu: Käytä yhdistelmävaraa tai vaihda halvempaan tasoon
**hintarajoitus**
- Tilauskiintiö loppu → Varaa GLM/MiniMaxiin
- Lisää yhdistelmä: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth-tunnus vanhentunut**
- OmniRoute päivittää automaattisesti
- Jos ongelmat jatkuvat: Kojelauta → Palveluntarjoaja → Yhdistä uudelleen
**Korkeat kustannukset**
- Tarkista käyttötilastot kohdassa Dashboard → Costs
- Vaihda ensisijaiseksi malliksi GLM/MiniMax
- Käytä ilmaista tasoa (Gemini CLI, iFlow) ei-kriittisiin tehtäviin
**Kojelauta avautuu väärään porttiin**
- Aseta `PORT=20128` ja `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Pilvisynkronointivirheet**
- Vahvista `BASE_URL` pistettä käynnissä olevaan esiintymääsi
- Vahvista `CLOUD_URL` pistettä odotettuun pilvipäätepisteeseen
- Pidä `NEXT_PUBLIC_*`-arvot kohdakkain palvelinpuolen arvojen kanssa
**Ensimmäinen kirjautuminen ei toimi**
- Tarkista `INITIAL_PASSWORD` kohteessa `.env`
- Jos ei ole asetettu, varasalasana on `123456`
**Ei pyyntölokeja**
- Aseta `ENABLE_REQUEST_LOGS=true` kohteeseen `.env`
**Yhteystesti näyttää "Virheellinen" OpenAI-yhteensopiville palveluntarjoajille**
- Monet palveluntarjoajat eivät paljasta `/models`-päätepistettä
- OmniRoute v1.0.6+ sisältää varatarkistuksen chatin loppuunsaattamisen kautta
- Varmista, että perus-URL sisältää `/v1`-liitteen
### 🔐 OAuth em Servidor Remoto (OAuth-etäasetus)
<a name="oauth-em-servidor-remoto"></a>
@@ -945,7 +950,7 @@ Agora o Google redirecionará corretamente para `https://seu-servidor.com/callba
---
### Workaround temporário (sem configurar credenciais próprias)
#### Workaround temporário (sem configurar credenciais próprias)
Se não quiser criar credenciais próprias agora, ainda é possível usar o fluxo **manual de URL**:
@@ -957,59 +962,6 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
> Este workaround funciona porque o código de autorização na URL é válido independente do redirect ter carregado ou não.
---
## 🐛 Vianetsintä
<details>
<summary><b>Laajenna vianetsintäopas napsauttamalla</b></summary>
**"Kielimalli ei antanut viestejä"**
- Palveluntarjoajan kiintiö käytetty loppuun → Tarkista kojelaudan kiintiön seuranta
- Ratkaisu: Käytä yhdistelmävaraa tai vaihda halvempaan tasoon
**hintarajoitus**
- Tilauskiintiö loppu → Varaa GLM/MiniMaxiin
- Lisää yhdistelmä: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth-tunnus vanhentunut**
- OmniRoute päivittää automaattisesti
- Jos ongelmat jatkuvat: Kojelauta → Palveluntarjoaja → Yhdistä uudelleen
**Korkeat kustannukset**
- Tarkista käyttötilastot kohdassa Dashboard → Costs
- Vaihda ensisijaiseksi malliksi GLM/MiniMax
- Käytä ilmaista tasoa (Gemini CLI, iFlow) ei-kriittisiin tehtäviin
**Kojelauta avautuu väärään porttiin**
- Aseta `PORT=20128` ja `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Pilvisynkronointivirheet**
- Vahvista `BASE_URL` pistettä käynnissä olevaan esiintymääsi
- Vahvista `CLOUD_URL` pistettä odotettuun pilvipäätepisteeseen
- Pidä `NEXT_PUBLIC_*`-arvot kohdakkain palvelinpuolen arvojen kanssa
**Ensimmäinen kirjautuminen ei toimi**
- Tarkista `INITIAL_PASSWORD` kohteessa `.env`
- Jos ei ole asetettu, varasalasana on `123456`
**Ei pyyntölokeja**
- Aseta `ENABLE_REQUEST_LOGS=true` kohteeseen `.env`
**Yhteystesti näyttää "Virheellinen" OpenAI-yhteensopiville palveluntarjoajille**
- Monet palveluntarjoajat eivät paljasta `/models`-päätepistettä
- OmniRoute v1.0.6+ sisältää varatarkistuksen chatin loppuunsaattamisen kautta
- Varmista, että perus-URL sisältää `/v1`-liitteen
</details>
---
@@ -1152,85 +1104,6 @@ MIT-lisenssi katso lisätietoja osoitteesta [LICENSE](LICENSE).
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento inteligente para **mallit de IA GRATUITOS e de baixo custo** com backback automático.
_Seu välityspalvelin universaali de API — um päätepiste, 36+ valmistajaa, nolla seisokkeja._
### 🌐 Internacionalização (i18n)
OmniRoute-kojelauta tukee **múltiplos idiomas**. Atualmente disponível em:
| Idioma | Código | Tila |
| ----------------------- | ------- | -------------- |
| 🇺🇸 englanti | `en` | ✅ Täydellinen |
| 🇧🇷 Português (Brasilia) | `pt-BR` | ✅ Täydellinen |
**Para trocar o idioma:** Clique no seletor de idioma (🇺🇸 FI) no header do dashboard → selecione o idioma desejado.
**Para adicionar um novo idioma:**
1. Itke `src/i18n/messages/{codigo}.json` baseado em `en.json`
2. Adicione o código em `src/i18n/config.ts``LOCALES` ja `LANGUAGES`
3. Reinicie o servidor
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Docker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ IA:n tuottajaa** Claude, GPT, Gemini, Llama, Qwen, DeepSeek, e mais
- **Roteamento inteligente** — Varastoautomatico entre provedores
- **Tradução de formato** — OpenAI ↔ Claude ↔ Gemini automaticamente
- **Multi-conta** — Múltiplas contas por provedor com seleção inteligente
- **Cache semântico** - Reduz custos e latência
- **OAuth automático** — Tokens renovam automaticamente
- **Yhdistelmät personoidut** - 6 estratégias de roteamento
- **Dashboard Completo** - Monitoramento, lokit, analyysit, konfiguraatiot
- **CLI-työkalut** — Määritä Claude Code, Codex, Cursor, Cline com um clique
- **100 % TypeScript** - Código limpo e tipado
### 📖 Documentação
| Documento | Kuvaus |
| ----------------------------------------------- | ------------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedorit, yhdistelmät, CLI, käyttöönotto |
| [Referência da API](docs/API_REFERENCE.md) | Todos os päätepisteet com exemplos |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do system |
| [Contribuição](CONTRIBUTING.md) | Desenvolvimento e -ohjeiden asennus |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Täydellinen versio: VM + nginx + Cloudflare |
### 📧 Tuki
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tire dúvidas, compartilhe dicas e fique atualizado.
- **Verkkosivusto**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Ongelmia**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Rakennettu ❤️-kehittäjille, jotka koodaavat 24/7</sub>
<br/>
+87 -129
View File
@@ -247,6 +247,32 @@ docker compose --profile cli up -d
---
---
## 🖥️ Application Bureau — Hors Ligne et Toujours Actif
> 🆕 **NOUVEAU !** OmniRoute est maintenant disponible en tant qu'**application de bureau native** pour Windows, macOS et Linux.
Exécutez OmniRoute en tant qu'application de bureau autonome — sans terminal, sans navigateur, sans internet requis pour les modèles locaux.
- 🖥️ **Fenêtre Native** — Fenêtre dédiée avec intégration dans la barre d'état système
- 🔄 **Démarrage Automatique** — Lancez OmniRoute à la connexion système
- 🔔 **Notifications Natives** — Alertes pour l'épuisement de quota ou les problèmes
- ⚡ **Installation en Un Clic** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Mode Hors Ligne** — Fonctionne entièrement hors ligne avec serveur intégré
```bash
npm run electron:dev # Mode développement
npm run electron:build # Plateforme actuelle
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Documentation complète : [`electron/README.md`](electron/README.md)
---
## 💰 Aperçu des tarifs
| Tier | Fournisseur | Coût | Réinitialisation | Idéal pour |
@@ -272,67 +298,6 @@ docker compose --profile cli up -d
---
## 🎯 Cas d'utilisation
### Cas 1 : « J'ai un abonnement Claude Pro »
**Problème :** Le quota expire inutilisé, limites de débit pendant le codage intensif
```
Combo : "maximize-claude"
1. cc/claude-opus-4-6 (utiliser l'abonnement au maximum)
2. glm/glm-4.7 (backup économique quand le quota est épuisé)
3. if/kimi-k2-thinking (fallback d'urgence gratuit)
Coût mensuel : 20 $ (abonnement) + ~5 $ (backup) = 25 $ au total
vs. 20 $ + atteindre les limites = frustration
```
### Cas 2 : « Je veux zéro coût »
**Problème :** Impossible de payer des abonnements, besoin d'IA fiable pour coder
```
Combo : "free-forever"
1. gc/gemini-3-flash (180K gratuits/mois)
2. if/kimi-k2-thinking (illimité gratuit)
3. qw/qwen3-coder-plus (illimité gratuit)
Coût mensuel : 0 $
Qualité : Modèles prêts pour la production
```
### Cas 3 : « Je dois coder 24/7, sans interruption »
**Problème :** Délais serrés, ne peut pas se permettre de temps d'arrêt
```
Combo : "always-on"
1. cc/claude-opus-4-6 (meilleure qualité)
2. cx/gpt-5.2-codex (deuxième abonnement)
3. glm/glm-4.7 (économique, reset quotidien)
4. minimax/MiniMax-M2.1 (le moins cher, reset 5h)
5. if/kimi-k2-thinking (gratuit illimité)
Résultat : 5 niveaux de fallback = zéro temps d'arrêt
```
### Cas 4 : « Je veux l'IA GRATUITE dans OpenClaw »
**Problème :** Besoin d'assistant IA dans les apps de messagerie, entièrement gratuit
```
Combo : "openclaw-free"
1. if/glm-4.7 (illimité gratuit)
2. if/minimax-m2.1 (illimité gratuit)
3. if/kimi-k2-thinking (illimité gratuit)
Coût mensuel : 0 $
Accès via : WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Fonctionnalités principales
### 🧠 Routage & Intelligence
@@ -474,6 +439,67 @@ Traduction transparente entre les formats :
---
## 🎯 Cas d'utilisation
### Cas 1 : « J'ai un abonnement Claude Pro »
**Problème :** Le quota expire inutilisé, limites de débit pendant le codage intensif
```
Combo : "maximize-claude"
1. cc/claude-opus-4-6 (utiliser l'abonnement au maximum)
2. glm/glm-4.7 (backup économique quand le quota est épuisé)
3. if/kimi-k2-thinking (fallback d'urgence gratuit)
Coût mensuel : 20 $ (abonnement) + ~5 $ (backup) = 25 $ au total
vs. 20 $ + atteindre les limites = frustration
```
### Cas 2 : « Je veux zéro coût »
**Problème :** Impossible de payer des abonnements, besoin d'IA fiable pour coder
```
Combo : "free-forever"
1. gc/gemini-3-flash (180K gratuits/mois)
2. if/kimi-k2-thinking (illimité gratuit)
3. qw/qwen3-coder-plus (illimité gratuit)
Coût mensuel : 0 $
Qualité : Modèles prêts pour la production
```
### Cas 3 : « Je dois coder 24/7, sans interruption »
**Problème :** Délais serrés, ne peut pas se permettre de temps d'arrêt
```
Combo : "always-on"
1. cc/claude-opus-4-6 (meilleure qualité)
2. cx/gpt-5.2-codex (deuxième abonnement)
3. glm/glm-4.7 (économique, reset quotidien)
4. minimax/MiniMax-M2.1 (le moins cher, reset 5h)
5. if/kimi-k2-thinking (gratuit illimité)
Résultat : 5 niveaux de fallback = zéro temps d'arrêt
```
### Cas 4 : « Je veux l'IA GRATUITE dans OpenClaw »
**Problème :** Besoin d'assistant IA dans les apps de messagerie, entièrement gratuit
```
Combo : "openclaw-free"
1. if/glm-4.7 (illimité gratuit)
2. if/minimax-m2.1 (illimité gratuit)
3. if/kimi-k2-thinking (illimité gratuit)
Coût mensuel : 0 $
Accès via : WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Guide de configuration
<details>
@@ -754,74 +780,6 @@ Paramètres → Configuration API :
---
## 📊 Modèles disponibles
<details>
<summary><b>Voir tous les modèles disponibles</b></summary>
**Claude Code (`cc/`)** - Pro/Max :
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - GRATUIT :
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)** :
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - Crédits GRATUITS :
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ modèles sur [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0.6/1M :
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0.2/1M :
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - GRATUIT :
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - GRATUIT :
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - GRATUIT :
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ modèles :
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Tout modèle de [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Évaluations (Evals)
OmniRoute inclut un framework d'évaluation intégré pour tester la qualité des réponses LLM contre un golden set. Accès via **Analytics → Evals** dans le tableau de bord.
+137 -264
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — שער הבינה המלאכותית החינמית
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### לעולם אל תפסיק לקוד. ניתוב חכם לדגמי בינה מלאכותית **בחינם ובעלות נמוכה** עם חזרה אוטומטית.
_שרת ה-API האוניברסלי שלך - נקודת קצה אחת, 36+ ספקים, אפס זמן השבתה._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 תמחור במבט חטוף
| שכבה | ספק | עלות | איפוס מכסה | הטוב ביותר עבור |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 מקרי שימוש
### מקרה 1: "יש לי מנוי לקלוד פרו"
**בעיה:** תוקף המכסה פג ללא שימוש, מגבלות תעריף במהלך קידוד כבד
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### מקרה 2: "אני רוצה עלות אפס"
**בעיה:** לא יכול להרשות לעצמו מנויים, צריך קידוד AI אמין
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### מקרה 3: "אני צריך קידוד 24/7, ללא הפרעות"
**בעיה:** מועדים, לא יכול להרשות לעצמו זמן השבתה
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### מקרה 4: "אני רוצה AI בחינם ב-OpenClaw"
**בעיה:** צריך עוזר בינה מלאכותית באפליקציות הודעות, בחינם לחלוטין
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 תכונות עיקריות
### 🧠 ניתוב ליבה ומודיעין
@@ -495,6 +456,67 @@ OmniRoute כולל מגרש משחקי מתרגמים מובנה רב עוצמה
---
## 🎯 מקרי שימוש
### מקרה 1: "יש לי מנוי לקלוד פרו"
**בעיה:** תוקף המכסה פג ללא שימוש, מגבלות תעריף במהלך קידוד כבד
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### מקרה 2: "אני רוצה עלות אפס"
**בעיה:** לא יכול להרשות לעצמו מנויים, צריך קידוד AI אמין
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### מקרה 3: "אני צריך קידוד 24/7, ללא הפרעות"
**בעיה:** מועדים, לא יכול להרשות לעצמו זמן השבתה
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### מקרה 4: "אני רוצה AI בחינם ב-OpenClaw"
**בעיה:** צריך עוזר בינה מלאכותית באפליקציות הודעות, בחינם לחלוטין
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 מדריך התקנה
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 דגמים זמינים
<details>
<summary><b>הצג את כל הדגמים הזמינים</b></summary>
**קוד קלוד (`cc/`)** - פרו/מקסימום:
- `cc/claude-opus-4-6`
- `cc/claude-sonnet-4-5-20250929`
- `cc/claude-haiku-4-5-20251001`
**קודקס (`cx/`)** - פלוס/יתרונות:
- `cx/gpt-5.2-codex`
- `cx/gpt-5.1-codex-max`
**Gemini CLI (`gc/`)** - בחינם:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - זיכויים בחינם:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ דגמים נוספים ב-[build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0.6/1 מיליון:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0.2/1 מיליון:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - בחינם:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - בחינם:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - בחינם:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ דגמים:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- כל דגם מ-[openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 הערכות (הערכות)
OmniRoute כולל מסגרת הערכה מובנית לבדיקת איכות תגובת LLM מול סט מוזהב. גש אליו דרך **Analytics → Evals** בלוח המחוונים.
@@ -866,7 +820,58 @@ OmniRoute כולל מסגרת הערכה מובנית לבדיקת איכות ת
---
## 🔐 OAuth em Servidor Remoto (הגדרת OAuth מרחוק)
## 🐛 פתרון בעיות
<details>
<summary><b>לחץ כדי להרחיב את המדריך לפתרון בעיות</b></summary>
**"מודל השפה לא סיפק הודעות"**
- מיצתה מכסת הספק ← בדוק את עוקב המכסות של לוח המחוונים
- פתרון: השתמש ב-combo fallback או עבור לשכבה זולה יותר
**הגבלת תעריפים**
- מכסת מנויים נגמרת ← Fallback ל-GLM/MiniMax
- הוסף שילוב: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**פג תוקפו של אסימון OAuth**
- רענון אוטומטי על ידי OmniRoute
- אם הבעיות נמשכות: לוח מחוונים ← ספק ← התחבר מחדש
**עלויות גבוהות**
- בדוק סטטיסטיקת שימוש בלוח המחוונים ← עלויות
- החלף את הדגם הראשי ל-GLM/MiniMax
- השתמש בשכבה חינמית (Gemini CLI, iFlow) עבור משימות לא קריטיות
**לוח המחוונים נפתח ביציאה שגויה**
- הגדר `PORT=20128` ו`NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**שגיאות סנכרון בענן**
- אמת `BASE_URL` נקודות למופע הריצה שלך
- אמת `CLOUD_URL` נקודות לנקודת הקצה הצפויה שלך בענן
- שמור על ערכי `NEXT_PUBLIC_*` מיושרים עם ערכי צד השרת
**הכניסה הראשונה לא עובדת**
- בדוק את `INITIAL_PASSWORD` ב-`.env`
- אם לא מוגדרת, סיסמת החלפה היא `123456`
**ללא יומני בקשות**
- הגדר `ENABLE_REQUEST_LOGS=true` ב-`.env`
**בדיקת חיבור מראה "לא חוקי" עבור ספקים תואמי OpenAI**
- ספקים רבים אינם חושפים נקודת קצה `/models`
- OmniRoute v1.0.6+ כולל אימות חוזר באמצעות השלמת צ'אט
- ודא שכתובת האתר הבסיסית כוללת את הסיומת `/v1`
### 🔐 OAuth em Servidor Remoto (הגדרת OAuth מרחוק)
<a name="oauth-em-servidor-remoto"></a>
@@ -957,59 +962,6 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
> פתרון עקיפת הבעיה או קוד אוטומטי של כתובת ה-URL או עצמאית להפנות את החשבון או לא.
---
## 🐛 פתרון בעיות
<details>
<summary><b>לחץ כדי להרחיב את המדריך לפתרון בעיות</b></summary>
**"מודל השפה לא סיפק הודעות"**
- מיצתה מכסת הספק ← בדוק את עוקב המכסות של לוח המחוונים
- פתרון: השתמש ב-combo fallback או עבור לשכבה זולה יותר
**הגבלת תעריפים**
- מכסת מנויים נגמרת ← Fallback ל-GLM/MiniMax
- הוסף שילוב: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**פג תוקפו של אסימון OAuth**
- רענון אוטומטי על ידי OmniRoute
- אם הבעיות נמשכות: לוח מחוונים ← ספק ← התחבר מחדש
**עלויות גבוהות**
- בדוק סטטיסטיקת שימוש בלוח המחוונים ← עלויות
- החלף את הדגם הראשי ל-GLM/MiniMax
- השתמש בשכבה חינמית (Gemini CLI, iFlow) עבור משימות לא קריטיות
**לוח המחוונים נפתח ביציאה שגויה**
- הגדר `PORT=20128` ו`NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**שגיאות סנכרון בענן**
- אמת `BASE_URL` נקודות למופע הריצה שלך
- אמת `CLOUD_URL` נקודות לנקודת הקצה הצפויה שלך בענן
- שמור על ערכי `NEXT_PUBLIC_*` מיושרים עם ערכי צד השרת
**הכניסה הראשונה לא עובדת**
- בדוק את `INITIAL_PASSWORD` ב-`.env`
- אם לא מוגדרת, סיסמת החלפה היא `123456`
**ללא יומני בקשות**
- הגדר `ENABLE_REQUEST_LOGS=true` ב-`.env`
**בדיקת חיבור מראה "לא חוקי" עבור ספקים תואמי OpenAI**
- ספקים רבים אינם חושפים נקודת קצה `/models`
- OmniRoute v1.0.6+ כולל אימות חוזר באמצעות השלמת צ'אט
- ודא שכתובת האתר הבסיסית כוללת את הסיומת `/v1`
</details>
---
@@ -1152,85 +1104,6 @@ gh release create v1.0.6 --title "v1.0.6" --generate-notes
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento intelligente עבור **מודלים של IA GRATUITOS e de baixo custo** com fallback automático.
_Seu proxy universal de API - נקודת קצה, 36+ בדיקות, אפס השבתה._
### 🌐 Internacionalização (i18n)
O לוח המחוונים של OmniRoute תומך ב-**רב ביטויים**. ניתנת הספק:
| אידיומה | קודיגו | סטטוס |
| -------------------- | ------- | ---------- |
| 🇺🇸 אנגלית | `en` | ✅ קומפלטו |
| 🇧🇷 פורטוגזית (ברזיל) | `pt-BR` | ✅ קומפלטו |
**למקרה של ביטוי:** לחץ על לא בחירה בשפה (🇺🇸 EN) ללא כותרת ללוח המחוונים ← בחירה בצורת ביטוי.
**לפרטים נוספים:**
1. Crie `src/i18n/messages/{codigo}.json` baseado em `en.json`
2. Adicone o código em `src/i18n/config.ts``LOCALES` e `LANGUAGES`
3. Reinicie o servidor
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 דוקר
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ provedores de IA** - קלוד, GPT, Gemini, Llama, Qwen, DeepSeek, e mais
- **Roteamento inteligente** - Fallback automático entre provedores
- **Tradução de formato** — OpenAI ↔ קלוד ↔ Gemini automaticamente
- **מולטי-קונטא** - Múltiplas contas por provedor com seleção intelligente
- **Cache semântico** — Reduz custos e latência
- **OAuth automático** — אסימונים renovam automaticamente
- **Combos personalizados** - 6 estratégias de roteamento
- **לוח המחוונים המלא** - מעקב, יומנים, ניתוחים, הגדרות
- **כלי CLI** - הגדר את קוד קלוד, Codex, Cursor, Cline com um clique
- **100% TypeScript** — קוד רגיל
### 📖 תיעוד
| דוקומנטו | תיאור |
| ----------------------------------------------- | ---------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | פרובדורים, שילובים, CLI, פריסה |
| [Referência da API](docs/API_REFERENCE.md) | Todos OS נקודות קצה com exemplos |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do sistema |
| [Contribuição](CONTRIBUTING.md) | התקנה של הנחיות והנחיות |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | גיאה מלאה: VM + nginx + Cloudflare |
### 📧 תמיכה
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tire dúvidas, compartilhe dicas e fique atualizado.
- **אתר**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **בעיות**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>נבנה עם ❤️ למפתחים שמקודדים 24/7</sub>
<br/>
+137 -264
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute Az ingyenes mesterséges intelligencia átjáró
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Soha ne hagyd abba a kódolást. Intelligens útválasztás **INGYENES és alacsony költségű mesterséges intelligencia modellekhez** automatikus visszaállítással.
_Az univerzális API-proxy egy végpont, 36+ szolgáltató, nulla állásidő._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Árazás egy pillantásra
| Tier | Szolgáltató | Költség | Kvóta visszaállítása | Legjobb a |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Használati esetek
### 1. eset: "Claude Pro előfizetésem van"
**Probléma:** A kvóta lejár, kihasználatlanul, sebességkorlátozások erős kódolás közben
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### 2. eset: "Nulla költséget akarok"
**Probléma:** Nem engedheti meg magának az előfizetést, megbízható mesterséges intelligencia kódolásra van szüksége
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### 3. eset: "24 órás kódolásra van szükségem, megszakítás nélkül"
**Probléma:** Határidők, nem engedheti meg magának az állásidőt
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### 4. eset: "INGYENES AI-t akarok az OpenClawban"
**Probléma:** AI-asszisztens szükséges az üzenetküldő alkalmazásokhoz, teljesen ingyenes
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Főbb jellemzők
### 🧠 Core Routing & Intelligence
@@ -495,6 +456,67 @@ Az OmniRoute egy erőteljes beépített fordítói játszóteret tartalmaz **4 m
---
## 🎯 Használati esetek
### 1. eset: "Claude Pro előfizetésem van"
**Probléma:** A kvóta lejár, kihasználatlanul, sebességkorlátozások erős kódolás közben
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### 2. eset: "Nulla költséget akarok"
**Probléma:** Nem engedheti meg magának az előfizetést, megbízható mesterséges intelligencia kódolásra van szüksége
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### 3. eset: "24 órás kódolásra van szükségem, megszakítás nélkül"
**Probléma:** Határidők, nem engedheti meg magának az állásidőt
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### 4. eset: "INGYENES AI-t akarok az OpenClawban"
**Probléma:** AI-asszisztens szükséges az üzenetküldő alkalmazásokhoz, teljesen ingyenes
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Beállítási útmutató
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Elérhető modellek
<details>
<summary><b>Az összes elérhető modell megtekintése</b></summary>
**Claude Code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `cc/claude-sonnet-4-5-20250929`
- `cc/claude-haiku-4-5-20251001`
**Kód (`cx/`)** - Plusz/Pro:
- `cx/gpt-5.2-codex`
- `cx/gpt-5.1-codex-max`
**Gemini CLI (`gc/`)** INGYENES:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub másodpilóta (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - INGYENES kreditek:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ további modell itt: [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - 0,6 USD/1 millió:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - 0,2 USD/1 millió:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** INGYENES:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - INGYENES:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** INGYENES:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ modell:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Bármelyik modell a [openrouter.ai/models](https://openrouter.ai/models) terméktől
</details>
---
## 🧪 Értékelések (Evals)
Az OmniRoute egy beépített értékelési keretrendszert tartalmaz az LLM-válasz minőségének tesztelésére egy aranykészlettel összehasonlítva. Az irányítópult **Analytics → Evals** menüpontjában érheti el.
@@ -866,7 +820,58 @@ Az előre feltöltött "OmniRoute Golden Set" 10 tesztesetet tartalmaz, amelyek
---
## 🔐 OAuth em Servidor Remoto (távoli OAuth beállítás)
## 🐛 Hibaelhárítás
<details>
<summary><b>Kattintson a hibaelhárítási útmutató kibontásához</b></summary>
**"A nyelvi modell nem adott üzenetet"**
- A szolgáltatói kvóta kimerült → Ellenőrizze az irányítópult kvótakövetőjét
- Megoldás: Használjon kombinált tartalékot, vagy váltson olcsóbb szintre
**Drátakorlát**
- Előfizetési kvóta lejárt → Tartalék a GLM/MiniMax-hoz
- Kombinó hozzáadása: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth token lejárt**
- Az OmniRoute automatikusan frissíti
- Ha a problémák továbbra is fennállnak: Irányítópult → Szolgáltató → Újracsatlakozás
**Magas költségek**
- Ellenőrizze a használati statisztikákat az Irányítópult → Költségek menüpontban
- Állítsa át az elsődleges modellt GLM/MiniMax-ra
- Használjon ingyenes réteget (Gemini CLI, iFlow) a nem kritikus feladatokhoz
**A műszerfal rossz porton nyílik meg**
- `PORT=20128` és `NEXT_PUBLIC_BASE_URL=http://localhost:20128` beállítása
**Felhő szinkronizálási hibák**
- Ellenőrizze, hogy `BASE_URL` mutat a futó példányra
- Ellenőrizzen `CLOUD_URL` pontot a várható felhő-végponthoz
- Tartsa az `NEXT_PUBLIC_*` értékeket a szerveroldali értékekkel összhangban
**Az első bejelentkezés nem működik**
- Ellenőrizze a `INITIAL_PASSWORD`-t itt: `.env`
- Ha nincs beállítva, a tartalék jelszó: `123456`
**Nincs kérésnapló**
- Állítsa be `ENABLE_REQUEST_LOGS=true` a `.env`-ban
**A csatlakozási teszt „Érvénytelen” üzenetet mutat az OpenAI-kompatibilis szolgáltatók esetében**
- Sok szolgáltató nem tesz közzé `/models` végpontot
- Az OmniRoute v1.0.6+ tartalmazza a tartalék érvényesítést a csevegés befejezésén keresztül
- Győződjön meg arról, hogy az alap URL tartalmazza a `/v1` utótagot
### 🔐 OAuth em Servidor Remoto (távoli OAuth beállítás)
<a name="oauth-em-servidor-remoto"></a>
@@ -957,59 +962,6 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
> Este workaround funciona porque o código de autorização na URL é válido independente do redirect ter carregado ou não.
---
## 🐛 Hibaelhárítás
<details>
<summary><b>Kattintson a hibaelhárítási útmutató kibontásához</b></summary>
**"A nyelvi modell nem adott üzenetet"**
- A szolgáltatói kvóta kimerült → Ellenőrizze az irányítópult kvótakövetőjét
- Megoldás: Használjon kombinált tartalékot, vagy váltson olcsóbb szintre
**Drátakorlát**
- Előfizetési kvóta lejárt → Tartalék a GLM/MiniMax-hoz
- Kombinó hozzáadása: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth token lejárt**
- Az OmniRoute automatikusan frissíti
- Ha a problémák továbbra is fennállnak: Irányítópult → Szolgáltató → Újracsatlakozás
**Magas költségek**
- Ellenőrizze a használati statisztikákat az Irányítópult → Költségek menüpontban
- Állítsa át az elsődleges modellt GLM/MiniMax-ra
- Használjon ingyenes réteget (Gemini CLI, iFlow) a nem kritikus feladatokhoz
**A műszerfal rossz porton nyílik meg**
- `PORT=20128` és `NEXT_PUBLIC_BASE_URL=http://localhost:20128` beállítása
**Felhő szinkronizálási hibák**
- Ellenőrizze, hogy `BASE_URL` mutat a futó példányra
- Ellenőrizzen `CLOUD_URL` pontot a várható felhő-végponthoz
- Tartsa az `NEXT_PUBLIC_*` értékeket a szerveroldali értékekkel összhangban
**Az első bejelentkezés nem működik**
- Ellenőrizze a `INITIAL_PASSWORD`-t itt: `.env`
- Ha nincs beállítva, a tartalék jelszó: `123456`
**Nincs kérésnapló**
- Állítsa be `ENABLE_REQUEST_LOGS=true` a `.env`-ban
**A csatlakozási teszt „Érvénytelen” üzenetet mutat az OpenAI-kompatibilis szolgáltatók esetében**
- Sok szolgáltató nem tesz közzé `/models` végpontot
- Az OmniRoute v1.0.6+ tartalmazza a tartalék érvényesítést a csevegés befejezésén keresztül
- Győződjön meg arról, hogy az alap URL tartalmazza a `/v1` utótagot
</details>
---
@@ -1152,85 +1104,6 @@ MIT-licenc a részletekért lásd: [LICENSE](LICENSE).
---
---
## 🇧🇷 OmniRoute — IA ingyenes átjáró
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento inteligente para **modelos de IA GRATUITOS e de baixo custo** com backback automatico.
_Seu proxy univerzális API um végpont, 36+ gyártó, nulla leállás._
### 🌐 Internacionalização (i18n)
O dashboard do OmniRoute támogatja a **múltiplos idiomas**. Atualmente disponível em:
| Idioma | Código | Állapot |
| --------------------- | ------- | ----------- |
| 🇺🇸 angol | `en` | ✅ Completo |
| 🇧🇷 Português (Brasil) | `pt-BR` | ✅ Completo |
**Para trocar o idioma:** Clique no seletor de idioma (🇺🇸 EN) no header do dashboard → Selectione o idioma desejado.
**Para adicionar um novo idioma:**
1. Sírj `src/i18n/messages/{codigo}.json` baseado em `en.json`
2. Adicione o código em `src/i18n/config.ts``LOCALES` e `LANGUAGES`
3. Reinicie o servidor
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Docker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ IA produkátor** Claude, GPT, Gemini, Llama, Qwen, DeepSeek, e mais
- **Roteamento inteligente** — Fallback automatico entre provedores
- **Tradução de formato** — OpenAI ↔ Claude ↔ Gemini automatamente
- **Multi-conta** — Múltiplas contas por provedor com seleção inteligente
- **Cache szemântico** Reduz custos e latência
- **OAuth automatico** — Tokens renovam automaticamente
- **Combos personalizados** - 6 estratégias de roteamento
- **Befejezett irányítópult** - Monitoring, naplók, elemzések, konfigurációk
- **CLI eszközök** — Claude Code, Codex, Cursor, Cline com um clique konfigurálása
- **100% TypeScript** Código limpo e tipado
### 📖 Documentação
| Documento | Leírás |
| ----------------------------------------------- | -------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, kombók, CLI, telepítés |
| [Referência da API](docs/API_REFERENCE.md) | Todos os végpontok com exemplos |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do sistema |
| [Contribuição](CONTRIBUTING.md) | Setup de desenvolvimento e Guidelines |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Teljes verzió: VM + nginx + Cloudflare |
### 📧 Támogatás
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tire dúvidas, compartilhe dicas e fique atualizado.
- **Webhely**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Problémák**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>A ❤️ segítségével készült a 24/7 kódoló fejlesztőknek</sub>
<br/>
+137 -264
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — Gerbang AI Gratis
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Jangan pernah berhenti membuat kode. Perutean cerdas ke **model AI GRATIS & berbiaya rendah** dengan fallback otomatis.
_Proksi API universal Anda — satu titik akhir, 36+ penyedia, tanpa waktu henti._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Sekilas tentang Harga
| Tingkat | Penyedia | Biaya | Reset Kuota | Terbaik Untuk |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Kasus Penggunaan
### Kasus 1: "Saya berlangganan Claude Pro"
**Masalah:** Kuota habis tanpa terpakai, batas kecepatan selama coding berat
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Kasus 2: "Saya ingin tanpa biaya"
**Masalah:** Tidak mampu berlangganan, memerlukan pengkodean AI yang andal
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Kasus 3: "Saya memerlukan pengkodean 24/7, tanpa gangguan"
**Masalah:** Tenggat waktu, tidak mampu membayar downtime
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Kasus 4: "Saya ingin AI GRATIS di OpenClaw"
**Masalah:** Membutuhkan asisten AI dalam aplikasi perpesanan, sepenuhnya gratis
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Fitur Utama
### 🧠 Perutean & Kecerdasan Inti
@@ -495,6 +456,67 @@ OmniRoute menyertakan Taman Bermain Penerjemah bawaan yang canggih dengan **4 mo
---
## 🎯 Kasus Penggunaan
### Kasus 1: "Saya berlangganan Claude Pro"
**Masalah:** Kuota habis tanpa terpakai, batas kecepatan selama coding berat
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Kasus 2: "Saya ingin tanpa biaya"
**Masalah:** Tidak mampu berlangganan, memerlukan pengkodean AI yang andal
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Kasus 3: "Saya memerlukan pengkodean 24/7, tanpa gangguan"
**Masalah:** Tenggat waktu, tidak mampu membayar downtime
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Kasus 4: "Saya ingin AI GRATIS di OpenClaw"
**Masalah:** Membutuhkan asisten AI dalam aplikasi perpesanan, sepenuhnya gratis
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Panduan Pengaturan
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Model yang Tersedia
<details>
<summary><b>Lihat semua model yang tersedia</b></summary>
**Kode Claude (`cc/`)** - Pro/Maks:
- `cc/claude-opus-4-6`
- `cc/claude-sonnet-4-5-20250929`
- `cc/claude-haiku-4-5-20251001`
**Kodeks (`cx/`)** - Plus/Pro:
- `cx/gpt-5.2-codex`
- `cx/gpt-5.1-codex-max`
**Gemini CLI (`gc/`)** - GRATIS:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**Copilot GitHub (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - Kredit GRATIS:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ model lainnya di [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0,6/1 juta:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0,2/1 juta:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - GRATIS:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - GRATIS:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - GRATIS:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ model:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Model apa pun dari [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Evaluasi (Eval)
OmniRoute menyertakan kerangka evaluasi bawaan untuk menguji kualitas respons LLM terhadap rangkaian emas. Akses melalui **Analytics → Evals** di dasbor.
@@ -866,7 +820,58 @@ OmniRoute menyertakan kerangka evaluasi bawaan untuk menguji kualitas respons LL
---
## 🔐 OAuth em Servidor Remoto (Pengaturan OAuth Jarak Jauh)
## 🐛 Pemecahan masalah
<details>
<summary><b>Klik untuk memperluas panduan pemecahan masalah</b></summary>
**"Model bahasa tidak memberikan pesan"**
- Kuota penyedia habis → Periksa dashboard pelacak kuota
- Solusi: Gunakan combo fallback atau beralih ke tier yang lebih murah
**Pembatasan tarif**
- Kuota berlangganan habis → Penggantian ke GLM/MiniMax
- Tambahkan kombo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Token OAuth kedaluwarsa**
- Disegarkan secara otomatis oleh OmniRoute
- Jika masalah terus berlanjut: Dasbor → Penyedia → Sambungkan kembali
**Biaya tinggi**
- Periksa statistik penggunaan di Dashboard → Biaya
- Ganti model utama ke GLM/MiniMax
- Gunakan tingkat gratis (Gemini CLI, iFlow) untuk tugas-tugas yang tidak penting
**Dasbor terbuka pada port yang salah**
- Tetapkan `PORT=20128` dan `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Kesalahan sinkronisasi cloud**
- Verifikasi `BASE_URL` poin ke instance Anda yang sedang berjalan
- Verifikasi `CLOUD_URL` poin ke titik akhir cloud yang Anda harapkan
- Jaga agar nilai `NEXT_PUBLIC_*` selaras dengan nilai sisi server
**Login pertama tidak berfungsi**
- Periksa `INITIAL_PASSWORD` di `.env`
- Jika tidak disetel, kata sandi cadangan adalah `123456`
**Tidak ada log permintaan**
- Tetapkan `ENABLE_REQUEST_LOGS=true` di `.env`
**Tes koneksi menunjukkan "Tidak Valid" untuk penyedia yang kompatibel dengan OpenAI**
- Banyak penyedia tidak mengekspos titik akhir `/models`
- OmniRoute v1.0.6+ menyertakan validasi fallback melalui penyelesaian obrolan
- Pastikan URL dasar menyertakan akhiran `/v1`
### 🔐 OAuth em Servidor Remoto (Pengaturan OAuth Jarak Jauh)
<a name="oauth-em-servidor-remoto"></a>
@@ -957,59 +962,6 @@ Jika Anda tidak ingin membuat kredensial pribadi sekarang, Anda mungkin dapat me
> Solusi ini berfungsi karena kode otorisasi pada URL valid secara independen untuk mengarahkan ulang ke akun atau tidak.
---
## 🐛 Pemecahan masalah
<details>
<summary><b>Klik untuk memperluas panduan pemecahan masalah</b></summary>
**"Model bahasa tidak memberikan pesan"**
- Kuota penyedia habis → Periksa dashboard pelacak kuota
- Solusi: Gunakan combo fallback atau beralih ke tier yang lebih murah
**Pembatasan tarif**
- Kuota berlangganan habis → Penggantian ke GLM/MiniMax
- Tambahkan kombo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Token OAuth kedaluwarsa**
- Disegarkan secara otomatis oleh OmniRoute
- Jika masalah terus berlanjut: Dasbor → Penyedia → Sambungkan kembali
**Biaya tinggi**
- Periksa statistik penggunaan di Dashboard → Biaya
- Ganti model utama ke GLM/MiniMax
- Gunakan tingkat gratis (Gemini CLI, iFlow) untuk tugas-tugas yang tidak penting
**Dasbor terbuka pada port yang salah**
- Tetapkan `PORT=20128` dan `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Kesalahan sinkronisasi cloud**
- Verifikasi `BASE_URL` poin ke instance Anda yang sedang berjalan
- Verifikasi `CLOUD_URL` poin ke titik akhir cloud yang Anda harapkan
- Jaga agar nilai `NEXT_PUBLIC_*` selaras dengan nilai sisi server
**Login pertama tidak berfungsi**
- Periksa `INITIAL_PASSWORD` di `.env`
- Jika tidak disetel, kata sandi cadangan adalah `123456`
**Tidak ada log permintaan**
- Tetapkan `ENABLE_REQUEST_LOGS=true` di `.env`
**Tes koneksi menunjukkan "Tidak Valid" untuk penyedia yang kompatibel dengan OpenAI**
- Banyak penyedia tidak mengekspos titik akhir `/models`
- OmniRoute v1.0.6+ menyertakan validasi fallback melalui penyelesaian obrolan
- Pastikan URL dasar menyertakan akhiran `/v1`
</details>
---
@@ -1152,85 +1104,6 @@ Lisensi MIT - lihat [LICENSE](LICENSE) untuk detailnya.
---
---
## 🇧🇷 OmniRoute — Gerbang IA Gratis
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Tidak ada kode apa pun. Roteamento cerdas untuk **model IA GRATIS dan hak istimewa** dengan fallback otomatis.
_Proksi universal API — um titik akhir, 36+ bukti, tanpa waktu henti._
### 🌐 Internasionalisasi (i18n)
Pada dasbor, lakukan OmniRoute mendukung **beberapa idiom**. Saat ini kami telah membagikannya:
| Idiom | Kode | Status |
| --------------------- | ------- | ---------- |
| 🇮🇩 Bahasa Inggris | `en` | ✅ Lengkap |
| 🇧🇷 Português (Brasil) | `pt-BR` | ✅ Lengkap |
**Untuk trocar o idioma:** Klik no selector de idioma (🇮🇩 EN) no header do dashboard → pilih idioma yang diinginkan.
**Untuk menambahkan idiom baru:**
1. Teriak `src/i18n/messages/{codigo}.json` berdasarkan `en.json`
2. Tambahan kode pada `src/i18n/config.ts``LOCALES` dan `LANGUAGES`
3. Memulai kembali server
### ⚡ Mulai Cepat
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 buruh pelabuhan
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Prinsip Fungsionalidades
- **36+ bukti IA** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek, dan lainnya
- **Roteamento inteligente** — Penggantian otomatis ke seluruh bukti
- **Penulisan format** — OpenAI ↔ Claude ↔ Gemini secara otomatis
- **Multi-konta** — Multi-konta berdasarkan pilihan yang cerdas
- **Cache semântico** — Memulihkan biaya dan latensi
- **OAuth otomatis** — Token diperbarui secara otomatis
- **Kombo yang dipersonalisasi** — 6 strategi roteamento
- **Dasbor lengkap** — Monitor, log, analisis, konfigurasi
- **Alat CLI** — Konfigurasikan Kode Claude, Codex, Kursor, Cline com um klik
- **100% TypeScript** — Kode limpo dan tipado
### 📖 Dokumentasi
| Dokumen | Deskripsi |
| ----------------------------------------------- | ---------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, kombo, CLI, terapkan |
| [Referência da API](docs/API_REFERENCE.md) | Semua titik akhir dengan contoh |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Masalah Umum dan Solusi |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura dan internal dalam sistem |
| [Contribuição](CONTRIBUTING.md) | Menyiapkan pedoman desenvolvimento |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Panduan lengkap: VM + nginx + Cloudflare |
### 📧 Dukungan
> 💬 **Entre to a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Ban dúvidas, compartilhe dicas dan fique aktualizado.
- **Situs Web**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Masalah**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Dibangun dengan ❤️ untuk pengembang yang membuat kode 24/7</sub>
<br/>
+75 -140
View File
@@ -144,6 +144,30 @@ docker run -d \
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 मूल्य निर्धारण एक नज़र में
| टियर | प्रदाता | लागत | कोटा रीसेट | के लिए सर्वश्रेष्ठ |
@@ -169,57 +193,6 @@ docker run -d \
---
## 🎯 उपयोग के मामले
### केस 1: "मेरे पास क्लाउड प्रो सदस्यता है"
**समस्या:** भारी कोडिंग के दौरान कोटा अप्रयुक्त, दर सीमा समाप्त हो जाता है
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### केस 2: "मुझे शून्य लागत चाहिए"
**समस्या:** सदस्यताएं वहन नहीं कर सकते, विश्वसनीय एआई कोडिंग की आवश्यकता है
### केस 3: "मुझे 24/7 कोडिंग चाहिए, कोई रुकावट नहीं"
**समस्या:** समय सीमा, डाउनटाइम बर्दाश्त नहीं कर सकते
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### केस 4: "मुझे ओपनक्लॉ में मुफ़्त एआई चाहिए"
**समस्या:** मैसेजिंग ऐप्स में AI सहायक की आवश्यकता है, पूरी तरह से निःशुल्क
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 मुख्य विशेषताएं
### 🧠 कोर रूटिंग और इंटेलिजेंस
@@ -367,6 +340,57 @@ Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
---
## 🎯 उपयोग के मामले
### केस 1: "मेरे पास क्लाउड प्रो सदस्यता है"
**समस्या:** भारी कोडिंग के दौरान कोटा अप्रयुक्त, दर सीमा समाप्त हो जाता है
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### केस 2: "मुझे शून्य लागत चाहिए"
**समस्या:** सदस्यताएं वहन नहीं कर सकते, विश्वसनीय एआई कोडिंग की आवश्यकता है
### केस 3: "मुझे 24/7 कोडिंग चाहिए, कोई रुकावट नहीं"
**समस्या:** समय सीमा, डाउनटाइम बर्दाश्त नहीं कर सकते
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### केस 4: "मुझे ओपनक्लॉ में मुफ़्त एआई चाहिए"
**समस्या:** मैसेजिंग ऐप्स में AI सहायक की आवश्यकता है, पूरी तरह से निःशुल्क
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 सेटअप गाइड
<summary><b>💳 सदस्यता प्रदाता</b></summary>
@@ -592,95 +616,6 @@ Cost: $0 forever!
---
## 🔐 OAuth em सर्विडोर रेमोटो (रिमोट OAuth सेटअप)
<a name="oauth-em-servidor-remoto"></a>
> **⚠️ वीपीएस/डॉकर/सर्विडोर रिमोट पर ओमनीरूट का उपयोग करने के लिए महत्वपूर्ण**
### क्या आप एंटीग्रेविटी/जेमिनी सीएलआई के लिए OAuth का उपयोग कर रहे हैं?
प्रमाणित करने के लिए **एंटीग्रेविटी** और **मिथुन सीएलआई** का उपयोग करें **Google OAuth 2.0** का उपयोग करें। Google के लिए यह आवश्यक है कि `redirect_uri` का उपयोग बिना किसी प्रवाह के OAuth सेजा **exatamente** के माध्यम से किया जाए ताकि URIs को Google क्लाउड कंसोल के लिए पूर्व-आवेदन किया जा सके।
जैसा कि OAuth का प्रमाण है, कोई ओम्निरूट कैडस्ट्राड नहीं है ** `localhost`** के लिए एपेनास। एक सर्विडोर रिमोट (उदा: `https://omniroute.meuservidor.com`) पर ओमनीरूट का उपयोग कैसे करें, या Google एक प्रमाणीकरण कॉम को पुनः प्राप्त करता है:
### समाधान: OAuth को कॉन्फ़िगर करें
आपका सटीक विवरण **OAuth 2.0 क्लाइंट आईडी** आपके सर्वर पर यूआरआई के साथ Google क्लाउड कंसोल नहीं है।
#### पासो ए पासो
**1. Google क्लाउड कंसोल तक पहुंच**
अब्राहम: [https://console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials)
**2. नया OAuth 2.0 क्लाइंट आईडी देखें**
- उन्हें क्लिक करें **"+ क्रेडेंशियल बनाएं"** → **"OAuth क्लाइंट आईडी"**
- आवेदन टिप: **"वेब एप्लिकेशन"**
- नोम: एस्कोल्हा क्वाल्कर नोम (उदा: `OmniRoute Remote`)
**3. अधिकृत रीडायरेक्ट यूआरआई के रूप में एडिकियोन**
कोई शिकायत नहीं **"अधिकृत रीडायरेक्ट यूआरआई"**, आदि:
```
https://seu-servidor.com/callback
```
> स्थानापन्न `seu-servidor.com` अपने आईपी को अपने सर्वर पर रखें (इसमें एक आवश्यक पोर्ट भी शामिल है, उदाहरण के लिए: `http://45.33.32.156:20128/callback`)।
**4. साख के रूप में सहेजें और कॉपी करें**
एपोस क्रियर, Google द्वारा **क्लाइंट आईडी** और **क्लाइंट सीक्रेट**
**5. परिवेश परिवर्तन** के रूप में कॉन्फ़िगर करें
कोई `.env` नहीं (आप डॉकर के परिवेश को कैसे बदल सकते हैं):
```bash
# Para Antigravity:
ANTIGRAVITY_OAUTH_CLIENT_ID=seu-client-id.apps.googleusercontent.com
ANTIGRAVITY_OAUTH_CLIENT_SECRET=GOCSPX-seu-secret
# Para Gemini CLI:
GEMINI_OAUTH_CLIENT_ID=seu-client-id.apps.googleusercontent.com
GEMINI_OAUTH_CLIENT_SECRET=GOCSPX-seu-secret
GEMINI_CLI_OAUTH_CLIENT_SECRET=GOCSPX-seu-secret
```
**6. ओम्निरूट का नवीनीकरण**
```bash
# Se usando npm:
npm run dev
# Se usando Docker:
docker restart omniroute
```
**7. नए सिरे से संपर्क करें**
डैशबोर्ड → प्रदाता → एंटीग्रेविटी (या जेमिनी सीएलआई) → OAuth
`https://seu-servidor.com/callback` और एक प्रमाणीकरण कार्य के लिए Google पुनर्निर्देशन।
---
### वर्कअराउंड टेम्पोरैरियो (सेम कॉन्फिगरेशन क्रेडेंशियल प्रोप्रियास)
यदि आप पहले से ही उचित क्रेडेंशियल प्राप्त नहीं करना चाहते हैं, तो आपके लिए फ्लक्सो का उपयोग करना संभव है **यूआरएल का मैनुअल**:
1. Google पर स्वचालित URL का उपयोग करके ओम्निरूट का उपयोग करें
2. ऑटोरिज़ार का लाभ, `localhost` के लिए Google पुनर्निर्देशन (यदि कोई सर्वर रिमोट नहीं है)
3. **एक यूआरएल को पूरा कॉपी करें** अपने ब्राउजर से दोबारा डाउनलोड करें (मुझे लगता है कि एक पेज अभी भी उपलब्ध है)
4. ओम्निरूट से जुड़ने के लिए कोई भी यूआरएल नहीं है
5. उन्हें क्लिक करें **"कनेक्ट"**
> यह समाधान यूआरएल को स्वचालित रूप से डाउनलोड करने के लिए काम कर रहा है और आपके द्वारा किए गए रीडायरेक्ट को स्वतंत्र रूप से वैध बनाता है।
---
## 🐛 समस्या निवारण
<summary><b>समस्या निवारण मार्गदर्शिका का विस्तार करने के लिए क्लिक करें</b></summary>
+85 -129
View File
@@ -247,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Panoramica Prezzi
| Tier | Provider | Costo | Reset Quota | Ideale Per |
@@ -272,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Casi d'Uso
### Caso 1: "Ho un abbonamento Claude Pro"
**Problema:** La quota scade inutilizzata, limiti di rate durante la programmazione intensa
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (usa l'abbonamento al massimo)
2. glm/glm-4.7 (backup economico quando la quota è esaurita)
3. if/kimi-k2-thinking (fallback d'emergenza gratuito)
Costo mensile: $20 (abbonamento) + ~$5 (backup) = $25 totale
vs. $20 + sbattere contro i limiti = frustrazione
```
### Caso 2: "Voglio costo zero"
**Problema:** Non può permettersi abbonamenti, ha bisogno di IA affidabile per programmare
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K gratis/mese)
2. if/kimi-k2-thinking (illimitato gratis)
3. qw/qwen3-coder-plus (illimitato gratis)
Costo mensile: $0
Qualità: Modelli pronti per la produzione
```
### Caso 3: "Devo programmare 24/7, senza interruzioni"
**Problema:** Scadenze strette, non può permettersi downtime
```
Combo: "always-on"
1. cc/claude-opus-4-6 (migliore qualità)
2. cx/gpt-5.2-codex (secondo abbonamento)
3. glm/glm-4.7 (economico, reset giornaliero)
4. minimax/MiniMax-M2.1 (più economico, reset 5h)
5. if/kimi-k2-thinking (gratuito illimitato)
Risultato: 5 livelli di fallback = zero downtime
```
### Caso 4: "Voglio IA GRATUITA in OpenClaw"
**Problema:** Ha bisogno di assistente IA nelle app di messaggistica, completamente gratuito
```
Combo: "openclaw-free"
1. if/glm-4.7 (illimitato gratis)
2. if/minimax-m2.1 (illimitato gratis)
3. if/kimi-k2-thinking (illimitato gratis)
Costo mensile: $0
Accesso via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Funzionalità Principali
### 🧠 Routing & Intelligenza
@@ -474,6 +437,67 @@ Traduzione trasparente tra formati:
---
## 🎯 Casi d'Uso
### Caso 1: "Ho un abbonamento Claude Pro"
**Problema:** La quota scade inutilizzata, limiti di rate durante la programmazione intensa
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (usa l'abbonamento al massimo)
2. glm/glm-4.7 (backup economico quando la quota è esaurita)
3. if/kimi-k2-thinking (fallback d'emergenza gratuito)
Costo mensile: $20 (abbonamento) + ~$5 (backup) = $25 totale
vs. $20 + sbattere contro i limiti = frustrazione
```
### Caso 2: "Voglio costo zero"
**Problema:** Non può permettersi abbonamenti, ha bisogno di IA affidabile per programmare
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K gratis/mese)
2. if/kimi-k2-thinking (illimitato gratis)
3. qw/qwen3-coder-plus (illimitato gratis)
Costo mensile: $0
Qualità: Modelli pronti per la produzione
```
### Caso 3: "Devo programmare 24/7, senza interruzioni"
**Problema:** Scadenze strette, non può permettersi downtime
```
Combo: "always-on"
1. cc/claude-opus-4-6 (migliore qualità)
2. cx/gpt-5.2-codex (secondo abbonamento)
3. glm/glm-4.7 (economico, reset giornaliero)
4. minimax/MiniMax-M2.1 (più economico, reset 5h)
5. if/kimi-k2-thinking (gratuito illimitato)
Risultato: 5 livelli di fallback = zero downtime
```
### Caso 4: "Voglio IA GRATUITA in OpenClaw"
**Problema:** Ha bisogno di assistente IA nelle app di messaggistica, completamente gratuito
```
Combo: "openclaw-free"
1. if/glm-4.7 (illimitato gratis)
2. if/minimax-m2.1 (illimitato gratis)
3. if/kimi-k2-thinking (illimitato gratis)
Costo mensile: $0
Accesso via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Guida alla Configurazione
<details>
@@ -754,74 +778,6 @@ Impostazioni → Configurazione API:
---
## 📊 Modelli Disponibili
<details>
<summary><b>Vedi tutti i modelli disponibili</b></summary>
**Claude Code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - GRATUITO:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - Crediti GRATUITI:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ modelli su [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0.6/1M:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0.2/1M:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - GRATUITO:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - GRATUITO:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - GRATUITO:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ modelli:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Qualsiasi modello da [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Valutazioni (Evals)
OmniRoute include un framework di valutazione integrato per testare la qualità delle risposte LLM contro un golden set. Accesso via **Analytics → Evals** nella dashboard.
+137 -183
View File
@@ -247,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ デスクトップアプリ — オフライン&常時稼働
> 🆕 **新機能!** OmniRouteが**ネイティブデスクトップアプリケーション**としてWindows、macOS、Linuxで利用可能になりました。
- 🖥️ **ネイティブウィンドウ** — システムトレイ統合付きの専用ウィンドウ
- 🔄 **自動起動** — システムログイン時にOmniRouteを起動
- 🔔 **ネイティブ通知** — クォータ枯渇やプロバイダー問題のアラート
- ⚡ **ワンクリックインストール** — NSIS (Windows)、DMG (macOS)、AppImage (Linux)
- 🌐 **オフラインモード** — 内蔵サーバーで完全オフライン動作
```bash
npm run electron:dev # 開発モード
npm run electron:build # 現在のプラットフォーム
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 完全なドキュメント:[`electron/README.md`](electron/README.md)
---
## 💰 価格の概要
| 階層 | プロバイダー | コスト | クォータのリセット | 最適な用途 |
@@ -272,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 使用例
### ケース 1: 「Claude Pro サブスクリプションを持っています」
**問題:** 大量のコーディング中にクォータが使用されずに期限切れになり、レート制限が発生する
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### ケース 2: 「コストをゼロにしたい」
**問題:** サブスクリプションを購入する余裕がないため、信頼性の高い AI コーディングが必要です
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### ケース 3: 「24 時間年中無休でコーディングが必要で、中断はありません」
**問題:** 締め切りが迫っており、ダウンタイムを許すことができません
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### ケース 4: 「OpenClaw に無料の AI が欲しい」
**問題:** メッセージング アプリには AI アシスタントが必要ですが、完全に無料です
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 主な機能
### 🧠 コアルーティングとインテリジェンス
@@ -493,6 +456,67 @@ OmniRoute には、API 翻訳のデバッグ、テスト、監視のための **
---
## 🎯 使用例
### ケース 1: 「Claude Pro サブスクリプションを持っています」
**問題:** 大量のコーディング中にクォータが使用されずに期限切れになり、レート制限が発生する
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### ケース 2: 「コストをゼロにしたい」
**問題:** サブスクリプションを購入する余裕がないため、信頼性の高い AI コーディングが必要です
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### ケース 3: 「24 時間年中無休でコーディングが必要で、中断はありません」
**問題:** 締め切りが迫っており、ダウンタイムを許すことができません
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### ケース 4: 「OpenClaw に無料の AI が欲しい」
**問題:** メッセージング アプリには AI アシスタントが必要ですが、完全に無料です
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 セットアップガイド
<details>
@@ -772,74 +796,6 @@ Settings → API Configuration:
---
## 📊 利用可能なモデル
<details>
<summary><b>利用可能なモデルをすべて表示</b></summary>
**クロード コード (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `cc/claude-sonnet-4-5-20250929`
- `cc/claude-haiku-4-5-20251001`
**コーデックス (`cx/`)** - プラス/プロ:
- `cx/gpt-5.2-codex`
- `cx/gpt-5.1-codex-max`
**Gemini CLI (`gc/`)** - 無料:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub コパイロット (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - 無料クレジット:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- [build.nvidia.com](https://build.nvidia.com) には 50 以上のモデル
**GLM (`glm/`)** - 0.6 ドル/100 万:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0.2/100 万:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - 無料:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**クウェン (`qw/`)** - 無料:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**キロ (`kr/`)** - 無料:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100 以上のモデル:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- [openrouter.ai/models](https://openrouter.ai/models) の任意のモデル
</details>
---
## 🧪 評価 (Evals)
OmniRoute には、ゴールデン セットに対して LLM 応答品質をテストするための評価フレームワークが組み込まれています。ダッシュボードの **Analytics → Evals** からアクセスします。
@@ -863,7 +819,58 @@ OmniRoute には、ゴールデン セットに対して LLM 応答品質をテ
---
## 🔐 サーバーリモートの OAuth (リモート OAuth セットアップ)
## 🐛 トラブルシューティング
<details>
<summary><b>クリックしてトラブルシューティング ガイドを展開</b></summary>
**「言語モデルがメッセージを提供しませんでした」**
- プロバイダー クォータが枯渇した → ダッシュボード クォータ トラッカーを確認してください
- 解決策: コンボフォールバックを使用するか、より安価なレベルに切り替える
**レート制限**
- サブスクリプション クォータ アウト → GLM/MiniMax へのフォールバック
- コンボを追加: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth トークンの有効期限が切れました**
- OmniRouteによる自動更新
- 問題が解決しない場合: ダッシュボード → プロバイダー → 再接続
**高コスト**
- [ダッシュボード] → [コスト] で使用状況の統計を確認します。
- プライマリ モデルを GLM/MiniMax に切り替えます
- 重要ではないタスクには無料枠 (Gemini CLI、iFlow) を使用する
**ダッシュボードが間違ったポートで開きます**
- `PORT=20128` および `NEXT_PUBLIC_BASE_URL=http://localhost:20128` を設定します
**クラウド同期エラー**
- `BASE_URL` が実行中のインスタンスを指していることを確認します
- `CLOUD_URL` が予想されるクラウド エンドポイントを指していることを確認します
- `NEXT_PUBLIC_*` 値をサーバー側の値と一致させます。
**最初のログインが機能しない**
- `.env``INITIAL_PASSWORD` を確認してください
- 設定されていない場合、フォールバック パスワードは `123456` です
**リクエストログなし**
- `.env``ENABLE_REQUEST_LOGS=true` を設定します
**OpenAI 互換プロバイダーの接続テストで「無効」と表示される**
- 多くのプロバイダーは `/models` エンドポイントを公開していません
- OmniRoute v1.0.6+ には、チャット完了によるフォールバック検証が含まれています
- ベース URL に `/v1` サフィックスが含まれていることを確認してください
### 🔐 サーバーリモートの OAuth (リモート OAuth セットアップ)
<a name="oauth-em-servidor-remoto"></a>
@@ -954,59 +961,6 @@ docker restart omniroute
> 自動回避策の機能は URL から独立してリダイレクトされます。
---
## 🐛 トラブルシューティング
<details>
<summary><b>クリックしてトラブルシューティング ガイドを展開</b></summary>
**「言語モデルがメッセージを提供しませんでした」**
- プロバイダー クォータが枯渇した → ダッシュボード クォータ トラッカーを確認してください
- 解決策: コンボフォールバックを使用するか、より安価なレベルに切り替える
**レート制限**
- サブスクリプション クォータ アウト → GLM/MiniMax へのフォールバック
- コンボを追加: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth トークンの有効期限が切れました**
- OmniRouteによる自動更新
- 問題が解決しない場合: ダッシュボード → プロバイダー → 再接続
**高コスト**
- [ダッシュボード] → [コスト] で使用状況の統計を確認します。
- プライマリ モデルを GLM/MiniMax に切り替えます
- 重要ではないタスクには無料枠 (Gemini CLI、iFlow) を使用する
**ダッシュボードが間違ったポートで開きます**
- `PORT=20128` および `NEXT_PUBLIC_BASE_URL=http://localhost:20128` を設定します
**クラウド同期エラー**
- `BASE_URL` が実行中のインスタンスを指していることを確認します
- `CLOUD_URL` が予想されるクラウド エンドポイントを指していることを確認します
- `NEXT_PUBLIC_*` 値をサーバー側の値と一致させます。
**最初のログインが機能しない**
- `.env``INITIAL_PASSWORD` を確認してください
- 設定されていない場合、フォールバック パスワードは `123456` です
**リクエストログなし**
- `.env``ENABLE_REQUEST_LOGS=true` を設定します
**OpenAI 互換プロバイダーの接続テストで「無効」と表示される**
- 多くのプロバイダーは `/models` エンドポイントを公開していません
- OmniRoute v1.0.6+ には、チャット完了によるフォールバック検証が含まれています
- ベース URL に `/v1` サフィックスが含まれていることを確認してください
</details>
---
+137 -264
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — 무료 AI 게이트웨이
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### 코딩을 멈추지 마세요. 자동 폴백을 통해 **무료 및 저가형 AI 모델**로 스마트 라우팅합니다.
_범용 API 프록시 — 하나의 엔드포인트, 36개 이상의 공급자, 가동 중지 시간 없음._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ 데스크톱 앱 — 오프라인 & 상시 가동
> 🆕 **새 기능!** OmniRoute가 Windows, macOS, Linux용 **네이티브 데스크톱 앱**으로 출시되었습니다.
- 🖥️ **네이티브 윈도우** — 시스템 트레이 통합 전용 창
- 🔄 **자동 시작** — 시스템 로그인 시 OmniRoute 실행
- 🔔 **네이티브 알림** — 할당량 소진 또는 공급자 문제 알림
- ⚡ **원클릭 설치** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **오프라인 모드** — 내장 서버로 완전 오프라인 작동
```bash
npm run electron:dev # 개발 모드
npm run electron:build # 현재 플랫폼
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 전체 문서: [`electron/README.md`](electron/README.md)
---
## 💰 가격 한눈에 보기
| 계층 | 공급자 | 비용 | 할당량 재설정 | 최고의 대상 |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 사용 사례
### 사례 1: "Claude Pro를 구독하고 있습니다."
**문제:** 할당량은 사용되지 않은 상태로 만료되며, 코딩 작업이 많은 동안 속도 제한이 발생합니다.
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### 사례 2: "비용이 0이길 원합니다"
**문제:** 구독료를 감당할 수 없고 안정적인 AI 코딩이 필요함
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### 사례 3: "중단 없이 연중무휴 코딩이 필요합니다."
**문제:** 마감일, 가동 중지 시간을 감당할 수 없음
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### 사례 4: "OpenClaw에서 무료 AI를 원합니다"
**문제:** 메시징 앱에 AI 도우미가 필요하며 완전 무료입니다.
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 주요 기능
### 🧠 코어 라우팅 및 인텔리전스
@@ -495,6 +456,67 @@ OmniRoute에는 API 번역 디버깅, 테스트 및 모니터링을 위한 **4
---
## 🎯 사용 사례
### 사례 1: "Claude Pro를 구독하고 있습니다."
**문제:** 할당량은 사용되지 않은 상태로 만료되며, 코딩 작업이 많은 동안 속도 제한이 발생합니다.
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### 사례 2: "비용이 0이길 원합니다"
**문제:** 구독료를 감당할 수 없고 안정적인 AI 코딩이 필요함
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### 사례 3: "중단 없이 연중무휴 코딩이 필요합니다."
**문제:** 마감일, 가동 중지 시간을 감당할 수 없음
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### 사례 4: "OpenClaw에서 무료 AI를 원합니다"
**문제:** 메시징 앱에 AI 도우미가 필요하며 완전 무료입니다.
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 설정 가이드
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 사용 가능한 모델
<details>
<summary><b>사용 가능한 모든 모델 보기</b></summary>
**Claude 코드(`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `cc/claude-sonnet-4-5-20250929`
- `cc/claude-haiku-4-5-20251001`
**코덱스(`cx/`)** - 플러스/프로:
- `cx/gpt-5.2-codex`
- `cx/gpt-5.1-codex-max`
**Gemini CLI(`gc/`)** - 무료:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub 부조종사(`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM(`nvidia/`)** - 무료 크레딧:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- [build.nvidia.com](https://build.nvidia.com)의 50개 이상의 모델
**GLM(`glm/`)** - $0.6/1M:
- `glm/glm-4.7`
**MiniMax(`minimax/`)** - $0.2/1M:
- `minimax/MiniMax-M2.1`
**iFlow(`if/`)** - 무료:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen(`qw/`)** - 무료:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**키로(`kr/`)** - 무료:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter(`or/`)** - 100개 이상의 모델:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- [openrouter.ai/models](https://openrouter.ai/models)의 모든 모델
</details>
---
## 🧪 평가(Evals)
OmniRoute에는 골든 세트에 대해 LLM 응답 품질을 테스트하기 위한 내장 평가 프레임워크가 포함되어 있습니다. 대시보드의 **분석 → 평가**를 통해 액세스하세요.
@@ -866,7 +820,58 @@ OmniRoute에는 골든 세트에 대해 LLM 응답 품질을 테스트하기 위
---
## 🔐 OAuth em Servidor Remoto(원격 OAuth 설정)
## 🐛 문제 해결
<details>
<summary><b>문제 해결 가이드를 확장하려면 클릭하세요</b></summary>
**"언어 모델이 메시지를 제공하지 않았습니다"**
- 공급자 할당량 소진 → 대시보드 할당량 추적기 확인
- 해결 방법: 콤보 폴백을 사용하거나 더 저렴한 계층으로 전환하세요.
**비율 제한**
- 구독 할당량 초과 → GLM/MiniMax로 대체
- 콤보 추가: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth 토큰이 만료되었습니다**
- OmniRoute에 의해 자동 새로고침
- 문제가 지속되는 경우: Dashboard → Provider → Reconnect
**높은 비용**
- 대시보드 → 비용에서 사용 통계를 확인하세요.
- 기본 모델을 GLM/MiniMax로 전환
- 중요하지 않은 작업에는 무료 계층(Gemini CLI, iFlow)을 사용합니다.
**대시보드가 잘못된 포트에서 열립니다**
- `PORT=20128``NEXT_PUBLIC_BASE_URL=http://localhost:20128` 설정
**클라우드 동기화 오류**
- `BASE_URL`이 실행 중인 인스턴스를 가리키는지 확인합니다.
- `CLOUD_URL`이 예상 클라우드 엔드포인트를 가리키는지 확인하세요.
- `NEXT_PUBLIC_*` 값을 서버측 값과 일치하도록 유지합니다.
**첫 번째 로그인이 작동하지 않습니다**
- `.env`에서 `INITIAL_PASSWORD`을 확인하세요.
- 설정되지 않은 경우 대체 비밀번호는 `123456`입니다.
**요청 로그 없음**
- `.env``ENABLE_REQUEST_LOGS=true`을 설정합니다.
**OpenAI 호환 공급자에 대한 연결 테스트에서 "잘못됨"이 표시됩니다**
- 많은 공급자가 `/models` 엔드포인트를 노출하지 않습니다.
- OmniRoute v1.0.6+에는 채팅 완료를 통한 대체 검증이 포함되어 있습니다.
- 기본 URL에 `/v1` 접미사가 포함되어 있는지 확인하세요.
### 🔐 OAuth em Servidor Remoto(원격 OAuth 설정)
<a name="oauth-em-servidor-remoto"></a>
@@ -957,59 +962,6 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
> 이 해결 방법은 URL을 통해 자동으로 코드를 확인하거나 독립적으로 리디렉션할 수 있도록 하는 것입니다.
---
## 🐛 문제 해결
<details>
<summary><b>문제 해결 가이드를 확장하려면 클릭하세요</b></summary>
**"언어 모델이 메시지를 제공하지 않았습니다"**
- 공급자 할당량 소진 → 대시보드 할당량 추적기 확인
- 해결 방법: 콤보 폴백을 사용하거나 더 저렴한 계층으로 전환하세요.
**비율 제한**
- 구독 할당량 초과 → GLM/MiniMax로 대체
- 콤보 추가: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth 토큰이 만료되었습니다**
- OmniRoute에 의해 자동 새로고침
- 문제가 지속되는 경우: Dashboard → Provider → Reconnect
**높은 비용**
- 대시보드 → 비용에서 사용 통계를 확인하세요.
- 기본 모델을 GLM/MiniMax로 전환
- 중요하지 않은 작업에는 무료 계층(Gemini CLI, iFlow)을 사용합니다.
**대시보드가 잘못된 포트에서 열립니다**
- `PORT=20128``NEXT_PUBLIC_BASE_URL=http://localhost:20128` 설정
**클라우드 동기화 오류**
- `BASE_URL`이 실행 중인 인스턴스를 가리키는지 확인합니다.
- `CLOUD_URL`이 예상 클라우드 엔드포인트를 가리키는지 확인하세요.
- `NEXT_PUBLIC_*` 값을 서버측 값과 일치하도록 유지합니다.
**첫 번째 로그인이 작동하지 않습니다**
- `.env`에서 `INITIAL_PASSWORD`을 확인하세요.
- 설정되지 않은 경우 대체 비밀번호는 `123456`입니다.
**요청 로그 없음**
- `.env``ENABLE_REQUEST_LOGS=true`을 설정합니다.
**OpenAI 호환 공급자에 대한 연결 테스트에서 "잘못됨"이 표시됩니다**
- 많은 공급자가 `/models` 엔드포인트를 노출하지 않습니다.
- OmniRoute v1.0.6+에는 채팅 완료를 통한 대체 검증이 포함되어 있습니다.
- 기본 URL에 `/v1` 접미사가 포함되어 있는지 확인하세요.
</details>
---
@@ -1152,85 +1104,6 @@ MIT 라이선스 - 자세한 내용은 [LICENSE](LICENSE)을 참조하세요.
---
---
## 🇧🇷 OmniRoute — IA 무료 게이트웨이
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. **IA 무료 모델 및 사용자 정의**가 자동 대체 기능으로 지능화되었습니다.
_Seu 프록시 범용 API — 음 엔드포인트, 36개 이상의 Prodoores, 가동 중지 시간 없음._
### 🌐 국제화(i18n)
O 대시보드는 OmniRoute를 지원하여 **다양한 관용어**를 지원합니다. 불만이 있는 경우:
| 관용구 | 코디고 | 상태 |
| --------------------- | ------- | ------- |
| 🇺🇸 영어 | `en` | ✅ 완료 |
| 🇧🇷 포르투갈어(브라질) | `pt-BR` | ✅ 완료 |
**Para trocar o idioma:** Clique no seletor de idioma(🇺🇸 EN) 헤더 없음 대시보드 → selecione o idioma desejado.
**추가적인 표현:**
1. `src/i18n/messages/{codigo}.json` 소리 지르기 `en.json` 기반으로
2. `src/i18n/config.ts``LOCALES` e `LANGUAGES` 코드를 사용하세요.
3. Reinicie o servidor
### ⚡ 이니시오 라피도
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 도커
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36개 이상의 IA 인증** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek 등
- **지능형 회전** — 예비 자동 대체
- **Tradução de formato** — OpenAI ⇔ Claude ⇔ Gemini 자동 번역
- **다중 연결** — 지능적인 선택을 통해 입증된 여러 콘타스
- **캐시 의미** — Reduz custos and latência
- **OAuth 자동** — 토큰 자동 업데이트
- **맞춤형 콤보** — 6가지 기본 전략
- **대시보드 완료** — 모니터링, 로그, 분석, 구성
- **CLI 도구** — Claude Code, Codex, Cursor, Cline com um clique 구성
- **100% TypeScript** — Código limpo etipado
### 📖 문서
| 도큐멘토 | 설명 |
| ----------------------------------------------- | ------------------------------------ |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedore, 콤보, CLI, 배포 |
| [Referência da API](docs/API_REFERENCE.md) | 예를 들어 Todos OS 엔드포인트 |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | 문제 및 솔루션 문제 |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do sistema |
| [Contribuição](CONTRIBUTING.md) | 자유 의지 설정 지침 |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | 완전한 기능: VM + nginx + Cloudflare |
### 📧 지원
> 💬 **공동체에 참여하세요!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tire dúvidas, compartilhe dicas e fique atualizado.
- **웹사이트**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **문제**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub> 연중무휴</sub>을 코딩하는 개발자를 위해 ❤️으로 구축됨
<br/>
+177 -291
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — The Free AI Gateway
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Never stop coding. Smart routing to **FREE & low-cost AI models** with automatic fallback.
_Your universal API proxy — one endpoint, 36+ providers, zero downtime._
@@ -13,6 +11,20 @@ _Your universal API proxy — one endpoint, 36+ providers, zero downtime._
---
[![npm version](https://img.shields.io/npm/v/omniroute?color=cb3837&logo=npm)](https://www.npmjs.com/package/omniroute)
[![Docker Hub](https://img.shields.io/docker/v/diegosouzapw/omniroute?label=Docker%20Hub&logo=docker&color=2496ED)](https://hub.docker.com/r/diegosouzapw/omniroute)
[![License](https://img.shields.io/github/license/diegosouzapw/OmniRoute)](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
[![Website](https://img.shields.io/badge/Website-omniroute.online-blue?logo=google-chrome&logoColor=white)](https://omniroute.online)
[![WhatsApp](https://img.shields.io/badge/WhatsApp-Community-25D366?logo=whatsapp&logoColor=white)](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
[🌐 Website](https://omniroute.online) • [🚀 Quick Start](#-quick-start) • [💡 Features](#-key-features) • [📖 Docs](#-documentation) • [💰 Pricing](#-pricing-at-a-glance) • [💬 WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
🌐 **Available in:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](README.pt-BR.md) | 🇪🇸 [Español](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [Italiano](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [Magyar](README.hu.md) | 🇮🇩 [Bahasa Indonesia](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Nederlands](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Portugal)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Polski](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [Filipino](README.phi.md)
</div>
---
### 🤖 Free AI Provider for your favorite coding agents
_Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway for unlimited coding._
@@ -98,17 +110,15 @@ _Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway f
---
[![npm version](https://img.shields.io/npm/v/omniroute?color=cb3837&logo=npm)](https://www.npmjs.com/package/omniroute)
[![Docker Hub](https://img.shields.io/docker/v/diegosouzapw/omniroute?label=Docker%20Hub&logo=docker&color=2496ED)](https://hub.docker.com/r/diegosouzapw/omniroute)
[![License](https://img.shields.io/github/license/diegosouzapw/OmniRoute)](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
[![Website](https://img.shields.io/badge/Website-omniroute.online-blue?logo=google-chrome&logoColor=white)](https://omniroute.online)
[![WhatsApp](https://img.shields.io/badge/WhatsApp-Community-25D366?logo=whatsapp&logoColor=white)](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
## 📧 Support
[🌐 Website](https://omniroute.online) • [🚀 Quick Start](#-quick-start) • [💡 Features](#-key-features) • [📖 Docs](#-documentation) • [💰 Pricing](#-pricing-at-a-glance) • [💬 WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
> 💬 **Join our community!** [WhatsApp Group](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Get help, share tips, and stay updated.
🌐 **Available in:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](README.pt-BR.md) | 🇪🇸 [Español](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [Italiano](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [Magyar](README.hu.md) | 🇮🇩 [Bahasa Indonesia](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Nederlands](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Portugal)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Polski](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [Filipino](README.phi.md)
</div>
- **Website**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
- **WhatsApp**: [Community Group](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
- **Original Project**: [9router by decolua](https://github.com/decolua/9router)
---
@@ -259,6 +269,43 @@ docker compose --profile cli up -d
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
Run OmniRoute as a standalone desktop app — no terminal, no browser, no internet required for local models. The Electron-based app includes:
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
### Quick Start
```bash
# Development mode
npm run electron:dev
# Build for your platform
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg) — x64 & arm64
npm run electron:build:linux # Linux (.AppImage)
```
### System Tray
When minimized, OmniRoute lives in your system tray with quick actions:
- Open dashboard
- Change server port
- Quit application
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Pricing at a Glance
| Tier | Provider | Cost | Quota Reset | Best For |
@@ -284,67 +331,6 @@ docker compose --profile cli up -d
---
## 🎯 Use Cases
### Case 1: "I have Claude Pro subscription"
**Problem:** Quota expires unused, rate limits during heavy coding
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Case 2: "I want zero cost"
**Problem:** Can't afford subscriptions, need reliable AI coding
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Case 3: "I need 24/7 coding, no interruptions"
**Problem:** Deadlines, can't afford downtime
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Case 4: "I want FREE AI in OpenClaw"
**Problem:** Need AI assistant in messaging apps, completely free
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Key Features
### 🧠 Core Routing & Intelligence
@@ -505,6 +491,67 @@ OmniRoute includes a powerful built-in Translator Playground with **4 modes** fo
---
## 🎯 Use Cases
### Case 1: "I have Claude Pro subscription"
**Problem:** Quota expires unused, rate limits during heavy coding
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Case 2: "I want zero cost"
**Problem:** Can't afford subscriptions, need reliable AI coding
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Case 3: "I need 24/7 coding, no interruptions"
**Problem:** Deadlines, can't afford downtime
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Case 4: "I want FREE AI in OpenClaw"
**Problem:** Need AI assistant in messaging apps, completely free
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Setup Guide
<details>
@@ -785,74 +832,6 @@ Settings → API Configuration:
---
## 📊 Available Models
<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`
**Codex (`cx/`)** - Plus/Pro:
- `cx/gpt-5.2-codex`
- `cx/gpt-5.1-codex-max`
**Gemini CLI (`gc/`)** - FREE:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - FREE credits:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ more models on [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0.6/1M:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0.2/1M:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - FREE:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - FREE:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - FREE:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ models:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Any model from [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Evaluations (Evals)
OmniRoute includes a built-in evaluation framework to test LLM response quality against a golden set. Access it via **Analytics → Evals** in the dashboard.
@@ -876,13 +855,67 @@ The pre-loaded "OmniRoute Golden Set" contains 10 test cases covering:
---
## 🔐 OAuth em Servidor Remoto (Remote OAuth Setup)
## 🐛 Troubleshooting
<details>
<summary><b>Click to expand troubleshooting guide</b></summary>
**"Language model did not provide messages"**
- Provider quota exhausted → Check dashboard quota tracker
- Solution: Use combo fallback or switch to cheaper tier
**Rate limiting**
- Subscription quota out → Fallback to GLM/MiniMax
- Add combo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth token expired**
- Auto-refreshed by OmniRoute
- If issues persist: Dashboard → Provider → Reconnect
**High costs**
- Check usage stats in Dashboard → Costs
- Switch primary model to GLM/MiniMax
- Use free tier (Gemini CLI, iFlow) for non-critical tasks
**Dashboard/API ports are wrong**
- `PORT` is the canonical base port (and API port by default)
- `API_PORT` overrides only OpenAI-compatible API listener
- `DASHBOARD_PORT` overrides only dashboard/Next.js listener
- Set `NEXT_PUBLIC_BASE_URL` to your dashboard/public URL (for OAuth callbacks)
**Cloud sync errors**
- Verify `BASE_URL` points to your running instance
- Verify `CLOUD_URL` points to your expected cloud endpoint
- Keep `NEXT_PUBLIC_*` values aligned with server-side values
**First login not working**
- Check `INITIAL_PASSWORD` in `.env`
- If unset, fallback password is `123456`
**No request logs**
- Set `ENABLE_REQUEST_LOGS=true` in `.env`
**Connection test shows "Invalid" for OpenAI-compatible providers**
- Many providers don't expose a `/models` endpoint
- OmniRoute v1.0.6+ includes fallback validation via chat completions
- Ensure base URL includes `/v1` suffix
### 🔐 OAuth em Servidor Remoto (Remote OAuth Setup)
<a name="oauth-em-servidor-remoto"></a>
> **⚠️ IMPORTANTE para usuários com OmniRoute em VPS/Docker/servidor remoto**
### Por que o OAuth do Antigravity / Gemini CLI falha em servidores remotos?
#### Por que o OAuth do Antigravity / Gemini CLI falha em servidores remotos?
Os provedores **Antigravity** e **Gemini CLI** usam **Google OAuth 2.0** para autenticação. O Google exige que a `redirect_uri` usada no fluxo OAuth seja **exatamente** uma das URIs pré-cadastradas no Google Cloud Console do aplicativo.
@@ -892,7 +925,7 @@ As credenciais OAuth embutidas no OmniRoute estão cadastradas **apenas para `lo
Error 400: redirect_uri_mismatch
```
### Solução: Configure suas próprias credenciais OAuth
#### Solução: Configure suas próprias credenciais OAuth
Você precisa criar um **OAuth 2.0 Client ID** no Google Cloud Console com a URI do seu servidor.
@@ -955,7 +988,7 @@ Agora o Google redirecionará corretamente para `https://seu-servidor.com/callba
---
### Workaround temporário (sem configurar credenciais próprias)
#### Workaround temporário (sem configurar credenciais próprias)
Se não quiser criar credenciais próprias agora, ainda é possível usar o fluxo **manual de URL**:
@@ -967,62 +1000,6 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
> Este workaround funciona porque o código de autorização na URL é válido independente do redirect ter carregado ou não.
---
## 🐛 Troubleshooting
<details>
<summary><b>Click to expand troubleshooting guide</b></summary>
**"Language model did not provide messages"**
- Provider quota exhausted → Check dashboard quota tracker
- Solution: Use combo fallback or switch to cheaper tier
**Rate limiting**
- Subscription quota out → Fallback to GLM/MiniMax
- Add combo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth token expired**
- Auto-refreshed by OmniRoute
- If issues persist: Dashboard → Provider → Reconnect
**High costs**
- Check usage stats in Dashboard → Costs
- Switch primary model to GLM/MiniMax
- Use free tier (Gemini CLI, iFlow) for non-critical tasks
**Dashboard/API ports are wrong**
- `PORT` is the canonical base port (and API port by default)
- `API_PORT` overrides only OpenAI-compatible API listener
- `DASHBOARD_PORT` overrides only dashboard/Next.js listener
- Set `NEXT_PUBLIC_BASE_URL` to your dashboard/public URL (for OAuth callbacks)
**Cloud sync errors**
- Verify `BASE_URL` points to your running instance
- Verify `CLOUD_URL` points to your expected cloud endpoint
- Keep `NEXT_PUBLIC_*` values aligned with server-side values
**First login not working**
- Check `INITIAL_PASSWORD` in `.env`
- If unset, fallback password is `123456`
**No request logs**
- Set `ENABLE_REQUEST_LOGS=true` in `.env`
**Connection test shows "Invalid" for OpenAI-compatible providers**
- Many providers don't expose a `/models` endpoint
- OmniRoute v1.0.6+ includes fallback validation via chat completions
- Ensure base URL includes `/v1` suffix
</details>
---
@@ -1104,18 +1081,6 @@ OmniRoute has **210+ features planned** across multiple development phases. Here
---
## 📧 Support
> 💬 **Join our community!** [WhatsApp Group](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Get help, share tips, and stay updated.
- **Website**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
- **WhatsApp**: [Community Group](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
- **Original Project**: [9router by decolua](https://github.com/decolua/9router)
---
## 👥 Contributors
[![Contributors](https://contrib.rocks/image?repo=diegosouzapw/OmniRoute&max=100&columns=20&anon=1)](https://github.com/diegosouzapw/OmniRoute/graphs/contributors)
@@ -1165,85 +1130,6 @@ MIT License - see [LICENSE](LICENSE) for details.
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento inteligente para **modelos de IA GRATUITOS e de baixo custo** com fallback automático.
_Seu proxy universal de API — um endpoint, 36+ provedores, zero downtime._
### 🌐 Internacionalização (i18n)
O dashboard do OmniRoute suporta **múltiplos idiomas**. Atualmente disponível em:
| Idioma | Código | Status |
| --------------------- | ------- | ----------- |
| 🇺🇸 English | `en` | ✅ Completo |
| 🇧🇷 Português (Brasil) | `pt-BR` | ✅ Completo |
**Para trocar o idioma:** Clique no seletor de idioma (🇺🇸 EN) no header do dashboard → selecione o idioma desejado.
**Para adicionar um novo idioma:**
1. Crie `src/i18n/messages/{codigo}.json` baseado em `en.json`
2. Adicione o código em `src/i18n/config.ts``LOCALES` e `LANGUAGES`
3. Reinicie o servidor
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Docker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ provedores de IA** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek, e mais
- **Roteamento inteligente** — Fallback automático entre provedores
- **Tradução de formato** — OpenAI ↔ Claude ↔ Gemini automaticamente
- **Multi-conta** — Múltiplas contas por provedor com seleção inteligente
- **Cache semântico** — Reduz custos e latência
- **OAuth automático** — Tokens renovam automaticamente
- **Combos personalizados** — 6 estratégias de roteamento
- **Dashboard completo** — Monitoramento, logs, análises, configurações
- **CLI Tools** — Configure Claude Code, Codex, Cursor, Cline com um clique
- **100% TypeScript** — Código limpo e tipado
### 📖 Documentação
| Documento | Descrição |
| ----------------------------------------------- | -------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, combos, CLI, deploy |
| [Referência da API](docs/API_REFERENCE.md) | Todos os endpoints com exemplos |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do sistema |
| [Contribuição](CONTRIBUTING.md) | Setup de desenvolvimento e guidelines |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Guia completo: VM + nginx + Cloudflare |
### 📧 Suporte
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tire dúvidas, compartilhe dicas e fique atualizado.
- **Website**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Built with ❤️ for developers who code 24/7</sub>
<br/>
+137 -264
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — Gerbang AI Percuma
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Jangan sekali-kali berhenti mengekod. Penghalaan pintar ke **model AI PERCUMA & kos rendah** dengan sandaran automatik.
_Proksi API universal anda — satu titik akhir, 36+ pembekal, masa henti sifar._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Sekilas Pandang Harga
| Peringkat | Pembekal | Kos | Set Semula Kuota | Terbaik Untuk |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Kes Penggunaan
### Kes 1: "Saya mempunyai langganan Claude Pro"
**Masalah:** Kuota tamat tempoh tidak digunakan, had kadar semasa pengekodan berat
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Kes 2: "Saya mahu kos sifar"
**Masalah:** Tidak mampu membayar langganan, memerlukan pengekodan AI yang boleh dipercayai
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Kes 3: "Saya memerlukan pengekodan 24/7, tiada gangguan"
**Masalah:** Tarikh akhir, tidak mampu membayar masa henti
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Kes 4: "Saya mahukan AI PERCUMA dalam OpenClaw"
**Masalah:** Memerlukan pembantu AI dalam apl pemesejan, percuma sepenuhnya
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Ciri Utama
### 🧠 Penghalaan Teras & Kepintaran
@@ -495,6 +456,67 @@ OmniRoute termasuk Taman Permainan Penterjemah terbina dalam yang berkuasa denga
---
## 🎯 Kes Penggunaan
### Kes 1: "Saya mempunyai langganan Claude Pro"
**Masalah:** Kuota tamat tempoh tidak digunakan, had kadar semasa pengekodan berat
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Kes 2: "Saya mahu kos sifar"
**Masalah:** Tidak mampu membayar langganan, memerlukan pengekodan AI yang boleh dipercayai
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Kes 3: "Saya memerlukan pengekodan 24/7, tiada gangguan"
**Masalah:** Tarikh akhir, tidak mampu membayar masa henti
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Kes 4: "Saya mahukan AI PERCUMA dalam OpenClaw"
**Masalah:** Memerlukan pembantu AI dalam apl pemesejan, percuma sepenuhnya
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Panduan Persediaan
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Model Tersedia
<details>
<summary><b>Lihat semua model yang tersedia</b></summary>
**Kod Claude (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - PERCUMA:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - Kredit PERCUMA:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ lagi model di [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0.6/1J:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0.2/1J:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - PERCUMA:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - PERCUMA:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - PERCUMA:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ model:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Mana-mana model daripada [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Penilaian (Evals)
OmniRoute termasuk rangka kerja penilaian terbina dalam untuk menguji kualiti tindak balas LLM terhadap set emas. Aksesnya melalui **Analytics → Evals** dalam papan pemuka.
@@ -866,7 +820,58 @@ OmniRoute termasuk rangka kerja penilaian terbina dalam untuk menguji kualiti ti
---
## 🔐 OAuth em Servidor Remoto (Persediaan OAuth Jauh)
## 🐛 Menyelesaikan masalah
<details>
<summary><b>Klik untuk mengembangkan panduan penyelesaian masalah</b></summary>
**"Model bahasa tidak memberikan mesej"**
- Kuota pembekal habis → Semak penjejak kuota papan pemuka
- Penyelesaian: Gunakan sandaran kombo atau tukar kepada peringkat yang lebih murah
**Penghadan kadar**
- Kuota langganan habis → Sandar kepada GLM/MiniMax
- Tambah kombo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Token OAuth tamat tempoh**
- Dikemas semula secara automatik oleh OmniRoute
- Jika isu berterusan: Papan Pemuka → Pembekal → Sambung semula
**Kos tinggi**
- Semak statistik penggunaan dalam Papan Pemuka → Kos
- Tukar model utama kepada GLM/MiniMax
- Gunakan peringkat percuma (Gemini CLI, iFlow) untuk tugasan yang tidak kritikal
**Papan pemuka dibuka pada port yang salah**
- Tetapkan `PORT=20128` dan `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Ralat penyegerakan awan**
- Sahkan `BASE_URL` mata pada contoh larian anda
- Sahkan `CLOUD_URL` mata ke titik akhir awan anda yang dijangkakan
- Pastikan nilai `NEXT_PUBLIC_*` sejajar dengan nilai sebelah pelayan
**Log masuk pertama tidak berfungsi**
- Semak `INITIAL_PASSWORD` dalam `.env`
- Jika tidak ditetapkan, kata laluan sandaran ialah `123456`
**Tiada log permintaan**
- Tetapkan `ENABLE_REQUEST_LOGS=true` dalam `.env`
**Ujian sambungan menunjukkan "Tidak sah" untuk pembekal yang serasi dengan OpenAI**
- Banyak pembekal tidak mendedahkan titik akhir `/models`
- OmniRoute v1.0.6+ termasuk pengesahan sandaran melalui pelengkapan sembang
- Pastikan URL asas mengandungi akhiran `/v1`
### 🔐 OAuth em Servidor Remoto (Persediaan OAuth Jauh)
<a name="oauth-em-servidor-remoto"></a>
@@ -957,59 +962,6 @@ Jika anda ingin mendapatkan credenciais próprias agora, ada kemungkinan penggun
> Penyelesaian ini berfungsi sebagai kodigo de autorização na URL adalah bebas untuk mengubah hala mengikut arahan atau tidak.
---
## 🐛 Menyelesaikan masalah
<details>
<summary><b>Klik untuk mengembangkan panduan penyelesaian masalah</b></summary>
**"Model bahasa tidak memberikan mesej"**
- Kuota pembekal habis → Semak penjejak kuota papan pemuka
- Penyelesaian: Gunakan sandaran kombo atau tukar kepada peringkat yang lebih murah
**Penghadan kadar**
- Kuota langganan habis → Sandar kepada GLM/MiniMax
- Tambah kombo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Token OAuth tamat tempoh**
- Dikemas semula secara automatik oleh OmniRoute
- Jika isu berterusan: Papan Pemuka → Pembekal → Sambung semula
**Kos tinggi**
- Semak statistik penggunaan dalam Papan Pemuka → Kos
- Tukar model utama kepada GLM/MiniMax
- Gunakan peringkat percuma (Gemini CLI, iFlow) untuk tugasan yang tidak kritikal
**Papan pemuka dibuka pada port yang salah**
- Tetapkan `PORT=20128` dan `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Ralat penyegerakan awan**
- Sahkan `BASE_URL` mata pada contoh larian anda
- Sahkan `CLOUD_URL` mata ke titik akhir awan anda yang dijangkakan
- Pastikan nilai `NEXT_PUBLIC_*` sejajar dengan nilai sebelah pelayan
**Log masuk pertama tidak berfungsi**
- Semak `INITIAL_PASSWORD` dalam `.env`
- Jika tidak ditetapkan, kata laluan sandaran ialah `123456`
**Tiada log permintaan**
- Tetapkan `ENABLE_REQUEST_LOGS=true` dalam `.env`
**Ujian sambungan menunjukkan "Tidak sah" untuk pembekal yang serasi dengan OpenAI**
- Banyak pembekal tidak mendedahkan titik akhir `/models`
- OmniRoute v1.0.6+ termasuk pengesahan sandaran melalui pelengkapan sembang
- Pastikan URL asas mengandungi akhiran `/v1`
</details>
---
@@ -1152,85 +1104,6 @@ Lesen MIT - lihat [LICENSE](LICENSE) untuk butiran.
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento intelligente para **models de IA GRATUITOS e de baixo custo** com fallback automático.
_Seu proksi universal de API — titik akhir, 36+ bukti, masa henti sifar._
### 🌐 Internacionalização (i18n)
Papan pemuka buat OmniRoute menyokong **multipplos idiomas**. Anda boleh membelinya:
| Idioma | Código | Status |
| --------------------- | ------- | ---------- |
| 🇺🇸 Bahasa Inggeris | `en` | ✅ Lengkap |
| 🇧🇷 Português (Brasil) | `pt-BR` | ✅ Lengkap |
**Para trocar o idioma:** Clique no seletor de idioma (🇺🇸 EN) no header do dashboard → selecione o idioma desejado.
**Para adicionar um novo idioma:**
1. Menangis `src/i18n/messages/{codigo}.json` baseado em `en.json`
2. Tambah código em `src/i18n/config.ts``LOCALES` e `LANGUAGES`
3. Reinicie o servidor
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Docker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ bukti IA** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek, dan lain-lain
- **Roteamento intelligente** — Fallback automático entre provedores
- **Tradução de formato** — OpenAI ↔ Claude ↔ Gemini automaticamente
- **Multi-conta** — Múltiplas contas por provedor com seleção intelligente
- **Cache semântico** — Reduz custos e latência
- **OAuth automático** — Token renovam automaticamente
- **Kombo personalizados** — 6 estratégias de roteamento
- **Papan pemuka siap** — Pemantauan, log, analisis, konfigurasi
- **Alat CLI** — Konfigurasikan Kod Claude, Codex, Kursor, Cline com um clique
- **100% TypeScript** — Código limpo dan tipado
### 📖 Dokumentasi
| Dokumentasi | Penerangan |
| ----------------------------------------------- | -------------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, gabungan, CLI, gunakan |
| [Referência da API](docs/API_REFERENCE.md) | Todos os endpoints com exemplos |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Masalah komun dan penyelesaian |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura dan internos do sistema |
| [Contribuição](CONTRIBUTING.md) | Persediaan desenvolvimento dan garis panduan |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Panduan lengkap: VM + nginx + Cloudflare |
### 📧 Sokongan
> 💬 **Entre for a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tire dúvidas, compartilhe dicas and fique atualizado.
- **Laman web**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Isu**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Dibina dengan ❤️ untuk pembangun yang kod 24/7</sub>
<br/>
+137 -264
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — De gratis AI-gateway
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Stop nooit met coderen. Slimme routering naar **GRATIS en voordelige AI-modellen** met automatische terugval.
_Uw universele API-proxy: één eindpunt, meer dan 36 providers, geen downtime._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Prijzen in één oogopslag
| Niveau | Aanbieder | Kosten | Quotum opnieuw instellen | Beste voor |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Gebruiksscenario's
### Geval 1: "Ik heb een Claude Pro-abonnement"
**Probleem:** Quotum verloopt ongebruikt, snelheidslimieten tijdens intensief coderen
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Geval 2: "Ik wil geen kosten"
**Probleem:** Ik kan geen abonnementen betalen, heb betrouwbare AI-codering nodig
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Geval 3: "Ik heb 24/7 codering nodig, geen onderbrekingen"
**Probleem:** Deadlines, downtime is niet mogelijk
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Case 4: "Ik wil GRATIS AI in OpenClaw"
**Probleem:** AI-assistent nodig in berichtenapps, geheel gratis
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Belangrijkste kenmerken
### 🧠 Kernroutering en intelligentie
@@ -495,6 +456,67 @@ OmniRoute bevat een krachtige ingebouwde Translator Playground met **4 modi** vo
---
## 🎯 Gebruiksscenario's
### Geval 1: "Ik heb een Claude Pro-abonnement"
**Probleem:** Quotum verloopt ongebruikt, snelheidslimieten tijdens intensief coderen
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Geval 2: "Ik wil geen kosten"
**Probleem:** Ik kan geen abonnementen betalen, heb betrouwbare AI-codering nodig
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Geval 3: "Ik heb 24/7 codering nodig, geen onderbrekingen"
**Probleem:** Deadlines, downtime is niet mogelijk
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Case 4: "Ik wil GRATIS AI in OpenClaw"
**Probleem:** AI-assistent nodig in berichtenapps, geheel gratis
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Installatiehandleiding
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Beschikbare modellen
<details>
<summary><b>Bekijk alle beschikbare modellen</b></summary>
**Claude-code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - GRATIS:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub-copiloot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - GRATIS tegoeden:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ meer modellen op [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $ 0,6/1 miljoen:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $ 0,2/1 miljoen:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - GRATIS:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - GRATIS:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - GRATIS:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ modellen:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Elk model vanaf [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Evaluaties (Evals)
OmniRoute bevat een ingebouwd evaluatieframework om de LLM-responskwaliteit te testen aan de hand van een gouden set. U kunt deze openen via **Analytics → Evaluaties** in het dashboard.
@@ -866,7 +820,58 @@ De vooraf geladen "OmniRoute Golden Set" bevat 10 testcases die betrekking hebbe
---
## 🔐 OAuth em Servidor Remoto (OAuth-installatie op afstand)
## 🐛 Problemen oplossen
<details>
<summary><b>Klik om de probleemoplossingsgids uit te vouwen</b></summary>
**"Taalmodel heeft geen berichten verstrekt"**
- Providerquotum opgebruikt → Controleer dashboardquotumtracker
- Oplossing: gebruik combo-fallback of schakel over naar een goedkoper niveau
**Snelheidslimiet**
- Abonnementquotum op → Terugval op GLM/MiniMax
- Combinatie toevoegen: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth-token verlopen**
- Automatisch vernieuwd door OmniRoute
- Als de problemen aanhouden: Dashboard → Provider → Opnieuw verbinding maken
**Hoge kosten**
- Controleer gebruiksstatistieken in Dashboard → Kosten
- Schakel het primaire model over naar GLM/MiniMax
- Gebruik de gratis laag (Gemini CLI, iFlow) voor niet-kritieke taken
**Dashboard opent op verkeerde poort**
- Stel `PORT=20128` en `NEXT_PUBLIC_BASE_URL=http://localhost:20128` in
**Cloudsynchronisatiefouten**
- Controleer of `BASE_URL` verwijst naar uw actieve exemplaar
- Controleer of `CLOUD_URL` verwijst naar uw verwachte cloudeindpunt
- Houd `NEXT_PUBLIC_*` waarden afgestemd op de waarden op de server
**Eerste login werkt niet**
- Controleer `INITIAL_PASSWORD` in `.env`
- Indien niet ingesteld, is het reservewachtwoord `123456`
**Geen verzoeklogboeken**
- Stel `ENABLE_REQUEST_LOGS=true` in in `.env`
**Verbindingstest toont "Ongeldig" voor OpenAI-compatibele providers**
- Veel providers stellen geen `/models` eindpunt beschikbaar
- OmniRoute v1.0.6+ omvat fallback-validatie via chat-voltooiingen
- Zorg ervoor dat de basis-URL het achtervoegsel `/v1` bevat
### 🔐 OAuth em Servidor Remoto (OAuth-installatie op afstand)
<a name="oauth-em-servidor-remoto"></a>
@@ -957,59 +962,6 @@ Als u geen geloofwaardige geloofwaardigheid meer heeft, is het mogelijk om de st
> Deze tijdelijke oplossing werkt door de autorisatiecode van de URL en is onafhankelijk van het omleiden naar uw autorisatie of niet.
---
## 🐛 Problemen oplossen
<details>
<summary><b>Klik om de probleemoplossingsgids uit te vouwen</b></summary>
**"Taalmodel heeft geen berichten verstrekt"**
- Providerquotum opgebruikt → Controleer dashboardquotumtracker
- Oplossing: gebruik combo-fallback of schakel over naar een goedkoper niveau
**Snelheidslimiet**
- Abonnementquotum op → Terugval op GLM/MiniMax
- Combinatie toevoegen: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth-token verlopen**
- Automatisch vernieuwd door OmniRoute
- Als de problemen aanhouden: Dashboard → Provider → Opnieuw verbinding maken
**Hoge kosten**
- Controleer gebruiksstatistieken in Dashboard → Kosten
- Schakel het primaire model over naar GLM/MiniMax
- Gebruik de gratis laag (Gemini CLI, iFlow) voor niet-kritieke taken
**Dashboard opent op verkeerde poort**
- Stel `PORT=20128` en `NEXT_PUBLIC_BASE_URL=http://localhost:20128` in
**Cloudsynchronisatiefouten**
- Controleer of `BASE_URL` verwijst naar uw actieve exemplaar
- Controleer of `CLOUD_URL` verwijst naar uw verwachte cloudeindpunt
- Houd `NEXT_PUBLIC_*` waarden afgestemd op de waarden op de server
**Eerste login werkt niet**
- Controleer `INITIAL_PASSWORD` in `.env`
- Indien niet ingesteld, is het reservewachtwoord `123456`
**Geen verzoeklogboeken**
- Stel `ENABLE_REQUEST_LOGS=true` in in `.env`
**Verbindingstest toont "Ongeldig" voor OpenAI-compatibele providers**
- Veel providers stellen geen `/models` eindpunt beschikbaar
- OmniRoute v1.0.6+ omvat fallback-validatie via chat-voltooiingen
- Zorg ervoor dat de basis-URL het achtervoegsel `/v1` bevat
</details>
---
@@ -1152,85 +1104,6 @@ MIT-licentie - zie [LICENSE](LICENSE) voor details.
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratis
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca de coder. Intelligente rotatie voor **gratis IA-modellen en klantgerichte** met automatische terugval.
_Seu proxy universal de API - een eindpunt, 36+ tests, geen downtime._
### 🌐 Internacionalização (i18n)
Het dashboard ondersteunt **meerdere uitdrukkingen** door OmniRoute. Uiteindelijk wordt dit afgewezen:
| Idioom | Código | Staat |
| ----------------------- | ------- | ----------- |
| 🇺🇸 Engels | `en` | ✅ Compleet |
| 🇧🇷 Português (Brazilië) | `pt-BR` | ✅ Compleet |
**Para trocar o idioma:** Clique no seletor de idioma (🇺🇸 EN) no header do dashboard → selectie van idioom desejado.
**Voor een nieuw idioom:**
1. Roep `src/i18n/messages/{codigo}.json` op `en.json`
2. Voeg een code toe aan `src/i18n/config.ts``LOCALES` en `LANGUAGES`
3. Reinicie of dienstverlener
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Docker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑Funcionalidades Principais
- **36+ IA-tests** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek, en meer
- **Roteamento inteligente** — Automatische terugval tussen de bewijzen
- **Formaattraditie** — OpenAI ↔ Claude ↔ Gemini automatisch
- **Multi-conta** — Meerdere contass door bewijs of met intelligente selectie
- **Semântico cache** — Verlaag de kosten en letaliteit
- **OAuth automático** — Tokens worden automatisch vernieuwd
- **Persoonlijke combinaties** — 6 roteamento-indelingen
- **Dashboard compleet** — Monitoren, logs, analyses, configuraties
- **CLI Tools** — Configureer Claude Code, Codex, Cursor, Cline als een kliek
- **100% TypeScript** — Code is limpo en tipado
### 📖 Documentação
| Document | Beschrijving |
| ----------------------------------------------- | ------------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, combo's, CLI, implementeren |
| [Referência da API](docs/API_REFERENCE.md) | Alle eindpunten met voorbeelden |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Gemeenschappelijke problemen en oplossingen |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura en internos do system |
| [Contribuição](CONTRIBUTING.md) | Opstelling van de ontwikkelingsrichtlijnen |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Volledige versie: VM + nginx + Cloudflare |
### 📧 Steun
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Banden, vergelijkingen en vijf gebeurtenissen.
- **Website**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Problemen**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Gebouwd met ❤️ voor ontwikkelaars die 24/7 coderen</sub>
<br/>
+137 -264
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — Den gratis AI-gatewayen
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Slutt aldri å kode. Smart ruting til **GRATIS og rimelige AI-modeller** med automatisk fallback.
_Din universelle API-proxy ett endepunkt, 36+ leverandører, null nedetid._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Priser på et øyeblikk
| Nivå | Leverandør | Kostnad | Kvote Tilbakestill | Best for |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Brukssaker
### Sak 1: "Jeg har Claude Pro-abonnement"
**Problem:** Kvoten utløper ubrukt, satsgrenser under tung koding
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Tilfelle 2: "Jeg vil ha null kostnad"
**Problem:** Har ikke råd til abonnementer, trenger pålitelig AI-koding
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Tilfelle 3: "Jeg trenger 24/7 koding, ingen avbrudd"
**Problem:** Tidsfrister, har ikke råd til nedetid
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Tilfelle 4: "Jeg vil ha GRATIS AI i OpenClaw"
**Problem:** Trenger AI-assistent i meldingsapper, helt gratis
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Nøkkelfunksjoner
### 🧠 Kjerneruting og intelligens
@@ -495,6 +456,67 @@ OmniRoute inkluderer en kraftig innebygd oversetterlekeplass med **4 moduser** f
---
## 🎯 Brukssaker
### Sak 1: "Jeg har Claude Pro-abonnement"
**Problem:** Kvoten utløper ubrukt, satsgrenser under tung koding
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Tilfelle 2: "Jeg vil ha null kostnad"
**Problem:** Har ikke råd til abonnementer, trenger pålitelig AI-koding
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Tilfelle 3: "Jeg trenger 24/7 koding, ingen avbrudd"
**Problem:** Tidsfrister, har ikke råd til nedetid
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Tilfelle 4: "Jeg vil ha GRATIS AI i OpenClaw"
**Problem:** Trenger AI-assistent i meldingsapper, helt gratis
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Oppsettveiledning
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Tilgjengelige modeller
<details>
<summary><b>Se alle tilgjengelige modeller</b></summary>
**Claude-kode (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `cc/claude-sonnet-4-5-20250929`
- `cc/claude-haiku-4-5-20251001`
**Kodex (`cx/`)** - Pluss/Proff:
- `cx/gpt-5.2-codex`
- `cx/gpt-5.1-codex-max`
**Gemini CLI (`gc/`)** - GRATIS:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - GRATIS kreditter:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ flere modeller på [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0,6/1M:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0,2/1M:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - GRATIS:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - GRATIS:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - GRATIS:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ modeller:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Alle modeller fra [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Evalueringer (evalueringer)
OmniRoute inkluderer et innebygd evalueringsrammeverk for å teste LLM-responskvaliteten mot et gyldent sett. Få tilgang til den via **Analytics → Evals** i dashbordet.
@@ -866,7 +820,58 @@ Det forhåndsinstallerte "OmniRoute Golden Set" inneholder 10 testcases som dekk
---
## 🔐 OAuth em Servidor Remoto (Ekstern OAuth-oppsett)
## 🐛 Feilsøking
<details>
<summary><b>Klikk for å utvide feilsøkingsveiledningen</b></summary>
**«Språkmodellen ga ikke meldinger»**
- Leverandørkvoten er oppbrukt → Sjekk dashboardkvotesporing
- Løsning: Bruk kombinasjonsalternativ eller bytt til et billigere nivå
**Satsbegrensning**
- Abonnementskvote ut → Fallback til GLM/MiniMax
- Legg til kombinasjon: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth-token er utløpt**
- Automatisk oppdatering av OmniRoute
- Hvis problemene vedvarer: Dashboard → Leverandør → Koble til på nytt
**Høye kostnader**
- Sjekk bruksstatistikk i Dashboard → Kostnader
- Bytt primærmodell til GLM/MiniMax
- Bruk gratis nivå (Gemini CLI, iFlow) for ikke-kritiske oppgaver
**Dashboard åpnes på feil port**
- Sett `PORT=20128` og `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Skysynkroniseringsfeil**
- Bekreft at `BASE_URL` peker på løpeforekomsten din
- Bekreft `CLOUD_URL` poeng til det forventede skyendepunktet
- Hold `NEXT_PUBLIC_*` verdier på linje med verdiene på tjenersiden
**Første pålogging fungerer ikke**
- Sjekk `INITIAL_PASSWORD` i `.env`
- Hvis det ikke er angitt, er reservepassordet `123456`
**Ingen forespørselslogger**
- Sett `ENABLE_REQUEST_LOGS=true` i `.env`
**Test viser «Ugyldig» for OpenAI-kompatible leverandører**
- Mange leverandører avslører ikke et `/models`-endepunkt
- OmniRoute v1.0.6+ inkluderer reservevalidering via chatfullføringer
- Sørg for at basis-URL inkluderer suffikset `/v1`
### 🔐 OAuth em Servidor Remoto (Ekstern OAuth-oppsett)
<a name="oauth-em-servidor-remoto"></a>
@@ -957,59 +962,6 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
> Este workaround funciona porque or código de autorização na URL é válido independente do redirect ter carregado or não.
---
## 🐛 Feilsøking
<details>
<summary><b>Klikk for å utvide feilsøkingsveiledningen</b></summary>
**«Språkmodellen ga ikke meldinger»**
- Leverandørkvoten er oppbrukt → Sjekk dashboardkvotesporing
- Løsning: Bruk kombinasjonsalternativ eller bytt til et billigere nivå
**Satsbegrensning**
- Abonnementskvote ut → Fallback til GLM/MiniMax
- Legg til kombinasjon: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth-token er utløpt**
- Automatisk oppdatering av OmniRoute
- Hvis problemene vedvarer: Dashboard → Leverandør → Koble til på nytt
**Høye kostnader**
- Sjekk bruksstatistikk i Dashboard → Kostnader
- Bytt primærmodell til GLM/MiniMax
- Bruk gratis nivå (Gemini CLI, iFlow) for ikke-kritiske oppgaver
**Dashboard åpnes på feil port**
- Sett `PORT=20128` og `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Skysynkroniseringsfeil**
- Bekreft at `BASE_URL` peker på løpeforekomsten din
- Bekreft `CLOUD_URL` poeng til det forventede skyendepunktet
- Hold `NEXT_PUBLIC_*` verdier på linje med verdiene på tjenersiden
**Første pålogging fungerer ikke**
- Sjekk `INITIAL_PASSWORD` i `.env`
- Hvis det ikke er angitt, er reservepassordet `123456`
**Ingen forespørselslogger**
- Sett `ENABLE_REQUEST_LOGS=true` i `.env`
**Test viser «Ugyldig» for OpenAI-kompatible leverandører**
- Mange leverandører avslører ikke et `/models`-endepunkt
- OmniRoute v1.0.6+ inkluderer reservevalidering via chatfullføringer
- Sørg for at basis-URL inkluderer suffikset `/v1`
</details>
---
@@ -1152,85 +1104,6 @@ MIT-lisens - se [LICENSE](LICENSE) for detaljer.
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento inteligente for **modeller av IA GRATUITOS og de baixo custo** com reserve automático.
_Seu proxy universal de API — et endepunkt, 36+ tester, null nedetid._
### 🌐 Internacionalização (i18n)
O dashbordet for OmniRoute støtter **multiplos idiomas**. Atualmente disponível em:
| Idioma | Kode | Status |
| --------------------- | ------- | ----------- |
| 🇺🇸 Engelsk | `en` | ✅ Komplett |
| 🇧🇷 Português (Brasil) | `pt-BR` | ✅ Komplett |
**Para trocar o idioma:** Clique no selector de idioma (🇺🇸 EN) no header do dashboard → selection o idioma desejado.
**Tillegg et nytt uttrykk:**
1. Crie `src/i18n/messages/{codigo}.json` baseado em `en.json`
2. Adicione o código em `src/i18n/config.ts``LOCALES` og `LANGUAGES`
3. Reinicie o servidor
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Docker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ provedores de IA** - Claude, GPT, Gemini, Llama, Qwen, DeepSeek, e mais
- **Roteamento inteligente** — Fallback automático entre provedores
- **Tradução de formato** — OpenAI ↔ Claude ↔ Gemini automaticamente
- **Multi-conta** — Multiplas-innhold for testing com seleção inteligente
- **Cache semântico** — Reduz custos e latência
- **OAuth automático** — Tokens renovam automaticamente
- **Personlig kombinasjoner** — 6 estratégias de roteamento
- **Dashboard komplett** — Monitoramento, logger, analyser, konfigurasjoner
- **CLI Tools** — Konfigurer Claude Code, Codex, Cursor, Cline com um clique
- **100 % TypeScript** — Código limpo e tipado
### 📖 Dokumentasjon
| Documento | Beskrivelse |
| ----------------------------------------------- | -------------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, combos, CLI, distribuere |
| [Referência da API](docs/API_REFERENCE.md) | Todos os endepunkter med eksempler |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do sistema |
| [Contribuição](CONTRIBUTING.md) | Oppsett av desenvolvimento og retningslinjer |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Fullfør: VM + nginx + Cloudflare |
### 📧 Støtte
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tire dúvidas, compartilhe dicas e fique atualizado.
- **Nettsted**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Problemer**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Bygget med ❤️ for utviklere som koder 24/7</sub>
<br/>
+138 -265
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — Ang Libreng AI Gateway
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Huwag kailanman ihinto ang coding. Smart routing sa **LIBRE at murang mga modelo ng AI** na may awtomatikong fallback.
_Iyong unibersal na API proxy — isang endpoint, 36+ provider, zero downtime._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Pagpepresyo sa isang Sulyap
| Tier | Provider | Gastos | I-reset ang Quota | Pinakamahusay Para sa |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Use Cases
### Case 1: "May subscription ako sa Claude Pro"
**Problema:** Nag-e-expire ang quota nang hindi nagamit, mga limitasyon sa rate sa panahon ng mabigat na coding
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Case 2: "Gusto ko ng zero cost"
**Problema:** Hindi kayang bayaran ang mga subscription, kailangan ng maaasahang AI coding
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Case 3: "Kailangan ko ng 24/7 coding, walang mga pagkaantala"
**Problema:** Mga deadline, hindi kayang bayaran ang downtime
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Kaso 4: "Gusto ko ng LIBRENG AI sa OpenClaw"
**Problema:** Kailangan ng AI assistant sa mga app sa pagmemensahe, ganap na libre
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Mga Pangunahing Tampok
### 🧠 Core Routing at Intelligence
@@ -495,6 +456,67 @@ Kasama sa OmniRoute ang isang malakas na built-in na Playground ng Translator na
---
## 🎯 Use Cases
### Case 1: "May subscription ako sa Claude Pro"
**Problema:** Nag-e-expire ang quota nang hindi nagamit, mga limitasyon sa rate sa panahon ng mabigat na coding
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Case 2: "Gusto ko ng zero cost"
**Problema:** Hindi kayang bayaran ang mga subscription, kailangan ng maaasahang AI coding
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Case 3: "Kailangan ko ng 24/7 coding, walang mga pagkaantala"
**Problema:** Mga deadline, hindi kayang bayaran ang downtime
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Kaso 4: "Gusto ko ng LIBRENG AI sa OpenClaw"
**Problema:** Kailangan ng AI assistant sa mga app sa pagmemensahe, ganap na libre
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Gabay sa Pag-setup
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Mga Magagamit na Modelo
<details>
<summary><b>Tingnan ang lahat ng available na modelo</b></summary>
**Claude Code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - LIBRE:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - LIBRENG mga kredito:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ pang mga modelo sa [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0.6/1M:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0.2/1M:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - LIBRE:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - LIBRE:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - LIBRE:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ na modelo:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Anumang modelo mula sa [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Mga Pagsusuri (Evals)
Ang OmniRoute ay may kasamang built-in na balangkas ng pagsusuri upang subukan ang kalidad ng pagtugon ng LLM laban sa isang ginintuang hanay. I-access ito sa pamamagitan ng **Analytics → Evals** sa dashboard.
@@ -866,7 +820,58 @@ Ang pre-loaded na "OmniRoute Golden Set" ay naglalaman ng 10 test case na sumasa
---
## 🔐 OAuth em Servidor Remoto (Remote OAuth Setup)
## 🐛 Pag-troubleshoot
<details>
<summary><b>Mag-click upang palawakin ang gabay sa pag-troubleshoot</b></summary>
**"Ang modelo ng wika ay hindi nagbigay ng mga mensahe"**
- Naubos na ang quota ng provider → Suriin ang tracker ng quota ng dashboard
- Solusyon: Gumamit ng combo fallback o lumipat sa mas murang tier
**Paglilimita sa rate**
- Out na ang quota ng subscription → Fallback sa GLM/MiniMax
- Magdagdag ng combo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Nag-expire ang token ng OAuth**
- Auto-refresh ng OmniRoute
- Kung magpapatuloy ang mga isyu: Dashboard → Provider → Muling kumonekta
**Mataas na gastos**
- Suriin ang mga istatistika ng paggamit sa Dashboard → Mga Gastos
- Ilipat ang pangunahing modelo sa GLM/MiniMax
- Gumamit ng libreng tier (Gemini CLI, iFlow) para sa mga hindi kritikal na gawain
**Nagbubukas ang dashboard sa maling port**
- Itakda ang `PORT=20128` at `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Mga error sa cloud sync**
- I-verify ang `BASE_URL` na mga puntos sa iyong running instance
- I-verify ang `CLOUD_URL` na mga puntos sa iyong inaasahang cloud endpoint
- Panatilihing nakahanay ang mga value ng `NEXT_PUBLIC_*` sa mga value sa gilid ng server
**Hindi gumagana ang unang pag-login**
- Suriin ang `INITIAL_PASSWORD` sa `.env`
- Kung hindi nakatakda, ang fallback na password ay `123456`
**Walang mga log ng kahilingan**
- Itakda ang `ENABLE_REQUEST_LOGS=true` sa `.env`
**Ang pagsubok sa koneksyon ay nagpapakita ng "Di-wasto" para sa mga provider na katugma sa OpenAI**
- Maraming provider ang hindi naglalantad ng `/models` endpoint
- Kasama sa OmniRoute v1.0.6+ ang fallback validation sa pamamagitan ng mga pagkumpleto ng chat
- Tiyaking may kasamang `/v1` suffix ang base URL
### 🔐 OAuth em Servidor Remoto (Remote OAuth Setup)
<a name="oauth-em-servidor-remoto"></a>
@@ -945,7 +950,7 @@ Agora o Google redirectionará corretamente para sa `https://seu-servidor.com/ca
---
### Workaround temporário (sem configurar credenciais próprias)
#### Workaround temporário (sem configurar credenciais próprias)
Se não quiser criar credenciais próprias agora, may posibilidad na magamit o fluxo **manual de URL**:
@@ -957,59 +962,6 @@ Se não quiser criar credenciais próprias agora, may posibilidad na magamit o f
> Ang workaround na ito ay gumagana sa pamamagitan ng código de authorização na URL ay maaaring mag-redirect sa iyong carregado ou não.
---
## 🐛 Pag-troubleshoot
<details>
<summary><b>Mag-click upang palawakin ang gabay sa pag-troubleshoot</b></summary>
**"Ang modelo ng wika ay hindi nagbigay ng mga mensahe"**
- Naubos na ang quota ng provider → Suriin ang tracker ng quota ng dashboard
- Solusyon: Gumamit ng combo fallback o lumipat sa mas murang tier
**Paglilimita sa rate**
- Out na ang quota ng subscription → Fallback sa GLM/MiniMax
- Magdagdag ng combo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Nag-expire ang token ng OAuth**
- Auto-refresh ng OmniRoute
- Kung magpapatuloy ang mga isyu: Dashboard → Provider → Muling kumonekta
**Mataas na gastos**
- Suriin ang mga istatistika ng paggamit sa Dashboard → Mga Gastos
- Ilipat ang pangunahing modelo sa GLM/MiniMax
- Gumamit ng libreng tier (Gemini CLI, iFlow) para sa mga hindi kritikal na gawain
**Nagbubukas ang dashboard sa maling port**
- Itakda ang `PORT=20128` at `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Mga error sa cloud sync**
- I-verify ang `BASE_URL` na mga puntos sa iyong running instance
- I-verify ang `CLOUD_URL` na mga puntos sa iyong inaasahang cloud endpoint
- Panatilihing nakahanay ang mga value ng `NEXT_PUBLIC_*` sa mga value sa gilid ng server
**Hindi gumagana ang unang pag-login**
- Suriin ang `INITIAL_PASSWORD` sa `.env`
- Kung hindi nakatakda, ang fallback na password ay `123456`
**Walang mga log ng kahilingan**
- Itakda ang `ENABLE_REQUEST_LOGS=true` sa `.env`
**Ang pagsubok sa koneksyon ay nagpapakita ng "Di-wasto" para sa mga provider na katugma sa OpenAI**
- Maraming provider ang hindi naglalantad ng `/models` endpoint
- Kasama sa OmniRoute v1.0.6+ ang fallback validation sa pamamagitan ng mga pagkumpleto ng chat
- Tiyaking may kasamang `/v1` suffix ang base URL
</details>
---
@@ -1152,85 +1104,6 @@ Lisensya ng MIT - tingnan ang [LICENSE](LICENSE) para sa mga detalye.
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento intelligente para **modelos de IA GRATUITOS e de baixo custo** com fallback automático.
_Seu proxy universal de API — um endpoint, 36+ provedores, zero downtime._
### 🌐 Internacionalização (i18n)
O dashboard ng OmniRoute suporta **multiplos idiomas**. Ibigay ang mga ito:
| Idyoma | Código | Katayuan |
| --------------------- | ------- | ----------- |
| 🇺🇸 Ingles | `en` | ✅ Kumpleto |
| 🇧🇷 Português (Brasil) | `pt-BR` | ✅ Kumpleto |
**Para trocar o idioma:** Clique no seletor de idioma (🇺🇸 EN) walang header do dashboard → selecione o idioma desejado.
**Para adicionar um novo idioma:**
1. Sumigaw `src/i18n/messages/{codigo}.json` baseado em `en.json`
2. Addicione o código em `src/i18n/config.ts``LOCALES` e `LANGUAGES`
3. Reinicie o servidor
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Docker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ provedores de IA** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek, at iba pa
- **Roteamento intelligente** — Fallback automatico entre provedores
- **Tradução de formato** — OpenAI ↔ Claude ↔ Gemini automaticamente
- **Multi-conta** — Múltiplas contas por provedor com seleção intelligente
- **Cache semântico** — Reduz custos at latência
- **OAuth automático** — Token renovam automaticamente
- **Combos personalizados** — 6 estratégias de roteamento
- **Dashboard completo** — Monitoramento, logs, análises, configurações
- **CLI Tools** — I-configure ang Claude Code, Codex, Cursor, Cline com um clique
- **100% TypeScript** — Código limpo at tipado
### 📖 Documentação
| Dokumento | Paglalarawan |
| ----------------------------------------------- | ------------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, combos, CLI, deploy |
| [Referência da API](docs/API_REFERENCE.md) | Todos os endpoints com exemplos |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problema communs at soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura at internos do sistema |
| [Contribuição](CONTRIBUTING.md) | Setup ng desenvolvimento at mga alituntunin |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Guia completo: VM + nginx + Cloudflare |
### 📧 Suporta
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tire dúvidas, compartilhe dicas e fique atualizado.
- **Website**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Mga Isyu**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Built with ❤️ para sa mga developer na nagko-code 24/7</sub>
<br/>
+138 -265
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — darmowa bramka AI
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Nigdy nie przestawaj kodować. Inteligentne przekierowywanie do **BEZPŁATNYCH i tanich modeli AI** z automatycznym powrotem.
_Twój uniwersalny serwer proxy API — jeden punkt końcowy, ponad 36 dostawców, zero przestojów._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Ceny w skrócie
| Poziom | Dostawca | Koszt | Reset przydziału | Najlepsze dla |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Przypadki użycia
### Przypadek 1: „Mam subskrypcję Claude Pro”
**Problem:** Limit wygasa niewykorzystany, limity szybkości podczas intensywnego kodowania
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Przypadek 2: „Chcę zerowych kosztów”
**Problem:** Nie stać Cię na subskrypcje, potrzebujesz niezawodnego kodowania AI
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Przypadek 3: „Potrzebuję kodowania 24 godziny na dobę, 7 dni w tygodniu, bez przerw”
**Problem:** Terminy, nie mogę sobie pozwolić na przestoje
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Przypadek 4: „Chcę DARMOWEJ sztucznej inteligencji w OpenClaw”
**Problem:** Potrzebujesz asystenta AI w aplikacjach do przesyłania wiadomości, całkowicie za darmo
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Kluczowe funkcje
### 🧠 Routing i inteligencja rdzenia
@@ -495,6 +456,67 @@ OmniRoute zawiera potężny, wbudowany plac zabaw dla tłumaczy z **4 trybami**
---
## 🎯 Przypadki użycia
### Przypadek 1: „Mam subskrypcję Claude Pro”
**Problem:** Limit wygasa niewykorzystany, limity szybkości podczas intensywnego kodowania
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Przypadek 2: „Chcę zerowych kosztów”
**Problem:** Nie stać Cię na subskrypcje, potrzebujesz niezawodnego kodowania AI
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Przypadek 3: „Potrzebuję kodowania 24 godziny na dobę, 7 dni w tygodniu, bez przerw”
**Problem:** Terminy, nie mogę sobie pozwolić na przestoje
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Przypadek 4: „Chcę DARMOWEJ sztucznej inteligencji w OpenClaw”
**Problem:** Potrzebujesz asystenta AI w aplikacjach do przesyłania wiadomości, całkowicie za darmo
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Przewodnik konfiguracji
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Dostępne modele
<details>
<summary><b>Wyświetl wszystkie dostępne modele</b></summary>
**Kod Claude (`cc/`)** Pro/Max:
- `cc/claude-opus-4-6`
- `cc/claude-sonnet-4-5-20250929`
- `cc/claude-haiku-4-5-20251001`
**Kodeks (`cx/`)** Plus/Pro:
- `cx/gpt-5.2-codex`
- `cx/gpt-5.1-codex-max`
**Gemini CLI (`gc/`)** BEZPŁATNIE:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**Drugi pilot GitHuba (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - DARMOWE kredyty:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- Ponad 50 więcej modeli na [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** 0,6 USD/1 mln:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** 0,2/1 mln USD:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - BEZPŁATNIE:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - ZA DARMO:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - ZA DARMO:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** ponad 100 modeli:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Dowolny model od [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Oceny (Ewaluacje)
OmniRoute zawiera wbudowaną platformę ewaluacyjną do testowania jakości odpowiedzi LLM na podstawie złotego zestawu. Uzyskaj do niego dostęp poprzez **Analytics → Evals** na pulpicie nawigacyjnym.
@@ -866,13 +820,64 @@ Fabrycznie załadowany „Złoty zestaw OmniRoute” zawiera 10 przypadków test
---
## 🔐 OAuth na serwerze zdalnym (zdalna konfiguracja OAuth)
## 🐛 Rozwiązywanie problemów
<details>
<summary><b>Kliknij, aby rozwinąć przewodnik rozwiązywania problemów</b></summary>
**„Model językowy nie dostarczał komunikatów”**
- Wyczerpany limit dostawcy → Sprawdź moduł śledzenia limitów na pulpicie nawigacyjnym
- Rozwiązanie: użyj kombinacji zastępczej lub przejdź na tańszy poziom
**Ograniczenie szybkości**
- Limit subskrypcji wyczerpany → Powrót do GLM/MiniMax
- Dodaj kombinację: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Token OAuth wygasł**
- Automatyczne odświeżanie przez OmniRoute
- Jeśli problemy nadal występują: Panel kontrolny → Dostawca → Połącz ponownie
**Wysokie koszty**
- Sprawdź statystyki użytkowania w Panelu → Koszty
- Zmień model podstawowy na GLM/MiniMax
- Korzystaj z bezpłatnej warstwy (Gemini CLI, iFlow) do zadań niekrytycznych
** Panel otwiera się na złym porcie **
- Ustaw `PORT=20128` i `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Błędy synchronizacji z chmurą**
- Sprawdź, czy `BASE_URL` wskazuje na działającą instancję
- Sprawdź, czy `CLOUD_URL` wskazuje na oczekiwany punkt końcowy w chmurze
- Zachowaj wyrównanie wartości `NEXT_PUBLIC_*` z wartościami po stronie serwera
**Pierwsze logowanie nie działa**
- Sprawdź `INITIAL_PASSWORD` w `.env`
- Jeśli nieustawione, hasło zastępcze to `123456`
**Brak dzienników żądań**
- Ustaw `ENABLE_REQUEST_LOGS=true` w `.env`
**Test połączenia pokazuje „Nieprawidłowy” dla dostawców kompatybilnych z OpenAI**
- Wielu dostawców nie udostępnia punktu końcowego `/models`
- OmniRoute v1.0.6+ zawiera weryfikację awaryjną poprzez uzupełnianie czatu
- Upewnij się, że podstawowy adres URL zawiera przyrostek `/v1`
### 🔐 OAuth na serwerze zdalnym (zdalna konfiguracja OAuth)
<a name="oauth-em-servidor-remoto"></a>
> **⚠️ WAŻNE dla zwykłych usług OmniRoute w VPS/Docker/serwidor zdalny**
### Por que o OAuth do Antigravity / Gemini CLI falha na zdalnych serwerach?
#### Por que o OAuth do Antigravity / Gemini CLI falha na zdalnych serwerach?
Sprawdzone **Antigravity** i **Gemini CLI** używane **Google OAuth 2.0** dla autentyczności. O Google, jeśli potrzebujesz `redirect_uri`, aby nie zmieniać protokołu OAuth seja **exatamente** uma das URI pre-cadastradas no Google Cloud Console to aplicativo.
@@ -957,59 +962,6 @@ Jeśli chcesz uzyskać dostęp do **podręcznika URL**:
> To obejście funkcji porque o kodigo de autorização na URL é válido niezależny do przekierowania ter carregado ou não.
---
## 🐛 Rozwiązywanie problemów
<details>
<summary><b>Kliknij, aby rozwinąć przewodnik rozwiązywania problemów</b></summary>
**„Model językowy nie dostarczał komunikatów”**
- Wyczerpany limit dostawcy → Sprawdź moduł śledzenia limitów na pulpicie nawigacyjnym
- Rozwiązanie: użyj kombinacji zastępczej lub przejdź na tańszy poziom
**Ograniczenie szybkości**
- Limit subskrypcji wyczerpany → Powrót do GLM/MiniMax
- Dodaj kombinację: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Token OAuth wygasł**
- Automatyczne odświeżanie przez OmniRoute
- Jeśli problemy nadal występują: Panel kontrolny → Dostawca → Połącz ponownie
**Wysokie koszty**
- Sprawdź statystyki użytkowania w Panelu → Koszty
- Zmień model podstawowy na GLM/MiniMax
- Korzystaj z bezpłatnej warstwy (Gemini CLI, iFlow) do zadań niekrytycznych
** Panel otwiera się na złym porcie **
- Ustaw `PORT=20128` i `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Błędy synchronizacji z chmurą**
- Sprawdź, czy `BASE_URL` wskazuje na działającą instancję
- Sprawdź, czy `CLOUD_URL` wskazuje na oczekiwany punkt końcowy w chmurze
- Zachowaj wyrównanie wartości `NEXT_PUBLIC_*` z wartościami po stronie serwera
**Pierwsze logowanie nie działa**
- Sprawdź `INITIAL_PASSWORD` w `.env`
- Jeśli nieustawione, hasło zastępcze to `123456`
**Brak dzienników żądań**
- Ustaw `ENABLE_REQUEST_LOGS=true` w `.env`
**Test połączenia pokazuje „Nieprawidłowy” dla dostawców kompatybilnych z OpenAI**
- Wielu dostawców nie udostępnia punktu końcowego `/models`
- OmniRoute v1.0.6+ zawiera weryfikację awaryjną poprzez uzupełnianie czatu
- Upewnij się, że podstawowy adres URL zawiera przyrostek `/v1`
</details>
---
@@ -1152,85 +1104,6 @@ Licencja MIT — szczegółowe informacje można znaleźć w [LICENSE](LICENSE).
---
---
## 🇧🇷 OmniRoute — bezpłatna bramka IA
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento inteligentne dla **modelos de IA GRATUITOS e de baixo custo** com fallback automático.
_Seu proxy universal de API — punkt końcowy, ponad 36 testów, zero przestojów._
### 🌐 Międzynarodowa analiza (i18n)
Panel obsługi OmniRoute obsługuje **wiele idiomów**. Atualmente disponível je:
| Idioma | Kodigo | Stan |
| ----------------------- | ------- | ------------ |
| 🇺🇸 angielski | `en` | ✅ Kompletne |
| 🇧🇷 Português (Brazylia) | `pt-BR` | ✅ Kompletne |
**Para trocar o idioma:** Kliknij przycisk no seletor de idioma (🇺🇸 EN) no header to dashboard → wybierz idioma desejado.
**Dosłowny nowy idiom:**
1. Płacz `src/i18n/messages/{codigo}.json` baseado em `en.json`
2. Adicione o kodigo em `src/i18n/config.ts``LOCALES` i `LANGUAGES`
3. Reinicie lub serwer
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Doker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ dowodów IA** — Claude, GPT, Gemini, Lama, Qwen, DeepSeek i e-mail
- **Roteamento inteligente** — Automatyczna awaria entre Providores
- **Przetłumaczenie formatu** — OpenAI ↔ Claude ↔ Gemini automatyczne
- **Multi-conta** — Múltiplas contas por proofor com seleção inteligente
- **Cache semantico** — Reduz custos e latência
- **Automatyczne OAuth** — Automatyczne odnawianie tokenów
- **Combos personalizados** — 6 estratégias de roteamento
- **Kompletny pulpit nawigacyjny** — Monitorowanie, logi, analizy, konfiguracje
- **Narzędzia CLI** — Skonfiguruj kod Claude, Kodeks, Kursor, Cline com um clique
- **100% TypeScript** — Kodigo limpo e tipado
### 📖 Dokumentacja
| Dokument | Opis |
| ----------------------------------------------- | ----------------------------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, kombinacje, CLI, wdrażanie |
| [Referência da API](docs/API_REFERENCE.md) | Wszystkie punkty końcowe systemu operacyjnego z przykładami |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do systemu |
| [Contribuição](CONTRIBUTING.md) | Konfiguracja desenvolvimento e wytyczne |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Kompletna instrukcja: VM + nginx + Cloudflare |
### 📧 Wsparcie
> 💬 **Enter para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tyre duvidas, compartilhe dicas e fique atualizado.
- **Strona internetowa**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Problemy**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Zbudowany z ❤️ dla programistów, którzy kodują 24 godziny na dobę, 7 dni w tygodniu</sub>
<br/>
+100 -129
View File
@@ -247,6 +247,45 @@ docker compose --profile cli up -d
---
---
## 🖥️ Aplicativo Desktop — Offline e Sempre Ativo
> 🆕 **NOVO!** O OmniRoute agora está disponível como **aplicativo desktop nativo** para Windows, macOS e Linux.
Execute o OmniRoute como um aplicativo desktop autônomo — sem terminal, sem navegador, sem internet necessária para modelos locais. O app baseado em Electron inclui:
- 🖥️ **Janela Nativa** — Janela dedicada com integração à bandeja do sistema
- 🔄 **Iniciar Automaticamente** — Inicie o OmniRoute ao fazer login no sistema
- 🔔 **Notificações Nativas** — Receba alertas sobre esgotamento de cota ou problemas
- ⚡ **Instalação com Um Clique** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Modo Offline** — Funciona totalmente offline com servidor embarcado
### Início Rápido
```bash
# Modo desenvolvimento
npm run electron:dev
# Compilar para sua plataforma
npm run electron:build # Plataforma atual
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg) — x64 & arm64
npm run electron:build:linux # Linux (.AppImage)
```
### Bandeja do Sistema
Quando minimizado, o OmniRoute fica na bandeja do sistema com ações rápidas:
- Abrir dashboard
- Alterar porta do servidor
- Sair do aplicativo
📖 Documentação completa: [`electron/README.md`](electron/README.md)
---
## 💰 Preços Resumidos
| Tier | Provedor | Custo | Reset de Cota | Melhor Para |
@@ -272,67 +311,6 @@ docker compose --profile cli up -d
---
## 🎯 Casos de Uso
### Caso 1: "Tenho assinatura Claude Pro"
**Problema:** Cota expira sem uso, limites de taxa durante programação intensa
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (usar assinatura ao máximo)
2. glm/glm-4.7 (backup barato quando a cota acabar)
3. if/kimi-k2-thinking (fallback de emergência gratuito)
Custo mensal: $20 (assinatura) + ~$5 (backup) = $25 total
vs. $20 + bater em limites = frustração
```
### Caso 2: "Quero custo zero"
**Problema:** Não pode pagar assinaturas, precisa de IA confiável para programar
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K grátis/mês)
2. if/kimi-k2-thinking (ilimitado grátis)
3. qw/qwen3-coder-plus (ilimitado grátis)
Custo mensal: $0
Qualidade: Modelos prontos para produção
```
### Caso 3: "Preciso programar 24/7, sem interrupções"
**Problema:** Prazos apertados, não pode ter tempo de inatividade
```
Combo: "always-on"
1. cc/claude-opus-4-6 (melhor qualidade)
2. cx/gpt-5.2-codex (segunda assinatura)
3. glm/glm-4.7 (barato, reset diário)
4. minimax/MiniMax-M2.1 (mais barato, reset 5h)
5. if/kimi-k2-thinking (gratuito ilimitado)
Resultado: 5 camadas de fallback = zero tempo de inatividade
```
### Caso 4: "Quero IA GRATUITA no OpenClaw"
**Problema:** Precisa de assistente de IA em aplicativos de mensagens, completamente gratuito
```
Combo: "openclaw-free"
1. if/glm-4.7 (ilimitado grátis)
2. if/minimax-m2.1 (ilimitado grátis)
3. if/kimi-k2-thinking (ilimitado grátis)
Custo mensal: $0
Acesso via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Funcionalidades Principais
### 🧠 Roteamento e Inteligência
@@ -487,6 +465,67 @@ O OmniRoute inclui um poderoso Playground de Tradução integrado com **4 modos*
---
## 🎯 Casos de Uso
### Caso 1: "Tenho assinatura Claude Pro"
**Problema:** Cota expira sem uso, limites de taxa durante programação intensa
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (usar assinatura ao máximo)
2. glm/glm-4.7 (backup barato quando a cota acabar)
3. if/kimi-k2-thinking (fallback de emergência gratuito)
Custo mensal: $20 (assinatura) + ~$5 (backup) = $25 total
vs. $20 + bater em limites = frustração
```
### Caso 2: "Quero custo zero"
**Problema:** Não pode pagar assinaturas, precisa de IA confiável para programar
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K grátis/mês)
2. if/kimi-k2-thinking (ilimitado grátis)
3. qw/qwen3-coder-plus (ilimitado grátis)
Custo mensal: $0
Qualidade: Modelos prontos para produção
```
### Caso 3: "Preciso programar 24/7, sem interrupções"
**Problema:** Prazos apertados, não pode ter tempo de inatividade
```
Combo: "always-on"
1. cc/claude-opus-4-6 (melhor qualidade)
2. cx/gpt-5.2-codex (segunda assinatura)
3. glm/glm-4.7 (barato, reset diário)
4. minimax/MiniMax-M2.1 (mais barato, reset 5h)
5. if/kimi-k2-thinking (gratuito ilimitado)
Resultado: 5 camadas de fallback = zero tempo de inatividade
```
### Caso 4: "Quero IA GRATUITA no OpenClaw"
**Problema:** Precisa de assistente de IA em aplicativos de mensagens, completamente gratuito
```
Combo: "openclaw-free"
1. if/glm-4.7 (ilimitado grátis)
2. if/minimax-m2.1 (ilimitado grátis)
3. if/kimi-k2-thinking (ilimitado grátis)
Custo mensal: $0
Acesso via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Guia de Configuração
<details>
@@ -767,74 +806,6 @@ Configurações → Configuração de API:
---
## 📊 Modelos Disponíveis
<details>
<summary><b>Ver todos os modelos disponíveis</b></summary>
**Claude Code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - GRATUITO:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - Créditos GRATUITOS:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ mais modelos em [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0.6/1M:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0.2/1M:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - GRATUITO:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - GRATUITO:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - GRATUITO:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ modelos:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Qualquer modelo de [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Avaliações (Evals)
OmniRoute inclui um framework de avaliação integrado para testar a qualidade de respostas de LLM contra um conjunto golden. Acesse via **Analytics → Evals** no dashboard.
+140 -267
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — O gateway de IA gratuito
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Nunca pare de codificar. Roteamento inteligente para **modelos de IA GRATUITOS e de baixo custo** com fallback automático.
_Seu proxy de API universal — um endpoint, mais de 36 provedores, tempo de inatividade zero._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Visão geral dos preços
| Nível | Provedor | Custo | Redefinição de cota | Melhor para |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Casos de uso
### Caso 1: "Tenho assinatura do Claude Pro"
**Problema:** A cota expira sem ser utilizada, limites de taxa durante codificação pesada
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Caso 2: "Quero custo zero"
**Problema:** Não posso pagar assinaturas, preciso de codificação de IA confiável
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Caso 3: "Preciso de codificação 24 horas por dia, 7 dias por semana, sem interrupções"
**Problema:** Prazos, não podemos arcar com o tempo de inatividade
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Caso 4: "Quero IA GRATUITA no OpenClaw"
**Problema:** Precisa de assistente de IA em aplicativos de mensagens, totalmente gratuito
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Principais recursos
### 🧠 Roteamento e inteligência central
@@ -495,6 +456,67 @@ OmniRoute inclui um poderoso Translator Playground integrado com **4 modos** par
---
## 🎯 Casos de uso
### Caso 1: "Tenho assinatura do Claude Pro"
**Problema:** A cota expira sem ser utilizada, limites de taxa durante codificação pesada
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Caso 2: "Quero custo zero"
**Problema:** Não posso pagar assinaturas, preciso de codificação de IA confiável
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Caso 3: "Preciso de codificação 24 horas por dia, 7 dias por semana, sem interrupções"
**Problema:** Prazos, não podemos arcar com o tempo de inatividade
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Caso 4: "Quero IA GRATUITA no OpenClaw"
**Problema:** Precisa de assistente de IA em aplicativos de mensagens, totalmente gratuito
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Guia de configuração
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Modelos Disponíveis
<details>
<summary><b>Ver todos os modelos disponíveis</b></summary>
**Código Claude (`cc/`)** - Pro/Máx:
- `cc/claude-opus-4-6`
- `cc/claude-sonnet-4-5-20250929`
- `cc/claude-haiku-4-5-20251001`
**Códice (`cx/`)** - Plus/Pro:
- `cx/gpt-5.2-codex`
- `cx/gpt-5.1-codex-max`
**Gemini CLI (`gc/`)** - GRATUITO:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**Copiloto do GitHub (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - Créditos GRATUITOS:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- Mais de 50 modelos em [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - US$ 0,6/1 milhão:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - US$ 0,2/1 milhão:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - GRATUITO:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - GRATUITO:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - GRATUITO:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - mais de 100 modelos:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Qualquer modelo de [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Avaliações (Evals)
OmniRoute inclui uma estrutura de avaliação integrada para testar a qualidade da resposta do LLM em relação a um conjunto dourado. Acesse-o em **Analytics → Evals** no painel.
@@ -866,13 +820,64 @@ O "OmniRoute Golden Set" pré-carregado contém 10 casos de teste cobrindo:
---
## 🔐 OAuth em Servidor Remoto (Remote OAuth Setup)
## 🐛 Solução de problemas
<details>
<summary><b>Clique para expandir o guia de solução de problemas</b></summary>
**"O modelo de linguagem não forneceu mensagens"**
- Cota do provedor esgotada → Verifique o rastreador de cota do painel
- Solução: use o combo substituto ou mude para um nível mais barato
** Limitação de taxa **
- Cota de assinatura esgotada → Fallback para GLM/MiniMax
- Adicionar combinação: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**O token OAuth expirou**
- Atualizado automaticamente pelo OmniRoute
- Se os problemas persistirem: Painel → Provedor → Reconectar
**Custos elevados**
- Verifique as estatísticas de uso em Painel → Custos
- Mude o modelo primário para GLM/MiniMax
- Use o nível gratuito (Gemini CLI, iFlow) para tarefas não críticas
**Painel abre na porta errada**
- Definir `PORT=20128` e `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Erros de sincronização na nuvem**
- Verifique `BASE_URL` aponta para sua instância em execução
- Verifique os pontos `CLOUD_URL` para o endpoint de nuvem esperado
- Mantenha os valores `NEXT_PUBLIC_*` alinhados com os valores do lado do servidor
**Primeiro login não funciona**
- Verifique `INITIAL_PASSWORD` em `.env`
- Se não definida, a senha substituta é `123456`
**Sem registros de solicitação**
- Definir `ENABLE_REQUEST_LOGS=true` em `.env`
**O teste de conexão mostra "Inválido" para provedores compatíveis com OpenAI**
- Muitos provedores não expõem um endpoint `/models`
- OmniRoute v1.0.6+ inclui validação de fallback por meio de conclusões de chat
- Certifique-se de que o URL base inclua o sufixo `/v1`
### 🔐 OAuth em Servidor Remoto (Remote OAuth Setup)
<a name="oauth-em-servidor-remoto"></a>
> **⚠️ IMPORTANTE para usuários com OmniRoute em VPS/Docker/servidor remoto**
### Por que o OAuth do Antigravity / Gemini CLI falha em servidores remotos?
#### Por que o OAuth do Antigravity / Gemini CLI falha em servidores remotos?
Os provedores **Antigravity** e **Gemini CLI** usam **Google OAuth 2.0** para autenticação. O Google exige que um `redirect_uri` usado no fluxo OAuth seja **exatamente** uma das URIs pré-cadastradas no Google Cloud Console do aplicativo.
@@ -882,7 +887,7 @@ As credenciais OAuth incorporadas no OmniRoute estão cadastradas **apenas para
Error 400: redirect_uri_mismatch
```
### Solução: Configure suas próprias credenciais OAuth
#### Solução: Configure suas próprias credenciais OAuth
Você precisa criar um **OAuth 2.0 Client ID** no Google Cloud Console com o URI do seu servidor.
@@ -945,7 +950,7 @@ Agora o Google redirecionará corretamente para `https://seu-servidor.com/callba
---
### Solução alternativa temporária (sem configurar credenciais próprias)
#### Solução alternativa temporária (sem configurar credenciais próprias)
Se não quiser criar credenciais próprias agora, ainda é possível usar o fluxo **manual de URL**:
@@ -957,59 +962,6 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
> Esta solução alternativa funciona porque o código de autorização na URL é válido, independentemente do redirecionamento ter sido carregado ou não.
---
## 🐛 Solução de problemas
<details>
<summary><b>Clique para expandir o guia de solução de problemas</b></summary>
**"O modelo de linguagem não forneceu mensagens"**
- Cota do provedor esgotada → Verifique o rastreador de cota do painel
- Solução: use o combo substituto ou mude para um nível mais barato
** Limitação de taxa **
- Cota de assinatura esgotada → Fallback para GLM/MiniMax
- Adicionar combinação: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**O token OAuth expirou**
- Atualizado automaticamente pelo OmniRoute
- Se os problemas persistirem: Painel → Provedor → Reconectar
**Custos elevados**
- Verifique as estatísticas de uso em Painel → Custos
- Mude o modelo primário para GLM/MiniMax
- Use o nível gratuito (Gemini CLI, iFlow) para tarefas não críticas
**Painel abre na porta errada**
- Definir `PORT=20128` e `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Erros de sincronização na nuvem**
- Verifique `BASE_URL` aponta para sua instância em execução
- Verifique os pontos `CLOUD_URL` para o endpoint de nuvem esperado
- Mantenha os valores `NEXT_PUBLIC_*` alinhados com os valores do lado do servidor
**Primeiro login não funciona**
- Verifique `INITIAL_PASSWORD` em `.env`
- Se não definida, a senha substituta é `123456`
**Sem registros de solicitação**
- Definir `ENABLE_REQUEST_LOGS=true` em `.env`
**O teste de conexão mostra "Inválido" para provedores compatíveis com OpenAI**
- Muitos provedores não expõem um endpoint `/models`
- OmniRoute v1.0.6+ inclui validação de fallback por meio de conclusões de chat
- Certifique-se de que o URL base inclua o sufixo `/v1`
</details>
---
@@ -1152,85 +1104,6 @@ Licença MIT - consulte [LICENSE](LICENSE) para obter detalhes.
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codificar. Roteamento inteligente para **modelos de IA GRATUITOS e de baixo custo** com fallback automático.
_Seu proxy universal de API — um endpoint, mais de 36 provedores, tempo de inatividade zero._
### 🌐 Internacionalização (i18n)
O painel do OmniRoute suporta **múltiplos idiomas**. Atualmente disponível em:
| Idioma | Código | Estado |
| --------------------- | ------- | ----------- |
| 🇺🇸 Inglês | `en` | ✅ Completo |
| 🇧🇷 Português (Brasil) | `pt-BR` | ✅ Completo |
**Para alterar o idioma:** Clique no seletor de idioma (🇺🇸 PT) no cabeçalho do painel → selecione o idioma desejado.
**Para adicionar um novo idioma:**
1. Crie `src/i18n/messages/{codigo}.json` baseado em `en.json`
2. Adicione o código em `src/i18n/config.ts``LOCALES` e `LANGUAGES`
3. Reinicie o servidor
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Docker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ provedores de IA** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek, e mais
- **Roteamento inteligente** — Fallback automático entre provedores
- **Tradução de formato** — OpenAI ↔ Claude ↔ Gemini automaticamente
- **Multi-conta** — Múltiplas contas por provedor com seleção inteligente
- **Cache semântico** — Reduz custos e latência
- **OAuth automático** — Tokens renovam automaticamente
- **Combos personalizados** — 6 estratégias de roteamento
- **Dashboard completo** — Monitoramento, logs, análises, configurações
- **Ferramentas CLI** — Configure Claude Code, Codex, Cursor, Cline com um clique
- **100% TypeScript** — Código limpo e digitado
### 📖 Documentação
| Documento | Descrição |
| ----------------------------------------------- | -------------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, combos, CLI, implantar |
| [Referência da API](docs/API_REFERENCE.md) | Todos os endpoints com exemplos |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e portas do sistema |
| [Contribuição](CONTRIBUTING.md) | Configuração de desenvolvimento e diretrizes |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Guia completo: VM + nginx + Cloudflare |
### 📧Suporte
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tire dúvidas, compartilhe dicas e fique atualizado.
- **Site**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Problemas**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Construído com ❤️ para desenvolvedores que codificam 24 horas por dia, 7 dias por semana</sub>
<br/>
+138 -265
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — Gateway-ul gratuit AI
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Nu opriți niciodată codificarea. Dirijare inteligentă către **modele AI GRATUITE și cu costuri reduse** cu rezervă automată.
_Proxy-ul dvs. universal API - un punct final, peste 36 de furnizori, zero timpi de nefuncționare._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Prețurile dintr-o privire
| Nivelul | Furnizor | Cost | Resetare cotă | Cel mai bun pentru |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Cazuri de utilizare
### Cazul 1: „Am abonament Claude Pro”
**Problemă:** Cota expiră neutilizată, limitele ratei în timpul codării grele
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Cazul 2: „Vreau cost zero”
**Problemă:** Nu-mi permit abonamente, au nevoie de codare AI de încredere
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Cazul 3: „Am nevoie de codare 24/7, fără întreruperi”
**Problemă:** Termenele limită, nu-mi permit timpi de nefuncționare
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Cazul 4: „Vreau AI GRATUIT în OpenClaw”
**Problemă:** Aveți nevoie de asistent AI în aplicațiile de mesagerie, complet gratuit
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Caracteristici cheie
### 🧠 Core Routing & Intelligence
@@ -495,6 +456,67 @@ OmniRoute include un puternic Translator Playground încorporat cu **4 moduri**
---
## 🎯 Cazuri de utilizare
### Cazul 1: „Am abonament Claude Pro”
**Problemă:** Cota expiră neutilizată, limitele ratei în timpul codării grele
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Cazul 2: „Vreau cost zero”
**Problemă:** Nu-mi permit abonamente, au nevoie de codare AI de încredere
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Cazul 3: „Am nevoie de codare 24/7, fără întreruperi”
**Problemă:** Termenele limită, nu-mi permit timpi de nefuncționare
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Cazul 4: „Vreau AI GRATUIT în OpenClaw”
**Problemă:** Aveți nevoie de asistent AI în aplicațiile de mesagerie, complet gratuit
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Ghid de configurare
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Modele disponibile
<details>
<summary><b>Vedeți toate modelele disponibile</b></summary>
**Cod Claude (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**CLI Gemini (`gc/`)** - GRATUIT:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**Copilot GitHub (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - credite GRATUITE:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- Mai mult de 50 de modele pe [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - 0,6 USD/1 milion:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - 0,2 USD/1 milion:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - GRATUIT:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - GRATUIT:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - GRATUIT:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - peste 100 de modele:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Orice model de la [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Evaluări (Evaluări)
OmniRoute include un cadru de evaluare încorporat pentru a testa calitatea răspunsului LLM față de un set de aur. Accesați-l prin **Analitice → Evaluări** în tabloul de bord.
@@ -866,13 +820,64 @@ OmniRoute include un cadru de evaluare încorporat pentru a testa calitatea răs
---
## 🔐 OAuth em Servidor Remoto (Configurare OAuth la distanță)
## 🐛 Depanare
<details>
<summary><b>Faceți clic pentru a extinde ghidul de depanare</b></summary>
**„Modelul de limbă nu a furnizat mesaje”**
- Cota de furnizor epuizată → Verificați instrumentul de urmărire a cotei din tabloul de bord
- Soluție: utilizați alternativă combinată sau treceți la un nivel mai ieftin
**Limitarea ratei**
- Scăderea cotei de abonament → Fallback la GLM/MiniMax
- Adăugați combo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Tokenul OAuth a expirat**
- Reîmprospătat automat de OmniRoute
- Dacă problemele persistă: Dashboard → Provider → Reconnect
**Costuri mari**
- Verificați statisticile de utilizare în Tabloul de bord → Costuri
- Comutați modelul principal la GLM/MiniMax
- Utilizați nivelul gratuit (Gemini CLI, iFlow) pentru sarcini necritice
**Tabloul de bord se deschide pe portul greșit**
- Setați `PORT=20128` și `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Erori de sincronizare în cloud**
- Verificați `BASE_URL` puncte către instanța dvs. care rulează
- Verificați `CLOUD_URL` puncte către punctul final din cloud așteptat
- Păstrați valorile `NEXT_PUBLIC_*` aliniate cu valorile de pe partea serverului
**Prima conectare nu funcționează**
- Verificați `INITIAL_PASSWORD` în `.env`
- Dacă nu este setată, parola de rezervă este `123456`
**Fără jurnal de solicitare**
- Setați `ENABLE_REQUEST_LOGS=true` în `.env`
**Testul de conectare arată „Invalid” pentru furnizorii compatibili cu OpenAI**
- Mulți furnizori nu expun un punct final `/models`
- OmniRoute v1.0.6+ include validarea de rezervă prin finalizarea chatului
- Asigurați-vă că adresa URL de bază include sufixul `/v1`
### 🔐 OAuth em Servidor Remoto (Configurare OAuth la distanță)
<a name="oauth-em-servidor-remoto"></a>
> **⚠️ IMPORTANT pentru utilizatorii cu OmniRoute în VPS/Docker/servidor remoto**
### Por que o OAuth do Antigravity / Gemini CLI falha em serveres remotes?
#### Por que o OAuth do Antigravity / Gemini CLI falha em serveres remotes?
Pentru autentificare, **Antigravity** și **Gemini CLI** folosesc **Google OAuth 2.0**. O Google exige que a `redirect_uri` utilizat nu fluxo OAuth seja **exatamente** uma das URIs pre-cadastradas no Google Cloud Console do aplicative.
@@ -957,59 +962,6 @@ Nu vă rugăm să vă convingeți acum, dar este posibil să utilizați sau să
> Această soluție de soluționare funcționează deoarece codul de autorizare a URL-ului este valabil independent de redirecționare pentru a încărca sau nu.
---
## 🐛 Depanare
<details>
<summary><b>Faceți clic pentru a extinde ghidul de depanare</b></summary>
**„Modelul de limbă nu a furnizat mesaje”**
- Cota de furnizor epuizată → Verificați instrumentul de urmărire a cotei din tabloul de bord
- Soluție: utilizați alternativă combinată sau treceți la un nivel mai ieftin
**Limitarea ratei**
- Scăderea cotei de abonament → Fallback la GLM/MiniMax
- Adăugați combo: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Tokenul OAuth a expirat**
- Reîmprospătat automat de OmniRoute
- Dacă problemele persistă: Dashboard → Provider → Reconnect
**Costuri mari**
- Verificați statisticile de utilizare în Tabloul de bord → Costuri
- Comutați modelul principal la GLM/MiniMax
- Utilizați nivelul gratuit (Gemini CLI, iFlow) pentru sarcini necritice
**Tabloul de bord se deschide pe portul greșit**
- Setați `PORT=20128` și `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Erori de sincronizare în cloud**
- Verificați `BASE_URL` puncte către instanța dvs. care rulează
- Verificați `CLOUD_URL` puncte către punctul final din cloud așteptat
- Păstrați valorile `NEXT_PUBLIC_*` aliniate cu valorile de pe partea serverului
**Prima conectare nu funcționează**
- Verificați `INITIAL_PASSWORD` în `.env`
- Dacă nu este setată, parola de rezervă este `123456`
**Fără jurnal de solicitare**
- Setați `ENABLE_REQUEST_LOGS=true` în `.env`
**Testul de conectare arată „Invalid” pentru furnizorii compatibili cu OpenAI**
- Mulți furnizori nu expun un punct final `/models`
- OmniRoute v1.0.6+ include validarea de rezervă prin finalizarea chatului
- Asigurați-vă că adresa URL de bază include sufixul `/v1`
</details>
---
@@ -1152,85 +1104,6 @@ Licență MIT - consultați [LICENSE](LICENSE) pentru detalii.
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento inteligente pentru **modele de IA GRATUITE și de baixo custo** com fallback automático.
_Seu proxy universal de API — um endpoint, peste 36 de probe, zero downtime._
### 🌐 Internaționalizare (i18n)
O tablou de bord pentru OmniRoute suportă **multiplos idiomas**. De fapt, sunt disponibile:
| Idioma | Cod | Stare |
| ----------------------- | ------- | ---------- |
| 🇺🇸 engleză | `en` | ✅ Complet |
| 🇧🇷 Português (Brazilia) | `pt-BR` | ✅ Complet |
**Para trocar o idioma:** Clique no selector de idioma (🇺🇸 EN) no header do dashboard → selecione o idioma desejado.
**Para adicionar um nou idioma:**
1. Plânge `src/i18n/messages/{codigo}.json` bazat pe `en.json`
2. Adăugați codul în `src/i18n/config.ts``LOCALES` și `LANGUAGES`
3. Reinicie o servidor
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Docker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcționalități principale
- **36+ provedores de IA** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek, și mai mult
- **Roteamento inteligente** — Fallback automat entre provedores
- **Tradução de format** — OpenAI ↔ Claude ↔ Gemeni automaticamente
- **Multi-conta** — Múltiplas contas por provedor com seleção inteligente
- **Cache semântico** — Reduz custos e latência
- **OAuth automat** — Jetoane renovate automat
- **Combos personalizados** — 6 estratégias de roteamento
- **Dashboard complet** — Monitorizare, jurnale, analize, configurații
- **CLI Tools** — Configurați Claude Code, Codex, Cursor, Cline com um clique
- **100% TypeScript** — Código limpo e tipado
### 📖 Documentação
| Documento | Descriere |
| ----------------------------------------------- | ---------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, combo-uri, CLI, implementare |
| [Referência da API](docs/API_REFERENCE.md) | Toate punctele finale, cum ar fi exemple |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do sistema |
| [Contribuição](CONTRIBUTING.md) | Configurare de dezvoltare și ghiduri |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Ghid complet: VM + nginx + Cloudflare |
### 📧 Suport
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tire dúvidas, compartilhe dicas e fique atualizado.
- **Site web**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Probleme**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Construit cu ❤️ pentru dezvoltatorii care codifică 24/7</sub>
<br/>
+85 -129
View File
@@ -247,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Настольное Приложение — Оффлайн и Всегда Активно
> 🆕 **НОВИНКА!** OmniRoute теперь доступен как **нативное настольное приложение** для Windows, macOS и Linux.
- 🖥️ **Нативное Окно** — Выделенное окно с интеграцией в системный трей
- 🔄 **Автозапуск** — Запуск OmniRoute при входе в систему
- 🔔 **Нативные Уведомления** — Оповещения об исчерпании квоты
- ⚡ **Установка в Один Клик** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Оффлайн Режим** — Полностью работает без интернета
```bash
npm run electron:dev # Режим разработки
npm run electron:build # Текущая платформа
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Полная документация: [`electron/README.md`](electron/README.md)
---
## 💰 Обзор цен
| Tier | Провайдер | Стоимость | Сброс квоты | Лучше всего для |
@@ -272,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Сценарии использования
### Сценарий 1: «У меня подписка Claude Pro»
**Проблема:** Квота истекает неиспользованной, лимиты скорости во время интенсивного программирования
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (используйте подписку полностью)
2. glm/glm-4.7 (дешёвый бэкап при исчерпании квоты)
3. if/kimi-k2-thinking (бесплатный аварийный fallback)
Месячная стоимость: $20 (подписка) + ~$5 (бэкап) = $25 итого
vs. $20 + упирание в лимиты = разочарование
```
### Сценарий 2: «Хочу нулевую стоимость»
**Проблема:** Не может позволить подписки, нужен надёжный AI для программирования
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K бесплатно/мес)
2. if/kimi-k2-thinking (неограниченно бесплатно)
3. qw/qwen3-coder-plus (неограниченно бесплатно)
Месячная стоимость: $0
Качество: Модели готовые к продакшену
```
### Сценарий 3: «Мне нужно программировать 24/7, без перерывов»
**Проблема:** Дедлайны, не может позволить простой
```
Combo: "always-on"
1. cc/claude-opus-4-6 (лучшее качество)
2. cx/gpt-5.2-codex (вторая подписка)
3. glm/glm-4.7 (дешёвый, ежедневный сброс)
4. minimax/MiniMax-M2.1 (самый дешёвый, сброс 5ч)
5. if/kimi-k2-thinking (бесплатно неограниченно)
Результат: 5 уровней fallback = нулевой простой
```
### Сценарий 4: «Хочу БЕСПЛАТНЫЙ AI в OpenClaw»
**Проблема:** Нужен AI-ассистент в мессенджерах, полностью бесплатно
```
Combo: "openclaw-free"
1. if/glm-4.7 (неограниченно бесплатно)
2. if/minimax-m2.1 (неограниченно бесплатно)
3. if/kimi-k2-thinking (неограниченно бесплатно)
Месячная стоимость: $0
Доступ через: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Основные функции
### 🧠 Маршрутизация и интеллект
@@ -474,6 +437,67 @@ Combo: "my-coding-stack"
---
## 🎯 Сценарии использования
### Сценарий 1: «У меня подписка Claude Pro»
**Проблема:** Квота истекает неиспользованной, лимиты скорости во время интенсивного программирования
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (используйте подписку полностью)
2. glm/glm-4.7 (дешёвый бэкап при исчерпании квоты)
3. if/kimi-k2-thinking (бесплатный аварийный fallback)
Месячная стоимость: $20 (подписка) + ~$5 (бэкап) = $25 итого
vs. $20 + упирание в лимиты = разочарование
```
### Сценарий 2: «Хочу нулевую стоимость»
**Проблема:** Не может позволить подписки, нужен надёжный AI для программирования
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K бесплатно/мес)
2. if/kimi-k2-thinking (неограниченно бесплатно)
3. qw/qwen3-coder-plus (неограниченно бесплатно)
Месячная стоимость: $0
Качество: Модели готовые к продакшену
```
### Сценарий 3: «Мне нужно программировать 24/7, без перерывов»
**Проблема:** Дедлайны, не может позволить простой
```
Combo: "always-on"
1. cc/claude-opus-4-6 (лучшее качество)
2. cx/gpt-5.2-codex (вторая подписка)
3. glm/glm-4.7 (дешёвый, ежедневный сброс)
4. minimax/MiniMax-M2.1 (самый дешёвый, сброс 5ч)
5. if/kimi-k2-thinking (бесплатно неограниченно)
Результат: 5 уровней fallback = нулевой простой
```
### Сценарий 4: «Хочу БЕСПЛАТНЫЙ AI в OpenClaw»
**Проблема:** Нужен AI-ассистент в мессенджерах, полностью бесплатно
```
Combo: "openclaw-free"
1. if/glm-4.7 (неограниченно бесплатно)
2. if/minimax-m2.1 (неограниченно бесплатно)
3. if/kimi-k2-thinking (неограниченно бесплатно)
Месячная стоимость: $0
Доступ через: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Руководство по настройке
<details>
@@ -754,74 +778,6 @@ Dashboard → CLI Tools → OpenClaw → Выбрать модель → При
---
## 📊 Доступные модели
<details>
<summary><b>Посмотреть все доступные модели</b></summary>
**Claude Code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - БЕСПЛАТНО:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - БЕСПЛАТНЫЕ кредиты:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ моделей на [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0.6/1M:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0.2/1M:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - БЕСПЛАТНО:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - БЕСПЛАТНО:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - БЕСПЛАТНО:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ моделей:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Любая модель с [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Оценки (Evals)
OmniRoute включает встроенный фреймворк оценки для тестирования качества ответов LLM по golden set. Доступ через **Analytics → Evals** в dashboard.
+137 -264
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — bezplatná brána AI
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Nikdy neprestávajte kódovať. Inteligentné smerovanie na **BEZPLATNÉ a nízkonákladové modely AI** s automatickým vrátením.
_Váš univerzálny proxy server API jeden koncový bod, 36+ poskytovateľov, nulové prestoje._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Prehľad cien
| Úroveň | Poskytovateľ | Náklady | Obnovenie kvóty | Najlepšie pre |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Prípady použitia
### Prípad 1: „Mám predplatné Claude Pro“
**Problém:** Platnosť kvóty vyprší nevyužitá, obmedzenia sadzieb počas náročného kódovania
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Prípad 2: „Chcem nulové náklady“
**Problém:** Nemôžem si dovoliť predplatné, potrebujem spoľahlivé kódovanie AI
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Prípad 3: „Potrebujem kódovanie 24/7, žiadne prerušenia“
**Problém:** Termíny, nemôžem si dovoliť prestoje
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Prípad 4: „Chcem AI ZDARMA v OpenClaw“
**Problém:** Potrebujete asistenta AI v aplikáciách na odosielanie správ, úplne zadarmo
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Kľúčové vlastnosti
### 🧠 Základné smerovanie a inteligencia
@@ -496,6 +457,67 @@ OmniRoute obsahuje výkonné vstavané ihrisko pre prekladateľov so **4 režima
---
## 🎯 Prípady použitia
### Prípad 1: „Mám predplatné Claude Pro“
**Problém:** Platnosť kvóty vyprší nevyužitá, obmedzenia sadzieb počas náročného kódovania
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Prípad 2: „Chcem nulové náklady“
**Problém:** Nemôžem si dovoliť predplatné, potrebujem spoľahlivé kódovanie AI
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Prípad 3: „Potrebujem kódovanie 24/7, žiadne prerušenia“
**Problém:** Termíny, nemôžem si dovoliť prestoje
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Prípad 4: „Chcem AI ZDARMA v OpenClaw“
**Problém:** Potrebujete asistenta AI v aplikáciách na odosielanie správ, úplne zadarmo
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Sprievodca nastavením
<details>
@@ -776,74 +798,6 @@ Settings → API Configuration:
---
## 📊 Dostupné modely
<details>
<summary><b>Zobraziť všetky dostupné modely</b></summary>
**Claude Code (`cc/`)** Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** ZDARMA:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** BEZPLATNÉ kredity:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ ďalších modelov na [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** 0,6 USD/1 milión:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** 0,2 USD/1 milión:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** ZDARMA:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** ZDARMA:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** ZDARMA:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** viac ako 100 modelov:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Akýkoľvek model od [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Hodnotenia (Evals)
OmniRoute obsahuje vstavaný hodnotiaci rámec na testovanie kvality odozvy LLM oproti zlatému súboru. Prístup k nej získate cez **Analytics → Evals** na hlavnom paneli.
@@ -867,7 +821,58 @@ Predinštalovaná sada „OmniRoute Golden Set“ obsahuje 10 testovacích príp
---
## 🔐 OAuth em Servidor Remoto (Vzdialené nastavenie OAuth)
## 🐛 Riešenie problémov
<details>
<summary><b>Kliknutím rozbalíte sprievodcu riešením problémov</b></summary>
**„Jazykový model neposkytol správy“**
- Kvóta poskytovateľa je vyčerpaná → Skontrolujte sledovanie kvót na paneli
- Riešenie: Použite záložnú kombináciu alebo prejdite na lacnejšiu úroveň
**Obmedzenie sadzby**
- Vyčerpaná kvóta predplatného → Návrat na GLM/MiniMax
- Pridať kombináciu: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Platnosť tokenu OAuth vypršala**
- Automaticky obnovuje OmniRoute
- Ak problémy pretrvávajú: Dashboard → Provider → Reconnect
**Vysoké náklady**
- Skontrolujte štatistiky používania v hlavnom paneli → Náklady
- Prepnite primárny model na GLM/MiniMax
- Používajte bezplatnú vrstvu (Gemini CLI, iFlow) pre nekritické úlohy
**Palubná doska sa otvára na nesprávnom porte**
- Nastavte `PORT=20128` a `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Chyby synchronizácie v cloude**
- Overte `BASE_URL` body na vašu spustenú inštanciu
Overte `CLOUD_URL` bodov k očakávanému koncovému bodu cloudu
- Ponechajte hodnoty `NEXT_PUBLIC_*` zarovnané s hodnotami na strane servera
**Prvé prihlásenie nefunguje**
- Skontrolujte `INITIAL_PASSWORD` v `.env`
Ak nie je nastavené, záložné heslo je `123456`
**Žiadne záznamy žiadostí**
- Nastaviť `ENABLE_REQUEST_LOGS=true` v `.env`
**Test pripojenia ukazuje „Neplatné“ pre poskytovateľov kompatibilných s OpenAI**
- Mnohí poskytovatelia nevystavujú koncový bod `/models`
- OmniRoute v1.0.6+ zahŕňa záložné overenie prostredníctvom dokončenia chatu
- Uistite sa, že základná adresa URL obsahuje príponu `/v1`
### 🔐 OAuth em Servidor Remoto (Vzdialené nastavenie OAuth)
<a name="oauth-em-servidor-remoto"></a>
@@ -958,59 +963,6 @@ Ak chcete získať prístup k dôvere, môžete použiť **príručku URL**:
> Toto riešenie funguje pomocou autorizačného kódu na adrese URL a nezávislého presmerovania.
---
## 🐛 Riešenie problémov
<details>
<summary><b>Kliknutím rozbalíte sprievodcu riešením problémov</b></summary>
**„Jazykový model neposkytol správy“**
- Kvóta poskytovateľa je vyčerpaná → Skontrolujte sledovanie kvót na paneli
- Riešenie: Použite záložnú kombináciu alebo prejdite na lacnejšiu úroveň
**Obmedzenie sadzby**
- Vyčerpaná kvóta predplatného → Návrat na GLM/MiniMax
- Pridať kombináciu: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Platnosť tokenu OAuth vypršala**
- Automaticky obnovuje OmniRoute
- Ak problémy pretrvávajú: Dashboard → Provider → Reconnect
**Vysoké náklady**
- Skontrolujte štatistiky používania v hlavnom paneli → Náklady
- Prepnite primárny model na GLM/MiniMax
- Používajte bezplatnú vrstvu (Gemini CLI, iFlow) pre nekritické úlohy
**Palubná doska sa otvára na nesprávnom porte**
- Nastavte `PORT=20128` a `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Chyby synchronizácie v cloude**
- Overte `BASE_URL` body na vašu spustenú inštanciu
Overte `CLOUD_URL` bodov k očakávanému koncovému bodu cloudu
- Ponechajte hodnoty `NEXT_PUBLIC_*` zarovnané s hodnotami na strane servera
**Prvé prihlásenie nefunguje**
- Skontrolujte `INITIAL_PASSWORD` v `.env`
Ak nie je nastavené, záložné heslo je `123456`
**Žiadne záznamy žiadostí**
- Nastaviť `ENABLE_REQUEST_LOGS=true` v `.env`
**Test pripojenia ukazuje „Neplatné“ pre poskytovateľov kompatibilných s OpenAI**
- Mnohí poskytovatelia nevystavujú koncový bod `/models`
- OmniRoute v1.0.6+ zahŕňa záložné overenie prostredníctvom dokončenia chatu
- Uistite sa, že základná adresa URL obsahuje príponu `/v1`
</details>
---
@@ -1153,85 +1105,6 @@ Licencia MIT podrobnosti nájdete na stránke [LICENSE](LICENSE).
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento inteligentné pre **modely IA GRATUITOS a vlastné zálohy** s záložným autom.
_Seu proxy universal de API um koncový bod, 36+ overorov, nulové prestoje._
### 🌐 Internacionalização (i18n)
Prístrojová doska podporuje OmniRoute **múltiplos idiomas**. Aktuálne k dispozícii:
| Idióm | Código | Stav |
| ----------------------- | ------- | ------------ |
| 🇺🇸 anglicky | `en` | ✅ Kompletné |
| 🇧🇷 Português (Brazília) | `pt-BR` | ✅ Kompletné |
**Para trocar o idioma:** Clique no seletor de idioma (🇺🇸 EN) no header to dashboard → selectione o idioma desejado.
**Pre nový idióm:**
1. Plač `src/i18n/messages/{codigo}.json` baseado em `en.json`
2. Adicione o kódigo em `src/i18n/config.ts``LOCALES` a `LANGUAGES`
3. Reinicie o servidor
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Docker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ overores de IA** Claude, GPT, Gemini, Llama, Qwen, DeepSeek a ďalšie
- **Roteamento inteligente** — Záložné automaty entre proveores
- **Preklad formátu** — OpenAI ↔ Claude ↔ Gemini automaticamente
- **Multi-conta** — Viacnásobné obsahy s vybranými inteligentnými
- **Cache semântico** — Reduz custos e latência
- **OAuth automático** — Tokeny renovam automaticamente
- **Combos personalizados** — 6 estratégias de roteamento
- **Úplný informačný panel** Monitorovanie, protokoly, analýzy, konfigurácie
- **Nástroje CLI** Konfigurácia Claude Code, Codex, Cursor, Cline com um clique
- **100 % TypeScript** jednoduché a jednoduché označenie
### 📖 Dokumentácia
| Documento | Popis |
| ----------------------------------------------- | --------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, combá, CLI, deploy |
| [Referência da API](docs/API_REFERENCE.md) | Todos os endpoints com exemplos |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do systému |
| [Contribuição](CONTRIBUTING.md) | Nastavenie desenvolvimento e guidelines |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Guia komplet: VM + nginx + Cloudflare |
### 📧 Podporte
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — pneumatiky dúvidas, compartilhe dicas e fique atualizado.
- **Web**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Problémy**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Vytvorené pomocou ❤️ pre vývojárov, ktorí kódujú 24/7</sub>
<br/>
+137 -264
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — Den kostnadsfria AI-gatewayen
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Sluta aldrig koda. Smart routing till **GRATIS & lågkostnads AI-modeller** med automatisk reserv.
_Din universella API-proxy — en slutpunkt, 36+ leverantörer, noll driftstopp._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Prissättning i en överblick
| Nivå | Leverantör | Kostnad | Kvotåterställning | Bäst för |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Användningsfall
### Fall 1: "Jag har Claude Pro-abonnemang"
**Problem:** Kvoten går ut oanvänd, hastighetsgränser under tung kodning
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Fall 2: "Jag vill ha noll kostnad"
**Problem:** Har inte råd med prenumerationer, behöver pålitlig AI-kodning
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Fall 3: "Jag behöver kodning dygnet runt, inga avbrott"
**Problem:** Deadlines, har inte råd med driftstopp
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Fall 4: "Jag vill ha GRATIS AI i OpenClaw"
**Problem:** Behöver AI-assistent i meddelandeappar, helt gratis
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Nyckelfunktioner
### 🧠 Core Routing & Intelligence
@@ -495,6 +456,67 @@ OmniRoute inkluderar en kraftfull inbyggd översättarlekplats med **4 lägen**
---
## 🎯 Användningsfall
### Fall 1: "Jag har Claude Pro-abonnemang"
**Problem:** Kvoten går ut oanvänd, hastighetsgränser under tung kodning
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Fall 2: "Jag vill ha noll kostnad"
**Problem:** Har inte råd med prenumerationer, behöver pålitlig AI-kodning
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Fall 3: "Jag behöver kodning dygnet runt, inga avbrott"
**Problem:** Deadlines, har inte råd med driftstopp
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Fall 4: "Jag vill ha GRATIS AI i OpenClaw"
**Problem:** Behöver AI-assistent i meddelandeappar, helt gratis
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Installationsguide
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Tillgängliga modeller
<details>
<summary><b>Visa alla tillgängliga modeller</b></summary>
**Claude Code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - GRATIS:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - GRATIS krediter:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ modeller till på [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0,6/1M:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0,2/1M:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - GRATIS:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - GRATIS:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - GRATIS:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ modeller:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Alla modeller från [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Utvärderingar (Evals)
OmniRoute inkluderar ett inbyggt utvärderingsramverk för att testa LLM-svarskvalitet mot en gyllene uppsättning. Få åtkomst till det via **Analytics → Evals** i instrumentpanelen.
@@ -866,7 +820,58 @@ Det förinstallerade "OmniRoute Golden Set" innehåller 10 testfall som täcker:
---
## 🔐 OAuth em Servidor Remoto (Remote OAuth Setup)
## 🐛 Felsökning
<details>
<summary><b>Klicka för att expandera felsökningsguide</b></summary>
**"Språkmodellen gav inga meddelanden"**
- Leverantörskvoten är slut → Kontrollera instrumentpanelens kvotföljare
- Lösning: Använd kombinationsalternativ eller byt till billigare nivå
**Taxebegränsning**
- Prenumerationskvot ute → Fallback till GLM/MiniMax
- Lägg till kombination: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth-token har löpt ut**
- Automatisk uppdatering av OmniRoute
- Om problemen kvarstår: Dashboard → Leverantör → Återanslut
**Höga kostnader**
- Kontrollera användningsstatistik i Dashboard → Kostnader
- Byt primär modell till GLM/MiniMax
- Använd gratis nivå (Gemini CLI, iFlow) för icke-kritiska uppgifter
**Dashboard öppnas på fel port**
- Set `PORT=20128` och `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Molnsynkroniseringsfel**
- Verifiera att `BASE_URL` pekar på din löpinstans
- Verifiera `CLOUD_URL` poäng till din förväntade molnslutpunkt
- Håll `NEXT_PUBLIC_*` värden i linje med värden på serversidan
**Första inloggningen fungerar inte**
- Kontrollera `INITIAL_PASSWORD` i `.env`
- Om det inte är inställt är reservlösenordet `123456`
**Inga förfrågningsloggar**
- Ställ in `ENABLE_REQUEST_LOGS=true` i `.env`
**Anslutningstest visar "Invalid" för OpenAI-kompatibla leverantörer**
- Många leverantörer exponerar inte en `/models` slutpunkt
- OmniRoute v1.0.6+ inkluderar reservvalidering via chattslutföranden
- Se till att baswebbadressen innehåller suffixet `/v1`
### 🔐 OAuth em Servidor Remoto (Remote OAuth Setup)
<a name="oauth-em-servidor-remoto"></a>
@@ -957,59 +962,6 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
> Este workaround funciona porque o código de autorização na URL é válido independente do redirect ter carregado ou não.
---
## 🐛 Felsökning
<details>
<summary><b>Klicka för att expandera felsökningsguide</b></summary>
**"Språkmodellen gav inga meddelanden"**
- Leverantörskvoten är slut → Kontrollera instrumentpanelens kvotföljare
- Lösning: Använd kombinationsalternativ eller byt till billigare nivå
**Taxebegränsning**
- Prenumerationskvot ute → Fallback till GLM/MiniMax
- Lägg till kombination: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**OAuth-token har löpt ut**
- Automatisk uppdatering av OmniRoute
- Om problemen kvarstår: Dashboard → Leverantör → Återanslut
**Höga kostnader**
- Kontrollera användningsstatistik i Dashboard → Kostnader
- Byt primär modell till GLM/MiniMax
- Använd gratis nivå (Gemini CLI, iFlow) för icke-kritiska uppgifter
**Dashboard öppnas på fel port**
- Set `PORT=20128` och `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Molnsynkroniseringsfel**
- Verifiera att `BASE_URL` pekar på din löpinstans
- Verifiera `CLOUD_URL` poäng till din förväntade molnslutpunkt
- Håll `NEXT_PUBLIC_*` värden i linje med värden på serversidan
**Första inloggningen fungerar inte**
- Kontrollera `INITIAL_PASSWORD` i `.env`
- Om det inte är inställt är reservlösenordet `123456`
**Inga förfrågningsloggar**
- Ställ in `ENABLE_REQUEST_LOGS=true` i `.env`
**Anslutningstest visar "Invalid" för OpenAI-kompatibla leverantörer**
- Många leverantörer exponerar inte en `/models` slutpunkt
- OmniRoute v1.0.6+ inkluderar reservvalidering via chattslutföranden
- Se till att baswebbadressen innehåller suffixet `/v1`
</details>
---
@@ -1152,85 +1104,6 @@ MIT-licens - se [LICENSE](LICENSE) för detaljer.
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento inteligente para **modeller de IA GRATUITOS e de baixo custo** com reservautomatisk.
_Seu proxy universal de API — um endpoint, 36+ tester, noll driftstopp._
### 🌐 Internacionalização (i18n)
O instrumentpanelen gör OmniRoute stöder **múltiplos idiomas**. Attualmente disponível em:
| Idiom | Código | Status |
| ------------------------ | ------- | ----------- |
| 🇺🇸 engelska | `en` | ✅ Komplett |
| 🇧🇷 Português (Brasilien) | `pt-BR` | ✅ Komplett |
**Para trocar o idioma:** Clique no selector de idioma (🇺🇸 EN) no header do dashboard → selecione o idioma desejado.
**För att lägga till ett nytt uttryck:**
1. Crie `src/i18n/messages/{codigo}.json` baseado em `en.json`
2. Adicione o código em `src/i18n/config.ts``LOCALES` och `LANGUAGES`
3. Reinicie o servidor
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Hamnarbetare
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ provedores de IA** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek, e mais
- **Roteamento inteligente** — Fallback automático entre provedores
- **Tradução de formato** — OpenAI ↔ Claude ↔ Gemini automaticamente
- **Multi-conta** — Múltiplas contas por provedor com seleção inteligente
- **Cache semântico** — Reduz custos e latência
- **OAuth automático** — Tokens renovam automaticamente
- **Combos personalizados** — 6 estratégias de roteamento
- **Dashboard komplett** — Övervakning, loggar, analyser, konfigurationer
- **CLI-verktyg** — Konfigurera Claude Code, Codex, Cursor, Cline com um clique
- **100 % TypeScript** — Código limpo e tipado
### 📖 Dokumentation
| Dokument | Beskrivning |
| ----------------------------------------------- | --------------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, combos, CLI, distribuera |
| [Referência da API](docs/API_REFERENCE.md) | Todos os endpoints com exemplos |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do sistema |
| [Contribuição](CONTRIBUTING.md) | Inställning av desenvolvimento och riktlinjer |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Komplettera med: VM + nginx + Cloudflare |
### 📧 Stöd
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tire dúvidas, compartilhe dicas e fique atualizado.
- **Webbplats**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Frågor**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Byggd med ❤️ för utvecklare som kodar 24/7</sub>
<br/>
+136 -263
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — เกตเวย์ AI ฟรี
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### อย่าหยุดเขียนโค้ด การกำหนดเส้นทางอัจฉริยะไปยัง **โมเดล AI ฟรีและราคาประหยัด** พร้อมทางเลือกสำรองอัตโนมัติ
_พร็อกซี API สากลของคุณ — จุดสิ้นสุดเดียว ผู้ให้บริการมากกว่า 36 ราย เวลาหยุดทำงานเป็นศูนย์_
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 ราคาโดยสรุป
| ชั้น | ผู้ให้บริการ | ราคา | รีเซ็ตโควต้า | ดีที่สุดสำหรับ |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 กรณีการใช้งาน
### กรณีที่ 1: "ฉันสมัครสมาชิก Claude Pro"
**ปัญหา:** โควต้าหมดอายุโดยไม่ได้ใช้ อัตราจำกัดระหว่างการเขียนโค้ดจำนวนมาก
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### กรณีที่ 2: "ฉันต้องการต้นทุนเป็นศูนย์"
**ปัญหา:** ไม่สามารถสมัครสมาชิกได้ ต้องการการเข้ารหัส AI ที่เชื่อถือได้
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### กรณีที่ 3: "ฉันต้องการการเข้ารหัสตลอด 24 ชั่วโมงทุกวัน ไม่มีการหยุดชะงัก"
**ปัญหา:** กำหนดเวลา ไม่สามารถหยุดการทำงานได้
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### กรณีที่ 4: "ฉันต้องการ AI ฟรีใน OpenClaw"
**ปัญหา:** ต้องการผู้ช่วย AI ในแอปส่งข้อความ ไม่มีค่าใช้จ่ายใดๆ ทั้งสิ้น
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 คุณสมบัติที่สำคัญ
### 🧠 การกำหนดเส้นทางหลักและความฉลาด
@@ -494,6 +455,67 @@ OmniRoute มี Translator Playground ในตัวอันทรงพล
---
## 🎯 กรณีการใช้งาน
### กรณีที่ 1: "ฉันสมัครสมาชิก Claude Pro"
**ปัญหา:** โควต้าหมดอายุโดยไม่ได้ใช้ อัตราจำกัดระหว่างการเขียนโค้ดจำนวนมาก
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### กรณีที่ 2: "ฉันต้องการต้นทุนเป็นศูนย์"
**ปัญหา:** ไม่สามารถสมัครสมาชิกได้ ต้องการการเข้ารหัส AI ที่เชื่อถือได้
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### กรณีที่ 3: "ฉันต้องการการเข้ารหัสตลอด 24 ชั่วโมงทุกวัน ไม่มีการหยุดชะงัก"
**ปัญหา:** กำหนดเวลา ไม่สามารถหยุดการทำงานได้
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### กรณีที่ 4: "ฉันต้องการ AI ฟรีใน OpenClaw"
**ปัญหา:** ต้องการผู้ช่วย AI ในแอปส่งข้อความ ไม่มีค่าใช้จ่ายใดๆ ทั้งสิ้น
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 คู่มือการตั้งค่า
<details>
@@ -768,74 +790,6 @@ Settings → API Configuration:
---
## 📊 รุ่นที่มีจำหน่าย
<details>
<summary><b>ดูรุ่นที่มีทั้งหมด</b></summary>
**รหัสโคลด (`cc/`)** - โปร/สูงสุด:
- `cc/claude-opus-4-6`
- `cc/claude-sonnet-4-5-20250929`
- `cc/claude-haiku-4-5-20251001`
**โคเด็กซ์ (`cx/`)** - บวก/โปร:
- `cx/gpt-5.2-codex`
- `cx/gpt-5.1-codex-max`
**ราศีเมถุน CLI (`gc/`)** - ฟรี:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**โปรแกรมควบคุม GitHub (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - เครดิตฟรี:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- มากกว่า 50 รุ่นบน [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0.6/1M:
- `glm/glm-4.7`
**มินิแม็กซ์ (`minimax/`)** - $0.2/1M:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - ฟรี:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**คิวเวน (`qw/`)** - ฟรี:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**คิโระ (`kr/`)** - ฟรี:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - มากกว่า 100 รุ่น:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- รุ่นใดก็ได้จาก [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 การประเมินผล (Evals)
OmniRoute มีกรอบการประเมินในตัวเพื่อทดสอบคุณภาพการตอบสนองของ LLM เทียบกับชุดทอง เข้าถึงได้ผ่านทาง **Analytics → Evals** ในแดชบอร์ด
@@ -859,7 +813,57 @@ OmniRoute มีกรอบการประเมินในตัวเพ
---
## 🔐 OAuth ในเซิร์ฟเวอร์ Remoto (การตั้งค่า OAuth ระยะไกล)
## 🐛 การแก้ไขปัญหา
<details>
<summary><b>คลิกเพื่อขยายคำแนะนำการแก้ปัญหา</b></summary>
**"โมเดลภาษาไม่ได้ระบุข้อความ"**
- โควต้าผู้ให้บริการหมด → ตรวจสอบตัวติดตามโควต้าแดชบอร์ด
- วิธีแก้ไข: ใช้ทางเลือกแบบคอมโบหรือเปลี่ยนไปใช้ระดับที่ถูกกว่า
**จำกัดอัตรา**
- โควต้าการสมัครสมาชิกหมด → สำรองไปที่ GLM/MiniMax
- เพิ่มคอมโบ: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**โทเค็น OAuth หมดอายุแล้ว**
- รีเฟรชอัตโนมัติโดย OmniRoute
- หากปัญหายังคงอยู่: แดชบอร์ด → ผู้ให้บริการ → เชื่อมต่อใหม่
**ค่าใช้จ่ายสูง**
- ตรวจสอบสถิติการใช้งานในแดชบอร์ด → ต้นทุน
- เปลี่ยนโมเดลหลักเป็น GLM/MiniMax
- ใช้ระดับฟรี (Gemini CLI, iFlow) สำหรับงานที่ไม่สำคัญ
**แดชบอร์ดเปิดผิดพอร์ต**
- ตั้งค่า `PORT=20128` และ `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**ข้อผิดพลาดในการซิงค์คลาวด์**
- ตรวจสอบ `BASE_URL` ชี้ไปยังอินสแตนซ์ที่ทำงานอยู่ของคุณ
- ตรวจสอบ `CLOUD_URL` ชี้ไปยังจุดปลายทางคลาวด์ที่คุณคาดหวัง
- เก็บค่า `NEXT_PUBLIC_*` ให้สอดคล้องกับค่าฝั่งเซิร์ฟเวอร์
**เข้าสู่ระบบครั้งแรกใช้งานไม่ได้**
- ตรวจสอบ `INITIAL_PASSWORD` ใน `.env`
- หากไม่ได้ตั้งค่า รหัสผ่านสำรองจะเป็น `123456`
** ไม่มีบันทึกคำขอ **
- ตั้งค่า `ENABLE_REQUEST_LOGS=true` ใน `.env`
**การทดสอบการเชื่อมต่อแสดงว่า "ไม่ถูกต้อง" สำหรับผู้ให้บริการที่รองรับ OpenAI**
- ผู้ให้บริการหลายรายไม่เปิดเผยปลายทาง `/models`
- OmniRoute v1.0.6+ มีการตรวจสอบทางเลือกผ่านการแชทให้เสร็จสิ้น
- ตรวจสอบให้แน่ใจว่า URL ฐานมีคำต่อท้าย `/v1`
### 🔐 OAuth ในเซิร์ฟเวอร์ Remoto (การตั้งค่า OAuth ระยะไกล)
<a name="oauth-em-servidor-remoto"></a>
@@ -950,58 +954,6 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
> วิธีแก้ปัญหาเบื้องต้นคือทำการเปลี่ยนเส้นทางโดยอัตโนมัติและทำการเปลี่ยนเส้นทางโดยอัตโนมัติ
---
## 🐛 การแก้ไขปัญหา
<details>
<summary><b>คลิกเพื่อขยายคำแนะนำการแก้ปัญหา</b></summary>
**"โมเดลภาษาไม่ได้ระบุข้อความ"**
- โควต้าผู้ให้บริการหมด → ตรวจสอบตัวติดตามโควต้าแดชบอร์ด
- วิธีแก้ไข: ใช้ทางเลือกแบบคอมโบหรือเปลี่ยนไปใช้ระดับที่ถูกกว่า
**จำกัดอัตรา**
- โควต้าการสมัครสมาชิกหมด → สำรองไปที่ GLM/MiniMax
- เพิ่มคอมโบ: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**โทเค็น OAuth หมดอายุแล้ว**
- รีเฟรชอัตโนมัติโดย OmniRoute
- หากปัญหายังคงอยู่: แดชบอร์ด → ผู้ให้บริการ → เชื่อมต่อใหม่
**ค่าใช้จ่ายสูง**
- ตรวจสอบสถิติการใช้งานในแดชบอร์ด → ต้นทุน
- เปลี่ยนโมเดลหลักเป็น GLM/MiniMax
- ใช้ระดับฟรี (Gemini CLI, iFlow) สำหรับงานที่ไม่สำคัญ
**แดชบอร์ดเปิดผิดพอร์ต**
- ตั้งค่า `PORT=20128` และ `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**ข้อผิดพลาดในการซิงค์คลาวด์**
- ตรวจสอบ `BASE_URL` ชี้ไปยังอินสแตนซ์ที่ทำงานอยู่ของคุณ
- ตรวจสอบ `CLOUD_URL` ชี้ไปยังจุดปลายทางคลาวด์ที่คุณคาดหวัง
- เก็บค่า `NEXT_PUBLIC_*` ให้สอดคล้องกับค่าฝั่งเซิร์ฟเวอร์
**เข้าสู่ระบบครั้งแรกใช้งานไม่ได้**
- ตรวจสอบ `INITIAL_PASSWORD` ใน `.env`
- หากไม่ได้ตั้งค่า รหัสผ่านสำรองจะเป็น `123456`
** ไม่มีบันทึกคำขอ **
- ตั้งค่า `ENABLE_REQUEST_LOGS=true` ใน `.env`
**การทดสอบการเชื่อมต่อแสดงว่า "ไม่ถูกต้อง" สำหรับผู้ให้บริการที่รองรับ OpenAI**
- ผู้ให้บริการหลายรายไม่เปิดเผยปลายทาง `/models`
- OmniRoute v1.0.6+ มีการตรวจสอบทางเลือกผ่านการแชทให้เสร็จสิ้น
- ตรวจสอบให้แน่ใจว่า URL ฐานมีคำต่อท้าย `/v1`
</details>
---
@@ -1143,85 +1095,6 @@ gh release create v1.0.6 --title "v1.0.6" --generate-notes
---
---
## 🇧🇷 OmniRoute — เกตเวย์ IA ฟรี
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### นันคา พาเร เด โคดาร์. อัจฉริยะสำหรับ **แบบจำลอง IA ฟรีและการปรับแต่ง** com ทางเลือกอัตโนมัติ
_Seu proxy universal de API — อืม endpoint, 36+ พิสูจน์แล้ว, ศูนย์หยุดทำงาน._
### 🌐 อินเตอร์นาซิอองนาลลิซาเซา (i18n)
O แดชบอร์ดรองรับ OmniRoute **múltiplos idiomas** สาเหตุที่แท้จริงคือ:
| ไอดิโอมา | โคดิโก้ | สถานะ |
| -------------------- | ------- | ------ |
| 🇮🇩 อังกฤษ | `en` | ✅ ครบ |
| 🇧🇷 โปรตุเกส (บราซิล) | `pt-BR` | ✅ ครบ |
**Para trocar o idioma:** Clique no seletor de idioma (USA) no header do Dashboard → selecione o idioma desejado.
**สำหรับการอ้างอิง um novo idioma:**
1. ร้องไห้ `src/i18n/messages/{codigo}.json` ฐาน `en.json`
2. อ้างอิงถึง `src/i18n/config.ts``LOCALES` และ `LANGUAGES`
3. Reinicie หรือผู้รับใช้
### ⚡ Início Rapido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 ด็อคเกอร์
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- ** IA มากกว่า 36 รายการ ** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek และอีเมลอื่น ๆ
- **Roteamento inteligente** — ทางเลือกสำรองอัตโนมัติ
- **รูปแบบการจัดรูปแบบ** — OpenAI ↔ Claude ↔ Gemini automaticamente
- **หลายคอนตา** — Múltiplas contas por provendor com seleção inteligente
- **ความหมายแคช** — Reduz custos e latência
- **OAuth automático** — โทเค็นปรับปรุงอัตโนมัติ
- **คอมโบส่วนบุคคล** — 6 estratégias de roteamento
- **แดชบอร์ดที่สมบูรณ์** — การตรวจสอบ บันทึก การวิเคราะห์ การกำหนดค่า
- **เครื่องมือ CLI** — กำหนดค่ารหัส Claude, Codex, เคอร์เซอร์, ไคลน์
- **TypeScript100%** — รวดเร็วทันใจ
### 📖 เอกสารประกอบ
| เอกสาร | คำอธิบาย |
| ----------------------------------------------- | --------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, คอมโบ, CLI, ปรับใช้ |
| [Referência da API](docs/API_REFERENCE.md) | Todos os endpoints com exemplos |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do sistema |
| [Contribuição](CONTRIBUTING.md) | ตั้งค่าแนวทางการพัฒนา |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | สมบูรณ์: VM + nginx + Cloudflare |
### 📧 สนับสนุน
> 💬 **เริ่มต้นการเดินทาง!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tyre dúvidas, compartilhe dicas e fique atualizado.
- **เว็บไซต์**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **ปัญหา**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>สร้างด้วย ❤️ สำหรับนักพัฒนาที่เขียนโค้ด 24/7</sub>
<br/>
+139 -266
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — безкоштовний ШІ-шлюз
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Ніколи не припиняйте кодувати. Розумна маршрутизація до **БЕЗКОШТОВНИХ і недорогих моделей штучного інтелекту** з автоматичним резервним копіюванням.
_Ваш універсальний API-проксі — одна кінцева точка, понад 36 провайдерів, нуль простоїв._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Короткий огляд цін
| Рівень | Постачальник | Вартість | Скидання квоти | Найкраще для |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Випадки використання
### Випадок 1: «У мене є підписка на Claude Pro»
**Проблема:** Квота закінчується невикористаною, обмеження швидкості під час інтенсивного кодування
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Випадок 2: "Я хочу нульову вартість"
**Проблема:** не можу дозволити собі підписку, потрібне надійне кодування ШІ
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Випадок 3: «Мені потрібне кодування 24/7, без перерв»
**Проблема:** Дедлайни, не можу дозволити собі простою
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Випадок 4: «Я хочу БЕЗКОШТОВНОГО ШІ в OpenClaw»
**Проблема:** потрібен помічник штучного інтелекту в програмах для обміну повідомленнями, повністю безкоштовний
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Основні характеристики
### 🧠 Основна маршрутизація та інтелект
@@ -495,6 +456,67 @@ OmniRoute містить потужний вбудований Translator Playgr
---
## 🎯 Випадки використання
### Випадок 1: «У мене є підписка на Claude Pro»
**Проблема:** Квота закінчується невикористаною, обмеження швидкості під час інтенсивного кодування
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Випадок 2: "Я хочу нульову вартість"
**Проблема:** не можу дозволити собі підписку, потрібне надійне кодування ШІ
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Випадок 3: «Мені потрібне кодування 24/7, без перерв»
**Проблема:** Дедлайни, не можу дозволити собі простою
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Випадок 4: «Я хочу БЕЗКОШТОВНОГО ШІ в OpenClaw»
**Проблема:** потрібен помічник штучного інтелекту в програмах для обміну повідомленнями, повністю безкоштовний
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Посібник із налаштування
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Доступні моделі
<details>
<summary><b>Переглянути всі доступні моделі</b></summary>
**Claude Code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - БЕЗКОШТОВНО:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**Копілот GitHub (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - БЕЗКОШТОВНІ кредити:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- більше 50 моделей на [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - 0,6 $/1 млн:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0,2/1 млн.:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - БЕЗКОШТОВНО:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - БЕЗКОШТОВНО:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - БЕЗКОШТОВНО:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ моделей:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Будь-яка модель від [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Оцінки (Evals)
OmniRoute містить вбудовану систему оцінювання для перевірки якості відповіді LLM на відповідність золотому набору. Доступ до нього через **Аналітика → Оцінки** на інформаційній панелі.
@@ -866,7 +820,60 @@ OmniRoute містить вбудовану систему оцінювання
---
## 🔐 OAuth em Servidor Remoto (віддалене налаштування OAuth)
## 🐛 Усунення несправностей
<details>
<summary><b>Натисніть, щоб розгорнути посібник з усунення несправностей</b></summary>
**"Мовна модель не надавала повідомлень"**
- Квота постачальника вичерпана → Перевірте систему відстеження квот на інформаційній панелі
- Рішення: скористайтеся комбінованим альтернативним варіантом або перейдіть на дешевший рівень
**Обмеження швидкості**
— Вичерпана квота на підписку → Повернення до GLM/MiniMax
- Додати комбо: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Термін дії маркера OAuth минув**
— Автоматично оновлено OmniRoute
- Якщо проблеми не зникають: Інформаційна панель → Постачальник → Повторне підключення
**Високі витрати**
- Перевірте статистику використання в Інформаційній панелі → Витрати
- Переключіть основну модель на GLM/MiniMax
- Використовуйте безкоштовний рівень (Gemini CLI, iFlow) для некритичних завдань
**Інформаційна панель відкривається через неправильний порт**
- Встановити `PORT=20128` та `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Помилки хмарної синхронізації**
- Переконайтеся, що `BASE_URL` вказує на ваш запущений екземпляр
- Перевірте `CLOUD_URL` вказує на очікувану кінцеву точку хмари
- Зберігайте значення `NEXT_PUBLIC_*` у відповідності зі значеннями на стороні сервера
**Перший вхід не працює**
- Перевірте `INITIAL_PASSWORD` в `.env`
- Якщо не встановлено, резервний пароль – `123456`
**Немає журналів запитів**
- Установіть `ENABLE_REQUEST_LOGS=true` в `.env`
**Тест з’єднання показує «Недійсне» для OpenAI-сумісних постачальників**
- Багато постачальників не розкривають кінцеву точку `/models`
- OmniRoute v1.0.6+ включає резервну перевірку через завершення чату
- Переконайтеся, що базова URL-адреса містить суфікс `/v1`
### 🔐 OAuth em Servidor Remoto (віддалене налаштування OAuth)
<a name="oauth-em-servidor-remoto"></a>
@@ -957,61 +964,6 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
> Este workaround funciona porque o código de autorização na URL é válido independente do redirect ter carregado ou não.
---
## 🐛 Усунення несправностей
<details>
<summary><b>Натисніть, щоб розгорнути посібник з усунення несправностей</b></summary>
**"Мовна модель не надавала повідомлень"**
- Квота постачальника вичерпана → Перевірте систему відстеження квот на інформаційній панелі
- Рішення: скористайтеся комбінованим альтернативним варіантом або перейдіть на дешевший рівень
**Обмеження швидкості**
— Вичерпана квота на підписку → Повернення до GLM/MiniMax
- Додати комбо: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Термін дії маркера OAuth минув**
— Автоматично оновлено OmniRoute
- Якщо проблеми не зникають: Інформаційна панель → Постачальник → Повторне підключення
**Високі витрати**
- Перевірте статистику використання в Інформаційній панелі → Витрати
- Переключіть основну модель на GLM/MiniMax
- Використовуйте безкоштовний рівень (Gemini CLI, iFlow) для некритичних завдань
**Інформаційна панель відкривається через неправильний порт**
- Встановити `PORT=20128` та `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Помилки хмарної синхронізації**
- Переконайтеся, що `BASE_URL` вказує на ваш запущений екземпляр
- Перевірте `CLOUD_URL` вказує на очікувану кінцеву точку хмари
- Зберігайте значення `NEXT_PUBLIC_*` у відповідності зі значеннями на стороні сервера
**Перший вхід не працює**
- Перевірте `INITIAL_PASSWORD` в `.env`
- Якщо не встановлено, резервний пароль – `123456`
**Немає журналів запитів**
- Установіть `ENABLE_REQUEST_LOGS=true` в `.env`
**Тест з’єднання показує «Недійсне» для OpenAI-сумісних постачальників**
- Багато постачальників не розкривають кінцеву точку `/models`
- OmniRoute v1.0.6+ включає резервну перевірку через завершення чату
- Переконайтеся, що базова URL-адреса містить суфікс `/v1`
</details>
---
@@ -1154,85 +1106,6 @@ gh release create v1.0.6 --title "v1.0.6" --generate-notes
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento inteligente para **modelos de IA GRATUITOS e de baixo custo** com reserve automático.
_Універсальний проксі-сервер API — кінцева точка, 36+ постачальників, нуль простоїв._
### 🌐 Internacionalização (i18n)
Інформаційна панель OmniRoute підтримує **багато ідіом**. Актуально доступні:
| Ідіома | Código | Статус |
| ----------------------- | ------- | -------- |
| 🇺🇸 англійська | `en` | ✅ Повне |
| 🇧🇷 Português (Бразилія) | `pt-BR` | ✅ Повне |
**Параметр троакар або ідіома:** Натисніть без вибору ідіоми (🇺🇸 EN) без заголовка на інформаційній панелі → вибір ідіоми.
**Para adicionar um nova idioma:**
1. Викличте `src/i18n/messages/{codigo}.json` на основі `en.json`
2. Додайте код `src/i18n/config.ts``LOCALES` і `LANGUAGES`
3. Reinicie або сервер
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Докер
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Funcionalidades Principais
- **36+ провідників IA** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek та ін.
- **Roteamento inteligente** — Запасні автоматичні постачальники
- **Tradução de formato** — OpenAI ↔ Claude ↔ Gemini automaticamente
- **Multi-conta** — Múltiplas contas por provedor com seleção inteligente
- **Cache semântico** — Зменшити налаштування та затримку
- **OAuth automático** — автоматичне оновлення токенів
- **Combos personalizados** — 6 estratégias de roteamento
- **Помна панель приладів** — Моніторинг, журнали, аналізи, конфігурації
- **Інструменти CLI** — налаштуйте Claude Code, Codex, Cursor, Cline за допомогою кліка
- **100% TypeScript** — Código limpo e tipado
### 📖 Documentação
| Documento | Опис |
| ----------------------------------------------- | ------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Провідори, комбо, CLI, розгортання |
| [Referência da API](docs/API_REFERENCE.md) | Усі кінцеві точки з прикладами |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Problemas comuns e soluções |
| [Arquitetura](docs/ARCHITECTURE.md) | Arquitetura e internos do sistema |
| [Contribuição](CONTRIBUTING.md) | Setup de desenvolvimento e guidelines |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Повна версія: VM + nginx + Cloudflare |
### 📧 Підтримуйте
> 💬 **Entre para a comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Тир dúvidas, compartilhe dicas e fique atualizado.
- **Веб-сайт**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Проблеми**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Створено з ❤️ для розробників, які працюють у режимі 24/7</sub>
<br/>
+137 -264
View File
@@ -3,8 +3,6 @@
# 🚀 OmniRoute — Cổng AI miễn phí
🌐 **[English](#-omniroute--the-free-ai-gateway)** | **[Português (BR)](#-omniroute--gateway-de-ia-gratuito)**
### Không bao giờ ngừng viết mã. Định tuyến thông minh tới **Mô hình AI MIỄN PHÍ và chi phí thấp** với tính năng dự phòng tự động.
_Proxy API phổ quát của bạn — một điểm cuối, hơn 36 nhà cung cấp, không có thời gian ngừng hoạt động._
@@ -249,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ Desktop App — Offline & Always-On
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
- 🖥️ **Native Window** — Dedicated app window with system tray integration
- 🔄 **Auto-Start** — Launch OmniRoute on system login
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
- 🌐 **Offline Mode** — Works fully offline with bundled server
```bash
npm run electron:dev # Development mode
npm run electron:build # Current platform
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 Full documentation: [`electron/README.md`](electron/README.md)
---
## 💰 Sơ lược về giá
| Bậc | Nhà cung cấp | Chi phí | Đặt lại hạn ngạch | Tốt nhất cho |
@@ -274,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 Trường hợp sử dụng
### Trường hợp 1: "Tôi có đăng ký Claude Pro"
**Vấn đề:** Hạn ngạch hết hạn không được sử dụng, giới hạn tốc độ trong quá trình mã hóa nặng
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Trường hợp 2: "Tôi muốn chi phí bằng 0"
**Vấn đề:** Không đủ khả năng đăng ký, cần mã hóa AI đáng tin cậy
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Trường hợp 3: "Tôi cần code 24/7, không bị gián đoạn"
**Vấn đề:** Thời hạn, không đủ khả năng cho thời gian ngừng hoạt động
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Trường hợp 4: "Tôi muốn AI MIỄN PHÍ trong OpenClaw"
**Vấn đề:** Cần trợ lý AI trong ứng dụng nhắn tin, hoàn toàn miễn phí
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 💡 Tính năng chính
### 🧠 Định tuyến lõi & thông minh
@@ -495,6 +456,67 @@ OmniRoute bao gồm Sân chơi dịch thuật tích hợp mạnh mẽ với **4
---
## 🎯 Trường hợp sử dụng
### Trường hợp 1: "Tôi có đăng ký Claude Pro"
**Vấn đề:** Hạn ngạch hết hạn không được sử dụng, giới hạn tốc độ trong quá trình mã hóa nặng
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (use subscription fully)
2. glm/glm-4.7 (cheap backup when quota out)
3. if/kimi-k2-thinking (free emergency fallback)
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
vs. $20 + hitting limits = frustration
```
### Trường hợp 2: "Tôi muốn chi phí bằng 0"
**Vấn đề:** Không đủ khả năng đăng ký, cần mã hóa AI đáng tin cậy
```
Combo: "free-forever"
1. gc/gemini-3-flash (180K free/month)
2. if/kimi-k2-thinking (unlimited free)
3. qw/qwen3-coder-plus (unlimited free)
Monthly cost: $0
Quality: Production-ready models
```
### Trường hợp 3: "Tôi cần code 24/7, không bị gián đoạn"
**Vấn đề:** Thời hạn, không đủ khả năng cho thời gian ngừng hoạt động
```
Combo: "always-on"
1. cc/claude-opus-4-6 (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)
5. if/kimi-k2-thinking (free unlimited)
Result: 5 layers of fallback = zero downtime
```
### Trường hợp 4: "Tôi muốn AI MIỄN PHÍ trong OpenClaw"
**Vấn đề:** Cần trợ lý AI trong ứng dụng nhắn tin, hoàn toàn miễn phí
```
Combo: "openclaw-free"
1. if/glm-4.7 (unlimited free)
2. if/minimax-m2.1 (unlimited free)
3. if/kimi-k2-thinking (unlimited free)
Monthly cost: $0
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
```
---
## 📖 Hướng dẫn thiết lập
<details>
@@ -775,74 +797,6 @@ Settings → API Configuration:
---
## 📊 Mẫu có sẵn
<details>
<summary><b>Xem tất cả các mẫu có sẵn</b></summary>
**Mã Claude (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - MIỄN PHÍ:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**Phi công phụ GitHub (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - Tín dụng MIỄN PHÍ:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- Hơn 50 mẫu khác trên [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - 0,6 USD/1 triệu:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - 0,2 USD/1 triệu:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - MIỄN PHÍ:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - MIỄN PHÍ:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - MIỄN PHÍ:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - Hơn 100 mẫu:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- Bất kỳ mẫu nào từ [openrouter.ai/models](https://openrouter.ai/models)
</details>
---
## 🧪 Đánh giá (Evals)
OmniRoute bao gồm khung đánh giá tích hợp để kiểm tra chất lượng phản hồi LLM dựa trên bộ vàng. Truy cập thông qua **Analytics → Đánh giá** trong bảng điều khiển.
@@ -866,7 +820,58 @@ OmniRoute bao gồm khung đánh giá tích hợp để kiểm tra chất lượ
---
## 🔐 OAuth trên Servidor Remoto (Thiết lập OAuth từ xa)
## 🐛 Khắc phục sự cố
<details>
<summary><b>Nhấp để mở rộng hướng dẫn khắc phục sự cố</b></summary>
**"Mô hình ngôn ngữ không cung cấp tin nhắn"**
- Đã hết hạn ngạch nhà cung cấp → Kiểm tra trình theo dõi hạn ngạch bảng điều khiển
- Giải pháp: Sử dụng combo dự phòng hoặc chuyển sang tầng rẻ hơn
**Giới hạn tỷ lệ**
- Hết hạn ngạch đăng ký → Dự phòng sang GLM/MiniMax
- Thêm tổ hợp: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Mã thông báo OAuth đã hết hạn**
- Tự động làm mới bởi OmniRoute
- Nếu sự cố vẫn tiếp diễn: Bảng điều khiển → Nhà cung cấp → Kết nối lại
**Chi phí cao**
- Kiểm tra số liệu thống kê sử dụng trong Bảng điều khiển → Chi phí
- Chuyển mô hình chính sang GLM/MiniMax
- Sử dụng bậc miễn phí (Gemini CLI, iFlow) cho các tác vụ không quan trọng
**Bảng điều khiển mở sai cổng**
- Đặt `PORT=20128``NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Lỗi đồng bộ hóa đám mây**
- Xác minh `BASE_URL` trỏ tới phiên bản đang chạy của bạn
- Xác minh `CLOUD_URL` điểm tới điểm cuối đám mây dự kiến của bạn
- Giữ các giá trị `NEXT_PUBLIC_*` được căn chỉnh với các giá trị phía máy chủ
**Đăng nhập lần đầu không hoạt động**
- Kiểm tra `INITIAL_PASSWORD` trong `.env`
- Nếu không được đặt, mật khẩu dự phòng là `123456`
**Không có nhật ký yêu cầu**
- Đặt `ENABLE_REQUEST_LOGS=true` trong `.env`
**Kiểm tra kết nối cho thấy "Không hợp lệ" đối với các nhà cung cấp tương thích với OpenAI**
- Nhiều nhà cung cấp không hiển thị điểm cuối `/models`
- OmniRoute v1.0.6+ bao gồm xác thực dự phòng thông qua hoàn thành trò chuyện
- Đảm bảo URL cơ sở bao gồm hậu tố `/v1`
### 🔐 OAuth trên Servidor Remoto (Thiết lập OAuth từ xa)
<a name="oauth-em-servidor-remoto"></a>
@@ -957,59 +962,6 @@ Nếu không có câu hỏi nào về thông tin xác thực trước đây, b
> Chức năng giải pháp này có thể giúp tự động cấp quyền cho URL và có thể chuyển hướng độc lập đến mục tiêu hoặc không.
---
## 🐛 Khắc phục sự cố
<details>
<summary><b>Nhấp để mở rộng hướng dẫn khắc phục sự cố</b></summary>
**"Mô hình ngôn ngữ không cung cấp tin nhắn"**
- Đã hết hạn ngạch nhà cung cấp → Kiểm tra trình theo dõi hạn ngạch bảng điều khiển
- Giải pháp: Sử dụng combo dự phòng hoặc chuyển sang tầng rẻ hơn
**Giới hạn tỷ lệ**
- Hết hạn ngạch đăng ký → Dự phòng sang GLM/MiniMax
- Thêm tổ hợp: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
**Mã thông báo OAuth đã hết hạn**
- Tự động làm mới bởi OmniRoute
- Nếu sự cố vẫn tiếp diễn: Bảng điều khiển → Nhà cung cấp → Kết nối lại
**Chi phí cao**
- Kiểm tra số liệu thống kê sử dụng trong Bảng điều khiển → Chi phí
- Chuyển mô hình chính sang GLM/MiniMax
- Sử dụng bậc miễn phí (Gemini CLI, iFlow) cho các tác vụ không quan trọng
**Bảng điều khiển mở sai cổng**
- Đặt `PORT=20128``NEXT_PUBLIC_BASE_URL=http://localhost:20128`
**Lỗi đồng bộ hóa đám mây**
- Xác minh `BASE_URL` trỏ tới phiên bản đang chạy của bạn
- Xác minh `CLOUD_URL` điểm tới điểm cuối đám mây dự kiến của bạn
- Giữ các giá trị `NEXT_PUBLIC_*` được căn chỉnh với các giá trị phía máy chủ
**Đăng nhập lần đầu không hoạt động**
- Kiểm tra `INITIAL_PASSWORD` trong `.env`
- Nếu không được đặt, mật khẩu dự phòng là `123456`
**Không có nhật ký yêu cầu**
- Đặt `ENABLE_REQUEST_LOGS=true` trong `.env`
**Kiểm tra kết nối cho thấy "Không hợp lệ" đối với các nhà cung cấp tương thích với OpenAI**
- Nhiều nhà cung cấp không hiển thị điểm cuối `/models`
- OmniRoute v1.0.6+ bao gồm xác thực dự phòng thông qua hoàn thành trò chuyện
- Đảm bảo URL cơ sở bao gồm hậu tố `/v1`
</details>
---
@@ -1152,85 +1104,6 @@ Giấy phép MIT - xem [LICENSE](LICENSE) để biết chi tiết.
---
---
## 🇧🇷 OmniRoute — Gateway de IA Gratuito
<a name="-omniroute--gateway-de-ia-gratuito"></a>
### Nunca pare de codar. Roteamento thông minh cho **mô hình IA MIỄN PHÍ và baixo tùy chỉnh** và tự động dự phòng.
_Seu proxy phổ quát de API — ừm điểm cuối, hơn 36 điểm đã được chứng minh, không có thời gian ngừng hoạt động._
### 🌐 Quốc tế hóa (i18n)
O bảng điều khiển hỗ trợ OmniRoute **nhiều thành ngữ**. Cuối cùng, bạn có thể giải quyết:
| Thành ngữ | Código | Trạng thái |
| --------------------- | ------- | ------------- |
| 🇺🇸 Tiếng Anh | `en` | ✅ Hoàn thiện |
| 🇧🇷 Português (Brasil) | `pt-BR` | ✅ Hoàn thiện |
**Para trocar o thành ngữ:** Clique no seletor de Idi chỉ (🇺🇸 EN) không có tiêu đề làm bảng điều khiển → chọn lựa hoặc thành ngữ desejado.
**Thêm một thành ngữ mới:**
1. Khóc `src/i18n/messages/{codigo}.json` dựa trên `en.json`
2. Adicione hoặc código em `src/i18n/config.ts``LOCALES` e `LANGUAGES`
3. Phục hồi hoặc phục vụ
### ⚡ Início Rápido
```bash
# Instalar via npm
npx omniroute@latest
# Ou rodar do código-fonte
cp .env.example .env
npm install
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
```
### 🐳 Docker
```bash
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
```
### 🔑 Chức năng chính
- **36+ chứng minh của IA** — Claude, GPT, Gemini, Llama, Qwen, DeepSeek, và nhiều hơn nữa
- **Roteamento inteligente** — Tự động dự phòng trong các phương pháp được chứng minh
- **Giao dịch định dạng** — OpenAI ↔ Claude ↔ Gemini tự động
- **Multi-conta** — Nhiều conta được chứng minh bằng cách lựa chọn thông minh
- **Cache semântico** — Reduz custos và latência
- **Tự động OAuth** — Tự động đổi mới mã thông báo
- **Combo cá nhân hóa** — 6 chiến lược roteamento
- **Hoàn thành bảng điều khiển** — Màn hình, nhật ký, phân tích, cấu hình
- **Công cụ CLI** — Định cấu hình Mã Claude, Codex, Con trỏ, Cline với một nhóm
- **100% TypeScript** — Código limbo e tipado
### 📖 Tài liệu
| Tài liệu | Mô tả |
| ----------------------------------------------- | --------------------------------------------------- |
| [Guia do Usuário](docs/USER_GUIDE.md) | Provedores, combo, CLI, triển khai |
| [Referência da API](docs/API_REFERENCE.md) | Tất cả các điểm cuối của hệ điều hành như các ví dụ |
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | Các vấn đề công cộng và giải pháp |
| [Arquitetura](docs/ARCHITECTURE.md) | Hệ thống Arquitetura và internos |
| [Contribuição](CONTRIBUTING.md) | Thiết lập các nguyên tắc phát triển |
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | Hướng dẫn hoàn chỉnh: VM + nginx + Cloudflare |
### 📧 Hỗ trợ
> 💬 **Entre para a communidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tyre duvidas, compartilhe dicas and fique atualizado.
- **Trang web**: [omniroute.online](https://omniroute.online)
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- **Vấn đề**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
---
<div align="center">
<sub>Được xây dựng với ❤️ dành cho nhà phát triển viết mã 24/7</sub>
<br/>
+85 -129
View File
@@ -247,6 +247,30 @@ docker compose --profile cli up -d
---
---
## 🖥️ 桌面应用 — 离线 & 始终在线
> 🆕 **全新!** OmniRoute 现已提供适用于 Windows、macOS 和 Linux 的**原生桌面应用程序**。
- 🖥️ **原生窗口** — 专属应用窗口,集成系统托盘
- 🔄 **自动启动** — 系统登录时启动 OmniRoute
- 🔔 **原生通知** — 配额耗尽或提供商问题时收到提醒
- ⚡ **一键安装** — NSIS (Windows)、DMG (macOS)、AppImage (Linux)
- 🌐 **离线模式** — 内置服务器,完全离线工作
```bash
npm run electron:dev # 开发模式
npm run electron:build # 当前平台
npm run electron:build:win # Windows (.exe)
npm run electron:build:mac # macOS (.dmg)
npm run electron:build:linux # Linux (.AppImage)
```
📖 完整文档:[`electron/README.md`](electron/README.md)
---
## 💰 定价概览
| 层级 | 提供商 | 费用 | 配额重置 | 最适合 |
@@ -272,67 +296,6 @@ docker compose --profile cli up -d
---
## 🎯 使用场景
### 场景 1"我有 Claude Pro 订阅"
**问题:** 配额未使用就过期,编程高峰期遇到速率限制
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (充分使用订阅)
2. glm/glm-4.7 (配额用完时的便宜备用)
3. if/kimi-k2-thinking (免费应急后备)
每月成本:$20(订阅)+ ~$5(备用)= $25 总计
对比:$20 + 遇到限制 = 受挫
```
### 场景 2"我想要零成本"
**问题:** 无法承担订阅费用,需要可靠的 AI 编程
```
Combo: "free-forever"
1. gc/gemini-3-flash (每月 180K 免费)
2. if/kimi-k2-thinking (无限免费)
3. qw/qwen3-coder-plus (无限免费)
每月成本:$0
质量:生产级模型
```
### 场景 3"我需要 24/7 编程,不中断"
**问题:** 截止日期紧迫,不能有停机时间
```
Combo: "always-on"
1. cc/claude-opus-4-6 (最佳质量)
2. cx/gpt-5.2-codex (第二个订阅)
3. glm/glm-4.7 (便宜,每日重置)
4. minimax/MiniMax-M2.1 (最便宜,5小时重置)
5. if/kimi-k2-thinking (免费无限制)
结果:5 层故障转移 = 零停机
```
### 场景 4"我想在 OpenClaw 中使用免费 AI"
**问题:** 需要在消息应用中使用 AI 助手,完全免费
```
Combo: "openclaw-free"
1. if/glm-4.7 (无限免费)
2. if/minimax-m2.1 (无限免费)
3. if/kimi-k2-thinking (无限免费)
每月成本:$0
访问方式:WhatsApp、Telegram、Slack、Discord、iMessage、Signal...
```
---
## 💡 核心功能
### 🧠 路由与智能
@@ -474,6 +437,67 @@ Combo: "my-coding-stack"
---
## 🎯 使用场景
### 场景 1"我有 Claude Pro 订阅"
**问题:** 配额未使用就过期,编程高峰期遇到速率限制
```
Combo: "maximize-claude"
1. cc/claude-opus-4-6 (充分使用订阅)
2. glm/glm-4.7 (配额用完时的便宜备用)
3. if/kimi-k2-thinking (免费应急后备)
每月成本:$20(订阅)+ ~$5(备用)= $25 总计
对比:$20 + 遇到限制 = 受挫
```
### 场景 2"我想要零成本"
**问题:** 无法承担订阅费用,需要可靠的 AI 编程
```
Combo: "free-forever"
1. gc/gemini-3-flash (每月 180K 免费)
2. if/kimi-k2-thinking (无限免费)
3. qw/qwen3-coder-plus (无限免费)
每月成本:$0
质量:生产级模型
```
### 场景 3"我需要 24/7 编程,不中断"
**问题:** 截止日期紧迫,不能有停机时间
```
Combo: "always-on"
1. cc/claude-opus-4-6 (最佳质量)
2. cx/gpt-5.2-codex (第二个订阅)
3. glm/glm-4.7 (便宜,每日重置)
4. minimax/MiniMax-M2.1 (最便宜,5小时重置)
5. if/kimi-k2-thinking (免费无限制)
结果:5 层故障转移 = 零停机
```
### 场景 4"我想在 OpenClaw 中使用免费 AI"
**问题:** 需要在消息应用中使用 AI 助手,完全免费
```
Combo: "openclaw-free"
1. if/glm-4.7 (无限免费)
2. if/minimax-m2.1 (无限免费)
3. if/kimi-k2-thinking (无限免费)
每月成本:$0
访问方式:WhatsApp、Telegram、Slack、Discord、iMessage、Signal...
```
---
## 📖 设置指南
<details>
@@ -754,74 +778,6 @@ codex "your prompt"
---
## 📊 可用模型
<details>
<summary><b>查看所有可用模型</b></summary>
**Claude Code (`cc/`)** - Pro/Max:
- `cc/claude-opus-4-6`
- `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`
**Gemini CLI (`gc/`)** - 免费:
- `gc/gemini-3-flash-preview`
- `gc/gemini-2.5-pro`
**GitHub Copilot (`gh/`)**:
- `gh/gpt-5`
- `gh/claude-4.5-sonnet`
**NVIDIA NIM (`nvidia/`)** - 免费积分:
- `nvidia/llama-3.3-70b-instruct`
- `nvidia/mistral-7b-instruct`
- 50+ 更多模型在 [build.nvidia.com](https://build.nvidia.com)
**GLM (`glm/`)** - $0.6/1M:
- `glm/glm-4.7`
**MiniMax (`minimax/`)** - $0.2/1M:
- `minimax/MiniMax-M2.1`
**iFlow (`if/`)** - 免费:
- `if/kimi-k2-thinking`
- `if/qwen3-coder-plus`
- `if/deepseek-r1`
- `if/glm-4.7`
- `if/minimax-m2`
**Qwen (`qw/`)** - 免费:
- `qw/qwen3-coder-plus`
- `qw/qwen3-coder-flash`
**Kiro (`kr/`)** - 免费:
- `kr/claude-sonnet-4.5`
- `kr/claude-haiku-4.5`
**OpenRouter (`or/`)** - 100+ 模型:
- `or/anthropic/claude-4-sonnet`
- `or/google/gemini-2.5-pro`
- [openrouter.ai/models](https://openrouter.ai/models) 上的任何模型
</details>
---
## 🧪 评估 (Evals)
OmniRoute 包含内置评估框架,用于针对黄金集测试 LLM 响应质量。通过仪表板中的 **Analytics → Evals** 访问。
+71 -7
View File
@@ -12,15 +12,69 @@
*/
import { spawn } from "node:child_process";
import { existsSync } from "node:fs";
import { existsSync, readFileSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { homedir, platform } from "node:os";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const ROOT = join(__dirname, "..");
const APP_DIR = join(ROOT, "app");
// ── Load .env file (for global npm install) ─────────────────
function loadEnvFile() {
const envPaths = [];
// 1. DATA_DIR/.env if set
if (process.env.DATA_DIR) {
envPaths.push(join(process.env.DATA_DIR, ".env"));
}
// 2. ~/.omniroute/.env (default data dir)
const home = homedir();
if (home) {
if (platform() === "win32") {
const appData = process.env.APPDATA || join(home, "AppData", "Roaming");
envPaths.push(join(appData, "omniroute", ".env"));
} else {
envPaths.push(join(home, ".omniroute", ".env"));
}
}
// 3. ./.env (current working directory)
envPaths.push(join(process.cwd(), ".env"));
for (const envPath of envPaths) {
try {
if (existsSync(envPath)) {
const content = readFileSync(envPath, "utf-8");
for (const line of content.split("\n")) {
const trimmed = line.trim();
// Skip empty lines and comments
if (!trimmed || trimmed.startsWith("#")) continue;
const eqIdx = trimmed.indexOf("=");
if (eqIdx > 0) {
const key = trimmed.slice(0, eqIdx).trim();
const value = trimmed.slice(eqIdx + 1).trim();
// Don't override existing env vars
if (process.env[key] === undefined) {
// Remove surrounding quotes
process.env[key] = value.replace(/^["']|["']$/g, "");
}
}
}
console.log(` \x1b[2m📋 Loaded env from ${envPath}\x1b[0m`);
return;
}
} catch {
// Ignore errors reading env files
}
}
}
loadEnvFile();
// ── Parse args ─────────────────────────────────────────────
const args = process.argv.slice(2);
@@ -35,6 +89,10 @@ if (args.includes("--help") || args.includes("-h")) {
omniroute --help Show this help
omniroute --version Show version
\x1b[1mConfig:\x1b[0m
Loads .env from: ~/.omniroute/.env or ./.env
Memory limit: OMNIROUTE_MEMORY_MB (default: 512)
\x1b[1mAfter starting:\x1b[0m
Dashboard: http://localhost:<dashboard-port>
API: http://localhost:<api-port>/v1
@@ -83,11 +141,11 @@ const noOpen = args.includes("--no-open");
// ── Banner ─────────────────────────────────────────────────
console.log(`
\x1b[36m ____ _ ____ _
/ __ \\ (_) __ \\ | |
| | | |_ __ ___ _ __ _| |__) |___ _ _| |_ ___
| | | | '_ \` _ \\| '_ \\ | _ // _ \\| | | | __/ _ \\
| |__| | | | | | | | | | | | \\ \\ (_) | |_| | || __/
\\____/|_| |_| |_|_| |_|_|_| \\_\\___/ \\__,_|\\__\\___|
/ __ \\ (_) __ \\ | |
| | | |_ __ ___ _ __ _| |__) |___ _ _| |_ ___
| | | | '_ \` _ \\| '_ \\ | _ // _ \\| | | | __/ _ \\
| |__| | | | | | | | | | | | \\ \\ (_) | |_| | || __/
\\____/|_| |_| |_|_| |_|_|_| \\_\\___/ \\__,_|\\__\\___|
\x1b[0m`);
// ── Node.js version check ──────────────────────────────────
@@ -117,6 +175,11 @@ if (!existsSync(serverJs)) {
// ── Start server ───────────────────────────────────────────
console.log(` \x1b[2m⏳ Starting server...\x1b[0m\n`);
// Sanitize memory limit — parseInt to prevent command injection (#150)
const rawMemory = parseInt(process.env.OMNIROUTE_MEMORY_MB || "512", 10);
const memoryLimit =
Number.isFinite(rawMemory) && rawMemory >= 64 && rawMemory <= 16384 ? rawMemory : 512;
const env = {
...process.env,
OMNIROUTE_PORT: String(port),
@@ -125,9 +188,10 @@ const env = {
API_PORT: String(apiPort),
HOSTNAME: "0.0.0.0",
NODE_ENV: "production",
NODE_OPTIONS: `--max-old-space-size=${memoryLimit}`,
};
const server = spawn("node", [serverJs], {
const server = spawn("node", [`--max-old-space-size=${memoryLimit}`, serverJs], {
cwd: APP_DIR,
env,
stdio: "pipe",
+17 -1
View File
@@ -56,7 +56,7 @@ General settings, system storage, backup management (export/import database), ap
## 🔧 CLI Tools
One-click configuration for AI coding tools: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, and Antigravity.
One-click configuration for AI coding tools: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, and **GitHub Copilot** (config generator for `chatLanguageModels.json`).
![CLI Tools Dashboard](screenshots/07-cli-tools.png)
@@ -75,3 +75,19 @@ Real-time request logging with filtering by provider, model, account, and API ke
Your unified API endpoint with capability breakdown: Chat Completions, Embeddings, Image Generation, Reranking, Audio Transcription, and registered API keys.
![Endpoint Dashboard](screenshots/09-endpoint.png)
---
## 🖥️ Desktop Application
Native Electron desktop app for Windows, macOS, and Linux. Run OmniRoute as a standalone application with system tray integration, offline support, and one-click install.
Key features:
- Server readiness polling (no blank screen on cold start)
- System tray with port management
- Content Security Policy
- Single-instance lock
- Platform-conditional UI (macOS traffic lights, Windows/Linux default titlebar)
📖 See [`electron/README.md`](../electron/README.md) for full documentation.
+125 -14
View File
@@ -318,6 +318,25 @@ Model: cc/claude-opus-4-6
## 🚀 Deployment
### Global npm install (Recommended)
```bash
npm install -g omniroute
# Create config directory
mkdir -p ~/.omniroute
# Create .env file (see .env.example)
cp .env.example ~/.omniroute/.env
# Start server
omniroute
# Or with custom port:
omniroute --port 3000
```
The CLI automatically loads `.env` from `~/.omniroute/.env` or `./.env`.
### VPS Deployment
```bash
@@ -337,6 +356,43 @@ npm run start
# Or: pm2 start npm --name omniroute -- start
```
### PM2 Deployment (Low Memory)
For servers with limited RAM, use the memory limit option:
```bash
# With 512MB limit (default)
pm2 start npm --name omniroute -- start
# Or with custom memory limit
OMNIROUTE_MEMORY_MB=512 pm2 start npm --name omniroute -- start
# Or using ecosystem.config.js
pm2 start ecosystem.config.js
```
Create `ecosystem.config.js`:
```javascript
module.exports = {
apps: [
{
name: "omniroute",
script: "npm",
args: "start",
env: {
NODE_ENV: "production",
OMNIROUTE_MEMORY_MB: "512",
JWT_SECRET: "your-secret",
INITIAL_PASSWORD: "your-password",
},
node_args: "--max-old-space-size=512",
max_memory_restart: "300M",
},
],
};
```
### Docker
```bash
@@ -351,20 +407,23 @@ For host-integrated mode with CLI binaries, see the Docker section in the main d
### Environment Variables
| Variable | Default | Description |
| --------------------- | ------------------------------------ | ------------------------------------------------------- |
| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT signing secret (**change in production**) |
| `INITIAL_PASSWORD` | `123456` | First login password |
| `DATA_DIR` | `~/.omniroute` | Data directory (db, usage, logs) |
| `PORT` | framework default | Service port (`20128` in examples) |
| `HOSTNAME` | framework default | Bind host (Docker defaults to `0.0.0.0`) |
| `NODE_ENV` | runtime default | Set `production` for deploy |
| `BASE_URL` | `http://localhost:20128` | Server-side internal base URL |
| `CLOUD_URL` | `https://omniroute.dev` | Cloud sync endpoint base URL |
| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC secret for generated API keys |
| `REQUIRE_API_KEY` | `false` | Enforce Bearer API key on `/v1/*` |
| `ENABLE_REQUEST_LOGS` | `false` | Enables request/response logs |
| `AUTH_COOKIE_SECURE` | `false` | Force `Secure` auth cookie (behind HTTPS reverse proxy) |
| Variable | Default | Description |
| ------------------------- | ------------------------------------ | ------------------------------------------------------- |
| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT signing secret (**change in production**) |
| `INITIAL_PASSWORD` | `123456` | First login password |
| `DATA_DIR` | `~/.omniroute` | Data directory (db, usage, logs) |
| `PORT` | framework default | Service port (`20128` in examples) |
| `HOSTNAME` | framework default | Bind host (Docker defaults to `0.0.0.0`) |
| `NODE_ENV` | runtime default | Set `production` for deploy |
| `BASE_URL` | `http://localhost:20128` | Server-side internal base URL |
| `CLOUD_URL` | `https://omniroute.dev` | Cloud sync endpoint base URL |
| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC secret for generated API keys |
| `REQUIRE_API_KEY` | `false` | Enforce Bearer API key on `/v1/*` |
| `ENABLE_REQUEST_LOGS` | `false` | Enables request/response logs |
| `AUTH_COOKIE_SECURE` | `false` | Force `Secure` auth cookie (behind HTTPS reverse proxy) |
| `OMNIROUTE_MEMORY_MB` | `512` | Node.js heap limit in MB |
| `PROMPT_CACHE_MAX_SIZE` | `50` | Max prompt cache entries |
| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Max semantic cache entries |
For the full environment variable reference, see the [README](../README.md).
@@ -696,3 +755,55 @@ Access via **Dashboard → Health**. Real-time system health overview with 6 car
| **Latency Telemetry** | p50/p95/p99 latency aggregation per provider |
**Pro Tip:** The Health page auto-refreshes every 10 seconds. Use the circuit breaker card to identify which providers are experiencing issues.
---
## 🖥️ Desktop Application (Electron)
OmniRoute is available as a native desktop application for Windows, macOS, and Linux.
### Installation
```bash
# From the electron directory:
cd electron
npm install
# Development mode (connect to running Next.js dev server):
npm run dev
# Production mode (uses standalone build):
npm start
```
### Building Installers
```bash
cd electron
npm run build # Current platform
npm run build:win # Windows (.exe NSIS)
npm run build:mac # macOS (.dmg universal)
npm run build:linux # Linux (.AppImage)
```
Output → `electron/dist-electron/`
### Key Features
| Feature | Description |
| --------------------------- | ---------------------------------------------------- |
| **Server Readiness** | Polls server before showing window (no blank screen) |
| **System Tray** | Minimize to tray, change port, quit from tray menu |
| **Port Management** | Change server port from tray (auto-restarts server) |
| **Content Security Policy** | Restrictive CSP via session headers |
| **Single Instance** | Only one app instance can run at a time |
| **Offline Mode** | Bundled Next.js server works without internet |
### Environment Variables
| Variable | Default | Description |
| --------------------- | ------- | -------------------------------- |
| `OMNIROUTE_PORT` | `20128` | Server port |
| `OMNIROUTE_MEMORY_MB` | `512` | Node.js heap limit (6416384 MB) |
📖 Full documentation: [`electron/README.md`](../electron/README.md)
+250
View File
@@ -0,0 +1,250 @@
# OmniRoute Electron Desktop App
This directory contains the Electron desktop application wrapper for OmniRoute.
## Architecture (v1.6.4)
```
electron/
├── main.js # Main process — window, tray, server lifecycle, CSP, IPC
├── preload.js # Preload script — secure IPC bridge with disposer pattern
├── package.json # Electron-specific dependencies & electron-builder config
├── types.d.ts # TypeScript definitions (AppInfo, ServerStatus, ElectronAPI)
└── assets/ # Application icons and resources
src/shared/hooks/
└── useElectron.ts # React hooks — useSyncExternalStore, zero re-renders
```
## Key Design Decisions
| Decision | Rationale |
| ----------------------------- | ------------------------------------------------------------------------------------------------ |
| `waitForServer()` polling | Prevents blank screen on cold start — polls `http://localhost:PORT` before loading |
| `stdio: 'pipe'` | Captures server stdout/stderr for logging + readiness detection (not `inherit`) |
| Disposer pattern | `onServerStatus()` returns `() => void` for precise listener cleanup (no `removeAllListeners`) |
| `useSyncExternalStore` | Zero re-renders for `useIsElectron()` — no `useState` + `useEffect` cycle |
| CSP via session headers | `Content-Security-Policy` restricts `script-src`, `connect-src` etc. per Electron best practices |
| Platform-conditional titlebar | `titleBarStyle: 'hiddenInset'` only on macOS; `default` on Windows/Linux |
## Development
### Prerequisites
1. Build the Next.js app first:
```bash
npm run build
```
2. Install Electron dependencies:
```bash
cd electron
npm install
```
### Running in Development
1. Start the Next.js development server:
```bash
npm run dev
```
2. In another terminal, start Electron:
```bash
cd electron
npm run dev
```
### Running in Production Mode
1. Build Next.js in standalone mode:
```bash
npm run build
```
2. Start Electron:
```bash
cd electron
npm start
```
## Building
### Build for Current Platform
```bash
cd electron
npm run build
```
### Build for Specific Platforms
```bash
# Windows
npm run build:win
# macOS (x64 + arm64)
npm run build:mac
# Linux
npm run build:linux
```
## Output
Built applications are placed in `dist-electron/`:
- Windows: `.exe` installer (NSIS) + portable `.exe`
- macOS: `.dmg` installer (Intel + Apple Silicon)
- Linux: `.AppImage`
## Installation
### macOS
1. Download the latest `.dmg` from the [Releases](https://github.com/diegosouzapw/OmniRoute/releases) page.
2. Open the `.dmg` file.
3. Drag `OmniRoute.app` to the Applications folder.
4. Launch from Applications.
> ⚠️ **Note:** The app is not signed with an Apple Developer certificate yet. If macOS blocks the app, run:
> ```bash
> xattr -cr /Applications/OmniRoute.app
> ```
> Or right-click the app → Open → Open (to bypass Gatekeeper on first launch).
### Windows
**Installer (Recommended):**
1. Download `OmniRoute.Setup.*.exe` from [Releases](https://github.com/diegosouzapw/OmniRoute/releases).
2. Run the installer.
3. Launch from Start Menu or Desktop shortcut.
**Portable (No Installation):**
1. Download `OmniRoute.exe` from [Releases](https://github.com/diegosouzapw/OmniRoute/releases).
2. Run directly from any folder.
### Linux
1. Download the `.AppImage` from [Releases](https://github.com/diegosouzapw/OmniRoute/releases).
2. Make it executable:
```bash
chmod +x OmniRoute-*.AppImage
```
3. Run:
```bash
./OmniRoute-*.AppImage
```
## Features
- **Server Readiness** — Waits for health check before showing window
- **System Tray** — Minimize to tray with quick actions (open, port change, quit)
- **Port Management** — Change port from tray menu (server restarts automatically)
- **Window Controls** — Custom minimize, maximize, close via IPC
- **Content Security Policy** — Restrictive CSP via session headers
- **Offline Support** — Bundled Next.js standalone server
- **Single Instance** — Only one app instance can run at a time
## Configuration
### Environment Variables
| Variable | Default | Description |
| --------------------- | ------------ | --------------------------------- |
| `OMNIROUTE_PORT` | `20128` | Server port |
| `OMNIROUTE_MEMORY_MB` | `512` | Node.js heap limit (6416384 MB) |
| `NODE_ENV` | `production` | Set to `development` for dev mode |
### Custom Icon
Place your icons in `assets/`:
- `icon.ico` — Windows icon (256×256)
- `icon.icns` — macOS icon bundle
- `icon.png` — Linux/general use (512×512)
- `tray-icon.png` — System tray icon (16×16 or 32×32)
## IPC Channels
### Invoke (Renderer → Main, async)
| Channel | Returns | Description |
| ---------------- | ------------- | --------------------------------------------- |
| `get-app-info` | `AppInfo` | App name, version, platform, isDev, port |
| `open-external` | `void` | Open URL in default browser (http/https only) |
| `get-data-dir` | `string` | Get userData directory path |
| `restart-server` | `{ success }` | Stop + restart server (5s timeout + SIGKILL) |
### Send (Renderer → Main, fire-and-forget)
| Channel | Description |
| ----------------- | ------------------------------- |
| `window-minimize` | Minimize window |
| `window-maximize` | Toggle maximize/restore |
| `window-close` | Close window (minimize to tray) |
### Receive (Main → Renderer, events)
| Channel | Payload | Emitted When |
| --------------- | -------------- | ----------------------------------------- |
| `server-status` | `ServerStatus` | Server starts, stops, errors, or restarts |
| `port-changed` | `number` | Port change via tray menu |
> **Note**: Listeners return disposer functions for precise cleanup. See `useServerStatus` and `usePortChanged` hooks.
## Security
| Feature | Implementation |
| ----------------- | ------------------------------------------------------------------------------- |
| Context Isolation | `contextIsolation: true` — renderer cannot access Node.js |
| Node Integration | `nodeIntegration: false` — no `require()` in renderer |
| IPC Whitelist | Channel names validated in preload via `safeInvoke`/`safeSend`/`safeOn` |
| URL Validation | `shell.openExternal()` only allows `http:` / `https:` protocols |
| CSP | `Content-Security-Policy` header set via `session.webRequest.onHeadersReceived` |
| Web Security | `webSecurity: true` — same-origin policy enforced |
## React Hooks
| Hook | Returns | Description |
| ---------------------- | ------------------------------- | ------------------------------------------------ |
| `useIsElectron()` | `boolean` | Zero-render detection via `useSyncExternalStore` |
| `useElectronAppInfo()` | `{ appInfo, loading, error }` | App info from main process |
| `useDataDir()` | `{ dataDir, loading, error }` | User data directory |
| `useWindowControls()` | `{ minimize, maximize, close }` | Window control actions |
| `useOpenExternal()` | `{ openExternal }` | Open URLs in browser |
| `useServerControls()` | `{ restart, restarting }` | Server restart control |
| `useServerStatus(cb)` | Disposer | Listen for server status events |
| `usePortChanged(cb)` | Disposer | Listen for port change events |
## Troubleshooting
### App Won't Start
1. Check if port 20128 is available: `lsof -i :20128`
2. Check console logs for `[Electron]` prefix
3. Verify the build output exists in `.next/standalone`
### White Screen
1. Verify Next.js build exists — server readiness waits 30s max
2. Check `[Server]` and `[Server:err]` log output
3. Look for CSP violations in developer console
### Build Fails
Ensure you have build tools installed:
- Windows: Visual Studio Build Tools
- macOS: Xcode Command Line Tools
- Linux: `build-essential`, `libsecret-1-dev`
## License
MIT
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B

+441
View File
@@ -0,0 +1,441 @@
/**
* OmniRoute Electron Desktop App - Main Process
*
* This is the entry point for the Electron desktop application.
* It manages the main window, system tray, server lifecycle, and IPC communication.
*
* Code Review Fixes Applied:
* #1 Server readiness wait for health check before loading window
* #2 Restart timeout 5s timeout + SIGKILL to prevent hanging
* #3 changePort stop + restart server on new port
* #4 Tray cleanup destroy old tray before recreating
* #5 Emit server-status/port-changed IPC events
* #8 Removed dead isProduction variable
* #9 Platform-conditional titleBarStyle
* #10 stdio: pipe + stdout/stderr capture for readiness detection
* #14 Removed dead omniroute:// protocol (no handler existed)
* #15 Content Security Policy via session headers
*/
const {
app,
BrowserWindow,
ipcMain,
Tray,
Menu,
nativeImage,
shell,
session,
} = require("electron");
const path = require("path");
const { spawn } = require("child_process");
const fs = require("fs");
// ── Single Instance Lock ───────────────────────────────────
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
app.quit();
process.exit(0);
}
app.on("second-instance", () => {
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.show();
mainWindow.focus();
}
});
// ── Environment Detection ──────────────────────────────────
const isDev = process.env.NODE_ENV === "development" || !app.isPackaged;
// ── Paths ──────────────────────────────────────────────────
const APP_PATH = app.getAppPath();
const RESOURCES_PATH = !isDev ? process.resourcesPath : APP_PATH;
const NEXT_SERVER_PATH = path.join(RESOURCES_PATH, "app");
// ── State ──────────────────────────────────────────────────
let mainWindow = null;
let tray = null;
let nextServer = null;
let serverPort = 20128;
const getServerUrl = () => `http://localhost:${serverPort}`;
// ── Helper: Send IPC event to renderer (#5) ────────────────
function sendToRenderer(channel, data) {
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.webContents.send(channel, data);
}
}
// ── Helper: Wait for server readiness (#1, #10) ────────────
async function waitForServer(url, timeoutMs = 30000) {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
try {
const res = await fetch(url);
if (res.ok || res.status < 500) return true;
} catch {
/* server not ready yet */
}
await new Promise((r) => setTimeout(r, 500));
}
console.warn("[Electron] Server readiness timeout — showing window anyway");
return false;
}
// ── Helper: Wait for server process exit with timeout (#2) ─
async function waitForServerExit(proc, timeoutMs = 5000) {
if (!proc) return;
await Promise.race([
new Promise((r) => proc.once("exit", r)),
new Promise((r) =>
setTimeout(() => {
try {
proc.kill("SIGKILL");
} catch {
/* already dead */
}
r();
}, timeoutMs)
),
]);
}
// ── Content Security Policy (#15) ──────────────────────────
function setupContentSecurityPolicy() {
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
const csp = [
"default-src 'self'",
`connect-src 'self' http://localhost:* ws://localhost:* https://*.omniroute.online https://*.omniroute.dev`,
"script-src 'self' 'unsafe-inline' 'unsafe-eval'",
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
"font-src 'self' https://fonts.gstatic.com data:",
"img-src 'self' data: blob: https:",
"media-src 'self'",
].join("; ");
callback({
responseHeaders: {
...details.responseHeaders,
"Content-Security-Policy": [csp],
},
});
});
}
// ── Create Window ──────────────────────────────────────────
function createWindow() {
// Platform-conditional options (#9)
const platformWindowOptions =
process.platform === "darwin"
? { titleBarStyle: "hiddenInset", trafficLightPosition: { x: 16, y: 16 } }
: { titleBarStyle: "default" };
mainWindow = new BrowserWindow({
width: 1400,
height: 900,
minWidth: 1024,
minHeight: 700,
title: "OmniRoute",
icon: path.join(RESOURCES_PATH, "assets", "icon.png"),
webPreferences: {
preload: path.join(__dirname, "preload.js"),
contextIsolation: true,
nodeIntegration: false,
webSecurity: true,
},
show: false,
backgroundColor: "#0a0a0a",
...platformWindowOptions,
});
// Load the Next.js app
mainWindow.loadURL(getServerUrl());
if (isDev) {
mainWindow.webContents.openDevTools({ mode: "detach" });
}
// Show window when ready
mainWindow.once("ready-to-show", () => {
mainWindow.show();
});
// Handle external links — validate URL protocol to prevent RCE
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
try {
const parsedUrl = new URL(url);
if (["http:", "https:"].includes(parsedUrl.protocol)) {
shell.openExternal(url);
} else {
console.warn("[Electron] Blocked unsafe protocol:", parsedUrl.protocol);
}
} catch {
console.error("[Electron] Blocked invalid URL:", url);
}
return { action: "deny" };
});
// Handle window close — minimize to tray
mainWindow.on("close", (event) => {
if (!app.isQuitting) {
event.preventDefault();
mainWindow.hide();
}
return false;
});
mainWindow.on("closed", () => {
mainWindow = null;
});
}
// ── System Tray ────────────────────────────────────────────
function createTray() {
// Fix #4: Destroy old tray before recreating
if (tray) {
tray.destroy();
tray = null;
}
const iconPath = path.join(RESOURCES_PATH, "assets", "tray-icon.png");
let icon;
try {
icon = nativeImage.createFromPath(iconPath);
if (icon.isEmpty()) icon = nativeImage.createEmpty();
} catch {
icon = nativeImage.createEmpty();
}
tray = new Tray(icon);
const contextMenu = Menu.buildFromTemplate([
{
label: "Open OmniRoute",
click: () => {
if (mainWindow) {
mainWindow.show();
mainWindow.focus();
}
},
},
{
label: "Open Dashboard",
click: () => shell.openExternal(getServerUrl()),
},
{ type: "separator" },
{
label: "Server Port",
submenu: [
{ label: `Port: ${serverPort}`, enabled: false },
{ type: "separator" },
{ label: "20128", click: () => changePort(20128) },
{ label: "3000", click: () => changePort(3000) },
{ label: "8080", click: () => changePort(8080) },
],
},
{ type: "separator" },
{
label: "Quit",
click: () => {
app.isQuitting = true;
app.quit();
},
},
]);
tray.setToolTip("OmniRoute");
tray.setContextMenu(contextMenu);
tray.on("double-click", () => {
if (mainWindow) {
mainWindow.show();
mainWindow.focus();
}
});
}
// ── Change Port (#3: now restarts server) ──────────────────
async function changePort(newPort) {
if (newPort === serverPort) return;
const oldPort = serverPort;
serverPort = newPort;
sendToRenderer("server-status", { status: "restarting", port: newPort });
// Stop current server and wait for exit
const serverToStop = nextServer;
stopNextServer();
await waitForServerExit(serverToStop);
// Start server on new port
startNextServer();
await waitForServer(getServerUrl());
// Reload window and update tray
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.loadURL(getServerUrl());
}
createTray();
sendToRenderer("port-changed", serverPort);
sendToRenderer("server-status", { status: "running", port: serverPort });
console.log(`[Electron] Port changed: ${oldPort}${serverPort}`);
}
// ── Server Lifecycle (#1, #5, #10) ─────────────────────────
function startNextServer() {
if (isDev) {
console.log("[Electron] Dev mode — connect to existing Next.js server");
sendToRenderer("server-status", { status: "running", port: serverPort });
return;
}
const serverScript = path.join(NEXT_SERVER_PATH, "server.js");
if (!fs.existsSync(serverScript)) {
console.error("[Electron] Server script not found:", serverScript);
sendToRenderer("server-status", { status: "error", port: serverPort });
return;
}
console.log("[Electron] Starting Next.js server on port", serverPort);
sendToRenderer("server-status", { status: "starting", port: serverPort });
// Fix #10: Use pipe instead of inherit for logging & readiness detection
nextServer = spawn("node", [serverScript], {
cwd: NEXT_SERVER_PATH,
env: {
...process.env,
PORT: String(serverPort),
NODE_ENV: "production",
},
stdio: "pipe",
});
// Capture server output for logging
nextServer.stdout?.on("data", (data) => {
const text = data.toString();
process.stdout.write(`[Server] ${text}`);
// Detect server ready
if (text.includes("Ready") || text.includes("started") || text.includes("listening")) {
sendToRenderer("server-status", { status: "running", port: serverPort });
}
});
nextServer.stderr?.on("data", (data) => {
process.stderr.write(`[Server:err] ${data}`);
});
nextServer.on("error", (err) => {
console.error("[Electron] Failed to start server:", err);
sendToRenderer("server-status", { status: "error", port: serverPort });
});
nextServer.on("exit", (code) => {
console.log("[Electron] Server exited with code:", code);
sendToRenderer("server-status", { status: "stopped", port: serverPort });
nextServer = null;
});
}
function stopNextServer() {
if (nextServer) {
nextServer.kill("SIGTERM");
nextServer = null;
}
}
// ── IPC Handlers ───────────────────────────────────────────
function setupIpcHandlers() {
ipcMain.handle("get-app-info", () => ({
name: app.getName(),
version: app.getVersion(),
platform: process.platform,
isDev,
port: serverPort,
}));
ipcMain.handle("open-external", (_event, url) => {
try {
const parsedUrl = new URL(url);
if (["http:", "https:"].includes(parsedUrl.protocol)) {
shell.openExternal(url);
}
} catch {
console.error("[Electron] Blocked invalid URL:", url);
}
});
ipcMain.handle("get-data-dir", () => app.getPath("userData"));
// Fix #2: Add timeout to restart
ipcMain.handle("restart-server", async () => {
const serverToStop = nextServer;
stopNextServer();
await waitForServerExit(serverToStop);
startNextServer();
await waitForServer(getServerUrl());
return { success: true };
});
// Window controls
ipcMain.on("window-minimize", () => mainWindow?.minimize());
ipcMain.on("window-maximize", () => {
if (mainWindow) {
mainWindow.isMaximized() ? mainWindow.unmaximize() : mainWindow.maximize();
}
});
ipcMain.on("window-close", () => mainWindow?.close());
}
// ── App Lifecycle ──────────────────────────────────────────
app.whenReady().then(async () => {
// Fix #15: Set up CSP before any content loads
setupContentSecurityPolicy();
// Fix #1: Start server and WAIT for readiness before showing window
startNextServer();
if (!isDev) {
await waitForServer(getServerUrl());
}
createWindow();
createTray();
setupIpcHandlers();
// macOS: recreate window when dock icon clicked
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
} else if (mainWindow) {
mainWindow.show();
}
});
});
// Quit when all windows closed (except macOS)
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
// Clean up before quit
app.on("before-quit", () => {
app.isQuitting = true;
stopNextServer();
});
// Global error handlers
process.on("uncaughtException", (error) => {
console.error("[Electron] Uncaught Exception:", error);
});
process.on("unhandledRejection", (reason) => {
console.error("[Electron] Unhandled Rejection:", reason);
});
+124
View File
@@ -0,0 +1,124 @@
{
"name": "omniroute-desktop",
"version": "1.6.9",
"description": "OmniRoute Desktop Application",
"main": "main.js",
"author": "OmniRoute Team",
"license": "MIT",
"homepage": "https://omniroute.online",
"scripts": {
"start": "electron .",
"dev": "electron . --no-sandbox",
"build": "electron-builder",
"build:win": "electron-builder --win",
"build:mac": "electron-builder --mac",
"build:linux": "electron-builder --linux",
"pack": "electron-builder --dir"
},
"dependencies": {},
"devDependencies": {
"electron": "^40.6.1",
"electron-builder": "^25.1.8"
},
"build": {
"appId": "online.omniroute.desktop",
"productName": "OmniRoute",
"copyright": "Copyright © 2025 OmniRoute",
"directories": {
"output": "dist-electron",
"buildResources": "assets"
},
"files": [
"main.js",
"preload.js",
"package.json"
],
"extraResources": [
{
"from": "../.next/standalone",
"to": "app",
"filter": [
"**/*"
]
},
{
"from": "../.next/static",
"to": "app/.next/static",
"filter": [
"**/*"
]
},
{
"from": "../public",
"to": "app/public",
"filter": [
"**/*"
]
}
],
"win": {
"target": [
{
"target": "nsis",
"arch": [
"x64"
]
},
{
"target": "portable",
"arch": [
"x64"
]
}
],
"icon": "assets/icon.ico"
},
"mac": {
"target": [
{
"target": "dmg",
"arch": [
"x64",
"arm64"
]
}
],
"icon": "assets/icon.icns",
"category": "public.app-category.productivity"
},
"linux": {
"target": [
{
"target": "AppImage",
"arch": [
"x64"
]
}
],
"icon": "assets/icons",
"category": "Utility"
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true,
"createDesktopShortcut": true,
"createStartMenuShortcut": true,
"installerIcon": "assets/icon.ico",
"uninstallerIcon": "assets/icon.ico"
},
"dmg": {
"contents": [
{
"x": 130,
"y": 220
},
{
"x": 410,
"y": 220,
"type": "link",
"path": "/Applications"
}
]
}
}
}
+65
View File
@@ -0,0 +1,65 @@
/**
* OmniRoute Electron Desktop App - Preload Script
*
* Secure bridge between renderer (Next.js) and main process (Electron).
* Uses contextIsolation: true for maximum security.
*
* Code Review Fixes Applied:
* #6 Listener accumulation return disposer functions instead of using removeAllListeners
* #16 Simplified channel validation generic wrapper reduces boilerplate
*/
const { contextBridge, ipcRenderer } = require("electron");
// ── Channel Whitelist ──────────────────────────────────────
const VALID_CHANNELS = {
invoke: ["get-app-info", "open-external", "get-data-dir", "restart-server"],
send: ["window-minimize", "window-maximize", "window-close"],
receive: ["server-status", "port-changed"],
};
// ── Fix #16: Generic IPC wrappers ──────────────────────────
function safeInvoke(channel, ...args) {
if (!VALID_CHANNELS.invoke.includes(channel)) {
return Promise.reject(new Error(`Blocked IPC invoke: ${channel}`));
}
return ipcRenderer.invoke(channel, ...args);
}
function safeSend(channel, ...args) {
if (VALID_CHANNELS.send.includes(channel)) {
ipcRenderer.send(channel, ...args);
}
}
// Fix #6: Return disposer function for proper listener cleanup
function safeOn(channel, callback) {
if (!VALID_CHANNELS.receive.includes(channel)) return () => {};
const handler = (_event, data) => callback(data);
ipcRenderer.on(channel, handler);
// Return a disposer — caller removes only THIS specific listener
return () => ipcRenderer.removeListener(channel, handler);
}
// ── Expose API to Renderer ─────────────────────────────────
contextBridge.exposeInMainWorld("electronAPI", {
// ── Invoke (async, returns Promise) ──────────────────────
getAppInfo: () => safeInvoke("get-app-info"),
openExternal: (url) => safeInvoke("open-external", url),
getDataDir: () => safeInvoke("get-data-dir"),
restartServer: () => safeInvoke("restart-server"),
// ── Send (fire-and-forget) ───────────────────────────────
minimizeWindow: () => safeSend("window-minimize"),
maximizeWindow: () => safeSend("window-maximize"),
closeWindow: () => safeSend("window-close"),
// ── Receive (event listeners) ────────────────────────────
// Fix #6: Returns a disposer function for precise cleanup
onServerStatus: (callback) => safeOn("server-status", callback),
onPortChanged: (callback) => safeOn("port-changed", callback),
// ── Static Properties ────────────────────────────────────
isElectron: true,
platform: process.platform,
});
+51
View File
@@ -0,0 +1,51 @@
/**
* OmniRoute Electron Types
*
* TypeScript definitions for the Electron API exposed to the renderer process.
*
* Updated to reflect:
* - Fix #6: onServerStatus/onPortChanged return disposer functions
* - Removed removeServerStatusListener/removePortChangedListener (replaced by disposers)
*/
export interface AppInfo {
name: string;
version: string;
platform: "win32" | "darwin" | "linux";
isDev: boolean;
port: number;
}
export interface ServerStatus {
status: "starting" | "running" | "stopped" | "restarting" | "error";
port: number;
}
export interface ElectronAPI {
// ── Invoke (async) ─────────────────────────────────────
getAppInfo(): Promise<AppInfo>;
openExternal(url: string): Promise<void>;
getDataDir(): Promise<string>;
restartServer(): Promise<{ success: boolean }>;
// ── Send (fire-and-forget) ─────────────────────────────
minimizeWindow(): void;
maximizeWindow(): void;
closeWindow(): void;
// ── Receive (returns disposer for cleanup) ─────────────
onServerStatus(callback: (data: ServerStatus) => void): () => void;
onPortChanged(callback: (port: number) => void): () => void;
// ── Static Properties ──────────────────────────────────
isElectron: boolean;
platform: "win32" | "darwin" | "linux";
}
declare global {
interface Window {
electronAPI: ElectronAPI;
}
}
export {};
+66 -12
View File
@@ -4,13 +4,39 @@ import { socksDispatcher } from "fetch-socks";
const DISPATCHER_CACHE_KEY = Symbol.for("omniroute.proxyDispatcher.cache");
const SUPPORTED_PROTOCOLS = new Set(["http:", "https:", "socks5:"]);
function getDispatcherCache() {
function getDispatcherCache(): Map<string, any> {
if (!globalThis[DISPATCHER_CACHE_KEY]) {
globalThis[DISPATCHER_CACHE_KEY] = new Map();
}
return globalThis[DISPATCHER_CACHE_KEY];
}
/**
* Clear all cached proxy dispatchers.
* Call this when proxy configuration changes to avoid stale connections.
*/
export function clearDispatcherCache() {
const cache = getDispatcherCache();
cache.clear();
}
/**
* Extract the port from a proxy URL string before URL parsing.
* `new URL("http://host:80")` strips port 80 since it's the HTTP default,
* but proxy servers commonly listen on port 80/443, so we need to preserve it.
*/
function extractExplicitPort(urlStr) {
try {
// Match port in the host portion: "scheme://[user:pass@]host:PORT[/...]"
const match = urlStr.match(/:\/\/(?:[^@]*@)?[^:/\s]+:(\d+)/);
if (match) {
const port = Number(match[1]);
if (Number.isInteger(port) && port >= 1 && port <= 65535) return String(port);
}
} catch {}
return null;
}
function defaultPortForProtocol(protocol) {
if (protocol === "https:" || protocol === "wss:") return "443";
if (protocol === "socks5:") return "1080";
@@ -26,13 +52,28 @@ function normalizePort(port, protocol) {
return String(parsed);
}
/**
* Build a proxy URL string manually from parsed URL components.
* We cannot use URL.toString() because the URL serializer silently strips
* default ports (80 for http, 443 for https). Proxy servers commonly
* listen on these ports, so we must always include the port explicitly.
*/
function buildProxyUrlString(parsed, port) {
const auth =
parsed.username
? `${parsed.username}${parsed.password ? `:${parsed.password}` : ""}@`
: "";
return `${parsed.protocol}//${auth}${parsed.hostname}:${port}`;
}
export function isSocks5ProxyEnabled() {
return process.env.ENABLE_SOCKS5_PROXY === "true";
}
export function proxyUrlForLogs(proxyUrl) {
const explicitPort = extractExplicitPort(proxyUrl);
const parsed = new URL(proxyUrl);
const port = parsed.port || defaultPortForProtocol(parsed.protocol);
const port = explicitPort || parsed.port || defaultPortForProtocol(parsed.protocol);
return `${parsed.protocol}//${parsed.hostname}:${port}`;
}
@@ -41,6 +82,11 @@ export function normalizeProxyUrl(
source = "proxy",
{ allowSocks5 = isSocks5ProxyEnabled() } = {}
) {
// Extract the explicit port from the raw URL string BEFORE parsing,
// because `new URL()` silently strips default ports (80 for http,
// 443 for https), which are valid and common for proxy servers.
const explicitPort = extractExplicitPort(proxyUrl);
let parsed;
try {
parsed = new URL(proxyUrl);
@@ -62,8 +108,12 @@ export function normalizeProxyUrl(
throw new Error(`[ProxyDispatcher] Invalid ${source} host`);
}
parsed.port = normalizePort(parsed.port, parsed.protocol);
return parsed.toString();
// Use the explicit port from the raw string if present, otherwise apply default.
const port = explicitPort || normalizePort(parsed.port, parsed.protocol);
// Build the URL string manually instead of using parsed.toString(),
// which would strip default ports (80/443) and break the proxy connection.
return buildProxyUrlString(parsed, port);
}
export function proxyConfigToUrl(proxyConfig, { allowSocks5 = isSocks5ProxyEnabled() } = {}) {
@@ -93,14 +143,15 @@ export function proxyConfigToUrl(proxyConfig, { allowSocks5 = isSocks5ProxyEnabl
}
const port = normalizePort(proxyConfig.port, protocol);
const proxyUrl = new URL(`${type}://${proxyConfig.host}:${port}`);
if (proxyConfig.username) {
proxyUrl.username = proxyConfig.username;
proxyUrl.password = proxyConfig.password || "";
}
// Build the URL string manually to preserve the port through normalization.
const auth = proxyConfig.username
? `${encodeURIComponent(proxyConfig.username)}:${proxyConfig.password ? encodeURIComponent(proxyConfig.password) : ""}@`
: "";
return normalizeProxyUrl(proxyUrl.toString(), "context proxy", { allowSocks5 });
const proxyUrlStr = `${type}://${auth}${proxyConfig.host}:${port}`;
return normalizeProxyUrl(proxyUrlStr, "context proxy", { allowSocks5 });
}
export function createProxyDispatcher(proxyUrl) {
@@ -111,11 +162,14 @@ export function createProxyDispatcher(proxyUrl) {
if (dispatcher) return dispatcher;
const parsed = new URL(normalizedUrl);
const explicitPort = extractExplicitPort(normalizedUrl);
const port = explicitPort || normalizePort(parsed.port, parsed.protocol);
if (parsed.protocol === "socks5:") {
const socksOptions: Record<string, any> = {
type: 5,
host: parsed.hostname,
port: Number(normalizePort(parsed.port, parsed.protocol)),
port: Number(port),
};
if (parsed.username) socksOptions.userId = decodeURIComponent(parsed.username);
if (parsed.password) socksOptions.password = decodeURIComponent(parsed.password);
@@ -126,4 +180,4 @@ export function createProxyDispatcher(proxyUrl) {
dispatcherCache.set(normalizedUrl, dispatcher);
return dispatcher;
}
}
+496 -3
View File
@@ -1,12 +1,12 @@
{
"name": "omniroute",
"version": "1.6.2",
"version": "1.6.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "omniroute",
"version": "1.6.2",
"version": "1.6.4",
"hasInstallScript": true,
"license": "MIT",
"workspaces": [
@@ -53,6 +53,8 @@
"@types/node": "^25.2.3",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"concurrently": "^9.2.1",
"cross-env": "^10.1.0",
"eslint": "^9.39.2",
"eslint-config-next": "16.1.6",
"husky": "^9.1.7",
@@ -61,7 +63,8 @@
"tailwindcss": "^4",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0"
"typescript-eslint": "^8.56.0",
"wait-on": "^9.0.4"
},
"engines": {
"node": ">=18.0.0 <24.0.0"
@@ -366,6 +369,13 @@
"tslib": "^2.4.0"
}
},
"node_modules/@epic-web/invariant": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
"integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==",
"dev": true,
"license": "MIT"
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz",
@@ -1004,6 +1014,60 @@
"tslib": "^2.8.1"
}
},
"node_modules/@hapi/address": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-5.1.1.tgz",
"integrity": "sha512-A+po2d/dVoY7cYajycYI43ZbYMXukuopIsqCjh5QzsBCipDtdofHntljDlpccMjIfTy6UOkg+5KPriwYch2bXA==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@hapi/hoek": "^11.0.2"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@hapi/formula": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-3.0.2.tgz",
"integrity": "sha512-hY5YPNXzw1He7s0iqkRQi+uMGh383CGdyyIGYtB+W5N3KHPXoqychklvHhKCC9M3Xtv0OCs/IHw+r4dcHtBYWw==",
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/@hapi/hoek": {
"version": "11.0.7",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.7.tgz",
"integrity": "sha512-HV5undWkKzcB4RZUusqOpcgxOaq6VOAH7zhhIr2g3G8NF/MlFO75SjOr2NfuSx0Mh40+1FqCkagKLJRykUWoFQ==",
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/@hapi/pinpoint": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.1.tgz",
"integrity": "sha512-EKQmr16tM8s16vTT3cA5L0kZZcTMU5DUOZTuvpnY738m+jyP3JIUj+Mm1xc1rsLkGBQ/gVnfKYPwOmPg1tUR4Q==",
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/@hapi/tlds": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@hapi/tlds/-/tlds-1.1.6.tgz",
"integrity": "sha512-xdi7A/4NZokvV0ewovme3aUO5kQhW9pQ2YD1hRqZGhhSi5rBv4usHYidVocXSi9eihYsznZxLtAiEYYUL6VBGw==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@hapi/topo": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-6.0.2.tgz",
"integrity": "sha512-KR3rD5inZbGMrHmgPxsJ9dbi6zEK+C3ZwUwTa+eMwWLz7oijWUTWD2pMSNNYJAU6Qq+65NkxXjqHr/7LM2Xkqg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@hapi/hoek": "^11.0.2"
}
},
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
@@ -3918,6 +3982,13 @@
"node": ">= 0.4"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"dev": true,
"license": "MIT"
},
"node_modules/atomic-sleep": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
@@ -3953,6 +4024,18 @@
"node": ">=4"
}
},
"node_modules/axios": {
"version": "1.13.6",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz",
"integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axobject-query": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
@@ -4337,6 +4420,94 @@
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
"license": "MIT"
},
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/cliui/node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/cliui/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/cliui/node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/cliui/node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/cliui/node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/cliui/node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/clsx": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
@@ -4372,6 +4543,19 @@
"integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
"license": "MIT"
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "14.0.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
@@ -4389,6 +4573,47 @@
"dev": true,
"license": "MIT"
},
"node_modules/concurrently": {
"version": "9.2.1",
"resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz",
"integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==",
"dev": true,
"license": "MIT",
"dependencies": {
"chalk": "4.1.2",
"rxjs": "7.8.2",
"shell-quote": "1.8.3",
"supports-color": "8.1.1",
"tree-kill": "1.2.2",
"yargs": "17.7.2"
},
"bin": {
"conc": "dist/bin/concurrently.js",
"concurrently": "dist/bin/concurrently.js"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
}
},
"node_modules/concurrently/node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/content-disposition": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
@@ -4436,6 +4661,24 @@
"node": ">=6.6.0"
}
},
"node_modules/cross-env": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
"integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@epic-web/invariant": "^1.0.0",
"cross-spawn": "^7.0.6"
},
"bin": {
"cross-env": "dist/bin/cross-env.js",
"cross-env-shell": "dist/bin/cross-env-shell.js"
},
"engines": {
"node": ">=20"
}
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -4785,6 +5028,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -5859,6 +6112,46 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/form-data": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
"dev": true,
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/form-data/node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/form-data/node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -5958,6 +6251,16 @@
"node": ">=6.9.0"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
"license": "ISC",
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/get-east-asian-width": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz",
@@ -7034,6 +7337,25 @@
"jiti": "lib/jiti-cli.mjs"
}
},
"node_modules/joi": {
"version": "18.0.2",
"resolved": "https://registry.npmjs.org/joi/-/joi-18.0.2.tgz",
"integrity": "sha512-RuCOQMIt78LWnktPoeBL0GErkNaJPTBGcYuyaBvUOQSpcpcLfWrHPPihYdOGbV5pam9VTWbeoF7TsGiHugcjGA==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@hapi/address": "^5.1.1",
"@hapi/formula": "^3.0.2",
"@hapi/hoek": "^11.0.7",
"@hapi/pinpoint": "^2.0.1",
"@hapi/tlds": "^1.1.1",
"@hapi/topo": "^6.0.2",
"@standard-schema/spec": "^1.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/jose": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz",
@@ -7506,6 +7828,13 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lodash": {
"version": "4.17.23",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
"dev": true,
"license": "MIT"
},
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -8686,6 +9015,13 @@
"node": ">= 0.10"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true,
"license": "MIT"
},
"node_modules/pump": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
@@ -8988,6 +9324,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -9127,6 +9473,16 @@
"queue-microtask": "^1.2.2"
}
},
"node_modules/rxjs": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/safe-array-concat": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
@@ -9443,6 +9799,19 @@
"node": ">=8"
}
},
"node_modules/shell-quote": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
"integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
@@ -10084,6 +10453,16 @@
"node": ">=0.6"
}
},
"node_modules/tree-kill": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
"integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
"dev": true,
"license": "MIT",
"bin": {
"tree-kill": "cli.js"
}
},
"node_modules/ts-api-utils": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
@@ -10523,6 +10902,26 @@
"d3-timer": "^3.0.1"
}
},
"node_modules/wait-on": {
"version": "9.0.4",
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-9.0.4.tgz",
"integrity": "sha512-k8qrgfwrPVJXTeFY8tl6BxVHiclK11u72DVKhpybHfUL/K6KM4bdyK9EhIVYGytB5MJe/3lq4Tf0hrjM+pvJZQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"axios": "^1.13.5",
"joi": "^18.0.2",
"lodash": "^4.17.23",
"minimist": "^1.2.8",
"rxjs": "^7.8.2"
},
"bin": {
"wait-on": "bin/wait-on"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -10734,6 +11133,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=10"
}
},
"node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
@@ -10757,6 +11166,90 @@
"url": "https://github.com/sponsors/eemeli"
}
},
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dev": true,
"license": "MIT",
"dependencies": {
"cliui": "^8.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.3",
"y18n": "^5.0.5",
"yargs-parser": "^21.1.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/yargs-parser": {
"version": "21.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/yargs/node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/yargs/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/yargs/node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/yargs/node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/yargs/node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+10 -2
View File
@@ -1,6 +1,6 @@
{
"name": "omniroute",
"version": "1.6.3",
"version": "1.6.9",
"description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.",
"type": "module",
"bin": {
@@ -48,6 +48,11 @@
"build:cli": "node scripts/prepublish.mjs",
"start": "node scripts/run-next.mjs start",
"lint": "eslint .",
"electron:dev": "concurrently \"npm run dev\" \"wait-on http://localhost:20128 && cd electron && npm run dev\"",
"electron:build": "npm run build && cd electron && npm run build",
"electron:build:win": "npm run build && cd electron && npm run build:win",
"electron:build:mac": "npm run build && cd electron && npm run build:mac",
"electron:build:linux": "npm run build && cd electron && npm run build:linux",
"test": "node --import tsx/esm --test tests/unit/*.test.mjs",
"test:unit": "node --import tsx/esm --test tests/unit/*.test.mjs",
"test:plan3": "node --test tests/unit/plan3-p0.test.mjs",
@@ -98,6 +103,8 @@
"@types/node": "^25.2.3",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"concurrently": "^9.2.1",
"cross-env": "^10.1.0",
"eslint": "^9.39.2",
"eslint-config-next": "16.1.6",
"husky": "^9.1.7",
@@ -106,7 +113,8 @@
"tailwindcss": "^4",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.56.0"
"typescript-eslint": "^8.56.0",
"wait-on": "^9.0.4"
},
"lint-staged": {
"*.{js,jsx,ts,tsx,mjs}": [
@@ -17,6 +17,7 @@ import {
KiloToolCard,
DefaultToolCard,
AntigravityToolCard,
CopilotToolCard,
} from "./components";
import { useTranslations } from "next-intl";
@@ -32,7 +33,6 @@ export default function CLIToolsPageClient({ machineId }) {
const [apiKeys, setApiKeys] = useState([]);
const [toolStatuses, setToolStatuses] = useState({});
const [statusesLoaded, setStatusesLoaded] = useState(false);
const [apiBaseUrl, setApiBaseUrl] = useState("");
useEffect(() => {
fetchConnections();
@@ -47,12 +47,6 @@ export default function CLIToolsPageClient({ machineId }) {
if (res.ok) {
const data = await res.json();
setCloudEnabled(data.cloudEnabled || false);
if (typeof window !== "undefined") {
const protocol = window.location.protocol;
const hostname = window.location.hostname;
const apiPort = data?.apiPort || 20128;
setApiBaseUrl(`${protocol}//${hostname}:${apiPort}`);
}
}
} catch (error) {
console.log("Error loading cloud settings:", error);
@@ -154,9 +148,8 @@ export default function CLIToolsPageClient({ machineId }) {
if (cloudEnabled && CLOUD_URL) {
return CLOUD_URL;
}
if (apiBaseUrl) {
return apiBaseUrl;
}
// Use window.location.origin directly — works correctly in Docker/reverse-proxy
// Per @alpgul feedback: don't use baseUrl prop (has port duplication issues)
if (typeof window !== "undefined") {
return window.location.origin;
}
@@ -263,6 +256,16 @@ export default function CLIToolsPageClient({ machineId }) {
cloudEnabled={cloudEnabled}
/>
);
case "copilot":
return (
<CopilotToolCard
key={toolId}
{...commonProps}
activeProviders={getActiveProviders()}
hasActiveProviders={hasActiveProviders}
cloudEnabled={cloudEnabled}
/>
);
default:
return (
<DefaultToolCard
@@ -0,0 +1,420 @@
"use client";
import { useState, useEffect } from "react";
import { Card, Button } from "@/shared/components";
import Image from "next/image";
import { useTranslations } from "next-intl";
/**
* GitHub Copilot Configuration Generator
*
* Generates the chatLanguageModels.json block for VS Code GitHub Copilot
* using the Azure vendor pattern as required by Copilot's architecture.
*
* Feature request: https://github.com/diegosouzapw/OmniRoute/issues/142
*/
export default function CopilotToolCard({
tool,
isExpanded,
onToggle,
baseUrl,
apiKeys,
activeProviders = [],
hasActiveProviders = false,
cloudEnabled = false,
batchStatus,
}) {
const t = useTranslations("cliTools");
const [copiedField, setCopiedField] = useState<string | null>(null);
const [selectedModels, setSelectedModels] = useState<Set<string>>(() => {
if (typeof window === "undefined") return new Set<string>();
try {
const saved = localStorage.getItem("omniroute-copilot-selected-models");
return saved ? new Set<string>(JSON.parse(saved)) : new Set<string>();
} catch {
return new Set<string>();
}
});
const [selectedApiKey, setSelectedApiKey] = useState(() => {
if (typeof window !== "undefined") {
const savedKey = localStorage.getItem("omniroute-cli-key-copilot");
if (savedKey && apiKeys?.some((k: any) => k.key === savedKey)) return savedKey;
}
return apiKeys?.length > 0 ? apiKeys[0].key : "";
});
const [maxInputTokens, setMaxInputTokens] = useState(128000);
const [maxOutputTokens, setMaxOutputTokens] = useState(16000);
const [toolCalling, setToolCalling] = useState(true);
const [vision, setVision] = useState(false);
const [allModels, setAllModels] = useState<Array<{ value: string; label: string }>>([]);
const [modelsLoaded, setModelsLoaded] = useState(false);
const [searchFilter, setSearchFilter] = useState("");
// Fetch ALL models dynamically from /v1/models (includes combos, custom, aliased)
// Per @alpgul feedback: /api/models/alias doesn't include combo definitions
useEffect(() => {
if (!isExpanded || modelsLoaded) return;
let cancelled = false;
fetch("/v1/models")
.then((res) => res.json())
.then((data) => {
if (cancelled) return;
const modelList = (data.data || [])
.filter((m: any) => m && !m.type && !m.parent && m.id) // Only chat models with valid IDs
.map((m: any) => ({
value: m.id,
label: m.id,
}));
setAllModels(modelList);
setModelsLoaded(true);
})
.catch(() => {
if (!cancelled) setModelsLoaded(true);
});
return () => {
cancelled = true;
};
}, [isExpanded, modelsLoaded]);
// Filter models by search
const availableModels = searchFilter
? allModels.filter((m) => m.label.toLowerCase().includes(searchFilter.toLowerCase()))
: allModels;
// Persist selection
useEffect(() => {
if (selectedModels.size > 0) {
localStorage.setItem(
"omniroute-copilot-selected-models",
JSON.stringify([...selectedModels])
);
}
}, [selectedModels]);
const toggleModel = (modelValue: string) => {
setSelectedModels((prev) => {
const next = new Set(prev);
if (next.has(modelValue)) {
next.delete(modelValue);
} else {
next.add(modelValue);
}
return next;
});
};
const selectAll = () => {
setSelectedModels(new Set(allModels.map((m) => m.value)));
};
const deselectAll = () => {
setSelectedModels(new Set());
};
const getBaseUrlForConfig = () => {
const url = baseUrl;
return `${url}/v1/chat/completions`;
};
// Generate the Copilot chatLanguageModels.json config
const generateConfig = () => {
const models = [...selectedModels].map((modelId) => ({
id: modelId,
name: modelId,
url: `${getBaseUrlForConfig()}#models.ai.azure.com`,
toolCalling,
vision,
maxInputTokens,
maxOutputTokens,
}));
const config = {
name: "OmniRoute",
vendor: "azure",
apiKey: `\${input:chat.lm.secret.omniroute}`,
models,
};
return JSON.stringify(config, null, 2);
};
const handleCopy = async (text: string, field: string) => {
await navigator.clipboard.writeText(text);
setCopiedField(field);
setTimeout(() => setCopiedField(null), 2000);
};
const handleApiKeyChange = (value: string) => {
setSelectedApiKey(value);
if (value) localStorage.setItem("omniroute-cli-key-copilot", value);
};
return (
<Card padding="sm" className="overflow-hidden">
{/* Header */}
<div className="flex items-center justify-between hover:cursor-pointer" onClick={onToggle}>
<div className="flex items-center gap-3">
<div className="size-8 rounded-lg flex items-center justify-center shrink-0">
<Image
src={tool.image || "/providers/copilot.png"}
alt={tool.name}
width={32}
height={32}
className="size-8 object-contain rounded-lg"
sizes="32px"
onError={(e) => {
(e.currentTarget as HTMLElement).style.display = "none";
}}
/>
</div>
<div className="min-w-0">
<div className="flex items-center gap-2">
<h3 className="font-medium text-sm">{tool.name}</h3>
<span className="inline-flex items-center gap-1.5 px-2 py-0.5 text-[11px] font-medium rounded-full bg-blue-500/10 text-blue-600 dark:text-blue-400">
<span className="size-1.5 rounded-full bg-blue-500" />
{t("guide")}
</span>
</div>
<p className="text-xs text-text-muted truncate">{tool.description}</p>
</div>
</div>
<span
className={`material-symbols-outlined text-text-muted text-[20px] transition-transform ${isExpanded ? "rotate-180" : ""}`}
>
expand_more
</span>
</div>
{/* Expanded content */}
{isExpanded && (
<div className="mt-6 pt-6 border-t border-border">
<div className="flex flex-col gap-5">
{/* Info box */}
<div className="flex items-start gap-3 p-3 bg-blue-500/10 border border-blue-500/30 rounded-lg">
<span className="material-symbols-outlined text-blue-500 text-lg">info</span>
<div className="text-sm text-blue-700 dark:text-blue-300">
<p className="font-medium">GitHub Copilot Config Generator</p>
<p className="mt-1 text-xs opacity-80">
Generates the{" "}
<code className="px-1 py-0.5 rounded bg-black/5 dark:bg-white/10">
chatLanguageModels.json
</code>{" "}
block for VS Code GitHub Copilot using the Azure vendor pattern. Select the models
you want, then copy the JSON into your config file.
</p>
</div>
</div>
{/* Version compatibility warning */}
<div className="flex items-start gap-3 p-3 bg-yellow-500/10 border border-yellow-500/30 rounded-lg">
<span className="material-symbols-outlined text-yellow-500 text-lg">warning</span>
<p className="text-xs text-yellow-600 dark:text-yellow-400">
This configuration uses the Azure vendor workaround for custom model lists. Tested
with <strong>VS Code 1.109</strong> and{" "}
<strong>GitHub Copilot Chat v0.37</strong>. Future extension updates may change
this behavior.
</p>
</div>
{/* Step 2: API Key (if cloud enabled) */}
{cloudEnabled && apiKeys?.length > 0 && (
<div>
<div className="flex items-center gap-2 mb-2">
<div
className="size-6 rounded-full flex items-center justify-center text-xs font-semibold text-white"
style={{ backgroundColor: tool.color }}
>
1
</div>
<span className="font-medium text-sm">API Key</span>
</div>
<select
value={selectedApiKey}
onChange={(e) => handleApiKeyChange(e.target.value)}
className="w-full px-3 py-2 bg-bg-secondary rounded-lg text-sm border border-border focus:outline-none focus:ring-1 focus:ring-primary/50"
>
{apiKeys.map((key: any) => (
<option key={key.id} value={key.key}>
{key.key}
</option>
))}
</select>
</div>
)}
{/* Step 3: Model Selection */}
<div>
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2">
<div
className="size-6 rounded-full flex items-center justify-center text-xs font-semibold text-white"
style={{ backgroundColor: tool.color }}
>
{cloudEnabled && apiKeys?.length > 0 ? "2" : "1"}
</div>
<span className="font-medium text-sm">
Select Models ({selectedModels.size}/{availableModels.length})
</span>
</div>
<div className="flex gap-2">
<button
onClick={selectAll}
className="px-2 py-1 text-xs bg-bg-secondary hover:bg-bg-tertiary rounded border border-border transition-colors"
>
Select All
</button>
<button
onClick={deselectAll}
className="px-2 py-1 text-xs bg-bg-secondary hover:bg-bg-tertiary rounded border border-border transition-colors"
>
Clear
</button>
</div>
</div>
{/* Search filter */}
<div className="mb-2">
<input
type="text"
value={searchFilter}
onChange={(e) => setSearchFilter(e.target.value)}
placeholder="Filter models..."
className="w-full px-3 py-1.5 bg-bg-secondary rounded-lg text-sm border border-border focus:outline-none focus:ring-1 focus:ring-primary/50"
/>
</div>
{!modelsLoaded && allModels.length === 0 ? (
<div className="flex items-center gap-2 p-3 text-text-muted text-sm">
<span className="material-symbols-outlined animate-spin text-base">
progress_activity
</span>
<span>Loading models...</span>
</div>
) : availableModels.length === 0 && allModels.length === 0 ? (
<div className="flex items-center gap-2 p-3 bg-yellow-500/10 border border-yellow-500/30 rounded-lg">
<span className="material-symbols-outlined text-yellow-500 text-lg">warning</span>
<p className="text-sm text-yellow-600 dark:text-yellow-400">
{t("noActiveProviders")}
</p>
</div>
) : (
<div className="max-h-64 overflow-y-auto rounded-lg border border-border bg-bg-secondary">
{availableModels.map((model) => (
<label
key={model.value}
className="flex items-center gap-3 px-3 py-2 hover:bg-bg-tertiary cursor-pointer border-b border-border last:border-0 transition-colors"
>
<input
type="checkbox"
checked={selectedModels.has(model.value)}
onChange={() => toggleModel(model.value)}
className="rounded border-border text-primary accent-[#1F6FEB]"
/>
<span className="text-sm font-mono truncate">{model.label}</span>
</label>
))}
</div>
)}
</div>
{/* Step 4: Advanced options (collapsible) */}
<details className="group">
<summary className="flex items-center gap-2 cursor-pointer text-sm text-text-muted hover:text-text-main transition-colors">
<span className="material-symbols-outlined text-base group-open:rotate-90 transition-transform">
chevron_right
</span>
Advanced Options
</summary>
<div className="mt-3 grid grid-cols-2 gap-3 pl-6">
<div>
<label className="text-xs text-text-muted block mb-1">Max Input Tokens</label>
<input
type="number"
value={maxInputTokens}
onChange={(e) => setMaxInputTokens(Number(e.target.value) || 128000)}
className="w-full px-3 py-1.5 bg-bg-secondary rounded-lg text-sm border border-border focus:outline-none focus:ring-1 focus:ring-primary/50"
/>
</div>
<div>
<label className="text-xs text-text-muted block mb-1">Max Output Tokens</label>
<input
type="number"
value={maxOutputTokens}
onChange={(e) => setMaxOutputTokens(Number(e.target.value) || 16000)}
className="w-full px-3 py-1.5 bg-bg-secondary rounded-lg text-sm border border-border focus:outline-none focus:ring-1 focus:ring-primary/50"
/>
</div>
<label className="flex items-center gap-2 cursor-pointer">
<input
type="checkbox"
checked={toolCalling}
onChange={(e) => setToolCalling(e.target.checked)}
className="rounded border-border accent-[#1F6FEB]"
/>
<span className="text-sm">Tool Calling</span>
</label>
<label className="flex items-center gap-2 cursor-pointer">
<input
type="checkbox"
checked={vision}
onChange={(e) => setVision(e.target.checked)}
className="rounded border-border accent-[#1F6FEB]"
/>
<span className="text-sm">Vision</span>
</label>
</div>
</details>
{/* Step 5: Generated config */}
{selectedModels.size > 0 && (
<div>
<div className="flex items-center justify-between mb-2">
<div className="flex items-center gap-2">
<div
className="size-6 rounded-full flex items-center justify-center text-xs font-semibold text-white"
style={{ backgroundColor: tool.color }}
>
{cloudEnabled && apiKeys?.length > 0 ? "3" : "2"}
</div>
<span className="font-medium text-sm">
Copy Config ({selectedModels.size} model{selectedModels.size !== 1 ? "s" : ""}
)
</span>
</div>
<Button
variant="primary"
size="sm"
onClick={() => handleCopy(generateConfig(), "config")}
>
<span className="material-symbols-outlined text-[14px] mr-1">
{copiedField === "config" ? "check" : "content_copy"}
</span>
{copiedField === "config" ? t("copied") : t("copyConfig")}
</Button>
</div>
<pre className="p-4 bg-bg-secondary rounded-lg border border-border overflow-x-auto max-h-80">
<code className="text-xs font-mono whitespace-pre text-text-main">
{generateConfig()}
</code>
</pre>
{/* Usage instructions */}
<div className="mt-3 p-3 bg-bg-secondary rounded-lg border border-border">
<p className="text-xs text-text-muted">
<span className="font-medium text-text-main">Paste into: </span>
<code className="px-1 py-0.5 rounded bg-black/5 dark:bg-white/10">
~/.config/Code/User/chatLanguageModels.json
</code>
</p>
<p className="text-xs text-text-muted mt-1">
Then reload VS Code and set the API key in the input prompt.
</p>
</div>
</div>
)}
</div>
</div>
)}
</Card>
);
}
@@ -6,3 +6,4 @@ export { default as ClineToolCard } from "./ClineToolCard";
export { default as KiloToolCard } from "./KiloToolCard";
export { default as DefaultToolCard } from "./DefaultToolCard";
export { default as AntigravityToolCard } from "./AntigravityToolCard";
export { default as CopilotToolCard } from "./CopilotToolCard";
+3
View File
@@ -5,6 +5,7 @@ import {
deleteProxyForLevel,
resolveProxyForConnection,
} from "../../../../lib/localDb";
import { clearDispatcherCache } from "@omniroute/open-sse/utils/proxyDispatcher";
const BASE_SUPPORTED_PROXY_TYPES = new Set(["http", "https"]);
@@ -129,6 +130,7 @@ export async function PUT(request) {
const body = await request.json();
const normalizedBody = normalizeProxyPayload(body);
const updated = await setProxyConfig(normalizedBody);
clearDispatcherCache();
return Response.json(updated);
} catch (error) {
const status = Number(error?.status) || 500;
@@ -155,6 +157,7 @@ export async function DELETE(request) {
}
const updated = await deleteProxyForLevel(level, id);
clearDispatcherCache();
return Response.json(updated);
} catch (error) {
return Response.json(
+70 -30
View File
@@ -3,6 +3,7 @@
*
* In-memory LRU cache for LLM prompt/response pairs.
* Uses content hashing for cache keys to handle semantic deduplication.
* Memory-optimized with byte-based limits.
*
* @module lib/cacheLayer
*/
@@ -19,22 +20,30 @@ import crypto from "node:crypto";
* @property {number} hits - Number of times this entry was accessed
*/
const DEFAULT_MAX_ENTRIES = 50;
const DEFAULT_MAX_BYTES = 2 * 1024 * 1024;
const DEFAULT_TTL = 300000;
export class LRUCache {
/** @type {Map<string, CacheEntry>} */
#cache = new Map();
#maxSize;
#maxBytes;
#defaultTTL;
#currentSize = 0;
#currentBytes = 0;
#stats = { hits: 0, misses: 0, evictions: 0 };
/**
* @param {Object} options
* @param {number} [options.maxSize=100] - Max number of entries
* @param {number} [options.maxSize=50] - Max number of entries (reduced for memory)
* @param {number} [options.maxBytes=2097152] - Max bytes (default: 2MB)
* @param {number} [options.defaultTTL=300000] - Default TTL in ms (5 min)
*/
constructor(options: any = {}) {
this.#maxSize = options.maxSize ?? 100;
this.#defaultTTL = options.defaultTTL ?? 300000;
constructor(options: { maxSize?: number; maxBytes?: number; defaultTTL?: number } = {}) {
this.#maxSize = options.maxSize ?? DEFAULT_MAX_ENTRIES;
this.#maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
this.#defaultTTL = options.defaultTTL ?? DEFAULT_TTL;
}
/**
@@ -42,7 +51,7 @@ export class LRUCache {
* @param {Object} params - Parameters to hash
* @returns {string} Cache key
*/
static generateKey(params) {
static generateKey(params: Record<string, unknown>) {
const normalized = JSON.stringify(params, Object.keys(params).sort());
return crypto.createHash("sha256").update(normalized).digest("hex").slice(0, 16);
}
@@ -52,7 +61,7 @@ export class LRUCache {
* @param {string} key
* @returns {*|undefined}
*/
get(key) {
get(key: string) {
const entry = this.#cache.get(key);
if (!entry) {
@@ -60,15 +69,12 @@ export class LRUCache {
return undefined;
}
// Check TTL
if (Date.now() - entry.createdAt > entry.ttl) {
this.#cache.delete(key);
this.#currentSize--;
this.#deleteEntry(key, entry);
this.#stats.misses++;
return undefined;
}
// Move to end (most recently used)
this.#cache.delete(key);
entry.hits++;
this.#cache.set(key, entry);
@@ -83,18 +89,25 @@ export class LRUCache {
* @param {*} value
* @param {number} [ttl] - Override default TTL
*/
set(key, value, ttl) {
// If key exists, delete it first (will be re-added at end)
set(key: string, value: unknown, ttl?: number) {
const entrySize = this.#estimateSize(value);
if (this.#cache.has(key)) {
this.#cache.delete(key);
const oldEntry = this.#cache.get(key)!;
this.#currentBytes -= oldEntry.size || 0;
this.#currentSize--;
this.#cache.delete(key);
}
// Evict oldest entries if at capacity
while (this.#currentSize >= this.#maxSize) {
while (
(this.#currentSize >= this.#maxSize || this.#currentBytes + entrySize > this.#maxBytes) &&
this.#cache.size > 0
) {
const oldestKey = this.#cache.keys().next().value;
this.#cache.delete(oldestKey);
this.#currentSize--;
const oldestEntry = this.#cache.get(oldestKey);
if (oldestEntry) {
this.#deleteEntry(oldestKey, oldestEntry);
}
this.#stats.evictions++;
}
@@ -103,12 +116,34 @@ export class LRUCache {
value,
createdAt: Date.now(),
ttl: ttl ?? this.#defaultTTL,
size: JSON.stringify(value).length,
size: entrySize,
hits: 0,
};
this.#cache.set(key, entry);
this.#currentSize++;
this.#currentBytes += entrySize;
}
/**
* Estimate size of a value in bytes.
*/
#estimateSize(value: unknown): number {
try {
return JSON.stringify(value).length * 2;
} catch {
return 1024;
}
}
/**
* Delete an entry and update counters.
*/
#deleteEntry(key: string, entry: { size?: number }) {
this.#cache.delete(key);
this.#currentSize--;
this.#currentBytes -= entry.size || 0;
if (this.#currentBytes < 0) this.#currentBytes = 0;
}
/**
@@ -116,12 +151,11 @@ export class LRUCache {
* @param {string} key
* @returns {boolean}
*/
has(key) {
has(key: string) {
const entry = this.#cache.get(key);
if (!entry) return false;
if (Date.now() - entry.createdAt > entry.ttl) {
this.#cache.delete(key);
this.#currentSize--;
this.#deleteEntry(key, entry);
return false;
}
return true;
@@ -132,10 +166,10 @@ export class LRUCache {
* @param {string} key
* @returns {boolean}
*/
delete(key) {
if (this.#cache.has(key)) {
this.#cache.delete(key);
this.#currentSize--;
delete(key: string) {
const entry = this.#cache.get(key);
if (entry) {
this.#deleteEntry(key, entry);
return true;
}
return false;
@@ -145,14 +179,17 @@ export class LRUCache {
clear() {
this.#cache.clear();
this.#currentSize = 0;
this.#currentBytes = 0;
}
/** @returns {{ size: number, maxSize: number, hits: number, misses: number, evictions: number, hitRate: number }} */
/** @returns {{ size: number, maxSize: number, bytes: number, maxBytes: number, hits: number, misses: number, evictions: number, hitRate: number }} */
getStats() {
const total = this.#stats.hits + this.#stats.misses;
return {
size: this.#currentSize,
maxSize: this.#maxSize,
bytes: this.#currentBytes,
maxBytes: this.#maxBytes,
...this.#stats,
hitRate: total > 0 ? (this.#stats.hits / total) * 100 : 0,
};
@@ -161,18 +198,21 @@ export class LRUCache {
// ─── Prompt Cache Singleton ─────────────────
let promptCache;
let promptCache: LRUCache | null = null;
/**
* Get the global prompt cache instance.
* @param {Object} [options]
* @returns {LRUCache}
*/
export function getPromptCache(options?: any) {
export function getPromptCache(
options?: { maxSize?: number; maxBytes?: number; defaultTTL?: number } & Record<string, unknown>
) {
if (!promptCache) {
promptCache = new LRUCache({
maxSize: parseInt(process.env.PROMPT_CACHE_MAX_SIZE || "200", 10),
defaultTTL: parseInt(process.env.PROMPT_CACHE_TTL_MS || "600000", 10),
maxSize: parseInt(process.env.PROMPT_CACHE_MAX_SIZE || "50", 10),
maxBytes: parseInt(process.env.PROMPT_CACHE_MAX_BYTES || String(2 * 1024 * 1024), 10),
defaultTTL: parseInt(process.env.PROMPT_CACHE_TTL_MS || "300000", 10),
...options,
});
}
+4 -4
View File
@@ -211,11 +211,11 @@ function migrateProxyEntry(value: any) {
try {
const url = new URL(value);
return {
type: url.protocol.replace(":", "").replace("//", "") || "http",
type: url.protocol.replace(":", "") || "http",
host: url.hostname,
port: url.port || (url.protocol === "socks5:" ? "1080" : "8080"),
username: url.username || "",
password: url.password || "",
port: url.port || (url.protocol === "socks5:" ? "1080" : url.protocol === "https:" ? "443" : "8080"),
username: url.username ? decodeURIComponent(url.username) : "",
password: url.password ? decodeURIComponent(url.password) : "",
};
} catch {
const parts = value.split(":");
+2 -2
View File
@@ -11,7 +11,7 @@ import { getDbInstance, isCloud, isBuildPhase } from "./db/core";
const shouldPersistToDisk = !isCloud && !isBuildPhase;
const MAX_ENTRIES = 500;
const MAX_ENTRIES = parseInt(process.env.PROXY_LOG_MAX_ENTRIES || "200", 10);
interface ProxyInfo {
type: string;
@@ -134,7 +134,7 @@ export function logProxyEvent(entry: Partial<ProxyLogEntry>) {
status: log.status,
proxyType: log.proxy?.type || null,
proxyHost: log.proxy?.host || null,
proxyPort: log.proxy?.port || null,
proxyPort: log.proxy?.port ? Number(log.proxy.port) : null,
level: log.level,
levelId: log.levelId,
provider: log.provider,
+4 -3
View File
@@ -16,14 +16,15 @@ import { getDbInstance } from "./db/core";
// ─── Singleton ─────────────────
let memoryCache;
let memoryCache: LRUCache | null = null;
let stats = { hits: 0, misses: 0, tokensSaved: 0 };
function getMemoryCache() {
if (!memoryCache) {
memoryCache = new LRUCache({
maxSize: parseInt(process.env.SEMANTIC_CACHE_MAX_SIZE || "500", 10),
defaultTTL: parseInt(process.env.SEMANTIC_CACHE_TTL_MS || "3600000", 10), // 1h
maxSize: parseInt(process.env.SEMANTIC_CACHE_MAX_SIZE || "100", 10),
maxBytes: parseInt(process.env.SEMANTIC_CACHE_MAX_BYTES || String(4 * 1024 * 1024), 10),
defaultTTL: parseInt(process.env.SEMANTIC_CACHE_TTL_MS || "1800000", 10),
});
}
return memoryCache;
+1 -1
View File
@@ -12,7 +12,7 @@ import fs from "fs";
import { getDbInstance } from "../db/core";
import { shouldPersistToDisk, CALL_LOGS_DIR } from "./migrations";
const CALL_LOGS_MAX = 500;
const CALL_LOGS_MAX = parseInt(process.env.CALL_LOGS_MAX || "200", 10);
const LOG_RETENTION_DAYS = parseInt(process.env.LOG_RETENTION_DAYS || "7", 10);
/** Fields that should always be redacted from logged payloads */
+3 -3
View File
@@ -131,9 +131,9 @@ export async function proxy(request) {
if (settings.requireLogin === false) {
return response;
}
// Skip auth if no password has been set yet (fresh install with no env override)
// This prevents an unresolvable loop where requireLogin=true but no password exists
if (!settings.password && !process.env.INITIAL_PASSWORD) {
// Skip auth ONLY for fresh installs (before onboarding) where no password exists yet.
// Once setupComplete is true, always require auth — prevents bypass if password row is lost (#151)
if (!settings.setupComplete && !settings.password && !process.env.INITIAL_PASSWORD) {
return response;
}
} catch (err) {
+5 -1
View File
@@ -48,7 +48,11 @@ export default function ProxyConfigModal({ isOpen, onClose, level, levelId, leve
const [hasOwnProxy, setHasOwnProxy] = useState(false);
const [formError, setFormError] = useState(null);
const getDefaultPort = (type) => (type === "socks5" ? "1080" : "8080");
const getDefaultPort = (type) => {
if (type === "socks5") return "1080";
if (type === "https") return "443";
return "8080";
};
// Load existing proxy config when modal opens
useEffect(() => {
+8
View File
@@ -164,6 +164,14 @@ export const CLI_TOOLS = {
{ id: "gpt-oss-120b-medium", name: "GPT OSS 120B Medium", alias: "gpt-oss-120b-medium" },
],
},
copilot: {
id: "copilot",
name: "GitHub Copilot",
image: "/providers/copilot.png",
color: "#1F6FEB",
description: "GitHub Copilot Chat — VS Code Extension",
configType: "custom",
},
// HIDDEN: gemini-cli
// "gemini-cli": {
// id: "gemini-cli",
+197
View File
@@ -0,0 +1,197 @@
"use client";
import { useState, useEffect, useCallback, useSyncExternalStore } from "react";
/**
* Code Review Fixes Applied:
* #7 useIsElectron useSyncExternalStore for zero re-renders
* #11 Import AppInfo type instead of inline duplication
* #12 useDataDir add error state (was swallowed silently)
*/
// ── Fix #7: Module-level detection (no state, no re-renders) ──
function getIsElectronSnapshot(): boolean {
return typeof window !== "undefined" && window.electronAPI?.isElectron === true;
}
function getServerSnapshot(): boolean {
return false; // SSR always returns false
}
const noop = () => () => {};
/**
* Check if running in Electron zero re-renders via useSyncExternalStore
*/
export function useIsElectron(): boolean {
return useSyncExternalStore(noop, getIsElectronSnapshot, getServerSnapshot);
}
/**
* App info shape from Electron main process
* Fix #11: Single source of truth (matches electron/types.d.ts)
*/
interface AppInfo {
name: string;
version: string;
platform: string;
isDev: boolean;
port: number;
}
/**
* Get Electron app information
*/
export function useElectronAppInfo() {
const hasApi = getIsElectronSnapshot();
const [appInfo, setAppInfo] = useState<AppInfo | null>(null);
const [loading, setLoading] = useState(hasApi);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
if (typeof window === "undefined" || !window.electronAPI) return;
window.electronAPI
.getAppInfo()
.then((info) => {
setAppInfo(info);
setLoading(false);
})
.catch((err) => {
setError(err);
setLoading(false);
});
}, []);
return { appInfo, loading, error };
}
/**
* Get the data directory path
* Fix #12: Now exposes error state (was swallowed silently)
*/
export function useDataDir() {
const hasApi = getIsElectronSnapshot();
const [dataDir, setDataDir] = useState<string | null>(null);
const [loading, setLoading] = useState(hasApi);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
if (typeof window === "undefined" || !window.electronAPI) return;
window.electronAPI
.getDataDir()
.then((dir) => {
setDataDir(dir);
setLoading(false);
})
.catch((err) => {
setError(err instanceof Error ? err : new Error(String(err)));
setLoading(false);
});
}, []);
return { dataDir, loading, error };
}
/**
* Window controls for Electron
*/
export function useWindowControls() {
const isElectron = useIsElectron();
const minimize = useCallback(() => {
if (isElectron && window.electronAPI) {
window.electronAPI.minimizeWindow();
}
}, [isElectron]);
const maximize = useCallback(() => {
if (isElectron && window.electronAPI) {
window.electronAPI.maximizeWindow();
}
}, [isElectron]);
const close = useCallback(() => {
if (isElectron && window.electronAPI) {
window.electronAPI.closeWindow();
}
}, [isElectron]);
return { isElectron, minimize, maximize, close };
}
/**
* Open external URL in default browser
*/
export function useOpenExternal() {
const isElectron = useIsElectron();
const openExternal = useCallback(
async (url: string) => {
if (isElectron && window.electronAPI) {
await window.electronAPI.openExternal(url);
} else {
window.open(url, "_blank", "noopener,noreferrer");
}
},
[isElectron]
);
return { openExternal };
}
/**
* Server controls for Electron
*/
export function useServerControls() {
const isElectron = useIsElectron();
const [restarting, setRestarting] = useState(false);
const restart = useCallback(async () => {
if (!isElectron || !window.electronAPI) {
return { success: false };
}
setRestarting(true);
try {
const result = await window.electronAPI.restartServer();
return result;
} finally {
setRestarting(false);
}
}, [isElectron]);
return { isElectron, restart, restarting };
}
/**
* Listen for server status updates
* Fix #6: Uses disposer returned by preload for precise cleanup
*/
export function useServerStatus(onStatus: (status: { status: string; port: number }) => void) {
const isElectron = useIsElectron();
useEffect(() => {
if (!isElectron || !window.electronAPI) return;
const dispose = window.electronAPI.onServerStatus(onStatus);
return dispose;
}, [isElectron, onStatus]);
}
/**
* Listen for port changes
* Fix #6: Uses disposer returned by preload for precise cleanup
*/
export function usePortChanged(onPortChanged: (port: number) => void) {
const isElectron = useIsElectron();
useEffect(() => {
if (!isElectron || !window.electronAPI) return;
const dispose = window.electronAPI.onPortChanged(onPortChanged);
return dispose;
}, [isElectron, onPortChanged]);
}
+4 -2
View File
@@ -134,8 +134,10 @@ export async function isAuthRequired(): Promise<boolean> {
try {
const settings = await getSettings();
if (settings.requireLogin === false) return false;
// If no password set and no env override, don't require auth (fresh install)
if (!settings.password && !process.env.INITIAL_PASSWORD) return false;
// Only skip auth for fresh installs (not yet onboarded) with no password.
// Once setupComplete is true, always require auth — prevents bypass if password row is lost (#151)
if (!settings.setupComplete && !settings.password && !process.env.INITIAL_PASSWORD)
return false;
return true;
} catch {
// On error, require auth (secure by default)
+1 -1
View File
@@ -173,7 +173,7 @@ export class StreamTracker {
// ─── Active Stream Registry ─────────────────
const activeStreams = new Map<string, StreamTracker>();
const MAX_COMPLETED_HISTORY = 100;
const MAX_COMPLETED_HISTORY = parseInt(process.env.STREAM_HISTORY_MAX || "50", 10);
const completedStreams: ReturnType<StreamTracker["getSummary"]>[] = [];
/**
+155
View File
@@ -0,0 +1,155 @@
/**
* Tests for CLI Memory Sanitization (bin/omniroute.mjs)
*
* Tests cover:
* - Memory limit parsing and validation
* - Command injection prevention
* - Boundary values
* - .env file loading
*/
import { describe, it } from "node:test";
import assert from "node:assert/strict";
// ─── Memory Limit Sanitization Tests ─────────────────────────
describe("CLI Memory Limit Sanitization", () => {
/**
* Replicate the memory sanitization logic from bin/omniroute.mjs
*/
function sanitizeMemoryLimit(envValue) {
const rawMemory = parseInt(envValue || "512", 10);
return Number.isFinite(rawMemory) && rawMemory >= 64 && rawMemory <= 16384 ? rawMemory : 512;
}
it("should default to 512 when no env var set", () => {
assert.equal(sanitizeMemoryLimit(undefined), 512);
assert.equal(sanitizeMemoryLimit(null), 512);
assert.equal(sanitizeMemoryLimit(""), 512);
});
it("should accept valid numeric values", () => {
assert.equal(sanitizeMemoryLimit("128"), 128);
assert.equal(sanitizeMemoryLimit("256"), 256);
assert.equal(sanitizeMemoryLimit("512"), 512);
assert.equal(sanitizeMemoryLimit("1024"), 1024);
assert.equal(sanitizeMemoryLimit("2048"), 2048);
assert.equal(sanitizeMemoryLimit("4096"), 4096);
assert.equal(sanitizeMemoryLimit("8192"), 8192);
});
it("should accept boundary values", () => {
assert.equal(sanitizeMemoryLimit("64"), 64); // minimum
assert.equal(sanitizeMemoryLimit("16384"), 16384); // maximum
});
it("should reject values below minimum (64MB)", () => {
assert.equal(sanitizeMemoryLimit("0"), 512);
assert.equal(sanitizeMemoryLimit("1"), 512);
assert.equal(sanitizeMemoryLimit("32"), 512);
assert.equal(sanitizeMemoryLimit("63"), 512);
assert.equal(sanitizeMemoryLimit("-1"), 512);
assert.equal(sanitizeMemoryLimit("-9999"), 512);
});
it("should reject values above maximum (16384MB)", () => {
assert.equal(sanitizeMemoryLimit("16385"), 512);
assert.equal(sanitizeMemoryLimit("99999"), 512);
assert.equal(sanitizeMemoryLimit("1000000"), 512);
});
// ── Command Injection Prevention ──────────────────────────
it("should prevent command injection via shell metacharacters", () => {
// parseInt('256; rm -rf /') returns 256 which is valid — but the sanitized
// integer value is safe because it's a pure number, not a shell string
const r1 = sanitizeMemoryLimit("256; rm -rf /");
assert.equal(typeof r1, "number"); // always returns a safe number
assert.ok(r1 >= 64 && r1 <= 16384); // within safe range
// These produce NaN via parseInt → fallback to 512
assert.equal(sanitizeMemoryLimit("`id`"), 512);
assert.equal(sanitizeMemoryLimit("$(whoami)"), 512);
});
it("should prevent injection via Node.js spawn args", () => {
// These would be dangerous if passed unsanitized to spawn()
assert.equal(sanitizeMemoryLimit("--require=/tmp/malware.js"), 512);
assert.equal(sanitizeMemoryLimit("--experimental-modules"), 512);
assert.equal(sanitizeMemoryLimit("-e 'process.exit()'"), 512);
});
it("should handle non-numeric strings gracefully", () => {
assert.equal(sanitizeMemoryLimit("abc"), 512);
assert.equal(sanitizeMemoryLimit("twelve"), 512);
assert.equal(sanitizeMemoryLimit("NaN"), 512);
assert.equal(sanitizeMemoryLimit("Infinity"), 512);
assert.equal(sanitizeMemoryLimit("undefined"), 512);
});
it("should handle special numeric formats", () => {
// parseInt('0x100') = 0 (stops at 'x'), outside 6416384? No, 0 < 64 → fallback
assert.equal(sanitizeMemoryLimit("0x100"), 512);
// parseInt('1e3') = 1, which is < 64 → fallback
assert.equal(sanitizeMemoryLimit("1e3"), 512);
assert.equal(sanitizeMemoryLimit("512.7"), 512); // parseInt truncates → 512 ✅
assert.equal(sanitizeMemoryLimit(" 256 "), 256); // whitespace → 256 ✅
});
});
// ─── .env Loading Tests ──────────────────────────────────────
describe("CLI .env File Loading", () => {
/**
* Simulate the .env parsing logic from bin/omniroute.mjs
*/
function parseEnvLine(line) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith("#")) return null;
const eqIdx = trimmed.indexOf("=");
if (eqIdx === -1) return null;
const key = trimmed.substring(0, eqIdx).trim();
let value = trimmed.substring(eqIdx + 1).trim();
// Remove surrounding quotes
value = value.replace(/^["']|["']$/g, "");
return { key, value };
}
it("should parse KEY=VALUE lines", () => {
const result = parseEnvLine("PORT=3000");
assert.deepEqual(result, { key: "PORT", value: "3000" });
});
it("should strip surrounding quotes", () => {
const dq = parseEnvLine('JWT_SECRET="my-secret"');
assert.deepEqual(dq, { key: "JWT_SECRET", value: "my-secret" });
const sq = parseEnvLine("JWT_SECRET='my-secret'");
assert.deepEqual(sq, { key: "JWT_SECRET", value: "my-secret" });
});
it("should skip comments", () => {
assert.equal(parseEnvLine("# This is a comment"), null);
assert.equal(parseEnvLine(" # Indented comment"), null);
});
it("should skip empty lines", () => {
assert.equal(parseEnvLine(""), null);
assert.equal(parseEnvLine(" "), null);
});
it("should skip lines without =", () => {
assert.equal(parseEnvLine("MALFORMED_LINE"), null);
});
it("should handle values with equals signs", () => {
const result = parseEnvLine("DATABASE_URL=postgres://user:pass@host:5432/db?sslmode=require");
assert.equal(result.key, "DATABASE_URL");
assert.equal(result.value, "postgres://user:pass@host:5432/db?sslmode=require");
});
it("should handle empty values", () => {
const result = parseEnvLine("EMPTY_VAR=");
assert.deepEqual(result, { key: "EMPTY_VAR", value: "" });
});
});
+286
View File
@@ -0,0 +1,286 @@
/**
* Tests for Electron main process (electron/main.js)
*
* Covers:
* - URL validation & RCE prevention
* - IPC channel security
* - Server readiness polling logic
* - Restart timeout + SIGKILL
* - Port change lifecycle
* - CSP header structure
* - Platform-conditional window options
*/
import { describe, it } from "node:test";
import assert from "node:assert/strict";
// ─── URL Validation Tests ────────────────────────────────────
describe("Electron URL Validation", () => {
function validateExternalUrl(url) {
try {
const parsedUrl = new URL(url);
if (["http:", "https:"].includes(parsedUrl.protocol)) {
return { allowed: true, url };
}
return { allowed: false, reason: `Blocked protocol: ${parsedUrl.protocol}` };
} catch {
return { allowed: false, reason: "Invalid URL" };
}
}
it("should allow http URLs", () => {
assert.equal(validateExternalUrl("http://example.com").allowed, true);
});
it("should allow https URLs", () => {
assert.equal(validateExternalUrl("https://github.com/diegosouzapw/OmniRoute").allowed, true);
});
it("should block file:// protocol (RCE risk)", () => {
const result = validateExternalUrl("file:///etc/passwd");
assert.equal(result.allowed, false);
assert.match(result.reason, /Blocked protocol/);
});
it("should block javascript: protocol (XSS risk)", () => {
assert.equal(validateExternalUrl("javascript:alert(1)").allowed, false);
});
it("should block custom protocol handlers", () => {
assert.equal(validateExternalUrl("vscode://extensions/install?name=malware").allowed, false);
});
it("should block data: URIs", () => {
assert.equal(validateExternalUrl("data:text/html,<script>alert(1)</script>").allowed, false);
});
it("should reject empty string", () => {
assert.equal(validateExternalUrl("").allowed, false);
});
it("should reject malformed URL", () => {
const result = validateExternalUrl("not a url");
assert.equal(result.allowed, false);
assert.match(result.reason, /Invalid URL/);
});
it("should allow localhost URLs", () => {
assert.equal(validateExternalUrl("http://localhost:20128/dashboard").allowed, true);
});
it("should allow URLs with paths and query params", () => {
assert.equal(validateExternalUrl("https://example.com/path?q=test&page=1#hash").allowed, true);
});
});
// ─── Window Open Handler Tests ───────────────────────────────
describe("Electron Window Open Handler", () => {
function windowOpenHandler({ url }) {
try {
const parsedUrl = new URL(url);
if (["http:", "https:"].includes(parsedUrl.protocol)) {
return { action: "allow-external" };
}
return { action: "deny" };
} catch {
return { action: "deny" };
}
}
it("should deny all windows (external links go to browser)", () => {
const result = windowOpenHandler({ url: "https://example.com" });
assert.ok(result.action);
});
it("should deny file:// URLs", () => {
assert.equal(windowOpenHandler({ url: "file:///etc/passwd" }).action, "deny");
});
});
// ─── IPC Channel Validation Tests ────────────────────────────
describe("IPC Channel Validation", () => {
const VALID_CHANNELS = {
invoke: ["get-app-info", "open-external", "get-data-dir", "restart-server"],
send: ["window-minimize", "window-maximize", "window-close"],
receive: ["server-status", "port-changed"],
};
function isValidChannel(channel, type) {
return VALID_CHANNELS[type]?.includes(channel) ?? false;
}
it("should allow valid invoke channels", () => {
assert.equal(isValidChannel("get-app-info", "invoke"), true);
assert.equal(isValidChannel("open-external", "invoke"), true);
assert.equal(isValidChannel("get-data-dir", "invoke"), true);
assert.equal(isValidChannel("restart-server", "invoke"), true);
});
it("should allow valid send channels", () => {
assert.equal(isValidChannel("window-minimize", "send"), true);
assert.equal(isValidChannel("window-maximize", "send"), true);
assert.equal(isValidChannel("window-close", "send"), true);
});
it("should allow valid receive channels", () => {
assert.equal(isValidChannel("server-status", "receive"), true);
assert.equal(isValidChannel("port-changed", "receive"), true);
});
it("should block unknown channels", () => {
assert.equal(isValidChannel("execute-arbitrary-code", "invoke"), false);
assert.equal(isValidChannel("delete-all-data", "send"), false);
assert.equal(isValidChannel("malicious-event", "receive"), false);
assert.equal(isValidChannel("", "invoke"), false);
});
it("should handle undefined type gracefully", () => {
assert.equal(isValidChannel("get-app-info", "nonexistent"), false);
assert.equal(isValidChannel("test", undefined), false);
});
it("should block prototype pollution attempts", () => {
assert.equal(isValidChannel("constructor", "invoke"), false);
assert.equal(isValidChannel("__proto__", "invoke"), false);
assert.equal(isValidChannel("toString", "invoke"), false);
});
});
// ─── Server Port Validation Tests ────────────────────────────
describe("Server Port Management", () => {
it("should have valid default port", () => {
const DEFAULT_PORT = 20128;
assert.ok(DEFAULT_PORT > 0 && DEFAULT_PORT <= 65535);
});
it("should validate port numbers", () => {
function isValidPort(port) {
return Number.isFinite(port) && port > 0 && port <= 65535;
}
assert.equal(isValidPort(20128), true);
assert.equal(isValidPort(3000), true);
assert.equal(isValidPort(8080), true);
assert.equal(isValidPort(0), false);
assert.equal(isValidPort(-1), false);
assert.equal(isValidPort(70000), false);
assert.equal(isValidPort(NaN), false);
});
it("should generate correct server URL", () => {
const port = 20128;
assert.equal(`http://localhost:${port}`, "http://localhost:20128");
});
});
// ─── Server Readiness Tests (#1) ─────────────────────────────
describe("Server Readiness Logic", () => {
it("waitForServer should timeout and return false", async () => {
// Simulate the polling logic with an always-failing fetch
async function waitForServer(url, timeoutMs = 100) {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
try {
const res = await fetch(url);
if (res.ok || res.status < 500) return true;
} catch {
/* not ready */
}
await new Promise((r) => setTimeout(r, 30));
}
return false;
}
// Should timeout immediately since nothing is running on that port
const result = await waitForServer("http://localhost:59999", 100);
assert.equal(result, false);
});
});
// ─── Restart Timeout Tests (#2) ──────────────────────────────
describe("Restart Timeout Logic", () => {
it("should resolve even if process doesn't exit", async () => {
// Simulate the timeout race
const start = Date.now();
await Promise.race([
new Promise((r) => setTimeout(r, 100000)), // simulates hung process
new Promise((r) => setTimeout(r, 50)), // timeout
]);
const elapsed = Date.now() - start;
assert.ok(elapsed < 200, "Should resolve in ~50ms via timeout");
});
it("should resolve immediately if process exits first", async () => {
const start = Date.now();
await Promise.race([
new Promise((r) => setTimeout(r, 10)), // simulates fast exit
new Promise((r) => setTimeout(r, 5000)), // timeout
]);
const elapsed = Date.now() - start;
assert.ok(elapsed < 200, "Should resolve in ~10ms via exit");
});
});
// ─── CSP Tests (#15) ─────────────────────────────────────────
describe("Content Security Policy", () => {
it("should have all required CSP directives", () => {
const directives = [
"default-src",
"connect-src",
"script-src",
"style-src",
"font-src",
"img-src",
"media-src",
];
const csp = [
"default-src 'self'",
"connect-src 'self' http://localhost:* ws://localhost:*",
"script-src 'self' 'unsafe-inline' 'unsafe-eval'",
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
"font-src 'self' https://fonts.gstatic.com data:",
"img-src 'self' data: blob: https:",
"media-src 'self'",
].join("; ");
for (const directive of directives) {
assert.ok(csp.includes(directive), `CSP should contain ${directive}`);
}
});
it("should not allow unsafe script sources from external domains", () => {
const scriptSrc = "script-src 'self' 'unsafe-inline' 'unsafe-eval'";
assert.ok(!scriptSrc.includes("http://"), "Should not allow external http scripts");
assert.ok(!scriptSrc.includes("*"), "Should not wildcard script sources");
});
});
// ─── Platform-Conditional Tests (#9) ─────────────────────────
describe("Platform-Conditional Window Options", () => {
it("should return hiddenInset for macOS", () => {
const platform = "darwin";
const options =
platform === "darwin"
? { titleBarStyle: "hiddenInset", trafficLightPosition: { x: 16, y: 16 } }
: { titleBarStyle: "default" };
assert.equal(options.titleBarStyle, "hiddenInset");
assert.deepEqual(options.trafficLightPosition, { x: 16, y: 16 });
});
it("should return default for Windows/Linux", () => {
for (const platform of ["win32", "linux"]) {
const options =
platform === "darwin" ? { titleBarStyle: "hiddenInset" } : { titleBarStyle: "default" };
assert.equal(options.titleBarStyle, "default");
}
});
});
+272
View File
@@ -0,0 +1,272 @@
/**
* Tests for Electron preload script (electron/preload.js)
*
* Covers:
* - Channel whitelist (Fix #16: validates generic wrappers)
* - API surface correctness
* - Security boundary enforcement
* - Disposer pattern for listeners (Fix #6)
*/
import { describe, it } from "node:test";
import assert from "node:assert/strict";
// ─── Channel Whitelist Tests ─────────────────────────────────
describe("Preload Channel Whitelist", () => {
const VALID_CHANNELS = {
invoke: ["get-app-info", "open-external", "get-data-dir", "restart-server"],
send: ["window-minimize", "window-maximize", "window-close"],
receive: ["server-status", "port-changed"],
};
function isValidChannel(channel, type) {
return VALID_CHANNELS[type]?.includes(channel) ?? false;
}
it("should have exactly 4 invoke channels", () => {
assert.equal(VALID_CHANNELS.invoke.length, 4);
});
it("should have exactly 3 send channels", () => {
assert.equal(VALID_CHANNELS.send.length, 3);
});
it("should have exactly 2 receive channels", () => {
assert.equal(VALID_CHANNELS.receive.length, 2);
});
it("should not allow crossing channel types", () => {
for (const ch of VALID_CHANNELS.invoke) {
assert.equal(isValidChannel(ch, "send"), false, `${ch} should not be valid as send`);
}
for (const ch of VALID_CHANNELS.send) {
assert.equal(isValidChannel(ch, "invoke"), false, `${ch} should not be valid as invoke`);
}
});
it("should reject null/undefined channels", () => {
assert.equal(isValidChannel(null, "invoke"), false);
assert.equal(isValidChannel(undefined, "invoke"), false);
});
});
// ─── API Surface Tests ───────────────────────────────────────
describe("Preload API Surface", () => {
// Updated: removed removeServerStatusListener/removePortChangedListener (Fix #6)
const EXPECTED_API_METHODS = [
"getAppInfo",
"openExternal",
"getDataDir",
"restartServer",
"minimizeWindow",
"maximizeWindow",
"closeWindow",
"onServerStatus", // now returns disposer
"onPortChanged", // now returns disposer
];
const EXPECTED_API_PROPERTIES = ["isElectron", "platform"];
it("should define all expected method names", () => {
for (const method of EXPECTED_API_METHODS) {
assert.ok(typeof method === "string" && method.length > 0);
}
});
it("should define expected property names", () => {
for (const prop of EXPECTED_API_PROPERTIES) {
assert.ok(typeof prop === "string" && prop.length > 0);
}
});
it("should have correct total API surface (11 items — reduced from 13)", () => {
const totalApi = EXPECTED_API_METHODS.length + EXPECTED_API_PROPERTIES.length;
assert.equal(totalApi, 11);
});
it("should not expose any Node.js internals", () => {
const DANGEROUS_APIS = [
"require",
"process",
"child_process",
"fs",
"exec",
"spawn",
"eval",
"__dirname",
"__filename",
];
const all = [...EXPECTED_API_METHODS, ...EXPECTED_API_PROPERTIES];
for (const api of DANGEROUS_APIS) {
assert.ok(!all.includes(api), `'${api}' should NOT be exposed`);
}
});
});
// ─── Disposer Pattern Tests (#6) ─────────────────────────────
describe("Preload Listener Disposer Pattern", () => {
it("safeOn should return a function (disposer)", () => {
// Simulate the safeOn pattern from the new preload.js
const VALID_RECEIVE = ["server-status", "port-changed"];
const listeners = [];
function safeOn(channel, callback) {
if (!VALID_RECEIVE.includes(channel)) return () => {};
const handler = { channel, callback };
listeners.push(handler);
return () => {
const idx = listeners.indexOf(handler);
if (idx !== -1) listeners.splice(idx, 1);
};
}
// Add a listener
const dispose = safeOn("server-status", () => {});
assert.equal(typeof dispose, "function");
assert.equal(listeners.length, 1);
// Dispose it
dispose();
assert.equal(listeners.length, 0);
});
it("safeOn should reject invalid channels and return noop disposer", () => {
const VALID_RECEIVE = ["server-status", "port-changed"];
function safeOn(channel, callback) {
if (!VALID_RECEIVE.includes(channel)) return () => {};
return () => {};
}
const dispose = safeOn("malicious-event", () => {});
assert.equal(typeof dispose, "function");
// Should not throw
dispose();
});
it("multiple listeners should be independently disposable", () => {
const listeners = [];
function safeOn(channel, callback) {
const handler = { channel, callback };
listeners.push(handler);
return () => {
const idx = listeners.indexOf(handler);
if (idx !== -1) listeners.splice(idx, 1);
};
}
const dispose1 = safeOn("server-status", () => "a");
const dispose2 = safeOn("server-status", () => "b");
const dispose3 = safeOn("port-changed", () => "c");
assert.equal(listeners.length, 3);
// Remove only the second one
dispose2();
assert.equal(listeners.length, 2);
assert.equal(listeners[0].callback(), "a");
assert.equal(listeners[1].callback(), "c");
// Remove first
dispose1();
assert.equal(listeners.length, 1);
// Double-dispose should be safe
dispose1();
assert.equal(listeners.length, 1);
});
});
// ─── Generic Wrapper Tests (#16) ─────────────────────────────
describe("Generic IPC Wrappers", () => {
const VALID_CHANNELS = {
invoke: ["get-app-info", "open-external", "get-data-dir", "restart-server"],
send: ["window-minimize", "window-maximize", "window-close"],
};
function safeInvoke(channel) {
if (!VALID_CHANNELS.invoke.includes(channel)) {
return { blocked: true };
}
return { blocked: false, channel };
}
function safeSend(channel) {
if (!VALID_CHANNELS.send.includes(channel)) {
return { blocked: true };
}
return { blocked: false, channel };
}
it("safeInvoke should allow valid channels", () => {
for (const ch of VALID_CHANNELS.invoke) {
assert.equal(safeInvoke(ch).blocked, false);
}
});
it("safeInvoke should block invalid channels", () => {
assert.equal(safeInvoke("shell-exec").blocked, true);
assert.equal(safeInvoke("").blocked, true);
assert.equal(safeInvoke("__proto__").blocked, true);
});
it("safeSend should allow valid channels", () => {
for (const ch of VALID_CHANNELS.send) {
assert.equal(safeSend(ch).blocked, false);
}
});
it("safeSend should block invalid channels", () => {
assert.equal(safeSend("window-nuke").blocked, true);
});
});
// ─── Open External URL Validation Tests ──────────────────────
describe("Preload openExternal Security", () => {
function validateBeforeOpen(url) {
try {
const parsed = new URL(url);
return ["http:", "https:"].includes(parsed.protocol);
} catch {
return false;
}
}
const SAFE_URLS = [
"https://github.com",
"http://localhost:20128",
"https://omniroute.dev/docs",
"https://example.com/path?q=1&p=2#section",
];
const DANGEROUS_URLS = [
"file:///etc/passwd",
"file:///C:/Windows/System32",
"javascript:alert(document.cookie)",
"vscode://extensions",
"data:text/html,<h1>pwned</h1>",
"blob:http://evil.com/abc123",
"ftp://unsafe-server.com",
"ssh://attacker.com",
"smb://network-share",
"",
" ",
"not-a-url",
];
for (const url of SAFE_URLS) {
it(`should allow safe URL: ${url.substring(0, 40)}`, () => {
assert.equal(validateBeforeOpen(url), true);
});
}
for (const url of DANGEROUS_URLS) {
it(`should block dangerous URL: ${url.substring(0, 40) || "(empty)"}`, () => {
assert.equal(validateBeforeOpen(url), false);
});
}
});