Compare commits

..

72 Commits

Author SHA1 Message Date
Diego Rodrigues de Sa e Souza f62dcc12a0 Merge pull request #608 from diegosouzapw/release/v3.0.1
Build Electron Desktop App / Validate version (push) Failing after 26s
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
Build Electron Desktop App / Publish to npm (push) Has been skipped
chore(release): v3.0.1 — hotfix for proxy_ prefix, LongCat validation, and MCP tool schemas
2026-03-25 09:07:27 -03:00
diegosouzapw 5907296d36 fix: proxy UI bugs, connection tag grouping, and function_call prefix stripping
## Proxy UI Bug Fixes
- fix: proxy badge on connection cards now uses resolveProxyForConnection()
  per-connection (covers registry + config-file assignments)
- fix: Test Connection button now works in 'saved' proxy mode by resolving
  proxy config from savedProxies list
- fix: ProxyConfigModal now calls onClose() after save/clear (fixes UI freeze)
- fix: ProxyRegistryManager loads usage eagerly on mount with deduplication
  by scope+scopeId to prevent double-counting; adds per-row Test button

## Connection Tag Grouping (new feature)
- feat: add Tag/Group field to EditConnectionModal (stored in
  providerSpecificData.tag, no DB schema change)
- feat: connections list groups by tag with visual dividers when any account
  has a tag; untagged accounts appear first without header

## Post-merge fix from PR #607 review
- fix: function_call blocks in translateNonStreamingResponse now also strip
  Claude OAuth proxy_ prefix via toolNameMap (kilo-code-bot #607 warning)
  Affects OpenAI Responses API format path — tool_use was fixed in PR #607
  but function_call was missed
2026-03-25 08:54:46 -03:00
diegosouzapw aa2a7d12be chore(release): v3.0.1 — hotfix for proxy_ prefix, LongCat validation, and MCP tool schemas 2026-03-25 08:20:04 -03:00
Diego Rodrigues de Sa e Souza 33fee5dcc5 fix: strip proxy_ prefix in non-streaming Claude responses & fix LongCat validation (#605, #592) (#607)
- fix(translator): pass toolNameMap to translateNonStreamingResponse so Claude
  OAuth proxy_ prefix is correctly stripped from tool_use block names in
  non-streaming responses (was only stripped in streaming path)
- fix(validation): add LongCat specialty validator that probes /chat/completions
  directly, bypassing the /v1/models endpoint that LongCat does not expose (#592)

Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
2026-03-25 08:16:46 -03:00
Randi e9ae50be0c fix: improve Provider Limits light mode contrast and Claude plan tier display (#591)
- Replace hardcoded rgba(255,255,255,...) borders/backgrounds with theme-aware
  CSS variables (--color-border, --color-bg-subtle) for proper light mode contrast
- Add dark: variants for hover states and progress bar backgrounds
- Fix Claude plan tier: try to extract actual plan from OAuth response instead
  of hardcoding "Claude Code"
- Recognize provider names (Claude Code, Kimi Coding, Kiro) as non-plan-tier
  values in normalizePlanTier() to avoid showing them as tier badges

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 08:16:28 -03:00
Flo 5886c0fd5e docs(i18n): fix russian translation for playground and testbed (#589)
Co-authored-by: Vladimir Alabov <vladimir.alabov@bsc-ideas.com>
2026-03-25 08:15:59 -03:00
diegosouzapw 9e640cac6b chore: merge remaining 3.0.0-rc.17 commits into main (ProviderIcon, docs, provider counts)
Build Electron Desktop App / Validate version (push) Failing after 38s
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
Build Electron Desktop App / Publish to npm (push) Has been skipped
2026-03-24 18:46:43 -03:00
diegosouzapw 061521f87f docs: comprehensive v3.0.0 CHANGELOG + fix all version references
- Consolidated all 17 RC entries (rc.1 through rc.17) into single v3.0.0 entry
- 31 new providers, 9 major features, 40+ bug fixes, 19 community PRs
- Fixed llm.txt: version 2.0.13 → 3.0.0, provider count 36+ → 67+
- package.json: 3.0.0, openapi.yaml: 3.0.0
2026-03-24 18:42:39 -03:00
diegosouzapw b15eb278e1 chore: bump version to 3.0.0, update openapi.yaml and CHANGELOG 2026-03-24 18:38:35 -03:00
diegosouzapw 142ac8eb96 Merge PR #587: fix(sse): revert resolveDataDir import for Workers compat 2026-03-24 18:32:21 -03:00
diegosouzapw 88705bb6e9 docs: update provider count to 67+ across all documentation
- README.md: 44+ → 67+ (3 occurrences)
- llm.txt: 40+ → 67+ (2 occurrences)
- 21 i18n READMEs: 44+ → 67+
- 3 i18n READMEs (it/nl/phi): 36+ → 67+
- Actual count: FREE=4, OAUTH=8, APIKEY=55, TOTAL=67
2026-03-24 18:05:19 -03:00
k0valik 60d4fcfe7e update the comments
**1. `open-sse/transformer/responsesTransformer.ts`**
- Removed `import { resolveDataDir } from "../../src/lib/dataPaths"`
- Restored: `typeof process !== "undefined" ? process.cwd() : "."`
- Added history comment: `// previous: const baseDir = logsDir || resolveDataDir(); — reverted in #555 for Workers compat`

**2. `open-sse/config/credentialLoader.ts`**
- Updated JSDoc with `resolveDataDir()` description
- Added history: `previous: Priority: DATA_DIR env → ./data (project root)`
2026-03-24 21:40:08 +01:00
diegosouzapw 038d19ec98 docs: update llm.txt to v3.0.0, add embeddings+speech to docs page
- llm.txt: complete rewrite for v3.0.0-rc.17 (40+ providers, 9 strategies,
  MCP/A2A/ACP, ProviderIcon, auto-combo, 926 tests, CodeQL fixes)
- docs/page.tsx: add /v1/embeddings and /v1/audio/speech to API reference
- en.json: add i18n keys for new endpoint descriptions
2026-03-24 17:31:47 -03:00
k0valik e1b98768c7 fix(sse): revert resolveDataDir import in responsesTransformer for Workers compat 2026-03-24 21:29:08 +01:00
diegosouzapw b82af2b849 fix(ui): add ProviderIcon to agents page CLI tools + maxDuration for transcription
- Agents page: use ProviderIcon with 21-entry AGENT_ICON_MAP for CLI tool
  icons (claude→anthropic, codex→openai, gemini-cli→google, etc.)
- Transcription route: add maxDuration=300 for large audio/video uploads
- Combos: verified all 4 templates + 9 strategies present in UI
2026-03-24 17:21:25 -03:00
diegosouzapw 703591d76a fix(ui): use ProviderIcon component on dashboard home page
Replace Image-based provider icons in ProviderOverviewCard with the same
ProviderIcon component used on the providers page (@lobehub/icons SVG
with PNG → generic fallback chain).
2026-03-24 17:11:34 -03:00
diegosouzapw 7142688a77 fix(types): Zod 4 z.record 2-arg form + header type cast in openapi/try 2026-03-24 17:01:56 -03:00
diegosouzapw a12622b3d8 docs: update CHANGELOG, README, and sync i18n for v3.0.0-rc.17
- CHANGELOG.md: add rc.17 entry (CodeQL, route validation, omniModel tag, Docker)
- README.md: add 3 new rows to What's New table (CodeQL, validation, #585)
- docs/i18n: sync What's New v3.0.0 section to all 30 translated READMEs
  (replacing outdated v2.7.0/v2.0.9 sections)
2026-03-24 16:44:38 -03:00
diegosouzapw 9248ab4dfd fix(ci): route validation, CodeQL alerts, Docker workflow
- Add Zod schemas + validateBody() to 5 routes missing validation:
  model-combo-mappings (POST, PUT), webhooks (POST, PUT), openapi/try (POST)
- Fix 6 polynomial-redos CodeQL alerts in provider.ts and chatCore.ts
  by replacing (?:^|/) alternation patterns with segment-based matching
- Fix insecure-randomness in acp/manager.ts (crypto.randomUUID)
- Fix shell-command-injection in prepublish.mjs (JSON.stringify)
- Upgrade docker/setup-buildx-action from v3 to v4 (Node.js 20 deprecation)

CI check:route-validation:t06 PASS (176/176 routes validated)
Tests: 926/926 pass
2026-03-24 16:08:02 -03:00
diegosouzapw 5a8c6440f0 fix(combo): strip omniModel tags from outbound streaming responses (#585)
The <omniModel> tag was leaking into user-visible content when
context_cache_protection was enabled on a combo. The tag is an internal
marker for model pinning across conversation turns.

Fix: Add a second TransformStream pass (sanitize) that strips the tag
from SSE chunk content before delivery to the client. The tag is still
injected for round-trip context pinning but cleaned from visible output.

Also adds X-OmniRoute-Model response header as a cleaner metadata channel.

Closes #585
2026-03-24 15:49:26 -03:00
diegosouzapw 74b694a4dd chore: bump version to 3.0.0-rc.17 2026-03-24 15:24:46 -03:00
diegosouzapw 896b52d5fb Merge branch '3.0.0-rc.16' into main
RC16 Sprint:
- feat(media): 4GB transcription file limit with validation
- feat: configurable context length in model metadata (PR #578)
- feat: per-model upstream headers, compat PATCH (PR #575)
- feat: model name prefix stripping option (PR #582)
- fix(npm): link electron-release to npm-publish (PR #581)
- fix(routing): unprefixed claude models now resolve to anthropic (#570)
- 12 issues resolved, 4 PRs merged
2026-03-24 15:23:08 -03:00
diegosouzapw 1429fea27a fix(routing): unprefixed claude models now resolve to anthropic provider (#570)
Build Electron Desktop App / Validate version (push) Failing after 30s
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
Build Electron Desktop App / Publish to npm (push) Has been skipped
Changed the heuristic fallback for claude-* models from 'antigravity' to 'anthropic'
as the canonical provider. Users without Antigravity credentials were getting
'No credentials for provider: antigravity' errors when sending unprefixed
Claude model names like 'claude-sonnet-4-5'.

Closes #570
2026-03-24 14:11:13 -03:00
diegosouzapw 3218563f32 chore: merge PRs #581, #582 + local improvements for rc16
Merged PRs:
- #582 — model prefix stripping option (closes #568)
- #581 — npm publish workflow fix (refs #579)

Local changes:
- Restored stashed i18n, CLI tools, and maintenance banner updates
- 926 tests passing
2026-03-24 13:32:05 -03:00
diegosouzapw d412edbbe1 Merge PR #581: fix(npm) — link electron-release to npm-publish via workflow_call (by @jay77721, refs #579) 2026-03-24 13:28:25 -03:00
diegosouzapw 968159a85d Merge PR #582: feat(proxy) — add model name prefix stripping option (by @jay77721, closes #568) 2026-03-24 13:27:59 -03:00
jay77721 18a3741fc2 feat(proxy): add model name prefix stripping option (#568)
Add stripModelPrefix boolean setting that, when enabled, strips
provider prefixes (e.g. openai/, anthropic/) from incoming model
names and re-resolves the bare model name using existing heuristics.

This allows tools to send prefixed model names while OmniRoute
handles provider routing at the proxy layer.

- Add stripModelPrefix to settings validation schema (Zod)
- Check setting in getModelInfo() after custom node matching fails
- Falls through to normal resolution on error or when disabled
- Backward compatible: opt-in, default behavior unchanged
2026-03-24 21:52:43 +08:00
jay77721 f1be3e6bb0 fix(npm): link electron-release to npm-publish via workflow_call
- Add workflow_call trigger to npm-publish.yml for direct cross-workflow invocation
- Add publish-npm job to electron-release.yml that calls npm-publish after release
- Add dist-tag support: prerelease versions auto-get 'next' tag, stable gets 'latest'
- Add v-prefix stripping for robust version handling
- Fixes issue where GitHub releases created by bots don't reliably trigger npm-publish
- Refs #579
2026-03-24 21:52:34 +08:00
diegosouzapw b717a02394 chore: remove PR documentation and unnecessary markdown files 2026-03-24 10:33:25 -03:00
diegosouzapw d68143e63d Merge PR #575: feat(dashboard,sse,api) — per-model upstream headers, compat PATCH, chat alignment (by @zhangqiang8vip) 2026-03-24 09:46:59 -03:00
diegosouzapw 0d306b8b1c Merge PR #578: feat — add configurable context length to model metadata (by @hijak) 2026-03-24 09:46:32 -03:00
diegosouzapw a655863855 feat(media): increase transcription file limit to 4GB with validation
- Added MAX_TRANSCRIPTION_FILE_SIZE constant (4GB)
- Added formatFileSize() helper for human-readable display (KB/MB/GB)
- Frontend validation rejects files > 4GB with error message
- Changed label from 'Audio File' to 'Audio / Video File'
- Shows 'Supports audio and video files up to 4 GB' hint
2026-03-24 09:42:36 -03:00
Jack Cowey 58264c80dd feat: add configurable context length to model metadata
- Add contextLength field to RegistryModel interface for per-model overrides
- Add defaultContextLength to RegistryEntry for provider-level defaults
- Set context lengths for major providers:
  - Claude: 200k
  - Codex: 400k (fixes combo context display)
  - Gemini: 1M
  - OpenAI: 128k
  - GitHub Copilot: 128k
  - Kiro/Cursor: 200k
  - OpenCode: 200k
- Include context_length in /v1/models API response
- Add context_length field to combo schema for custom combo context
- Update contextManager to use registry defaults and support env overrides
  - CONTEXT_LENGTH_<PROVIDER> for per-provider override
  - CONTEXT_LENGTH_DEFAULT for global override

This allows clients like OpenClaw to display accurate context windows
for combo models instead of guessing based on model name patterns.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 12:29:34 +00:00
diegosouzapw 6f9f1aec65 chore(release): v3.0.0-rc.15 — CHANGELOG + openapi version sync
Build Electron Desktop App / Validate version (push) Failing after 32s
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
Updated CHANGELOG with sprint results:
- i18n: 2,788 keys synced across 30 languages
- 16 provider icons + SVG fallback in ProviderIcon
- Agents fingerprint synced (14 providers)
- dompurify XSS vulnerability fixed (0 npm vulns)
- openapi.yaml version synced
2026-03-24 09:22:02 -03:00
diegosouzapw 97b1ee5b02 fix: sync CLI agents fingerprinting + fix dompurify XSS vulnerability
- Agents page: Added droid, openclaw, copilot, opencode to fingerprinting list
  (synced with CLI Tools — now 14 providers total)
- Fixed dompurify XSS vulnerability (GHSA-v2wj-7wpq-c8vv) via npm overrides
  forcing dompurify ^3.3.2 across all transitive deps (monaco-editor)
- npm audit now reports 0 vulnerabilities
2026-03-24 08:14:24 -03:00
diegosouzapw fe033cd0b3 fix: add SVG fallback to ProviderIcon component
ProviderIcon now tries: Lobehub → PNG → SVG → GenericIcon.
This resolves 11 providers that only have SVG icons
(comfyui, sdwebui, vertex, cartesia, zai, synthetic,
opencode-go/zen, puter, apikey, oauth).
2026-03-24 07:52:07 -03:00
diegosouzapw afbd07c62a fix: sync i18n keys across 30 languages + add 16 missing provider icons
Task 01 - i18n:
- Synced 2,788 missing keys across 30 language files (all now at 100%)
- Added 6 new agents namespace keys for OpenCode Integration
- i18n-ified agents page OpenCode section (was hardcoded English)
- Added scanning progress text during agents page loading

Task 02 - Provider Icons:
- Added 16 missing provider icons:
  - 3 copied from existing (alibaba, kimi-coding-apikey, bailian-coding-plan)
  - 2 downloaded (huggingface, deepgram)
  - 11 created as SVG (comfyui, sdwebui, vertex, cartesia, zai,
    synthetic, opencode-go/zen, puter, apikey, oauth)
- Total: 86 icon files covering all 69 providers
2026-03-24 07:34:07 -03:00
diegosouzapw 9b15996545 fix: prevent login lockout when skipping wizard password setup (#574)
When users skip password setup during onboarding (either via 'Skip Password'
checkbox or 'Skip Wizard' button), the app now explicitly sets requireLogin=false.

Previously, requireLogin defaulted to true with no password hash stored,
leaving users permanently stuck on the login page.

Two code paths fixed in onboarding/page.tsx:
- handleSetPassword() with skipSecurity=true
- handleFinish() when no password was configured
2026-03-24 07:06:54 -03:00
zhang-qiang 1dbbd7241d fix(mcp-server): type list-models locals for typecheck:core
Annotate rawModels as unknown[] and warning as string | undefined (avoid never[] / undefined-only inference)

Made-with: Cursor
2026-03-24 17:50:13 +08:00
zhang-qiang 6c0ef48d45 docs(zws_docs): archive PR memory and CI notes in README
Upstream PR context: #575, T06/T11/keytar, commit hygiene, links to V8 and PR draft

Made-with: Cursor
2026-03-24 17:45:34 +08:00
zhang-qiang 8b57f88ca3 fix(open-sse): satisfy T11 explicit-any budget (regex counts word any)
- Reword comments that contained the token any; replace any types with typed shapes

- stream.ts: passthrough tool-call flag via local boolean (state is null in passthrough)

- Document T11 in zws_docs/ZWS_README_V8.md

Made-with: Cursor
2026-03-24 17:42:52 +08:00
zhang-qiang 3e9fdc777e fix(api,zed): T06 validateBody on JSON routes; lazy-load keytar for CI build
- Add validateBody() alongside request.json() on 5 routes (t06:route-validation)

- Dynamic import keytar in zed keychain-reader to avoid libsecret/keytar load during next build

- Document in zws_docs/ZWS_README_V8.md section 9

Made-with: Cursor
2026-03-24 17:36:55 +08:00
zhang-qiang a8ca88797a feat(dashboard,sse,api): per-model upstream headers, compat PATCH, chat alignment
- Store/sanitize upstreamHeaders; shared forbidden header names (upstreamHeaders.ts)

- chatCore: buildUpstreamHeadersForExecute; T5 recomputes; 401 retry uses translatedBody.model

- Dashboard compat popover + i18n; Zod partialRecord + header value newline guard

- Executors merge upstreamExtraHeaders; sanitize unit tests

- Dev: bootstrap env in run-next, instrumentation-node import, credentialLoader dedupe

Made-with: Cursor
2026-03-24 17:24:11 +08:00
zhang-qiang 71540b5dc0 merge: sync upstream/main (diegosouzapw/OmniRoute) 2026-03-24 13:01:08 +08:00
diegosouzapw b5a145d7b3 Merge branch 'pr-565' into 3.0.0-rc.14
Build Electron Desktop App / Validate version (push) Failing after 30s
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
# Conflicts:
#	docs/i18n/cs/API_REFERENCE.md
#	docs/i18n/cs/CODEBASE_DOCUMENTATION.md
#	docs/i18n/cs/README.md
#	src/i18n/messages/cs.json
2026-03-24 00:19:01 -03:00
diegosouzapw 21d6a0a2dd fix: replace custom YAML parser with js-yaml for correct OpenAPI spec parsing 2026-03-23 22:18:04 -03:00
diegosouzapw 80cc7340ac feat: API Endpoints dashboard — interactive catalog, webhooks, OpenAPI viewer
Phase 1: Interactive REST API Catalog
- GET /api/openapi/spec: serves parsed openapi.yaml as JSON catalog
- POST /api/openapi/try: Try It proxy for inline endpoint testing
- Endpoint catalog with tag grouping, search, method badges
- Expand: schemas, auth, curl examples, Try It panel

Phase 2: OpenAPI Spec Viewer
- Spec info header with version, download YAML/JSON, schema browser

Phase 3: Webhooks & Event Subscriptions
- Migration 011: webhooks table
- src/lib/db/webhooks.ts: CRUD + delivery tracking + auto-disable
- src/lib/webhookDispatcher.ts: HMAC-SHA256, retries
- API: CRUD /api/webhooks + test delivery
- Dashboard: add/edit/toggle/test/delete webhook UI

923 tests pass, tsc clean
2026-03-23 22:07:10 -03:00
diegosouzapw 45b272ee2f chore: bump version to 3.0.0-rc.15
- CHANGELOG: add rc.14 (PRs #562, #561) and rc.15 (#563 per-model combo routing)
- package.json: 3.0.0-rc.13 → 3.0.0-rc.15
- openapi.yaml: version sync to 3.0.0-rc.15
2026-03-23 21:05:44 -03:00
zenobit f765664580 Update docs/i18n/cs/CLI-TOOLS.md
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-03-24 00:47:41 +01:00
zenobit 10b44f036d Update docs/i18n/cs/USER_GUIDE.md
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-03-24 00:47:25 +01:00
zenobit 1bf4ee3a3c Update docs/i18n/cs/CODEBASE_DOCUMENTATION.md
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-03-24 00:46:58 +01:00
zenobit 5d82ffa503 fix(i18n): Improve Czech translation and variables 2026-03-24 00:43:47 +01:00
diegosouzapw 5dc3fd2ec0 feat: per-model combo routing support (#563)
Add model-pattern → combo mapping feature that automatically routes requests
to specific combos based on model name patterns (glob matching).

Implementation:
- New migration 010: model_combo_mappings table with pattern, combo_id, priority
- DB module with CRUD + resolveComboForModel() using glob-to-regex matching
- getComboForModel() in model.ts: augments getCombo() with pattern fallback
- chat.ts: replaced getCombo() → getComboForModel() at routing decision point
- API endpoints: GET/POST /api/model-combo-mappings, GET/PUT/DELETE by [id]
- ModelRoutingSection.tsx: dashboard UI with inline add/edit/toggle/delete
- Integrated into Combos page
- 15 new unit tests (glob matching, priority ordering, disabled filtering)
- Full test suite: 923/923 pass

Examples:
  claude-sonnet* → code-combo
  claude-*-opus* → frontier-combo
  gpt-4o*       → openai-combo
  gemini-*      → google-combo

Resolves: #563
2026-03-23 20:36:00 -03:00
diegosouzapw 4562fdda92 fix(i18n): improve Czech translation — correct HTTP methods and documentation text
Squash-merge from PR #561 by @zen0bit:
- Replace machine-translated HTTP method names (ZÍSKAT→GET, ZVEŘEJNIT→POST, VLOŽIT→PUT, SMAZAT→DELETE)
- Fix Czech documentation text in API_REFERENCE.md and CODEBASE_DOCUMENTATION.md
- Clean up cs.json translation entries

PR: #561
2026-03-23 19:55:42 -03:00
diegosouzapw 18258b9b0d fix: merge PR #562 — MCP session management, Claude passthrough, OAuth modal, detectFormat fixes
Cherry-pick from codex/omniroute-fixes-20260324:
- Replace MCP singleton transport with per-session architecture for Streamable HTTP
- Fix Claude passthrough via OpenAI round-trip normalization
- Add detectFormatFromEndpoint() for endpoint-aware format detection
- Support raw code#state in OAuth modal for Claude Code remote auth
- Expose cloudConfigured/cloudUrl/machineId in settings API
- Switch docker-compose.prod.yml target to runner-cli
- Add 3 new tests for round-trip and detectFormat

PR: #562
2026-03-23 19:53:02 -03:00
diegosouzapw 92e0f242c7 fix(build): resolve all TypeScript compilation errors and Next.js 15 dynamic route slug conflicts
- Fix Next.js 15 async params in 4 API route handlers (accounts, providers, registered-keys)
- Move providers/[id]/limits → providers/[provider]/limits to resolve slug name conflict
- Add keytar to serverExternalPackages and KNOWN_EXTERNALS in next.config.mjs
- Fix Zod z.record() arity across a2a.ts and issues/report/route.ts
- Fix SearchResponse interface (optional answer property) in SearchTools and ResultsPanel
- Fix ProviderLimits implicit any types in index.tsx and utils.tsx
- Fix better-sqlite3 prepare<T> generic usage in secrets.ts
- Remove duplicate pricing keys (gemini-3-flash-preview)
- Cast analytics result, ApiErrorType import, TaskRoutingConfig type
- Remove rogue app/ duplicate directory from project root

Resolves: #560
2026-03-23 18:23:08 -03:00
diegosouzapw 428fa9404c Merge branch 'main' into 3.0.0-rc 2026-03-23 17:10:35 -03:00
diegosouzapw 3cccc480fb feat: add update notification banner to dashboard homepage (resolves #552) 2026-03-23 16:00:03 -03:00
diegosouzapw acb94216c8 fix(providers): secure Zed import route and add dashboard UI component 2026-03-23 15:58:18 -03:00
Abhinav 5fa97841b2 fix: Address all 4 bot review warnings
- FIX #1: Add null check for cred.password (prevent undefined access)
- FIX #2: Prioritize actual credentials over hardcoded account patterns
- FIX #3: Convert CommonJS require() to ES imports for consistency
- FIX #4: Move to App Router, add credential metadata response, document maintainer integration

Additional improvements:
- Better TypeScript error typing with optional chaining
- Improved error messages for missing dependencies
- Added maintainer TODO for provider system integration
- Proper Next.js App Router format (route.ts)

All bot warnings resolved. Ready for maintainer review.
2026-03-23 15:58:18 -03:00
Abhinav 4ad66bf7b9 feat: Add Zed IDE OAuth credential import support
- Implement keychain-based credential extractor for Zed IDE
- Support macOS (Keychain), Windows (Credential Manager), Linux (libsecret)
- Add API endpoint: POST /api/providers/zed/import
- Auto-discover OAuth tokens for OpenAI, Anthropic, Google, Mistral, xAI, etc.
- Cross-platform support via keytar library
- Complete documentation with security considerations

Closes community request from OmniRoute Telegram group.
Follows proven pattern used by VS Code, GitHub Copilot CLI, Claude Code.
2026-03-23 15:58:18 -03:00
Diego Rodrigues de Sa e Souza 64860ed5e5 Merge pull request #557 from diegosouzapw/dependabot/npm_and_yarn/production-834ce0f99d
deps: bump the production group with 4 updates
2026-03-23 15:47:48 -03:00
dependabot[bot] b17faf6e1e deps: bump the production group with 4 updates
Bumps the production group with 4 updates: [jose](https://github.com/panva/jose), [next](https://github.com/vercel/next.js), [undici](https://github.com/nodejs/undici) and [wreq-js](https://github.com/sqdshguy/wreq-js).


Updates `jose` from 6.2.1 to 6.2.2
- [Release notes](https://github.com/panva/jose/releases)
- [Changelog](https://github.com/panva/jose/blob/main/CHANGELOG.md)
- [Commits](https://github.com/panva/jose/compare/v6.2.1...v6.2.2)

Updates `next` from 16.1.7 to 16.2.1
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.1.7...v16.2.1)

Updates `undici` from 7.24.4 to 7.24.5
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v7.24.4...v7.24.5)

Updates `wreq-js` from 2.2.0 to 2.2.2
- [Release notes](https://github.com/sqdshguy/wreq-js/releases)
- [Commits](https://github.com/sqdshguy/wreq-js/compare/v2.2.0...v2.2.2)

---
updated-dependencies:
- dependency-name: jose
  dependency-version: 6.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: next
  dependency-version: 16.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: undici
  dependency-version: 7.24.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: wreq-js
  dependency-version: 2.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-23 18:45:59 +00:00
diegosouzapw 0ea73bd527 chore(release): bump version to 3.0.0-rc.13
Build Electron Desktop App / Validate version (push) Failing after 28s
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
2026-03-23 15:39:11 -03:00
diegosouzapw b2f0820560 fix(#549): resolve real API key from keyId in codex/droid/kilo settings
CLI settings routes (codex-settings, droid-settings, kilo-settings) were
writing the masked API key string directly to config files when the
dashboard sent a keyId. Now resolves the real key from the database via
getApiKeyById() before writing, matching the pattern already implemented
in claude-settings, openclaw-settings, and cline-settings.

Closes #549
2026-03-23 15:31:34 -03:00
diegosouzapw 7ad5d42982 release: v3.0.0-rc.12 — merge PRs #542, #544, #546, #555 + TDZ fix + build fixes
Build Electron Desktop App / Validate version (push) Failing after 29s
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
Community PRs:
- #546: fix(cli): --version returning unknown on Windows
- #555: fix(sse): centralized resolveDataDir() for path resolution
- #544: fix(cli): secure CLI tool detection via known installation paths
- #542: fix(ui): light mode contrast — missing CSS theme variables

Additional:
- Fix TDZ error in cliRuntime.ts (validateEnvPath before getExpectedParentPaths)
- Add pino/pino-pretty to serverExternalPackages for build stability
- 905 tests passing
2026-03-23 15:11:18 -03:00
diegosouzapw 3912734498 fix: cherry-pick PR #542 (light mode contrast) + fix TDZ in cliRuntime.ts
- Add missing CSS theme variables (bg-primary, bg-subtle, text-primary)
- Fix hardcoded dark-mode-only colors with proper dark: variants
- Fix ReferenceError: move validateEnvPath before getExpectedParentPaths
2026-03-23 15:10:19 -03:00
k0valik 0fa3f9a057 fix: (cli) secure CLI tool detection via known installation paths (Win… (#544)
fix(cli): secure CLI tool detection via known installation paths with security hardening — symlink validation, file-type checks, size bounds, minimal env in healthcheck for 8 CLI tools
2026-03-23 15:04:14 -03:00
k0valik 0fbabdcf25 fix(sse): use centralized resolveDataDir() for path resolution (#555)
fix(sse): use centralized resolveDataDir() for path resolution in credentialLoader, autoCombo persistence, responsesTransformer, and requestLogger
2026-03-23 15:04:03 -03:00
k0valik 67b7ae98a6 fix(cli): resolve --version returning 'unknown' on Windows (#546)
fix(cli): resolve --version returning 'unknown' on Windows by using JSON.parse(readFileSync) instead of ESM import with { type: 'json' }
2026-03-23 15:03:51 -03:00
diegosouzapw 0f703c95dd fix(build): add pino and pino-pretty to serverExternalPackages 2026-03-23 11:19:53 -03:00
zhang-qiang 23e3a1c269 docs: move ZWS_README_V4/V5 into zws_docs/
Made-with: Cursor
2026-03-23 14:04:11 +08:00
216 changed files with 13570 additions and 3607 deletions
+118
View File
@@ -0,0 +1,118 @@
---
description: Read all open GitHub Discussions, summarize them, respond to pending ones, and create issues from actionable feature requests
---
# /review-discussions — GitHub Discussions Review & Response Workflow
## Overview
This workflow reads all open GitHub Discussions, generates a categorized summary, identifies which ones need a response, drafts and posts replies, and optionally creates issues from actionable feature requests. It follows the same flow used for Issues but adapted for the Discussions forum.
// turbo-all
## Steps
### 1. Identify the GitHub Repository
- Run: `git -C <project_root> remote get-url origin` to extract the owner/repo
- Parse the owner and repo name from the URL
### 2. Fetch All Open Discussions
- Use `read_url_content` to fetch `https://github.com/<owner>/<repo>/discussions`
- Parse the discussion list to get all discussion titles, IDs, authors, categories, and dates
- For each discussion, fetch the individual page to read the full content and all comments/replies
### 3. Summarize All Discussions
For each discussion, extract:
- **Title** and **#Number**
- **Author** (GitHub username)
- **Category** (Announcements, General, Ideas, Q&A, Show and tell)
- **Date** created
- **Summary** of the original post (1-2 sentences)
- **Comments count** and key participants
- **Your previous response** (if any)
- **Pending action** — whether a response or follow-up is needed
### 4. Present Summary Report to User
Present the full summary to the user organized by category, using a table:
| # | Category | Title | Author | Date | Status |
| --- | -------- | ----- | ------ | ------ | ----------------- |
| #N | Ideas | Title | @user | Mar 23 | ⚠️ Needs response |
| #N | Q&A | Title | @user | Mar 9 | ✅ Answered |
| #N | General | Title | @user | Mar 19 | ⚠️ Needs response |
Highlight:
- **⚠️ Needs response** — No reply from maintainer, or a follow-up comment was left unanswered
- **✅ Answered** — Maintainer already responded
- **🐛 Bug reported** — A bug was mentioned that needs tracking
- **💡 Actionable** — Contains a concrete feature request that could become an issue
### 5. Draft & Post Responses
For each discussion that needs a response, draft a reply following these guidelines:
#### Response Style
- **Friendly and professional** — Start with "Hey @username!"
- **Acknowledge the contribution** — Thank the user for their input
- **Be specific** — Reference existing features, settings, or dashboard pages if the feature already exists
- **Provide workarounds** — If the request isn't implemented yet, suggest current alternatives
- **Commit to action** — If the request is valid, state that you'll open an issue or add it to the roadmap
- **Keep it concise** — 3-5 paragraphs max
#### Posting via Browser
- Use `browser_subagent` to navigate to each discussion and post the comment
- **IMPORTANT**: When typing text in GitHub comment boxes via the browser, use only plain ASCII characters:
- Use regular hyphens `-` instead of em-dashes
- Use `->` instead of arrow symbols
- Do NOT use emoji Unicode characters (the browser keyboard may fail on them)
- Use `**bold**` and `\`code\`` markdown formatting
- Click the green "Comment" button (or "Reply" for threaded replies) after typing
- Verify the comment was posted by checking the page shows the new comment
### 6. Create Issues from Actionable Feature Requests
For discussions that contain concrete, actionable feature requests:
1. Ask the user which ones should become issues
2. For each approved request, create a GitHub issue via `browser_subagent`:
- Navigate to `https://github.com/<owner>/<repo>/issues/new`
- **Title**: `<Feature Name> - <Short description>`
- **Body** should include:
- `## Feature Request` header
- `**Source:** Discussion #N by @author`
- `## Problem` — What limitation the user hit
- `## Proposed Solution` — How it could work
- `### Implementation Ideas` — Technical approach
- `### Current Workarounds` — What users can do today
- `## Additional Context` — Links to related issues/discussions
- Add `enhancement` label
- Click "Submit new issue" / "Create"
3. After creation, go back to the original discussion and post a comment linking to the new issue:
- "I've opened Issue #N to track this feature request. Follow along there for updates!"
### 7. Final Report
Present a final summary to the user:
| Discussion | Action Taken |
| ---------- | ---------------------------------- |
| #N — Title | Responded with workarounds |
| #N — Title | Responded + created Issue #N |
| #N — Title | Already answered, no action needed |
| #N — Title | Responded to follow-up comment |
## Notes
- This workflow is **interactive** — always present the summary and wait for user approval before posting responses or creating issues
- If the user says "pode responder" (or similar approval), proceed with posting all drafted responses
- For discussions in non-English languages, respond in the same language as the original post
- Always reference specific dashboard paths, config options, or code files when explaining existing features
- When a discussion reveals a bug, note it separately from feature requests
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
- name: Login to Docker Hub
uses: docker/login-action@v4
+10
View File
@@ -201,3 +201,13 @@ jobs:
release-assets/*.source.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-npm:
name: Publish to npm
needs: [validate, release]
uses: ./.github/workflows/npm-publish.yml
with:
version: ${{ needs.validate.outputs.version }}
tag: latest
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
+59 -12
View File
@@ -6,9 +6,31 @@ on:
workflow_dispatch:
inputs:
version:
description: "Version tag to publish (e.g. 2.6.0)"
description: "Version to publish (e.g. 2.9.5 or 3.0.0-rc.15)"
required: true
type: string
tag:
description: "npm dist-tag (latest / next)"
required: false
default: "latest"
type: choice
options:
- latest
- next
workflow_call:
inputs:
version:
description: "Version to publish (without v prefix)"
required: true
type: string
tag:
description: "npm dist-tag (latest / next)"
required: false
default: "latest"
type: string
secrets:
NPM_TOKEN:
required: true
permissions:
contents: read
@@ -31,16 +53,35 @@ jobs:
- name: Install dependencies (skip scripts to avoid heavy build)
run: npm install --ignore-scripts --no-audit --no-fund
- name: Sync version from release tag or input
- name: Resolve version and dist-tag
id: resolve
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION="${{ inputs.version }}"
else
VERSION="${GITHUB_REF_NAME}"
VERSION="${VERSION#v}"
case "${{ github.event_name }}" in
workflow_dispatch|workflow_call)
VERSION="${{ inputs.version }}"
TAG="${{ inputs.tag }}"
;;
release)
VERSION="${GITHUB_REF_NAME}"
;;
esac
# Strip v prefix if present
VERSION="${VERSION#v}"
# Default dist-tag logic
if [ -z "$TAG" ]; then
if [[ "$VERSION" == *-* ]]; then
TAG="next"
else
TAG="latest"
fi
fi
npm version "$VERSION" --no-git-tag-version --allow-same-version
echo "Publishing version: $VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "tag=$TAG" >> $GITHUB_OUTPUT
echo "📦 Publishing omniroute@$VERSION with tag=$TAG"
- name: Sync package.json version
run: |
npm version "${{ steps.resolve.outputs.version }}" --no-git-tag-version --allow-same-version
- name: Build CLI bundle (standalone app)
env:
@@ -49,12 +90,18 @@ jobs:
- name: Publish to npm
run: |
VERSION=$(node -p "require('./package.json').version")
VERSION="${{ steps.resolve.outputs.version }}"
TAG="${{ steps.resolve.outputs.tag }}"
# Check if this version is already published — skip instead of failing with E403
if npm view "omniroute@${VERSION}" version --silent 2>/dev/null | grep -q "^${VERSION}$"; then
echo "⚠️ Version ${VERSION} is already published on npm — skipping."
echo "⚠️ Version ${VERSION} is already published on npm — skipping."
exit 0
fi
npm publish --access public
if [ "$TAG" = "latest" ]; then
npm publish --access public
else
npm publish --access public --tag "$TAG"
fi
echo "✅ Published omniroute@$VERSION (tag: $TAG)"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+22 -18
View File
@@ -49,19 +49,22 @@ but the real logic lives in `src/lib/db/`.
Translation between provider formats: `open-sse/translator/`
**Upstream model extra headers** (`compatByProtocol` / custom models): merged in executors after default auth; **same header name replaces** the executor value (e.g. custom `Authorization` overrides Bearer). In `open-sse/handlers/chatCore.ts`, the primary request merges headers for **both** the client model id and `resolveModelAlias(clientModel)` (resolved id wins on key conflicts). **T5 intra-family fallback** recomputes headers using only the fallback model id and `resolveModelAlias(fallback)` so sibling models do not inherit another models headers. Forbidden header names live in `src/shared/constants/upstreamHeaders.ts` — keep sanitize (`models.ts`), Zod (`schemas.ts`), and unit tests aligned when editing that list.
### MCP Server (`open-sse/mcp-server/`)
16 tools for AI agent control via **3 transport modes**:
- **stdio** — Local IDE integration (Claude Desktop, Cursor, VS Code)
- **SSE** — Remote Server-Sent Events at `/api/mcp/sse`
- **Streamable HTTP** — Modern bidirectional HTTP at `/api/mcp/stream`
HTTP transports run in-process via `httpTransport.ts` singleton using `WebStandardStreamableHTTPServerTransport`.
| Category | Tools |
| ---------- | ------------------------------------------------------------------------------------------------------------------------- |
| Essential | `get_health`, `list_combos`, `get_combo_metrics`, `switch_combo`, `check_quota`, `route_request`, `cost_report`, `list_models_catalog` |
| Advanced | `simulate_route`, `set_budget_guard`, `set_resilience_profile`, `test_combo`, `get_provider_metrics`, `best_combo_for_task`, `explain_route`, `get_session_snapshot` |
| Category | Tools |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Essential | `get_health`, `list_combos`, `get_combo_metrics`, `switch_combo`, `check_quota`, `route_request`, `cost_report`, `list_models_catalog` |
| Advanced | `simulate_route`, `set_budget_guard`, `set_resilience_profile`, `test_combo`, `get_provider_metrics`, `best_combo_for_task`, `explain_route`, `get_session_snapshot` |
- Scoped authorization (9 scopes), audit logging, Zod schemas
- IDE configs for Claude Desktop, Cursor, VS Code Copilot
@@ -79,25 +82,26 @@ Agent-to-Agent v0.3 protocol:
### Auto-Combo Engine (`open-sse/services/autoCombo/`)
Self-healing routing optimization:
- 6-factor scoring, 4 mode packs, bandit exploration
- Progressive cooldown, probe-based re-admission
### Dashboard (`src/app/(dashboard)/`)
| Page | Description |
| ---------------------------- | -------------------------------------------------------------- |
| `/dashboard` | Home with quick start, provider overview |
| `/dashboard/endpoint` | **Endpoints** (tabbed): Endpoint Proxy, MCP, A2A, API Endpoints |
| `/dashboard/providers` | Provider management and connections |
| `/dashboard/combos` | Combo configurations with routing strategies |
| `/dashboard/logs` | Request, Proxy, Audit, Console logs (tabbed) |
| `/dashboard/analytics` | Usage analytics and evaluations |
| `/dashboard/costs` | Cost tracking and breakdown |
| `/dashboard/health` | Uptime, circuit breakers, latency |
| `/dashboard/cli-tools` | CLI tool integrations (Claude, Codex, Antigravity, etc.) |
| `/dashboard/media` | Image, Video, Music generation playground |
| `/dashboard/settings` | System settings with multiple tabs |
| `/dashboard/api-manager` | API key management with model permissions |
| Page | Description |
| ------------------------ | --------------------------------------------------------------- |
| `/dashboard` | Home with quick start, provider overview |
| `/dashboard/endpoint` | **Endpoints** (tabbed): Endpoint Proxy, MCP, A2A, API Endpoints |
| `/dashboard/providers` | Provider management and connections |
| `/dashboard/combos` | Combo configurations with routing strategies |
| `/dashboard/logs` | Request, Proxy, Audit, Console logs (tabbed) |
| `/dashboard/analytics` | Usage analytics and evaluations |
| `/dashboard/costs` | Cost tracking and breakdown |
| `/dashboard/health` | Uptime, circuit breakers, latency |
| `/dashboard/cli-tools` | CLI tool integrations (Claude, Codex, Antigravity, etc.) |
| `/dashboard/media` | Image, Video, Music generation playground |
| `/dashboard/settings` | System settings with multiple tabs |
| `/dashboard/api-manager` | API key management with model permissions |
### OAuth & Tokens (`src/lib/oauth/`)
+445 -1
View File
@@ -2,7 +2,451 @@
## [Unreleased]
> **Coming next** — see [3.0.0-rc branch](https://github.com/diegosouzapw/OmniRoute/tree/3.0.0-rc).
---
## [3.0.1] — 2026-03-25
### 🔧 Hotfix Patch — Critical Bug Fixes
Three critical regressions reported by users after the v3.0.0 launch have been resolved.
#### fix(translator): strip `proxy_` prefix in non-streaming Claude responses (#605)
The `proxy_` prefix added by Claude OAuth was only stripped from **streaming** responses. In **non-streaming** mode, `translateNonStreamingResponse` had no access to the `toolNameMap`, causing clients to receive mangled tool names like `proxy_read_file` instead of `read_file`.
**Fix:** Added optional `toolNameMap` parameter to `translateNonStreamingResponse` and applied prefix stripping in the Claude `tool_use` block handler. `chatCore.ts` now passes the map through.
#### fix(validation): add LongCat specialty validator to skip /models probe (#592)
LongCat AI does not expose `GET /v1/models`. The generic `validateOpenAICompatibleProvider` validator fell through to a chat-completions fallback only if `validationModelId` was set, which LongCat doesn't configure. This caused provider validation to fail with a misleading error on add/save.
**Fix:** Added `longcat` to the specialty validators map, probing `/chat/completions` directly and treating any non-auth response as a pass.
#### fix(translator): normalize object tool schemas for Anthropic (#595)
MCP tools (e.g. `pencil`, `computer_use`) forward tool definitions with `{type:"object"}` but without a `properties` field. Anthropic's API rejects these with: `object schema missing properties`.
**Fix:** In `openai-to-claude.ts`, inject `properties: {}` as a safe default when `type` is `"object"` and `properties` is absent.
---
### 🔀 Community PRs Merged (2)
| PR | Author | Summary |
| -------- | ------- | -------------------------------------------------------------------------- |
| **#589** | @flobo3 | docs(i18n): fix Russian translation for Playground and Testbed |
| **#591** | @rdself | fix(ui): improve Provider Limits light mode contrast and plan tier display |
---
### ✅ Issues Resolved
`#592` `#595` `#605`
---
### 🧪 Tests
- **926 tests, 0 failures** (unchanged from v3.0.0)
---
## [3.0.0] — 2026-03-24
### 🎉 OmniRoute v3.0.0 — The Free AI Gateway, Now with 67+ Providers
> **The biggest release ever.** From 36 providers in v2.9.5 to **67+ providers** in v3.0.0 — with MCP Server, A2A Protocol, auto-combo engine, Provider Icons, Registered Keys API, 926 tests, and contributions from **12 community members** across **10 merged PRs**.
>
> Consolidated from v3.0.0-rc.1 through rc.17 (17 release candidates over 3 days of intense development).
---
### 🆕 New Providers (+31 since v2.9.5)
| Provider | Alias | Tier | Notes |
| ----------------------------- | --------------- | ----------- | --------------------------------------------------------------------------- |
| **OpenCode Zen** | `opencode-zen` | Free | 3 models via `opencode.ai/zen/v1` (PR #530 by @kang-heewon) |
| **OpenCode Go** | `opencode-go` | Paid | 4 models via `opencode.ai/zen/go/v1` (PR #530 by @kang-heewon) |
| **LongCat AI** | `lc` | Free | 50M tokens/day (Flash-Lite) + 500K/day (Chat/Thinking) during public beta |
| **Pollinations AI** | `pol` | Free | No API key needed — GPT-5, Claude, Gemini, DeepSeek V3, Llama 4 (1 req/15s) |
| **Cloudflare Workers AI** | `cf` | Free | 10K Neurons/day — ~150 LLM responses or 500s Whisper audio, edge inference |
| **Scaleway AI** | `scw` | Free | 1M free tokens for new accounts — EU/GDPR compliant (Paris) |
| **AI/ML API** | `aiml` | Free | $0.025/day free credits — 200+ models via single endpoint |
| **Puter AI** | `pu` | Free | 500+ models (GPT-5, Claude Opus 4, Gemini 3 Pro, Grok 4, DeepSeek V3) |
| **Alibaba Cloud (DashScope)** | `ali` | Paid | International + China endpoints via `alicode`/`alicode-intl` |
| **Alibaba Coding Plan** | `bcp` | Paid | Alibaba Model Studio with Anthropic-compatible API |
| **Kimi Coding (API Key)** | `kmca` | Paid | Dedicated API-key-based Kimi access (separate from OAuth) |
| **MiniMax Coding** | `minimax` | Paid | International endpoint |
| **MiniMax (China)** | `minimax-cn` | Paid | China-specific endpoint |
| **Z.AI (GLM-5)** | `zai` | Paid | Zhipu AI next-gen GLM models |
| **Vertex AI** | `vertex` | Paid | Google Cloud — Service Account JSON or OAuth access_token |
| **Ollama Cloud** | `ollamacloud` | Paid | Ollama's hosted API service |
| **Synthetic** | `synthetic` | Paid | Passthrough models gateway |
| **Kilo Gateway** | `kg` | Paid | Passthrough models gateway |
| **Perplexity Search** | `pplx-search` | Paid | Dedicated search-grounded endpoint |
| **Serper Search** | `serper-search` | Paid | Web search API integration |
| **Brave Search** | `brave-search` | Paid | Brave Search API integration |
| **Exa Search** | `exa-search` | Paid | Neural search API integration |
| **Tavily Search** | `tavily-search` | Paid | AI search API integration |
| **NanoBanana** | `nb` | Paid | Image generation API |
| **ElevenLabs** | `el` | Paid | Text-to-speech voice synthesis |
| **Cartesia** | `cartesia` | Paid | Ultra-fast TTS voice synthesis |
| **PlayHT** | `playht` | Paid | Voice cloning and TTS |
| **Inworld** | `inworld` | Paid | AI character voice chat |
| **SD WebUI** | `sdwebui` | Self-hosted | Stable Diffusion local image generation |
| **ComfyUI** | `comfyui` | Self-hosted | ComfyUI local workflow node-based generation |
| **GLM Coding** | `glm` | Paid | BigModel/Zhipu coding-specific endpoint |
**Total: 67+ providers** (4 Free, 8 OAuth, 55 API Key) + unlimited OpenAI/Anthropic-Compatible custom providers.
---
### ✨ Major Features
#### 🔑 Registered Keys Provisioning API (#464)
Auto-generate and issue OmniRoute API keys programmatically with per-provider and per-account quota enforcement.
| Endpoint | Method | Description |
| ------------------------------- | ------------ | ------------------------------------------------ |
| `/api/v1/registered-keys` | `POST` | Issue a new key — raw key returned **once only** |
| `/api/v1/registered-keys` | `GET` | List registered keys (masked) |
| `/api/v1/registered-keys/{id}` | `GET/DELETE` | Get metadata / Revoke |
| `/api/v1/quotas/check` | `GET` | Pre-validate quota before issuing |
| `/api/v1/providers/{id}/limits` | `GET/PUT` | Configure per-provider issuance limits |
| `/api/v1/accounts/{id}/limits` | `GET/PUT` | Configure per-account issuance limits |
| `/api/v1/issues/report` | `POST` | Report quota events to GitHub Issues |
**Security:** Keys stored as SHA-256 hashes. Raw key shown once on creation, never retrievable again.
#### 🎨 Provider Icons via @lobehub/icons (#529)
130+ provider logos using `@lobehub/icons` React components (SVG). Fallback chain: **Lobehub SVG → existing PNG → generic icon**. Applied across Dashboard, Providers, and Agents pages with standardized `ProviderIcon` component.
#### 🔄 Model Auto-Sync Scheduler (#488)
Auto-refreshes model lists for connected providers every **24 hours**. Runs on server startup. Configurable via `MODEL_SYNC_INTERVAL_HOURS`.
#### 🔀 Per-Model Combo Routing (#563)
Map model name patterns (glob) to specific combos for automatic routing:
- `claude-sonnet*` → code-combo, `gpt-4o*` → openai-combo, `gemini-*` → google-combo
- New `model_combo_mappings` table with glob-to-regex matching
- Dashboard UI section: "Model Routing Rules" with inline add/edit/toggle/delete
#### 🧭 API Endpoints Dashboard
Interactive catalog, webhooks management, OpenAPI viewer — all in one tabbed page at `/dashboard/endpoint`.
#### 🔍 Web Search Providers
5 new search provider integrations: **Perplexity Search**, **Serper**, **Brave Search**, **Exa**, **Tavily** — enabling grounded AI responses with real-time web data.
#### 📊 Search Analytics
New tab in `/dashboard/analytics` — provider breakdown, cache hit rate, cost tracking. API: `GET /api/v1/search/analytics`.
#### 🛡️ Per-API-Key Rate Limits (#452)
`max_requests_per_day` and `max_requests_per_minute` columns with in-memory sliding-window enforcement returning HTTP 429.
#### 🎵 Media Playground
Full media generation playground at `/dashboard/media`: Image Generation, Video, Music, Audio Transcription (2GB upload limit), and Text-to-Speech.
---
### 🔒 Security & CI/CD
- **CodeQL remediation** — Fixed 10+ alerts: 6 polynomial-redos, 1 insecure-randomness (`Math.random()``crypto.randomUUID()`), 1 shell-command-injection
- **Route validation** — Zod schemas + `validateBody()` on **176/176 API routes** — CI enforced
- **CVE fix** — dompurify XSS vulnerability (GHSA-v2wj-7wpq-c8vv) resolved via npm overrides
- **Flatted** — Bumped 3.3.3 → 3.4.2 (CWE-1321 prototype pollution)
- **Docker** — Upgraded `docker/setup-buildx-action` v3 → v4
---
### 🐛 Bug Fixes (40+)
#### OAuth & Auth
- **#537** — Gemini CLI OAuth: clear actionable error when `GEMINI_OAUTH_CLIENT_SECRET` missing in Docker
- **#549** — CLI settings routes now resolve real API key from `keyId` (not masked strings)
- **#574** — Login no longer freezes after skipping wizard password setup
- **#506** — Cross-platform `machineId` rewritten (Windows REG.exe → macOS ioreg → Linux → hostname fallback)
#### Providers & Routing
- **#536** — LongCat AI: fixed `baseUrl` and `authHeader`
- **#535** — Pinned model override: `body.model` correctly set to `pinnedModel`
- **#570** — Unprefixed Claude models now resolve to Anthropic provider
- **#585** — `<omniModel>` internal tags no longer leak to clients in SSE streaming
- **#493** — Custom provider model naming no longer mangled by prefix stripping
- **#490** — Streaming + context cache protection via `TransformStream` injection
- **#511** — `<omniModel>` tag injected into first content chunk (not after `[DONE]`)
#### CLI & Tools
- **#527** — Claude Code + Codex loop: `tool_result` blocks now converted to text
- **#524** — OpenCode config saved correctly (XDG_CONFIG_HOME, TOML format)
- **#522** — API Manager: removed misleading "Copy masked key" button
- **#546** — `--version` returning `unknown` on Windows (PR by @k0valik)
- **#544** — Secure CLI tool detection via known installation paths (PR by @k0valik)
- **#510** — Windows MSYS2/Git-Bash paths normalized automatically
- **#492** — CLI detects `mise`/`nvm`-managed Node when `app/server.js` missing
#### Streaming & SSE
- **PR #587** — Revert `resolveDataDir` import in responsesTransformer for Cloudflare Workers compat (@k0valik)
- **PR #495** — Bottleneck 429 infinite wait: drop waiting jobs on rate limit (@xandr0s)
- **#483** — Stop trailing `data: null` after `[DONE]` signal
- **#473** — Zombie SSE streams: timeout reduced 300s → 120s for faster fallback
#### Media & Transcription
- **Transcription** — Deepgram `video/mp4``audio/mp4` MIME mapping, auto language detection, punctuation
- **TTS** — `[object Object]` error display fixed for ElevenLabs-style nested errors
- **Upload limits** — Media transcription increased to 2GB (nginx `client_max_body_size 2g` + `maxDuration=300`)
---
### 🔧 Infrastructure & Improvements
#### Sub2api Gap Analysis (T01T15 + T23T42)
- **T01** — `requested_model` column in call logs (migration 009)
- **T02** — Strip empty text blocks from nested `tool_result.content`
- **T03** — Parse `x-codex-5h-*` / `x-codex-7d-*` quota headers
- **T04** — `X-Session-Id` header for external sticky routing
- **T05** — Rate-limit DB persistence with dedicated API
- **T06** — Account deactivated → permanent block (1-year cooldown)
- **T07** — X-Forwarded-For IP validation (`extractClientIp()`)
- **T08** — Per-API-key session limits with sliding-window enforcement
- **T09** — Codex vs Spark rate-limit scopes (separate pools)
- **T10** — Credits exhausted → distinct 1h cooldown fallback
- **T11** — `max` reasoning effort → 131072 budget tokens
- **T12** — MiniMax M2.7 pricing entries
- **T13** — Stale quota display fix (reset window awareness)
- **T14** — Proxy fast-fail TCP check (≤2s, cached 30s)
- **T15** — Array content normalization for Anthropic
- **T23** — Intelligent quota reset fallback (header extraction)
- **T24** — `503` cooldown + `406` mapping
- **T25** — Provider validation fallback
- **T29** — Vertex AI Service Account JWT auth
- **T33** — Thinking level to budget conversion
- **T36** — `403` vs `429` error classification
- **T38** — Centralized model specifications (`modelSpecs.ts`)
- **T39** — Endpoint fallback for `fetchAvailableModels`
- **T41** — Background task auto-redirect to flash models
- **T42** — Image generation aspect ratio mapping
#### Other Improvements
- **Per-model upstream custom headers** — via configuration UI (PR #575 by @zhangqiang8vip)
- **Model context length** — configurable in model metadata (PR #578 by @hijak)
- **Model prefix stripping** — option to remove provider prefix from model names (PR #582 by @jay77721)
- **Gemini CLI deprecation** — marked deprecated with Google OAuth restriction warning
- **YAML parser** — replaced custom parser with `js-yaml` for correct OpenAPI spec parsing
- **ZWS v5** — HMR leak fix (485 DB connections → 1, memory 2.4GB → 195MB)
- **Log export** — New JSON export button on dashboard with time range dropdown
- **Update notification banner** — dashboard homepage shows when new versions are available
---
### 🌐 i18n & Documentation
- **30 languages** at 100% parity — 2,788 missing keys synced
- **Czech** — Full translation: 22 docs, 2,606 UI strings (PR by @zen0bit)
- **Chinese (zh-CN)** — Complete retranslation (PR by @only4copilot)
- **VM Deployment Guide** — Translated to English as source document
- **API Reference** — Added `/v1/embeddings` and `/v1/audio/speech` endpoints
- **Provider count** — Updated from 36+/40+/44+ to **67+** across README and all 30 i18n READMEs
---
### 🔀 Community PRs Merged (10)
| PR | Author | Summary |
| -------- | --------------- | -------------------------------------------------------------------- |
| **#587** | @k0valik | fix(sse): revert resolveDataDir import for Cloudflare Workers compat |
| **#582** | @jay77721 | feat(proxy): model name prefix stripping option |
| **#581** | @jay77721 | fix(npm): link electron-release to npm-publish workflow |
| **#578** | @hijak | feat: configurable context length in model metadata |
| **#575** | @zhangqiang8vip | feat: per-model upstream headers, compat PATCH, chat alignment |
| **#562** | @coobabm | fix: MCP session management, Claude passthrough, detectFormat |
| **#561** | @zen0bit | fix(i18n): Czech translation corrections |
| **#555** | @k0valik | fix(sse): centralized `resolveDataDir()` for path resolution |
| **#546** | @k0valik | fix(cli): `--version` returning `unknown` on Windows |
| **#544** | @k0valik | fix(cli): secure CLI tool detection via installation paths |
| **#542** | @rdself | fix(ui): light mode contrast CSS theme variables |
| **#530** | @kang-heewon | feat: OpenCode Zen + Go providers with `OpencodeExecutor` |
| **#512** | @zhangqiang8vip | feat: per-protocol model compatibility (`compatByProtocol`) |
| **#497** | @zhangqiang8vip | fix: dev-mode HMR resource leaks (ZWS v5) |
| **#495** | @xandr0s | fix: Bottleneck 429 infinite wait (drop waiting jobs) |
| **#494** | @zhangqiang8vip | feat: MiniMax developer→system role fix |
| **#480** | @prakersh | fix: stream flush usage extraction |
| **#479** | @prakersh | feat: Codex 5.3/5.4 and Anthropic pricing entries |
| **#475** | @only4copilot | feat(i18n): improved Chinese translation |
**Thank you to all contributors!** 🙏
---
### 📋 Issues Resolved (50+)
`#452` `#458` `#462` `#464` `#466` `#473` `#474` `#481` `#483` `#487` `#488` `#489` `#490` `#491` `#492` `#493` `#506` `#508` `#509` `#510` `#511` `#513` `#520` `#521` `#522` `#524` `#525` `#527` `#529` `#531` `#532` `#535` `#536` `#537` `#541` `#546` `#549` `#563` `#570` `#574` `#585`
---
### 🧪 Tests
- **926 tests, 0 failures** (up from 821 in v2.9.5)
- +105 new tests covering: model-combo mappings, registered keys, OpencodeExecutor, Bailian provider, route validation, error classification, aspect ratio mapping, and more
---
### 📦 Database Migrations
| Migration | Description |
| --------- | --------------------------------------------------------------------- |
| **008** | `registered_keys`, `provider_key_limits`, `account_key_limits` tables |
| **009** | `requested_model` column in `call_logs` |
| **010** | `model_combo_mappings` table for per-model combo routing |
---
### ⬆️ Upgrading from v2.9.5
```bash
# npm
npm install -g omniroute@3.0.0
# Docker
docker pull diegosouzapw/omniroute:3.0.0
# Migrations run automatically on first startup
```
> **Breaking changes:** None. All existing configurations, combos, and API keys are preserved.
> Database migrations 008-010 run automatically on startup.
---
## [3.0.0-rc.17] — 2026-03-24
### 🔒 Security & CI/CD
- **CodeQL remediation** — Fixed 10+ alerts:
- 6 polynomial-redos in `provider.ts` / `chatCore.ts` (replaced `(?:^|/)` alternation patterns with segment-based matching)
- 1 insecure-randomness in `acp/manager.ts` (`Math.random()``crypto.randomUUID()`)
- 1 shell-command-injection in `prepublish.mjs` (`JSON.stringify()` path escaping)
- **Route validation** — Added Zod schemas + `validateBody()` to 5 routes missing validation:
- `model-combo-mappings` (POST, PUT), `webhooks` (POST, PUT), `openapi/try` (POST)
- CI `check:route-validation:t06` now passes: **176/176 routes validated**
### 🐛 Bug Fixes
- **#585** — `<omniModel>` internal tags no longer leak to clients in SSE responses. Added outbound sanitization `TransformStream` in `combo.ts`
### ⚙️ Infrastructure
- **Docker** — Upgraded `docker/setup-buildx-action` from v3 → v4 (Node.js 20 deprecation fix)
- **CI cleanup** — Deleted 150+ failed/cancelled workflow runs
### 🧪 Tests
- Test suite: **926 tests, 0 failures** (+3 new)
---
## [3.0.0-rc.16] — 2026-03-24
### ✨ New Features
- Increased media transcription limits
- Added Model Context Length to registry metadata
- Added per-model upstream custom headers via configuration UI
- Fixed multiple bugs, Zod valiadation for patches, and resolved various community issues.
## [3.0.0-rc.15] — 2026-03-24
### ✨ New Features
- **#563** — Per-model Combo Routing: map model name patterns (glob) to specific combos for automatic routing
- New `model_combo_mappings` table (migration 010) with pattern, combo_id, priority, enabled
- `resolveComboForModel()` DB function with glob-to-regex matching (case-insensitive, `*` and `?` wildcards)
- `getComboForModel()` in `model.ts`: augments `getCombo()` with model-pattern fallback
- `chat.ts`: routing decision now checks model-combo mappings before single-model handling
- API: `GET/POST /api/model-combo-mappings`, `GET/PUT/DELETE /api/model-combo-mappings/:id`
- Dashboard: "Model Routing Rules" section added to Combos page with inline add/edit/toggle/delete
- Examples: `claude-sonnet*` → code-combo, `gpt-4o*` → openai-combo, `gemini-*` → google-combo
### 🌐 i18n
- **Full i18n Sync**: 2,788 missing keys added across 30 language files — all languages now at 100% parity with `en.json`
- **Agents page i18n**: OpenCode Integration section fully internationalized (title, description, scanning, download labels)
- **6 new keys** added to `agents` namespace for OpenCode section
### 🎨 UI/UX
- **Provider Icons**: 16 missing provider icons added (3 copied, 2 downloaded, 11 SVG created)
- **SVG fallback**: `ProviderIcon` component updated with 4-tier strategy: Lobehub → PNG → SVG → Generic icon
- **Agents fingerprinting**: Synced with CLI tools — added droid, openclaw, copilot, opencode to fingerprint list (14 total)
### 🔒 Security
- **CVE fix**: Resolved dompurify XSS vulnerability (GHSA-v2wj-7wpq-c8vv) via npm overrides forcing `dompurify@^3.3.2`
- `npm audit` now reports **0 vulnerabilities**
### 🧪 Tests
- Test suite: **923 tests, 0 failures** (+15 new model-combo mapping tests)
---
## [3.0.0-rc.14] — 2026-03-23
### 🔀 Community PRs Merged
| PR | Author | Summary |
| -------- | -------- | -------------------------------------------------------------------------------------------- |
| **#562** | @coobabm | fix(ux): MCP session management, Claude passthrough normalization, OAuth modal, detectFormat |
| **#561** | @zen0bit | fix(i18n): Czech translation corrections — HTTP method names and documentation updates |
### 🧪 Tests
- Test suite: **908 tests, 0 failures**
---
## [3.0.0-rc.13] — 2026-03-23
### 🔧 Bug Fixes
- **config:** resolve real API key from `keyId` in CLI settings routes (`codex-settings`, `droid-settings`, `kilo-settings`) to prevent writing masked strings (#549)
---
## [3.0.0-rc.12] — 2026-03-23
### 🔀 Community PRs Merged
| PR | Author | Summary |
| -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **#546** | @k0valik | fix(cli): `--version` returning `unknown` on Windows — use `JSON.parse(readFileSync)` instead of ESM import |
| **#555** | @k0valik | fix(sse): centralized `resolveDataDir()` for path resolution in credentials, autoCombo, responses logger, and request logger |
| **#544** | @k0valik | fix(cli): secure CLI tool detection via known installation paths (8 tools) with symlink validation, file-type checks, size bounds, minimal env in healthcheck |
| **#542** | @rdself | fix(ui): improve light mode contrast — add missing CSS theme variables (`bg-primary`, `bg-subtle`, `text-primary`) and fix dark-only colors in log detail |
### 🔧 Bug Fixes
- **TDZ fix in `cliRuntime.ts`** — `validateEnvPath` was used before initialization at module startup by `getExpectedParentPaths()`. Reordered declarations to fix `ReferenceError`.
- **Build fixes** — Added `pino` and `pino-pretty` to `serverExternalPackages` to prevent Turbopack from breaking Pino's internal worker loading.
### 🧪 Tests
- Test suite: **905 tests, 0 failures**
---
+6 -3
View File
@@ -2,7 +2,7 @@
### Never stop coding. Smart routing to **FREE & low-cost AI models** with automatic fallback.
_Your universal API proxy — one endpoint, 44+ providers, zero downtime. Now with **MCP & A2A** agent orchestration._
_Your universal API proxy — one endpoint, 67+ providers, zero downtime. Now with **MCP & A2A** agent orchestration._
**Chat Completions • Embeddings • Image Generation • Video • Music • Audio • Reranking • **Web Search** • MCP Server • A2A Protocol • 100% TypeScript**
@@ -32,6 +32,9 @@ _Your universal API proxy — one endpoint, 44+ providers, zero downtime. Now wi
| Area | Change |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection remediation |
| ✅ **Route Validation** | All 176 API routes now validated with Zod schemas + `validateBody()` — CI `check:route-validation:t06` passes |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streaming responses (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with per-provider/account quota enforcement, idempotency, SHA-256 storage, and optional GitHub issue reporting |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG → generic fallback chain |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers on startup — configurable via `MODEL_SYNC_INTERVAL_HOURS` |
@@ -255,7 +258,7 @@ OpenAI uses one format, Claude (Anthropic) uses another, Gemini yet another. If
**How OmniRoute solves it:**
- **Unified Endpoint** — A single `http://localhost:20128/v1` serves as proxy for all 44+ providers
- **Unified Endpoint** — A single `http://localhost:20128/v1` serves as proxy for all 67+ providers
- **Format Translation** — Automatic and transparent: OpenAI ↔ Claude ↔ Gemini ↔ Responses API
- **Response Sanitization** — Strips non-standard fields (`x_groq`, `usage_breakdown`, `service_tier`) that break OpenAI SDK v1.83+
- **Role Normalization** — Converts `developer``system` for non-OpenAI providers; `system``user` for GLM/ERNIE
@@ -341,7 +344,7 @@ Developers use Cursor, Claude Code, Codex CLI, OpenClaw, Gemini CLI, Kilo Code..
- **CLI Tools Dashboard** — Dedicated page with one-click setup for Claude Code, Codex CLI, OpenClaw, Kilo Code, Antigravity, Cline
- **GitHub Copilot Config Generator** — Generates `chatLanguageModels.json` for VS Code with bulk model selection
- **Onboarding Wizard** — Guided 4-step setup for first-time users
- **One endpoint, all models** — Configure `http://localhost:20128/v1` once, access 44+ providers
- **One endpoint, all models** — Configure `http://localhost:20128/v1` once, access 67+ providers
</details>
-374
View File
@@ -1,374 +0,0 @@
# ZWS_README_V4 — 启动性能优化:HMR 泄漏修复与 Turbopack 迁移
## 一、如何发现问题
### 现象
- `npm run dev` 后,首次打开浏览器白屏等待 **5-22 秒**不等。
- 运行一段时间后 Node 进程内存飙升至 **2.4 GB**,触发 Next.js 内存阈值保护强制重启。
- 重启后 `Ready in 82.6s`(正常冷启动仅 3.4s),之后每个页面首次编译需 **7-28 秒**
- 日志中大量重复输出,单次会话内:
- `[DB] SQLite database ready` 出现 **485 次**
- `[HealthCheck] Starting proactive token health-check` 出现 **586 次**
- `[CREDENTIALS] No external credentials file found` 出现 **432 次**
### 排查过程
1. **Terminal 日志分析**:统计关键日志出现次数,发现 DB 连接和 HealthCheck 定时器被反复创建。
2. **代码审计**:追踪到所有受影响模块使用 `let initialized = false` 作为单例守卫——这在 Next.js dev 模式的 Webpack HMR 下会被重置。
3. **对比**`apiBridgeServer.ts` 使用了 `globalThis.__omnirouteApiBridgeStarted`,在日志中无重复初始化,验证了 `globalThis` 方案的有效性。
4. **内存快照**:通过 `Get-Process node` 观察到两个 node 进程分别占用 1.7GB 和 1.0GB。
5. **编译时间分析**:日志中 `compile:` 字段显示 Webpack 编译每个路由需 2-26 秒,对比 Turbopack 应在 0.5-3 秒。
---
## 二、根因分析
### 根因 1(P0):模块级单例在 HMR 中丢失
Next.js dev 模式下,Webpack HMR 会重新执行被修改(或依赖链变化)的模块。模块级 `let` 变量在每次重新执行时被重置为初始值。
```typescript
// 修复前 — 每次 HMR 重新执行时 _db 重置为 null
let _db: SqliteDatabase | null = null;
export function getDbInstance() {
if (_db) return _db; // HMR 后这里永远 false
// ... 重新打开一个新的 DB 连接(旧连接泄漏)
}
```
**受影响的模块与泄漏类型:**
| 模块 | 泄漏资源 | 累计次数 | 后果 |
| ----------------------- | ---------------------- | -------- | ----------------------- |
| `db/core.ts` | SQLite 连接 | 485 | 文件句柄泄漏 + 内存占用 |
| `tokenHealthCheck.ts` | `setInterval` 定时器 | 586 | CPU 空转 + DB 查询风暴 |
| `localHealthCheck.ts` | `setTimeout` 定时器链 | ~400 | 重复 HTTP 请求 + CPU |
| `consoleInterceptor.ts` | console 方法包装 | ~400 | 日志 double-write |
| `gracefulShutdown.ts` | SIGTERM/SIGINT handler | ~400 | 信号处理器堆叠 |
**级联效应**:泄漏的资源持续消耗内存和 CPU → 触发 Next.js 内存阈值保护 → 进程重启 → Webpack 从零重建模块图 → **Ready in 82.6s**
### 根因 2P0):强制使用 Webpack 而非 Turbopack
`scripts/run-next.mjs` 中硬编码了 `--webpack` 标志:
```javascript
if (mode === "dev") {
args.splice(2, 0, "--webpack");
}
```
Next.js 16 默认使用 TurbopackRust 编写的增量打包器),dev 编译速度是 Webpack 的 5-10 倍。强制回退到 Webpack 导致:
| 指标 | Webpack | Turbopack(预期) |
| ----------------------- | ------- | ----------------- |
| 首页编译 | 3.7s | ~0.5s |
| Provider 详情页首次编译 | 22s | ~2-3s |
| API route 首次编译 | 2-7s | ~0.3-1s |
| 内存重启后 Ready | 82.6s | 不会触发 |
### 根因 3P1):`node:crypto` 被拉入客户端 bundle
`src/lib/db/proxies.ts` 使用了 `import { randomUUID } from "node:crypto"`。通过 `localDb.ts` 的 re-export 链,这个 Node.js 原生模块被间接拉入客户端组件的 bundle,导致 Webpack 报错:
```
UnhandledSchemeError: Reading from "node:crypto" is not handled by plugins
Import trace: node:crypto → ./src/lib/db/proxies.ts → ./src/lib/localDb.ts → page.tsx
```
Webpack 无法处理 `node:` URI scheme 前缀。`crypto`(不带 `node:` 前缀)已在 `next.config.mjs``serverExternalPackages` 中声明为服务端外部包。
### 根因 4P1):Edge Runtime 编译警告刷屏
Next.js 16 会同时为 **Node.js****Edge** 两种运行时编译 `instrumentation.ts`。虽然 `register()` 函数内有 `process.env.NEXT_RUNTIME === "nodejs"` 的运行时守卫,但 Turbopack 在打包 Edge 版本时仍会**静态追踪**所有动态 `import()` 的依赖链:
```
instrumentation.ts
→ import("@/lib/db/secrets")
@/lib/db/core.ts → fs, path, better-sqlite3
@/lib/dataPaths.ts → path, os
@/lib/db/migrationRunner.ts → fs, path, url
```
对每个 Node.js 原生模块,Turbopack 都输出一条 "not supported in Edge Runtime" 警告。每次有新请求触发热编译时,这组 **10+ 条警告重复刷一遍**,严重污染终端输出,干扰开发调试。
### 根因 5P2):启动 import 完全串行
`instrumentation.ts` 中 9 个 `await import()` 完全串行执行,每个都可能触发 Webpack 编译其依赖树:
```typescript
await ensureSecrets(); // 串行 1
const { initConsoleInterceptor } = await import(...); // 串行 2
const { initGracefulShutdown } = await import(...); // 串行 3
const { initApiBridgeServer } = await import(...); // 串行 4
const { startBackgroundRefresh } = await import(...); // 串行 5
const { getSettings } = await import(...); // 串行 6
const { setCustomAliases } = await import(...); // 串行 7
const { setDefaultFastServiceTierEnabled } = await import(...); // 串行 8
const { initAuditLog, cleanupExpiredLogs } = await import(...); // 串行 9
```
其中 4-6 互不依赖,7-8 互不依赖,完全可以并行。
---
## 三、修复方案
### 修复 1globalThis 单例守卫(core.ts, tokenHealthCheck.ts, localHealthCheck.ts, consoleInterceptor.ts, gracefulShutdown.ts
**原理**`globalThis` 对象在 Node.js 进程生命周期内全局唯一,不受 Webpack 模块重新执行的影响。
```typescript
// 修复后 — globalThis 在 HMR 后依然保留
declare global {
var __omnirouteDb: import("better-sqlite3").Database | undefined;
}
function getDb() {
return globalThis.__omnirouteDb ?? null;
}
function setDb(db) {
/* ... */
}
export function getDbInstance() {
const existing = getDb();
if (existing) return existing; // HMR 后命中缓存
// ...
}
```
**每个模块的具体改动:**
| 模块 | globalThis key | 守卫内容 |
| ----------------------- | ----------------------------------- | ----------------------------------------------------------- |
| `db/core.ts` | `__omnirouteDb` | SQLite 连接实例 |
| `tokenHealthCheck.ts` | `__omnirouteTokenHC` | `{ initialized, interval }` |
| `localHealthCheck.ts` | `__omnirouteLocalHC` | `{ initialized, sweepTimer, healthCache, sweepInProgress }` |
| `consoleInterceptor.ts` | `__omnirouteConsoleInterceptorInit` | `boolean` |
| `gracefulShutdown.ts` | `__omnirouteShutdownInit` | `boolean` |
**优点**
- 零依赖,无需额外库。
- 与 `apiBridgeServer.ts` 已有模式一致。
- 对生产环境零影响(非 HMR 场景下行为完全相同)。
**缺点/注意**
- `globalThis` 键名需全局唯一,使用 `__omniroute` 前缀避免冲突。
- 需要 `declare global` 类型声明以保持 TypeScript 类型安全。
- 生产构建中 `globalThis` 存储略冗余(但仅是一个对象引用,几乎零开销)。
### 修复 2:支持通过环境变量切换 Turbopackrun-next.mjs
```javascript
// 修复后 — 默认仍用 webpack(保持原有行为),设置环境变量可启用 Turbopack
if (mode === "dev" && process.env.OMNIROUTE_USE_TURBOPACK !== "1") {
args.splice(2, 0, "--webpack");
}
```
**默认行为不变**:dev 模式仍使用 Webpack,与修复前完全一致。设置 `OMNIROUTE_USE_TURBOPACK=1` 可切换到 Turbopack 以获得更快的 dev 编译速度。
**优点**
- 零风险:不改变任何人的现有体验。
- 需要时设置 `OMNIROUTE_USE_TURBOPACK=1` 即可获得 5-10 倍编译加速。
- `next.config.mjs` 中已有 `turbopack.resolveAlias` 配置,说明项目已在准备 Turbopack 迁移。
**缺点/注意**
- Turbopack 对某些 Webpack 特定配置(如自定义 externals 函数)的支持方式不同,启用前需测试兼容性。
- 默认走 Webpack 意味着不主动启用 Turbopack 的用户无法享受编译加速。
### 修复 3`node:crypto``crypto`proxies.ts, errorResponse.ts
```typescript
// 修复前
import { randomUUID } from "node:crypto";
// 修复后
import { randomUUID } from "crypto";
```
**优点**
- `crypto`(无 `node:` 前缀)已在 `next.config.mjs``serverExternalPackages` 列表中,Webpack/Turbopack 会正确将其标记为外部包。
- 消除 `UnhandledSchemeError` 构建失败。
- Node.js 中 `crypto``node:crypto` 解析到同一模块。
**缺点**
- 无。`crypto` 是 Node.js 内建模块,两种写法功能完全等价。
### 修复 4:分离 Edge/Node.js Instrumentationinstrumentation.ts → instrumentation-node.ts
**问题**`instrumentation.ts` 中所有 Node.js 逻辑(`ensureSecrets`、DB 初始化、审计日志等)虽然只在 `NEXT_RUNTIME === "nodejs"` 时执行,但 Turbopack 编译 Edge 版本时仍静态追踪其 import 链,对每个 `fs`/`path`/`os`/`better-sqlite3` 等原生模块输出警告。
**方案**:将所有 Node.js 专属逻辑提取到 `src/instrumentation-node.ts`,主文件通过**计算的 import 路径**引入,阻止 Turbopack 静态解析:
```typescript
// src/instrumentation.ts — 精简后仅 ~20 行
export async function register() {
if (process.env.NEXT_RUNTIME === "nodejs") {
// 拼接路径阻止 Turbopack 在 Edge 编译时静态解析模块依赖
const nodeMod = "./instrumentation-" + "node";
const { registerNodejs } = await import(nodeMod);
await registerNodejs();
}
}
```
```typescript
// src/instrumentation-node.ts — 包含全部 Node.js 启动逻辑
export async function registerNodejs(): Promise<void> {
await ensureSecrets();
// initConsoleInterceptor, initGracefulShutdown, initApiBridgeServer, ...
// (原 instrumentation.ts 的完整 Node.js 逻辑)
}
```
**关键技术**`"./instrumentation-" + "node"` 是运行时拼接的字符串,Turbopack 无法在编译期确定其值,因此**不会追踪**该 import 的依赖树。Node.js 运行时则正常解析该路径并执行。
**优点**
- Edge 编译时完全跳过 Node.js 模块追踪,**10+ 条重复警告全部消除**。
- Node.js 运行时行为与修复前完全一致。
- 启动时间从 **13.9s → 1.25s**Turbopack 不再在 Edge 编译中处理 Node.js 模块图)。
**缺点/注意**
- 新增一个文件 `instrumentation-node.ts`,需同步维护。
- 计算 import 路径是有意为之的 bundler 逃逸技巧,需加注释说明原因防止后续重构时被"优化"回静态字符串。
### 修复 5:并行化 instrumentation.ts 中的启动 import
```typescript
// 修复后 — 4 个独立模块并行导入
const [
{ initGracefulShutdown },
{ initApiBridgeServer },
{ startBackgroundRefresh },
{ getSettings },
] = await Promise.all([
import("@/lib/gracefulShutdown"),
import("@/lib/apiBridgeServer"),
import("@/domain/quotaCache"),
import("@/lib/db/settings"),
]);
// 2 个 open-sse 模块也并行导入
const [{ setCustomAliases }, { setDefaultFastServiceTierEnabled }] = await Promise.all([
import("@omniroute/open-sse/services/modelDeprecation.ts"),
import("@omniroute/open-sse/executors/codex.ts"),
]);
```
**优点**
- `consoleInterceptor` 仍保持第一个(必须在任何日志前初始化)。
- 后续 4 个无依赖模块并行加载,节省 3 次串行等待。
- open-sse 的 2 个模块也并行加载。
**缺点**
- 并行 import 的错误堆栈略复杂(Promise.all 中某一个失败会 reject 整个组)。
- 这里的 compliance 模块仍保持独立 try/catch 串行,因为它有自己的错误处理逻辑。
---
## 四、预期效果
| 指标 | 修复前 | 修复后(预期) |
| ----------------------------- | ------------------------- | ------------------------ |
| DB 连接创建次数 | 485 次/会话 | 1 次 |
| HealthCheck 定时器 | 586 个泄漏 | 1 个 |
| 信号处理器注册 | ~400 次重复 | 1 次 |
| Console 拦截层数 | ~400 层嵌套 | 1 层 |
| 内存使用峰值 | 2.4 GB → OOM 重启 | 预期 < 500 MB |
| 冷启动 Ready | 3.4s | ~3s(略快) |
| 内存重启 Ready | 82.6s | 不再触发内存重启 |
| Login 页首次编译 | 3.7s | ~0.5s (需启用 Turbopack) |
| Provider 详情页首次编译 | 22s | ~2-3s (需启用 Turbopack) |
| `node:crypto` 构建错误 | 反复出现 | 消除 |
| Edge Runtime 编译警告 | 每次热编译刷出 10+ 条 | **0 条** |
| instrumentation 启动耗时 | 13.9s(含 Edge 模块追踪) | **1.25s** |
| instrumentation import 并行度 | 9 次串行 import | 3 批并行 import |
---
## 五、涉及文件清单
| 区域 | 文件 | 改动类型 |
| ------------------- | ------------------------------- | ------------------------------------------------------------------ |
| DB 单例 | `src/lib/db/core.ts` | `let _db``globalThis.__omnirouteDb` |
| Token 健康检查 | `src/lib/tokenHealthCheck.ts` | `let initialized``globalThis.__omnirouteTokenHC` |
| 本地节点健康检查 | `src/lib/localHealthCheck.ts` | `let initialized``globalThis.__omnirouteLocalHC` |
| Console 拦截 | `src/lib/consoleInterceptor.ts` | `let initialized``globalThis.__omnirouteConsoleInterceptorInit` |
| 优雅关停 | `src/lib/gracefulShutdown.ts` | 新增 `globalThis.__omnirouteShutdownInit` 守卫 |
| Dev 启动脚本 | `scripts/run-next.mjs` | 新增 `OMNIROUTE_USE_TURBOPACK=1` 开关 |
| Proxy 注册表 | `src/lib/db/proxies.ts` | `node:crypto``crypto` |
| API 错误响应 | `src/lib/api/errorResponse.ts` | `node:crypto``crypto` |
| 启动钩子(主入口) | `src/instrumentation.ts` | 精简为 ~20 行,计算 import 路径阻止 Edge 追踪 |
| 启动钩子(Node.js | `src/instrumentation-node.ts` | 新文件,承载全部 Node.js 启动逻辑 + `Promise.all` 并行 |
---
## 六、回退方案
- **启用 Turbopack**:设置 `OMNIROUTE_USE_TURBOPACK=1` 环境变量;不设置则默认使用 Webpack(原有行为不变)。
- **globalThis 方案异常**:所有 globalThis key 都以 `__omniroute` 为前缀,可通过 `delete globalThis.__omnirouteDb` 等方式手动重置。
- **Edge 警告回退**:若 `instrumentation-node.ts` 拆分导致问题,可将其内容合并回 `instrumentation.ts`,恢复为直接 `import()` 调用(警告会重新出现但不影响功能)。
- **生产环境**:以上修复对生产构建无负面影响——生产环境不存在 HMR,globalThis 单例仅在首次调用时初始化一次。计算 import 路径在 `next build` 时由 Node.js 正常解析,不影响打包产物。
---
## 七、单元测试与备份恢复(pre-commit 验证通过)
为保证提交前必须通过验证(不再使用 `--no-verify`),对以下失败用例与生产逻辑做了修复与加固。
### 问题与根因
| 失败项 | 根因 |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| bootstrap-env 4 个用例 | Windows 上 DATA_DIR 解析用 `APPDATA`/`homedir()`,测试只设了 `HOME`,脚本读不到测试用的 `.env`。 |
| domain-persistence costRules 2 个用例 | `core` 在首次 import 时缓存 `DATA_DIR`;测试每测一个 tmpDir 并在 afterEach 删目录,导致后续 describe 使用的 DB 路径已被删,读写得到 0。 |
| fixes-p1 restoreDbBackup | 测试在 DB 仍打开时写 stale 侧文件;`restoreDbBackup` 内 pre-restore 备份未 await 就关库,Windows 上句柄未及时释放,unlink 报 EBUSY。 |
| fixes-p1 resetStorage 及后续用例 | 上一测留下 DB 打开,下一测 `resetStorage()` 删目录时文件仍被占用,EBUSY。 |
### 修复 6bootstrap-env 测试(tests/unit/bootstrap-env.test.mjs
在每个用例的 `withTempEnv` 回调开头增加 `process.env.DATA_DIR = dataDir`,使脚本在任意平台(含 Windows)都使用测试临时目录,而不是依赖 `HOME`/`APPDATA`
### 修复 7domain-persistence 测试(tests/unit/domain-persistence.test.mjs
- **单例 tmpDir**:全文件共用一个 `fileTmpDir`,在模块加载时创建并设置 `process.env.DATA_DIR`,与 `core` 首次加载时缓存的路径一致。
- **每测清 DB 不清目录**`beforeEach``resetDbInstance()` 后删除 `storage.sqlite` 及其 `-wal`/`-shm`/`-journal`,保证每测干净 DB,不在 afterEach 删目录,避免路径失效。
- **收尾**`after()` 中恢复 `DATA_DIR` 并删除 `fileTmpDir`
- **costRules 断言**:改为小容差精确校验(`assertAlmostEqual`),继续验证 `4.5` / `4.0` 这类业务关键值,避免把真实累计错误放过去。
### 修复 8fixes-p1 测试(tests/unit/fixes-p1.test.mjs
- **restoreDbBackup 用例**:在写入 stale 侧文件前调用 `core.resetDbInstance()`,避免 DB 仍打开时写 `-wal`/`-shm` 触发 Windows 锁错误。
- **Windows 跳过**:该用例在 Windows 上仍使用 `test(..., { skip: isWindows })`。原因不是业务逻辑不支持 Windows,而是 better-sqlite3 关闭后底层句柄释放存在时序抖动,这条真实 sidecar 集成测试容易退化成不稳定的文件锁测试;Linux/macOS 上照常运行。
- **核心兜底测试**:新增平台无关的 `unlinkFileWithRetry` 单测,直接模拟 `EBUSY` / `EPERM` 后重试并最终成功,确保 Windows 相关的重试删除逻辑被稳定覆盖,而不是完全依赖 flaky 的真实文件锁时序。
- **resetStorage**:改为 async,对 `rmSync(TEST_DATA_DIR)` 做最多 10 次、间隔 100ms 的 EBUSY/EPERM 重试,避免下一测因上一测句柄未释放而失败。
### 修复 9:备份恢复逻辑(src/lib/db/backup.ts
- **pre-restore 备份改为同步等待**:在 `restoreDbBackup` 内用内联逻辑做 pre-restore 备份并 `await` 完成,再调用 `resetDbInstance()`,避免异步 backup 未结束就关库导致后续 unlink 失败。
- **节流语义保持一致**pre-restore 备份成功后补回 `_lastBackupAt = Date.now()`,避免恢复后紧接着又触发一轮额外自动备份。
- **关库后短延迟**`resetDbInstance()``await new Promise(r => setTimeout(r, 500))`,再执行 unlink,给 Windows 等平台释放句柄留时间。
- **unlink 重试**:将主库及 `-wal`/`-shm`/`-journal` 的删除提取为 `unlinkFileWithRetry`,统一做最多 10 次、间隔 100ms 的 EBUSY/EPERM 重试,提高恢复流程在锁释放较慢环境下的成功率,也便于单测直接覆盖重试逻辑。
### 涉及文件(本节)
| 区域 | 文件 | 改动类型 |
| -------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| 单元测试 | `tests/unit/bootstrap-env.test.mjs` | 各用例内设置 `process.env.DATA_DIR = dataDir` |
| 单元测试 | `tests/unit/domain-persistence.test.mjs` | 单例 tmpDir、beforeEach 清 DB 文件、after 删目录;costRules 改为小容差精确断言 |
| 单元测试 | `tests/unit/fixes-p1.test.mjs` | restoreDbBackup 前 resetDbInstance、Windows skip 说明、resetStorage 重试、`unlinkFileWithRetry` 核心单测 |
| 备份恢复 | `src/lib/db/backup.ts` | pre-restore 内联并 await、恢复 `_lastBackupAt` 节流语义、关库后 500ms 延迟、抽取 `unlinkFileWithRetry` 重试删除 |
-332
View File
@@ -1,332 +0,0 @@
# ZWS_README_V5 — 按协议配置模型兼容性 + 前端性能优化
V4 内容(HMR 泄漏修复、Edge 警告消除、测试稳定性)已完成;V5 在 V4 基础上实现**按协议维度配置模型兼容性**,新增前端查找性能优化与类型安全改进。
---
## 一、如何发现问题
### 现象
- 同一模型被 **OpenAI Chat Completions**、**OpenAI Responses API**、**Anthropic Messages** 三种客户端请求形态调用时,V2 的兼容性开关(工具 ID 9 位、不保留 developer 角色)是**全局生效**的——无法为不同协议设置不同的兼容策略。
- 例如:用户希望 OpenAI Responses API 请求时不保留 developer 角色(MiniMax 422 修复),但 OpenAI Chat Completions 请求时保留。V2 下只能二选一。
- 前端兼容性弹层未标明当前配置对应哪种协议,容易误导。
- 前端组件中 `Array.find()` 在每次渲染时对 customModels 和 modelCompatOverrides 做 O(n) 线性扫描,模型数量多时存在不必要的性能开销。
- `ModelCompatPatch` 类型定义与运行时逻辑不一致:`preserveOpenAIDeveloperRole` 字段需要支持 `null`(表示取消设置/恢复默认),但类型仅允许 `boolean`
### 排查过程
1. **需求分析**:梳理 `detectFormat(body)` 返回的三种协议键(`openai``openai-responses``claude`),确认每种协议对 developer 角色和 tool call ID 的需求不同。
2. **数据模型设计**:在现有 `normalizeToolCallId` / `preserveOpenAIDeveloperRole` 顶层字段基础上,设计 `compatByProtocol` 嵌套结构,按协议键细分。
3. **构建问题**:客户端 `"use client"` 组件直接从 `@/lib/localDb` 引入常量时,间接拉入了 `node:crypto`(经由 `db/proxies.ts`),触发 Webpack `UnhandledSchemeError`。需将常量拆到 `shared/` 层。
4. **前端性能**:通过 React DevTools 和代码审计发现 `effectiveNormalizeForProtocol` 等函数每次调用都对数组做 `find()`,在渲染列表时存在 O(n²) 的隐患。
---
## 二、根因分析
### 根因 1(P0):兼容选项无协议维度
V2 的 `normalizeToolCallId` / `preserveOpenAIDeveloperRole` 存储在模型级别的顶层字段,无法区分请求来源协议。`chatCore.ts` 中的 getter 函数只接收 `(providerId, modelId)` 两个参数,不感知当前请求的 `sourceFormat`
**影响**:跨协议场景下用户只能设置一个全局值,无法精确控制。
### 根因 2P1):客户端构建拉入 Node.js 模块
`page.tsx`"use client")→ `@/lib/localDb``db/proxies.ts``import { randomUUID } from "node:crypto"`
Webpack 无法处理 `node:` URI scheme,报 `UnhandledSchemeError`。虽然 V4 已将 `node:crypto``crypto` 修复了 `proxies.ts`,但 `localDb.ts` 的 barrel export 链仍然存在风险——客户端组件不应引入任何可能传递到 Node.js 模块的路径。
### 根因 3P2):前端查找性能
`effectiveNormalizeForProtocol``effectivePreserveForProtocol``anyNormalizeCompatBadge``anyNoPreserveCompatBadge` 四个函数每次调用都使用 `Array.find()``customModels``modelCompatOverrides` 数组中查找目标模型。在模型列表渲染时,每个模型行会调用多次这些函数,导致 O(n × m) 的查找开销(n = 模型数,m = 每行调用次数)。
### 根因 4(P2):类型定义与运行时不一致
```typescript
// V3 暂存区版本(有问题)
export type ModelCompatPatch = Partial<
Pick<
ModelCompatOverride,
"normalizeToolCallId" | "preserveOpenAIDeveloperRole" | "compatByProtocol"
>
>;
```
`ModelCompatOverride.preserveOpenAIDeveloperRole` 类型为 `boolean | undefined`,但 `mergeModelCompatOverride()` 内部有 `=== null` 判断(用于取消设置/恢复默认),类型层面无法覆盖。
---
## 三、修复方案
### 修复 1`compatByProtocol` 存储与读取(models.ts
**新增数据结构**
```typescript
type CompatByProtocolMap = Partial<Record<ModelCompatProtocolKey, ModelCompatPerProtocol>>;
export type ModelCompatOverride = {
id: string;
normalizeToolCallId?: boolean;
preserveOpenAIDeveloperRole?: boolean;
compatByProtocol?: CompatByProtocolMap; // 新增
};
```
**读取优先级链**(适用于 `getModelNormalizeToolCallId``getModelPreserveOpenAIDeveloperRole`):
```
compatByProtocol[sourceFormat].field → 顶层 field → 默认值
```
1. 若 `sourceFormat` 属于已知协议键(`openai` / `openai-responses` / `claude`),且 `compatByProtocol[sourceFormat]` 中存在目标字段,使用该值。
2. 否则回退到顶层字段。
3. 顶层字段也不存在时使用默认值(normalizeToolCallId=falsepreserveOpenAIDeveloperRole=undefined)。
**深度合并逻辑** `deepMergeCompatByProtocol()`
- 对每个协议键,逐字段合并而非覆盖。
- `normalizeToolCallId=false` 时删除该字段(不存储 false,减少冗余)。
- 合并后若整个协议条目为空对象,删除该协议条目。
- 协议键通过 `isCompatProtocolKey()` 白名单校验,拒绝未知键。
**Getter 签名扩展**(向后兼容,第三参数可选):
```typescript
export function getModelNormalizeToolCallId(
providerId: string,
modelId: string,
sourceFormat?: string | null
): boolean;
export function getModelPreserveOpenAIDeveloperRole(
providerId: string,
modelId: string,
sourceFormat?: string | null
): boolean | undefined;
```
**优点**
- 完全向后兼容:无 `sourceFormat` 参数时行为与 V2 完全一致。
- 协议键白名单校验防止存储污染。
- 深度合并保留未变更协议的配置。
**缺点/注意**
- JSON 存储体积略增(每个模型最多增加 3 个协议条目)。
- 新增 ~80 行 TypeScript 代码。
### 修复 2:请求管线传入 sourceFormatchatCore.ts
```typescript
const normalizeToolCallId = getModelNormalizeToolCallId(
provider || "",
model || "",
sourceFormat // 新增第三参
);
const preserveDeveloperRole = getModelPreserveOpenAIDeveloperRole(
provider || "",
model || "",
sourceFormat // 新增第三参
);
```
`sourceFormat` 由已有的 `detectFormat(body)` 返回,无需新增检测逻辑。
**优点**
- 改动仅 2 行,精准传参。
- 不影响其他 handlerembeddings、imageGeneration 等不涉及 developer 角色和 tool call ID)。
### 修复 3API 路由支持 compatByProtocolroute.ts
**PUT 请求体扩展**
- 解构 `compatByProtocol` 并传入 `updateCustomModel()`
- `compatOnly` 判断扩展:仅含 `provider` + `modelId` + 兼容字段时,走 `mergeModelCompatOverride()` 路径。
- 使用 `ModelCompatPatch` 类型替代行内类型定义,统一类型来源。
**Zod 校验 schema**
```typescript
const modelCompatPerProtocolSchema = z.object({
normalizeToolCallId: z.boolean().optional(),
preserveOpenAIDeveloperRole: z.boolean().optional(),
}).strict(); // strict: 拒绝额外字段
compatByProtocol: z
.record(z.enum(["openai", "openai-responses", "claude"]), modelCompatPerProtocolSchema)
.optional(),
```
**优点**
- `.strict()` 防止客户端注入额外字段。
- `z.enum()` 限定协议键,与后端白名单一致。
- 仅传 `compatByProtocol` 即可更新,前端无需拼装完整模型对象。
### 修复 4:客户端安全常量拆分(modelCompat.ts
**新增** `src/shared/constants/modelCompat.ts`
```typescript
export const MODEL_COMPAT_PROTOCOL_KEYS = ["openai", "openai-responses", "claude"] as const;
export type ModelCompatProtocolKey = (typeof MODEL_COMPAT_PROTOCOL_KEYS)[number];
```
- 不依赖 Node.js / DB 代码,客户端组件可安全引入。
- `models.ts` 从此模块引入并再导出。
- `localDb.ts` 新增 `ModelCompatPatch` 类型导出(供 route.ts 使用),不导出协议常量。
- `page.tsx` 改为从 `@/shared/constants/modelCompat` 引入。
**优点**
- 彻底切断客户端 → localDb → db → proxies → node:crypto 的依赖链。
- 协议键定义单一来源(Single Source of Truth)。
### 修复 5:前端协议选择器与按协议解析(page.tsx)
**ModelCompatPopover 重构**
- 新增协议下拉选择器(`<select>`),可选 OpenAI Chat / OpenAI Responses / Anthropic Messages。
- 两个开关(工具 ID 9 位、不保留 developer**针对选中协议**生效。
- 选择 Claude 协议时隐藏 developer 角色开关(developer 仅对 OpenAI 系有意义)。
- 保存时以 `{ compatByProtocol: { [protocol]: payload } }` 形式提交,后端按协议合并。
- 深色模式适配:下拉框使用 `bg-white dark:bg-zinc-800``text-zinc-900 dark:text-zinc-100`
**Props 接口重构**
旧接口(4 个独立值/回调):
```typescript
(normalizeToolCallId, preserveDeveloperRole, onNormalizeChange, onPreserveChange);
```
新接口(3 个函数式 props):
```typescript
effectiveModelNormalize: (protocol: string) => boolean
effectiveModelPreserveDeveloper: (protocol: string) => boolean
onCompatPatch: (protocol: string, payload: {...}) => void
```
所有消费方(`ModelRow``PassthroughModelRow``CustomModelsSection``CompatibleModelsSection`)已同步更新。
**角标显示逻辑**
- `anyNormalizeCompatBadge()`:任意协议或顶层存在 `normalizeToolCallId=true` 即显示「ID×9」角标。
- `anyNoPreserveCompatBadge()`:任意协议或顶层存在 `preserveOpenAIDeveloperRole=false` 即显示「不保留」角标。
**CustomModelsSection 增强**
- 新增 `modelCompatOverrides` 状态,从 API 响应中获取。
- 新增 `saveCustomCompat()` 函数,支持仅传 `compatByProtocol` 的独立保存。
### 修复 6:前端 Map 查找性能优化(page.tsx
**问题**`effectiveNormalizeForProtocol` 等函数对 `customModels``modelCompatOverrides``Array.find()` 做 O(n) 查找,在列表渲染时每个模型行多次调用。
**方案**:使用 `useMemo` + `Map` 将数组预建为 O(1) 查找表。
```typescript
type CompatModelMap = Map<string, CompatModelRow>;
function buildCompatMap(rows: CompatModelRow[]): CompatModelMap {
const m = new Map<string, CompatModelRow>();
for (const r of rows) if (r.id) m.set(r.id, r);
return m;
}
// 在组件内
const customMap = useMemo(() => buildCompatMap(modelMeta.customModels), [modelMeta.customModels]);
const overrideMap = useMemo(
() => buildCompatMap(modelMeta.modelCompatOverrides),
[modelMeta.modelCompatOverrides]
);
```
所有查找函数签名从 `(modelId, protocol, customModels[], overrides[])` 改为 `(modelId, protocol, customMap, overrideMap)`,内部使用 `Map.get()` 替代 `Array.find()`
**优点**
- 查找从 O(n) 降为 O(1)。
- `useMemo` 依赖项正确,仅在数据变化时重建 Map。
- `CustomModelsSection` 内部也独立构建 Map,不依赖父组件。
### 修复 7ModelCompatPatch 类型修正(models.ts
```typescript
// 修复后 — 显式允许 null
export type ModelCompatPatch = {
normalizeToolCallId?: boolean;
preserveOpenAIDeveloperRole?: boolean | null; // null = 取消设置/恢复默认
compatByProtocol?: CompatByProtocolMap;
};
```
`mergeModelCompatOverride()` 内的 `=== null` 判断逻辑一致,类型安全。
### 修复 8CompatByProtocolMap 类型收紧(page.tsx
客户端 `CompatByProtocolMap``Record<string, ...>` 改为 `Record<ModelCompatProtocolKey, ...>`,增强类型安全,防止传入未知协议键。
### 修复 9i18n 文案新增
| 键名 | 中文 | 英文 |
| ------------------------------- | --------------------------------------------- | -------------------------------------------------------------- |
| `compatProtocolLabel` | 客户端请求协议 | Client request protocol |
| `compatProtocolHint` | 以下选项在 OmniRoute 识别到该请求形态时生效。 | These options apply when OmniRoute detects this request shape. |
| `compatProtocolOpenAI` | OpenAI Chat Completions | OpenAI Chat Completions |
| `compatProtocolOpenAIResponses` | OpenAI Responses API | OpenAI Responses API |
| `compatProtocolClaude` | Anthropic Messages | Anthropic Messages |
---
## 四、使用方式
1. 点击模型行的 **「兼容性」** 按钮。
2. 在弹层内先选择 **「客户端请求协议」**OpenAI Chat / OpenAI Responses / Anthropic Messages)。
3. 勾选该协议下的「工具 ID 9 位」或「不保留 developer 角色」。
4. 保存后,仅在该协议形态的请求下生效。
5. 未配置某协议时,该协议下行为回退到顶层兼容字段(若存在),再回退到默认值(保留 developer、不规范化 tool id)。
6. 角标「ID×9」「不保留」在任意协议存在对应配置时显示。
---
## 五、预期效果
| 指标 | 修复前 | 修复后 |
| ------------------------- | --------------------- | ------------------------------------------ |
| 兼容性配置维度 | 全局(模型级) | 按协议(OpenAI Chat / Responses / Claude |
| developer 角色精确控制 | 不支持 | 支持(如:仅 Responses API 不保留) |
| 前端兼容性查找性能 | O(n) Array.find | O(1) Map.getuseMemo 缓存) |
| ModelCompatPatch 类型安全 | null 值无类型覆盖 | 显式 `boolean \| null` |
| 客户端构建风险 | 可能引入 Node.js 模块 | 已隔离(shared/constants 层) |
| API 验证 | 无 compatByProtocol | Zod strict schema 校验 |
| 深色模式 | 协议选择器不可读 | bg/text 适配 dark 主题 |
---
## 六、涉及文件清单
| 区域 | 文件 | 改动类型 |
| ---------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| 协议常量 | `src/shared/constants/modelCompat.ts` | **新建**,客户端安全的协议键与类型 |
| 存储与读写 | `src/lib/db/models.ts` | `compatByProtocol` 数据结构、深度合并、getter 第三参 `sourceFormat``ModelCompatPatch` 类型修正 |
| 再导出层 | `src/lib/localDb.ts` | 新增 `ModelCompatPatch` 类型导出 |
| API 路由 | `src/app/api/provider-models/route.ts` | PUT 支持 `compatByProtocol`,使用 `ModelCompatPatch` 类型 |
| 输入校验 | `src/shared/validation/schemas.ts` | `modelCompatPerProtocolSchema`strict+ `compatByProtocol` 记录校验 |
| 请求管线 | `open-sse/handlers/chatCore.ts` | `getModelNormalizeToolCallId` / `getModelPreserveOpenAIDeveloperRole` 传入 `sourceFormat` |
| 前端 UI | `src/app/(dashboard)/dashboard/providers/[id]/page.tsx` | 协议选择器、按协议解析/保存、角标逻辑、Map 性能优化、类型收紧 |
| i18n | `src/i18n/messages/en.json``src/i18n/messages/zh-CN.json` | 5 条新文案 |
---
## 七、回退方案
- **禁用按协议配置**:删除 `compatByProtocol` 字段后,getter 自动回退到顶层字段,行为与 V2 一致。
- **前端 Map 优化回退**:将 `Map.get()` 改回 `Array.find()` 即可,纯性能优化无功能耦合。
- **客户端常量回退**:将 `MODEL_COMPAT_PROTOCOL_KEYS` 定义移回 `models.ts` 并从 `localDb.ts` 导出(需同时确保 `node:crypto` 问题不再存在)。
- **生产环境**:以上修复对生产构建无负面影响。`compatByProtocol` 为可选字段,未配置时默认行为不变。API Zod 校验确保不会接受畸形数据。
+2 -4
View File
@@ -116,10 +116,8 @@ if (args.includes("--help") || args.includes("-h")) {
if (args.includes("--version") || args.includes("-v")) {
try {
const pkg = await import(join(ROOT, "package.json"), {
with: { type: "json" },
});
console.log(pkg.default.version);
const { version } = JSON.parse(readFileSync(join(ROOT, "package.json"), "utf8"));
console.log(version);
} catch {
console.log("unknown");
}
+1 -1
View File
@@ -16,7 +16,7 @@ services:
container_name: omniroute-prod
build:
context: .
target: runner-base
target: runner-cli
image: omniroute:prod
restart: unless-stopped
env_file: .env
+6 -6
View File
@@ -142,10 +142,10 @@ The provider prefix is auto-added if missing. Mismatched models return `400`.
```bash
# Get cache stats
GET /api/cache
GET /api/cache/stats
# Clear all caches
DELETE /api/cache
DELETE /api/cache/stats
```
Response example:
@@ -218,7 +218,7 @@ Response example:
| Endpoint | Method | Description |
| ------------------------------- | ------- | ---------------------- |
| `/api/settings` | GET/PUT | General settings |
| `/api/settings` | GET/PUT/PATCH | General settings |
| `/api/settings/proxy` | GET/PUT | Network proxy config |
| `/api/settings/proxy/test` | POST | Test proxy connection |
| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist |
@@ -231,8 +231,8 @@ Response example:
| ------------------------ | ---------- | ----------------------- |
| `/api/sessions` | GET | Active session tracking |
| `/api/rate-limits` | GET | Per-account rate limits |
| `/api/monitoring/health` | GET | Health check |
| `/api/cache` | GET/DELETE | Cache stats / clear |
| `/api/monitoring/health` | GET | Health check + provider summary (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`) |
| `/api/cache/stats` | GET/DELETE | Cache stats / clear |
### Backup & Export/Import
@@ -279,7 +279,7 @@ GET response includes `agents[]` (id, name, binary, version, installed, protocol
| Endpoint | Method | Description |
| ----------------------- | ------- | ------------------------------- |
| `/api/resilience` | GET/PUT | Get/update resilience profiles |
| `/api/resilience` | GET/PATCH | Get/update resilience profiles |
| `/api/resilience/reset` | POST | Reset circuit breakers |
| `/api/rate-limits` | GET | Per-account rate limit status |
| `/api/rate-limit` | GET | Global rate limit configuration |
+21 -1
View File
@@ -2,7 +2,7 @@
🌐 **Languages:** 🇺🇸 [English](ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](i18n/es/ARCHITECTURE.md) | 🇫🇷 [Français](i18n/fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](i18n/it/ARCHITECTURE.md) | 🇷🇺 [Русский](i18n/ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](i18n/de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](i18n/in/ARCHITECTURE.md) | 🇹🇭 [ไทย](i18n/th/ARCHITECTURE.md) | 🇺🇦 [Українська](i18n/uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](i18n/ar/ARCHITECTURE.md) | 🇯🇵 [日本語](i18n/ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/ARCHITECTURE.md) | 🇧🇬 [Български](i18n/bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](i18n/da/ARCHITECTURE.md) | 🇫🇮 [Suomi](i18n/fi/ARCHITECTURE.md) | 🇮🇱 [עברית](i18n/he/ARCHITECTURE.md) | 🇭🇺 [Magyar](i18n/hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/ARCHITECTURE.md) | 🇰🇷 [한국어](i18n/ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](i18n/nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](i18n/no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/ARCHITECTURE.md) | 🇷🇴 [Română](i18n/ro/ARCHITECTURE.md) | 🇵🇱 [Polski](i18n/pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](i18n/sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](i18n/sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](i18n/phi/ARCHITECTURE.md) | 🇨🇿 [Čeština](i18n/cs/ARCHITECTURE.md)
_Last updated: 2026-03-04_
_Last updated: 2026-03-24_
## Executive Summary
@@ -65,6 +65,26 @@ Primary runtime model:
- Provider SLA/control plane outside local process
- External CLI binaries themselves (Claude CLI, Codex CLI, etc.)
## Dashboard Surface (Current)
Main pages under `src/app/(dashboard)/dashboard/`:
- `/dashboard` — quick start + provider overview
- `/dashboard/endpoint` — endpoint proxy + MCP + A2A + API endpoint tabs
- `/dashboard/providers` — provider connections and credentials
- `/dashboard/combos` — combo strategies, templates, model routing rules
- `/dashboard/costs` — cost aggregation and pricing visibility
- `/dashboard/analytics` — usage analytics and evaluations
- `/dashboard/limits` — quota/rate controls
- `/dashboard/cli-tools` — CLI onboarding, runtime detection, config generation
- `/dashboard/agents` — detected ACP agents + custom agent registration
- `/dashboard/media` — image/video/music playground
- `/dashboard/search-tools` — search provider testing and history
- `/dashboard/health` — uptime, circuit breakers, rate limits
- `/dashboard/logs` — request/proxy/audit/console logs
- `/dashboard/settings` — system settings tabs (general, routing, combo defaults, etc.)
- `/dashboard/api-manager` — API key lifecycle and model permissions
## High-Level System Context
```mermaid
+35 -38
View File
@@ -9,7 +9,7 @@ cost tracking, model switching, and request logging across every tool.
## How It Works
```
Claude / Codex / Gemini CLI / OpenCode / Cline / KiloCode / Continue / Kiro CLI
Claude / Codex / OpenCode / Cline / KiloCode / Continue / Kiro / Cursor / Copilot
▼ (all point to OmniRoute)
http://YOUR_SERVER:20128/v1
@@ -27,21 +27,38 @@ Claude / Codex / Gemini CLI / OpenCode / Cline / KiloCode / Continue / Kiro CLI
---
## Supported Tools
## Supported Tools (Dashboard Source of Truth)
| Tool | Command | Type | Install Method |
| ---------------- | ------------------- | ----------------- | -------------- |
| **Claude Code** | `claude` | CLI | npm |
| **OpenAI Codex** | `codex` | CLI | npm |
| **Gemini CLI** | `gemini` | CLI | npm |
| **OpenCode** | `opencode` | CLI | npm |
| **Cline** | `cline` | CLI + VS Code ext | npm |
| **KiloCode** | `kilocode` / `kilo` | CLI + VS Code ext | npm |
| **Continue** | guide-based | VS Code ext | VS Code |
| **Kiro CLI** | `kiro-cli` | CLI | curl installer |
| **Cursor** | `cursor` | Desktop app | Download |
| **Droid** | web-based | Built-in agent | OmniRoute |
| **OpenClaw** | web-based | Built-in agent | OmniRoute |
The dashboard cards in `/dashboard/cli-tools` are generated from `src/shared/constants/cliTools.ts`.
Current list (v3.0.0-rc.16):
| Tool | ID | Command | Setup Mode | Install Method |
| ---------------- | ------------- | ------------ | ---------- | -------------- |
| **Claude Code** | `claude` | `claude` | env | npm |
| **OpenAI Codex** | `codex` | `codex` | custom | npm |
| **Factory Droid**| `droid` | `droid` | custom | bundled/CLI |
| **OpenClaw** | `openclaw` | `openclaw` | custom | bundled/CLI |
| **Cursor** | `cursor` | app | guide | desktop app |
| **Cline** | `cline` | `cline` | custom | npm |
| **Kilo Code** | `kilo` | `kilocode` | custom | npm |
| **Continue** | `continue` | extension | guide | VS Code |
| **Antigravity** | `antigravity` | internal | mitm | OmniRoute |
| **GitHub Copilot**| `copilot` | extension | custom | VS Code |
| **OpenCode** | `opencode` | `opencode` | guide | npm |
| **Kiro AI** | `kiro` | app/cli | mitm | desktop/CLI |
### CLI fingerprint sync (Agents + Settings)
`/dashboard/agents` and `Settings > CLI Fingerprint` use `src/shared/constants/cliCompatProviders.ts`.
This keeps provider IDs aligned with CLI cards and legacy IDs.
| CLI ID | Fingerprint Provider ID |
| ------ | ----------------------- |
| `kilo` | `kilocode` |
| `copilot` | `github` |
| `claude` / `codex` / `antigravity` / `kiro` / `cursor` / `cline` / `opencode` / `droid` / `openclaw` | same ID |
Legacy IDs still accepted for compatibility: `copilot`, `kimi-coding`, `qwen`.
---
@@ -67,9 +84,6 @@ npm install -g @anthropic-ai/claude-code
# OpenAI Codex
npm install -g @openai/codex
# Gemini CLI (Google)
npm install -g @google/gemini-cli
# OpenCode
npm install -g opencode-ai
@@ -77,7 +91,7 @@ npm install -g opencode-ai
npm install -g cline
# KiloCode
npm install -g kilecode
npm install -g kilocode
# Kiro CLI (Amazon — requires curl + unzip)
apt-get install -y unzip # on Debian/Ubuntu
@@ -90,7 +104,6 @@ export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
```bash
claude --version # 2.x.x
codex --version # 0.x.x
gemini --version # 0.x.x
opencode --version # x.x.x
cline --version # 2.x.x
kilocode --version # x.x.x (or: kilo --version)
@@ -153,21 +166,6 @@ EOF
---
### Gemini CLI
```bash
mkdir -p ~/.gemini && cat > ~/.gemini/settings.json << EOF
{
"apiKey": "sk-your-omniroute-key",
"baseUrl": "http://localhost:20128/v1"
}
EOF
```
**Test:** `gemini "hello"`
---
### OpenCode
```bash
@@ -324,17 +322,16 @@ They run as internal routes and use OmniRoute's model routing automatically.
OMNIROUTE_URL="http://localhost:20128/v1"
OMNIROUTE_KEY="sk-your-omniroute-key"
npm install -g @anthropic-ai/claude-code @openai/codex @google/gemini-cli opencode-ai cline kilecode
npm install -g @anthropic-ai/claude-code @openai/codex opencode-ai cline kilocode
# Kiro CLI
apt-get install -y unzip 2>/dev/null; curl -fsSL https://cli.kiro.dev/install | bash
# Write configs
mkdir -p ~/.claude ~/.codex ~/.gemini ~/.config/opencode ~/.continue
mkdir -p ~/.claude ~/.codex ~/.config/opencode ~/.continue
cat > ~/.claude/settings.json <<< "{\"apiBaseUrl\":\"$OMNIROUTE_URL\",\"apiKey\":\"$OMNIROUTE_KEY\"}"
cat > ~/.codex/config.yaml <<< "model: auto\napiKey: $OMNIROUTE_KEY\napiBaseUrl: $OMNIROUTE_URL"
cat > ~/.gemini/settings.json <<< "{\"apiKey\":\"$OMNIROUTE_KEY\",\"baseUrl\":\"$OMNIROUTE_URL\"}"
cat >> ~/.bashrc << EOF
export OPENAI_BASE_URL="$OMNIROUTE_URL"
export OPENAI_API_KEY="$OMNIROUTE_KEY"
+32 -67
View File
@@ -8,73 +8,6 @@ _وكيل API العالمي الخاص بك - نقطة نهاية واحدة،
---
### 🆕 الجديد في v2.7.0
- **RouterStrategy قابل للتوصيل** — استراتيجيات القواعد والتكلفة والكمون
- **كشف النية متعدد اللغات** — تسجيل التوجيه بأكثر من 30 لغة
- **إلغاء تكرار الطلبات** — تجنب مكالمات API المكررة عبر تجزئة المحتوى
- **مزودون جدد:** Grok-4 Fast (xAI) وGLM-5 / Z.AI وMiniMax M2.5 وKimi K2.5
- **أسعار محدثة:** Grok-4 Fast $0.20/$0.50/M، GLM-5 $0.50/M، MiniMax M2.5 $0.30/M
---
<div align="center">
[![إصدار npm](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)
[![الترخيص](https://img.shields.io/github/license/diegosouzapw/OmniRoute)](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
[![موقع الويب](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)
[🌐 الموقع الإلكتروني](https://omniroute.online) • [🚀 البداية السريعة](#-quick-start) • [💡 الميزات](#-key-features) • [📖 المستندات](#-documentation) • [💰 التسعير](#-pricing-at-a-glance) • [💬 واتساب](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
</div>
🌐 **متوفر باللغة:** 🇺🇸 [الإنجليزية](../../README.md) | 🇧🇷 [البرتغالية (البرازيل)](../pt-BR/README.md) | 🇪🇸 [الإسبانية](../es/README.md) | 🇫🇷 [Français](../fr/README.md) | 🇮🇹 [الإيطالية](../it/README.md) | 🇷🇺 [Русский](../ru/README.md) | 🇨🇳 [中文 (简体)](../zh-CN/README.md) | 🇩🇪 [الألمانية](../de/README.md) | 🇮🇳 [هندي](../in/README.md) | 🇹🇭 [ไทย](../th/README.md) | 🇺🇦 [أوكرانيا](../uk-UA/README.md) | 🇸🇦 [العربية](../ar/README.md) | 🇯🇵 [日本語](../ja/README.md) | 🇻🇳 [تيانج فيت](../vi/README.md) | 🇧🇬 [بلغارسكي](../bg/README.md) | 🇩🇰 [الدانسك](../da/README.md) | 🇫🇮 [سومي](../fi/README.md) | 🇮🇱 [العربية](../he/README.md) | 🇭🇺 [المجرية](../hu/README.md) | 🇮🇩 [البهاسا الإندونيسية](../id/README.md) | 🇰🇷 [한국어](../ko/README.md) | 🇲🇾 [البهاسا ملايو](../ms/README.md) | 🇳🇱 [هولندا](../nl/README.md) | 🇳🇴 [نورسك](../no/README.md) | 🇵🇹 [البرتغالية (البرتغال)](../pt/README.md) | 🇷🇴 [روماني](../ro/README.md) | 🇵🇱 [بولسكي](../pl/README.md) | 🇸🇰 [سلوفينسينا](../sk/README.md) | 🇸🇪 [سفينسكا](../sv/README.md) | 🇵🇭 [فلبينية](../phi/README.md)
---
## 🖼️ لوحة التحكم الرئيسية
<div align="center">
<img src="./docs/screenshots/MainOmniRoute.png" alt="OmniRoute Dashboard" width="800"/>
</div>
---
## 📸 معاينة لوحة التحكم
<details>
<summary><b>انقر لرؤية لقطات شاشة لوحة القيادة</b></summary>
| صفحة | لقطة شاشة |
| --------------------- | -------------------------------------------------- |
| ** مقدمو الخدمة ** | ![مقدمو الخدمة](docs/screenshots/01-providers.png) |
| **المجموعات** | ![المجموعات](docs/screenshots/02-combos.png) |
| **تحليلات** | ![تحليلات](docs/screenshots/03-analytics.png) |
| **الصحة** | ![الصحة](docs/screenshots/04-health.png) |
| **مترجم** | ![مترجم](docs/screenshots/05-translator.png) |
| **الإعدادات** | ![الإعدادات](docs/screenshots/06-settings.png) |
| **أدوات سطر الأوامر** | ![أدوات CLI](docs/screenshots/07-cli-tools.png) |
| **سجلات الاستخدام** | ![الاستخدام](docs/screenshots/08-usage.png) |
| **نقطة النهاية** | ![نقطة النهاية](docs/screenshots/09-endpoint.png) |
</details>
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 موفر الذكاء الاصطناعي المجاني لوكلاء البرمجة المفضلين لديك
_قم بتوصيل أي أداة IDE أو CLI مدعومة بالذكاء الاصطناعي من خلال OmniRoute - بوابة واجهة برمجة التطبيقات المجانية للترميز غير المحدود._
@@ -159,6 +92,38 @@ _قم بتوصيل أي أداة IDE أو CLI مدعومة بالذكاء الا
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
## 🤔 لماذا OmniRoute؟
**توقف عن إهدار المال وضرب الحدود:**
+32 -67
View File
@@ -8,73 +8,6 @@ _Вашият универсален API прокси — една крайна
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
<div align="center">
[![npm версия](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)
[![Лиценз](https://img.shields.io/github/license/diegosouzapw/OmniRoute)](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
[![Уебсайт](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)
[🌐 Уебсайт](https://omniroute.online) • [🚀 Бърз старт](#-quick-start) • [💡 Функции](#-key-features) • [📖 Документи](#-documentation) • [💰 Ценообразуване](#-pricing-at-a-glance) • [💬 WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
</div>
🌐 **Налично на:** 🇺🇸 [английски](../../README.md) | 🇧🇷 [Португалски (Бразилия)](../pt-BR/README.md) | 🇪🇸 [Испански] (../es/README.md) | 🇫🇷 [Français](../fr/README.md) | 🇮🇹 [италиански] (../it/README.md) | 🇷🇺 [Русский](../ru/README.md) | 🇨🇳 [中文 (简体)](../zh-CN/README.md) | 🇩🇪 [Deutsch](../de/README.md) | 🇮🇳 [हिन्दी] (../in/README.md) | 🇹🇭 [ไทย](../th/README.md) | 🇺🇦 [Українська](../uk-UA/README.md) | 🇸🇦 [العربية](../ar/README.md) | 🇯🇵 [日本語](../ja/README.md) | 🇻🇳 [Tiếng Việt](../vi/README.md) | 🇧🇬 [Български](../bg/README.md) | 🇩🇰 [Dansk](../da/README.md) | 🇫🇮 [Suomi](../fi/README.md) | 🇮🇱 [עברית](../he/README.md) | 🇭🇺 [маджарски] (../hu/README.md) | 🇮🇩 [бахаса Индонезия](../id/README.md) | 🇰🇷 [한국어](../ko/README.md) | 🇲🇾 [Bahasa Melayu](../ms/README.md) | 🇳🇱 [Нидерландия](../nl/README.md) | 🇳🇴 [Norsk](../no/README.md) | 🇵🇹 [Português (Португалия)](../pt/README.md) | 🇷🇴 [Română](../ro/README.md) | 🇵🇱 [Полски](../pl/README.md) | 🇸🇰 [Slovenčina](../sk/README.md) | 🇸🇪 [Svenska](../sv/README.md) | 🇵🇭 [филипински] (../phi/README.md)
---
## 🖼️ Главно табло за управление
<div align="center">
<img src="./docs/screenshots/MainOmniRoute.png" alt="OmniRoute Dashboard" width="800"/>
</div>
---
## 📸 Визуализация на таблото за управление
<details>
<summary><b>Щракнете, за да видите екранни снимки на таблото </b></summary>
| Страница | Екранна снимка |
| -------------------------- | ----------------------------------------------------- |
| **Доставчици** | ![Доставчици](docs/screenshots/01-providers.png) |
| **Комбота** | ![Комбота](docs/screenshots/02-combos.png) |
| **Анализ** | ![Анализ](docs/screenshots/03-analytics.png) |
| **Здраве** | ![Здраве](docs/screenshots/04-health.png) |
| **Преводач** | ![Преводач](docs/screenshots/05-translator.png) |
| **Настройки** | ![Настройки](docs/screenshots/06-settings.png) |
| **CLI инструменти** | ![CLI инструменти](docs/screenshots/07-cli-tools.png) |
| **Регистри за използване** | ![Използване](docs/screenshots/08-usage.png) |
| **Крайна точка** | ![Крайна точка](docs/screenshots/09-endpoint.png) |
</details>
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Безплатен доставчик на AI за вашите любими кодиращи агенти
_Свържете всеки базиран на AI IDE или CLI инструмент чрез OmniRoute — безплатен API шлюз за неограничено кодиране._
@@ -159,6 +92,38 @@ _Свържете всеки базиран на AI IDE или CLI инстру
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
## 🤔 Защо OmniRoute?
**Спрете да пилеете пари и да достигате лимити:**
+115 -115
View File
@@ -38,15 +38,15 @@ Content-Type: application/json
### Vlastní záhlaví
Záhlaví | Směr | Popis
--- | --- | ---
`X-OmniRoute-No-Cache` | Žádost | Nastavením na `true` se vynechá mezipaměť
`X-OmniRoute-Progress` | Žádost | Nastaveno na `true` pro události průběhu
`Idempotency-Key` | Žádost | Klíč pro deduplikaci (okno 5 s)
`X-Request-Id` | Žádost | Alternativní klíč pro odstranění duplicitních dat
`X-OmniRoute-Cache` | Odpověď | `HIT` or `MISS` (nestreamované)
`X-OmniRoute-Idempotent` | Odpověď | `true` , pokud je odstraněna duplikace
`X-OmniRoute-Progress` | Odpověď | `enabled` pokud je zapnuto sledování průběhu
| Záhlaví | Směr | Popis |
| ------------------------ | ------- | ------------------------------------------------- |
| `X-OmniRoute-No-Cache` | Žádost | Nastavením na `true` se vynechá mezipaměť |
| `X-OmniRoute-Progress` | Žádost | Nastaveno na `true` pro události průběhu |
| `Idempotency-Key` | Žádost | Klíč pro deduplikaci (okno 5 s) |
| `X-Request-Id` | Žádost | Alternativní klíč pro odstranění duplicitních dat |
| `X-OmniRoute-Cache` | Odpověď | `HIT` or `MISS` (nestreamované) |
| `X-OmniRoute-Idempotent` | Odpověď | `true` , pokud je odstraněna duplikace |
| `X-OmniRoute-Progress` | Odpověď | `enabled` pokud je zapnuto sledování průběhu |
---
@@ -108,18 +108,18 @@ Authorization: Bearer your-api-key
## Koncové body kompatibility
Metoda | Cesta | Formát
--- | --- | ---
ZVEŘEJNIT | `/v1/chat/completions` | OpenAI
ZVEŘEJNIT | `/v1/messages` | Antropic
ZVEŘEJNIT | `/v1/responses` | Reakce OpenAI
ZVEŘEJNIT | `/v1/embeddings` | OpenAI
ZVEŘEJNIT | `/v1/images/generations` | OpenAI
ZÍSKAT | `/v1/models` | OpenAI
ZVEŘEJNIT | `/v1/messages/count_tokens` | Antropic
ZÍSKAT | `/v1beta/models` | Blíženci
ZVEŘEJNIT | `/v1beta/models/{...path}` | Gemini generuje obsah
ZVEŘEJNIT | `/v1/api/chat` | Ollama
| Metoda | Cesta | Formát |
| ------ | --------------------------- | --------------------- |
| POST | `/v1/chat/completions` | OpenAI |
| POST | `/v1/messages` | Anthropic |
| POST | `/v1/responses` | Reakce OpenAI |
| POST | `/v1/embeddings` | OpenAI |
| POST | `/v1/images/generations` | OpenAI |
| GET | `/v1/models` | OpenAI |
| POST | `/v1/messages/count_tokens` | Anthropic |
| GET | `/v1beta/models` | Blíženci |
| POST | `/v1beta/models/{...path}` | Gemini generuje obsah |
| POST | `/v1/api/chat` | Ollama |
### Vyhrazené trasy poskytovatelů
@@ -166,154 +166,154 @@ Příklad odpovědi:
### Ověřování
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/auth/login` | ZVEŘEJNIT | Přihlášení
`/api/auth/logout` | ZVEŘEJNIT | Odhlásit se
`/api/settings/require-login` | ZÍSKAT/VLOŽIT | Vyžaduje se přepnutí přihlášení
| Koncový bod | Metoda | Popis |
| ----------------------------- | ------- | ------------------------------- |
| `/api/auth/login` | POST | Přihlášení |
| `/api/auth/logout` | POST | Odhlásit se |
| `/api/settings/require-login` | GET/PUT | Vyžaduje se přepnutí přihlášení |
### Správa poskytovatelů
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/providers` | ZÍSKAT/ODESLAT | Seznam / vytvoření poskytovatelů
`/api/providers/[id]` | ZÍSKAT/VLOŽIT/ODSTRANIT | Správa poskytovatele
`/api/providers/[id]/test` | ZVEŘEJNIT | Testovací připojení poskytovatele
`/api/providers/[id]/models` | ZÍSKAT | Seznam modelů poskytovatelů
`/api/providers/validate` | ZVEŘEJNIT | Ověření konfigurace poskytovatele
`/api/provider-nodes*` | Různé | Správa uzlů poskytovatelů
`/api/provider-models` | ZÍSKAT/ODESLAT/SMAZAT | Vlastní modely
| Koncový bod | Metoda | Popis |
| ---------------------------- | --------------- | --------------------------------- |
| `/api/providers` | GET/POST | Seznam / vytvoření poskytovatelů |
| `/api/providers/[id]` | GET/PUT/DELETE | Správa poskytovatele |
| `/api/providers/[id]/test` | POST | Testovací připojení poskytovatele |
| `/api/providers/[id]/models` | GET | Seznam modelů poskytovatelů |
| `/api/providers/validate` | POST | Ověření konfigurace poskytovatele |
| `/api/provider-nodes*` | Různé | Správa uzlů poskytovatelů |
| `/api/provider-models` | GET/POST/DELETE | Vlastní modely |
### Toky OAuth
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/oauth/[provider]/[action]` | Různé | OAuth specifický pro poskytovatele
| Koncový bod | Metoda | Popis |
| -------------------------------- | ------ | ---------------------------------- |
| `/api/oauth/[provider]/[action]` | Různé | OAuth specifický pro poskytovatele |
### Směrování a konfigurace
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/models/alias` | ZÍSKAT/ODESLAT | Aliasy modelů
`/api/models/catalog` | ZÍSKAT | Všechny modely podle poskytovatele + typu
`/api/combos*` | Různé | Správa kombinací
`/api/keys*` | Různé | Správa klíčů API
`/api/pricing` | ZÍSKAT | Cena modelu
| Koncový bod | Metoda | Popis |
| --------------------- | -------- | ----------------------------------------- |
| `/api/models/alias` | GET/POST | Aliasy modelů |
| `/api/models/catalog` | GET | Všechny modely podle poskytovatele + typu |
| `/api/combos*` | Různé | Správa kombinací |
| `/api/keys*` | Různé | Správa klíčů API |
| `/api/pricing` | GET | Cena modelu |
### Využití a analýzy
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/usage/history` | ZÍSKAT | Historie používání
`/api/usage/logs` | ZÍSKAT | Protokoly používání
`/api/usage/request-logs` | ZÍSKAT | Protokoly na úrovni požadavků
`/api/usage/[connectionId]` | ZÍSKAT | Využití na připojení
| Koncový bod | Metoda | Popis |
| --------------------------- | ------ | ----------------------------- |
| `/api/usage/history` | GET | Historie používání |
| `/api/usage/logs` | GET | Protokoly používání |
| `/api/usage/request-logs` | GET | Protokoly na úrovni požadavků |
| `/api/usage/[connectionId]` | GET | Využití na připojení |
### Nastavení
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/settings` | ZÍSKAT/VLOŽIT | Obecná nastavení
`/api/settings/proxy` | ZÍSKAT/VLOŽIT | Konfigurace síťového proxy serveru
`/api/settings/proxy/test` | ZVEŘEJNIT | Testovací připojení k proxy serveru
`/api/settings/ip-filter` | ZÍSKAT/VLOŽIT | Seznam povolených/blokovaných IP adres
`/api/settings/thinking-budget` | ZÍSKAT/VLOŽIT | Zdůvodnění rozpočtu tokenů
`/api/settings/system-prompt` | ZÍSKAT/VLOŽIT | Globální systémový výzva
| Koncový bod | Metoda | Popis |
| ------------------------------- | ------- | -------------------------------------- |
| `/api/settings` | GET/PUT | Obecná nastavení |
| `/api/settings/proxy` | GET/PUT | Konfigurace síťového proxy serveru |
| `/api/settings/proxy/test` | POST | Testovací připojení k proxy serveru |
| `/api/settings/ip-filter` | GET/PUT | Seznam povolených/blokovaných IP adres |
| `/api/settings/thinking-budget` | GET/PUT | Zdůvodnění rozpočtu tokenů |
| `/api/settings/system-prompt` | GET/PUT | Globální systémový výzva |
### Monitorování
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/sessions` | ZÍSKAT | Sledování aktivních relací
`/api/rate-limits` | ZÍSKAT | Limity sazeb na účet
`/api/monitoring/health` | ZÍSKAT | Kontrola stavu
`/api/cache` | ZÍSKAT/SMAZAT | Statistiky mezipaměti / vymazat
| Koncový bod | Metoda | Popis |
| ------------------------ | ---------- | ------------------------------- |
| `/api/sessions` | GET | Sledování aktivních relací |
| `/api/rate-limits` | GET | Limity sazeb na účet |
| `/api/monitoring/health` | GET | Kontrola stavu |
| `/api/cache` | GET/DELETE | Statistiky mezipaměti / vymazat |
### Zálohování a export/import
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/db-backups` | ZÍSKAT | Seznam dostupných záloh
`/api/db-backups` | DÁT | Vytvořte ruční zálohu
`/api/db-backups` | ZVEŘEJNIT | Obnovení z konkrétní zálohy
`/api/db-backups/export` | ZÍSKAT | Stáhnout databázi jako soubor .sqlite
`/api/db-backups/import` | ZVEŘEJNIT | Nahrajte soubor .sqlite pro nahrazení databáze
`/api/db-backups/exportAll` | ZÍSKAT | Stáhnout plnou zálohu jako archiv .tar.gz
| Koncový bod | Metoda | Popis |
| --------------------------- | ------ | ---------------------------------------------- |
| `/api/db-backups` | GET | Seznam dostupných záloh |
| `/api/db-backups` | DÁT | Vytvořte ruční zálohu |
| `/api/db-backups` | POST | Obnovení z konkrétní zálohy |
| `/api/db-backups/export` | GET | Stáhnout databázi jako soubor .sqlite |
| `/api/db-backups/import` | POST | Nahrajte soubor .sqlite pro nahrazení databáze |
| `/api/db-backups/exportAll` | GET | Stáhnout plnou zálohu jako archiv .tar.gz |
### Synchronizace s cloudem
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/sync/cloud` | Různé | Operace synchronizace s cloudem
`/api/sync/initialize` | ZVEŘEJNIT | Inicializovat synchronizaci
`/api/cloud/*` | Různé | Správa cloudu
| Koncový bod | Metoda | Popis |
| ---------------------- | ------ | ------------------------------- |
| `/api/sync/cloud` | Různé | Operace synchronizace s cloudem |
| `/api/sync/initialize` | POST | Inicializovat synchronizaci |
| `/api/cloud/*` | Různé | Správa cloudu |
### Nástroje CLI
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/cli-tools/claude-settings` | ZÍSKAT | Stav Clauda CLI
`/api/cli-tools/codex-settings` | ZÍSKAT | Stav příkazového řádku Codexu
`/api/cli-tools/droid-settings` | ZÍSKAT | Stav příkazového řádku Droidu
`/api/cli-tools/openclaw-settings` | ZÍSKAT | Stav rozhraní příkazového řádku OpenClaw
`/api/cli-tools/runtime/[toolId]` | ZÍSKAT | Generické běhové prostředí CLI
| Koncový bod | Metoda | Popis |
| ---------------------------------- | ------ | ---------------------------------------- |
| `/api/cli-tools/claude-settings` | GET | Stav Clauda CLI |
| `/api/cli-tools/codex-settings` | GET | Stav příkazového řádku Codexu |
| `/api/cli-tools/droid-settings` | GET | Stav příkazového řádku Droidu |
| `/api/cli-tools/openclaw-settings` | GET | Stav rozhraní příkazového řádku OpenClaw |
| `/api/cli-tools/runtime/[toolId]` | GET | Generické běhové prostředí CLI |
Mezi odpovědi CLI patří: `installed` , `runnable` , `command` , `commandPath` , `runtimeMode` , `reason` .
### Agenti ACP
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/acp/agents` | ZÍSKAT | Zobrazit seznam všech detekovaných agentů (vestavěných + vlastních) se stavem
`/api/acp/agents` | ZVEŘEJNIT | Přidat vlastního agenta nebo obnovit mezipaměť detekce
`/api/acp/agents` | VYMAZAT | Odebrání vlastního agenta podle parametru dotazu `id`
| Koncový bod | Metoda | Popis |
| ----------------- | ------- | ----------------------------------------------------------------------------- |
| `/api/acp/agents` | GET | Zobrazit seznam všech detekovaných agentů (vestavěných + vlastních) se stavem |
| `/api/acp/agents` | POST | Přidat vlastního agenta nebo obnovit mezipaměť detekce |
| `/api/acp/agents` | VYMAZAT | Odebrání vlastního agenta podle parametru dotazu `id` |
Odpověď GET obsahuje `agents[]` (id, name, binary, version, installed, protocol, isCustom) a `summary` (total, installed, notFound, builtIn, custom).
### Odolnost a limity rychlosti
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/resilience` | ZÍSKAT/VLOŽIT | Získání/aktualizace profilů odolnosti
`/api/resilience/reset` | ZVEŘEJNIT | Resetujte jističe
`/api/rate-limits` | ZÍSKAT | Stav limitu sazby na účet
`/api/rate-limit` | ZÍSKAT | Konfigurace globálního limitu rychlosti
| Koncový bod | Metoda | Popis |
| ----------------------- | ------- | --------------------------------------- |
| `/api/resilience` | GET/PUT | Získání/aktualizace profilů odolnosti |
| `/api/resilience/reset` | POST | Resetujte jističe |
| `/api/rate-limits` | GET | Stav limitu sazby na účet |
| `/api/rate-limit` | GET | Konfigurace globálního limitu rychlosti |
### Evals
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/evals` | ZÍSKAT/ODESLAT | Vypsat eval sady / spustit vyhodnocení
| Koncový bod | Metoda | Popis |
| ------------ | -------- | -------------------------------------- |
| `/api/evals` | GET/POST | Vypsat eval sady / spustit vyhodnocení |
### Zásady
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/policies` | ZÍSKAT/ODESLAT/SMAZAT | Správa směrovacích zásad
| Koncový bod | Metoda | Popis |
| --------------- | --------------- | ------------------------ |
| `/api/policies` | GET/POST/DELETE | Správa směrovacích zásad |
### Dodržování
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/compliance/audit-log` | ZÍSKAT | Protokol auditu shody (poslední N)
| Koncový bod | Metoda | Popis |
| --------------------------- | ------ | ---------------------------------- |
| `/api/compliance/audit-log` | GET | Protokol auditu shody (poslední N) |
### v1beta (kompatibilní s Gemini)
Koncový bod | Metoda | Popis
--- | --- | ---
`/v1beta/models` | ZÍSKAT | Seznam modelů ve formátu Gemini
`/v1beta/models/{...path}` | ZVEŘEJNIT | Koncový bod Gemini `generateContent`
| Koncový bod | Metoda | Popis |
| -------------------------- | ------ | ------------------------------------ |
| `/v1beta/models` | GET | Seznam modelů ve formátu Gemini |
| `/v1beta/models/{...path}` | POST | Koncový bod Gemini `generateContent` |
Tyto koncové body zrcadlí formát API Gemini pro klienty, kteří očekávají nativní kompatibilitu sady Gemini SDK.
### Interní / systémová API
Koncový bod | Metoda | Popis
--- | --- | ---
`/api/init` | ZÍSKAT | Kontrola inicializace aplikace (používá se při prvním spuštění)
`/api/tags` | ZÍSKAT | Tagy modelů kompatibilní s Ollamou (pro klienty Ollamy)
`/api/restart` | ZVEŘEJNIT | Spustit řádný restart serveru
`/api/shutdown` | ZVEŘEJNIT | Spustit řádné vypnutí serveru
| Koncový bod | Metoda | Popis |
| --------------- | ------ | --------------------------------------------------------------- |
| `/api/init` | GET | Kontrola inicializace aplikace (používá se při prvním spuštění) |
| `/api/tags` | GET | Tagy modelů kompatibilní s Ollamou (pro klienty Ollamy) |
| `/api/restart` | POST | Spustit řádný restart serveru |
| `/api/shutdown` | POST | Spustit řádné vypnutí serveru |
> **Poznámka:** Tyto koncové body používá interně systém nebo pro kompatibilitu s klienty Ollama. Koncoví uživatelé je obvykle nevolají.
+55 -55
View File
@@ -2,7 +2,7 @@
🌐 **Jazyky:** 🇺🇸 [angličtina](ARCHITECTURE.md) | 🇧🇷 [Português (Brazílie)](i18n/pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](i18n/es/ARCHITECTURE.md) | 🇫🇷 [Français](i18n/fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](i18n/it/ARCHITECTURE.md) | 🇷🇺 [Русский](i18n/ru/ARCHITECTURE.md) | 🇨🇳[中文 (简体)](i18n/zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](i18n/de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](i18n/in/ARCHITECTURE.md) | 🇹🇭 [ไทย](i18n/th/ARCHITECTURE.md) | 🇺🇦 [Українська](i18n/uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](i18n/ar/ARCHITECTURE.md) | 🇯🇵[日本語](i18n/ja/ARCHITECTURE.md)| 🇻🇳 [Tiếng Việt](i18n/vi/ARCHITECTURE.md) | 🇧🇬 [Български](i18n/bg/ARCHITECTURE.md) | 🇩🇰 [Dánsko](i18n/da/ARCHITECTURE.md) | 🇫🇮 [Suomi](i18n/fi/ARCHITECTURE.md) | 🇮🇱 [עברית](i18n/he/ARCHITECTURE.md) | 🇭🇺 [maďarština](i18n/hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonésie](i18n/id/ARCHITECTURE.md) | 🇰🇷 [한국어](i18n/ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/ARCHITECTURE.md) | 🇳🇱 [Nizozemsko](i18n/nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](i18n/no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugalsko)](i18n/pt/ARCHITECTURE.md) | 🇷🇴 [Română](i18n/ro/ARCHITECTURE.md) | 🇵🇱 [Polski](i18n/pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](i18n/sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](i18n/sv/ARCHITECTURE.md) | 🇵🇭 [Filipínec](i18n/phi/ARCHITECTURE.md) | 🇨🇿 [Čeština](i18n/cs/ARCHITECTURE.md)
*Poslední aktualizace: 2026-03-04*
_Poslední aktualizace: 2026-03-04_
## Shrnutí pro manažery
@@ -590,45 +590,45 @@ flowchart LR
Každý poskytovatel má specializovaný exekutor rozšiřující `BaseExecutor` (v `open-sse/executors/base.ts` ), který zajišťuje vytváření URL adres, konstrukci hlaviček, opakování s exponenciálním odkladem, hooky pro obnovení pověření a orchestrační metodu `execute()` .
Vykonavatel | Poskytovatel(é) | Speciální manipulace
--- | --- | ---
`DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Konfigurace dynamické adresy URL/záhlaví pro každého poskytovatele
`AntigravityExecutor` | Google Antigravitace | Vlastní ID projektů/relací, analýza Opakování po
`CodexExecutor` | Kodex OpenAI | Vkládá systémové instrukce, vynucuje úsilí k uvažování
`CursorExecutor` | IDE kurzoru | Protokol ConnectRPC, kódování Protobuf, podepisování požadavků pomocí kontrolního součtu
`GithubExecutor` | GitHub Copilot | Aktualizace tokenu Copilot, hlavičky napodobující VSCode
`KiroExecutor` | AWS CodeWhisperer/Kiro | Binární formát AWS EventStream → konverze SSE
`GeminiCLIExecutor` | Rozhraní příkazového řádku Gemini | Cyklus obnovy tokenu Google OAuth
| Vykonavatel | Poskytovatel(é) | Speciální manipulace |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- |
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Konfigurace dynamické adresy URL/záhlaví pro každého poskytovatele |
| `AntigravityExecutor` | Google Antigravity | Vlastní ID projektů/relací, analýza Opakování po |
| `CodexExecutor` | OpenAI Codex | Vkládá systémové instrukce, vynucuje úsilí k uvažování |
| `CursorExecutor` | IDE kurzoru | Protokol ConnectRPC, kódování Protobuf, podepisování požadavků pomocí kontrolního součtu |
| `GithubExecutor` | GitHub Copilot | Aktualizace tokenu Copilot, hlavičky napodobující VSCode |
| `KiroExecutor` | AWS CodeWhisperer/Kiro | Binární formát AWS EventStream → konverze SSE |
| `GeminiCLIExecutor` | Gemini CLI | Cyklus obnovy tokenu Google OAuth |
Všichni ostatní poskytovatelé (včetně uzlů kompatibilních s vlastními funkcemi) používají `DefaultExecutor` .
## Matice kompatibility poskytovatelů
Poskytovatel | Formát | Autorizace | Proud | Nestreamované | Obnovení tokenu | API pro použití
--- | --- | --- | --- | --- | --- | ---
Claude | Claude | Klíč API / OAuth | ✅ | ✅ | ✅ | ⚠️ Pouze pro administrátory
Blíženci | Blíženci | Klíč API / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloudová konzole
Rozhraní příkazového řádku Gemini | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloudová konzole
Antigravitace | antigravitace | OAuth | ✅ | ✅ | ✅ | ✅ Plná kvóta API
OpenAI | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
Kodex | openai-odpovědi | OAuth | ✅ vynucený | ❌ | ✅ | ✅ Limity sazeb
GitHub Copilot | otevřeno | OAuth + token Copilota | ✅ | ✅ | ✅ | ✅ Snímky kvót
Kurzor | kurzor | Vlastní kontrolní součet | ✅ | ✅ | ❌ | ❌
Kiro | Kiro | OIDC pro jednotné přihlašování AWS | ✅ (Stream událostí) | ❌ | ✅ | ✅ Limity použití
Qwen | otevřeno | OAuth | ✅ | ✅ | ✅ | ⚠️ Na vyžádání
iFlow | otevřeno | OAuth (základní) | ✅ | ✅ | ✅ | ⚠️ Na vyžádání
OpenRouter | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
GLM/Kimi/MiniMax | Claude | Klíč API | ✅ | ✅ | ❌ | ❌
Hluboké vyhledávání | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
Groq | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
xAI (Grok) | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
Mistral | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
Zmatek | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
Společně s umělou inteligencí | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
Ohňostroj s umělou inteligencí | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
Mozky | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
Soudržný | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
NVIDIA NIM | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
| Poskytovatel | Formát | Autorizace | Proud | Nestreamované | Obnovení tokenu | API pro použití |
| ------------------------------ | --------------- | ---------------------------------- | -------------------- | ------------- | --------------- | --------------------------- |
| Claude | Claude | Klíč API / OAuth | ✅ | ✅ | ✅ | ⚠️ Pouze pro administrátory |
| Blíženci | Blíženci | Klíč API / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloudová konzole |
| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloudová konzole |
| Antigravity | antigravitace | OAuth | ✅ | ✅ | ✅ | ✅ Plná kvóta API |
| OpenAI | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌ |
| Kodex | openai-odpovědi | OAuth | ✅ vynucený | ❌ | ✅ | ✅ Limity sazeb |
| GitHub Copilot | otevřeno | OAuth + token Copilota | ✅ | ✅ | ✅ | ✅ Snímky kvót |
| Kurzor | kurzor | Vlastní kontrolní součet | ✅ | ✅ | ❌ | ❌ |
| Kiro | Kiro | OIDC pro jednotné přihlašování AWS | ✅ (Stream událostí) | ❌ | ✅ | ✅ Limity použití |
| Qwen | otevřeno | OAuth | ✅ | ✅ | ✅ | ⚠️ Na vyžádání |
| iFlow | otevřeno | OAuth (základní) | ✅ | ✅ | ✅ | ⚠️ Na vyžádání |
| OpenRouter | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌ |
| GLM/Kimi/MiniMax | Claude | Klíč API | ✅ | ✅ | ❌ | ❌ |
| Hluboké vyhledávání | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌ |
| Groq | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌ |
| xAI (Grok) | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌ |
| Mistral | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌ |
| Zmatek | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌ |
| Společně s umělou inteligencí | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌ |
| Ohňostroj s umělou inteligencí | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌ |
| Mozky | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌ |
| Soudržný | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌ |
| NVIDIA NIM | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌ |
## Pokrytí překladů formátů
@@ -643,7 +643,7 @@ Cílové formáty zahrnují:
- Chat/Odpovědi v OpenAI
- Claude
- Obálka Gemini/Gemini-CLI/Antigravitace
- Obálka Gemini/Gemini-CLI/Antigravity
- Kiro
- Kurzor
@@ -664,25 +664,25 @@ Další vrstvy zpracování v překladovém kanálu:
## Podporované koncové body API
Koncový bod | Formát | Psovod
--- | --- | ---
`POST /v1/chat/completions` | Chat s OpenAI | `src/sse/handlers/chat.ts`
`POST /v1/messages` | Claude Messages | Stejný obslužný program (automaticky detekováno)
`POST /v1/responses` | Reakce OpenAI | `open-sse/handlers/responsesHandler.ts`
`POST /v1/embeddings` | Vkládání OpenAI | `open-sse/handlers/embeddings.ts`
`GET /v1/embeddings` | Seznam modelů | Trasa API
`POST /v1/images/generations` | Obrázky OpenAI | `open-sse/handlers/imageGeneration.ts`
`GET /v1/images/generations` | Seznam modelů | Trasa API
`POST /v1/providers/{provider}/chat/completions` | Chat s OpenAI | Vyhrazené pro každého poskytovatele s ověřováním modelu
`POST /v1/providers/{provider}/embeddings` | Vkládání OpenAI | Vyhrazené pro každého poskytovatele s ověřováním modelu
`POST /v1/providers/{provider}/images/generations` | Obrázky OpenAI | Vyhrazené pro každého poskytovatele s ověřováním modelu
`POST /v1/messages/count_tokens` | Počet žetonů Claude | Trasa API
`GET /v1/models` | Seznam modelů OpenAI | Trasa API (chat + vkládání + obrázek + vlastní modely)
`GET /api/models/catalog` | Katalog | Všechny modely seskupené podle poskytovatele + typu
`POST /v1beta/models/*:streamGenerateContent` | Rodák z Blíženců | Trasa API
`GET/PUT/DELETE /api/settings/proxy` | Konfigurace proxy serveru | Konfigurace síťového proxy serveru
`POST /api/settings/proxy/test` | Připojení proxy serveru | Koncový bod testu stavu/připojení proxy serveru
`GET/POST/DELETE /api/provider-models` | Vlastní modely | Správa vlastních modelů pro každého poskytovatele
| Koncový bod | Formát | Psovod |
| -------------------------------------------------- | ------------------------- | ------------------------------------------------------- |
| `POST /v1/chat/completions` | Chat s OpenAI | `src/sse/handlers/chat.ts` |
| `POST /v1/messages` | Claude Messages | Stejný obslužný program (automaticky detekováno) |
| `POST /v1/responses` | Reakce OpenAI | `open-sse/handlers/responsesHandler.ts` |
| `POST /v1/embeddings` | Vkládání OpenAI | `open-sse/handlers/embeddings.ts` |
| `GET /v1/embeddings` | Seznam modelů | Trasa API |
| `POST /v1/images/generations` | Obrázky OpenAI | `open-sse/handlers/imageGeneration.ts` |
| `GET /v1/images/generations` | Seznam modelů | Trasa API |
| `POST /v1/providers/{provider}/chat/completions` | Chat s OpenAI | Vyhrazené pro každého poskytovatele s ověřováním modelu |
| `POST /v1/providers/{provider}/embeddings` | Vkládání OpenAI | Vyhrazené pro každého poskytovatele s ověřováním modelu |
| `POST /v1/providers/{provider}/images/generations` | Obrázky OpenAI | Vyhrazené pro každého poskytovatele s ověřováním modelu |
| `POST /v1/messages/count_tokens` | Počet žetonů Claude | Trasa API |
| `GET /v1/models` | Seznam modelů OpenAI | Trasa API (chat + vkládání + obrázek + vlastní modely) |
| `GET /api/models/catalog` | Katalog | Všechny modely seskupené podle poskytovatele + typu |
| `POST /v1beta/models/*:streamGenerateContent` | Rodák z Blíženců | Trasa API |
| `GET/PUT/DELETE /api/settings/proxy` | Konfigurace proxy serveru | Konfigurace síťového proxy serveru |
| `POST /api/settings/proxy/test` | Připojení proxy serveru | Koncový bod testu stavu/připojení proxy serveru |
| `GET/POST/DELETE /api/provider-models` | Vlastní modely | Správa vlastních modelů pro každého poskytovatele |
## Obejít obslužnou rutinu
+33 -33
View File
@@ -27,19 +27,19 @@ Claude / Codex / Gemini CLI / OpenCode / Cline / KiloCode / Continue / Kiro CLI
## Podporované nástroje
Nástroj | Příkaz | Typ | Metoda instalace
--- | --- | --- | ---
**Claude Code** | `claude` | Rozhraní příkazového řádku | npm
**Kodex OpenAI** | `codex` | Rozhraní příkazového řádku | npm
**Rozhraní příkazového řádku Gemini** | `gemini` | Rozhraní příkazového řádku | npm
**OpenCode** | `opencode` | Rozhraní příkazového řádku | npm
**Cline** | `cline` | Rozšíření CLI + VS kódu | npm
**KiloCode** | `kilocode` / `kilo` | Rozšíření CLI + VS kódu | npm
**Pokračovat** | průvodce | VS Code ext | VS kód
**Kiro CLI** | `kiro-cli` | Rozhraní příkazového řádku | instalační program Curl
**Kurzor** | `cursor` | Aplikace pro stolní počítače | Stáhnout
**Droid** | webový | Vestavěný agent | OmniRoute
**OpenClaw** | webový | Vestavěný agent | OmniRoute
| Nástroj | Příkaz | Typ | Instalace |
| ---------------- | ------------------- | --------------- | -------------- |
| **Claude Code** | `claude` | CLI | npm |
| **OpenAI Codex** | `codex` | CLI | npm |
| **Gemini CLI** | `gemini` | CLI | npm |
| **OpenCode** | `opencode` | CLI | npm |
| **Cline** | `cline` | CLI + VS Code | npm |
| **KiloCode** | `kilocode` / `kilo` | CLI + VS Code | npm |
| **Continue** | průvodce | VS Code ext | VS kód |
| **Kiro CLI** | `kiro-cli` | CLI | curl instalace |
| **Kurzor** | `cursor` | Aplikace pro PC | Download |
| **Droid** | webový | Built-in agent | OmniRoute |
| **OpenClaw** | webový | Built-in agent | OmniRoute |
---
@@ -136,7 +136,7 @@ EOF
---
### Kodex OpenAI
### OpenAI Codex
```bash
mkdir -p ~/.codex && cat > ~/.codex/config.yaml << EOF
@@ -150,7 +150,7 @@ EOF
---
### Rozhraní příkazového řádku Gemini
### Gemini CLI
```bash
mkdir -p ~/.gemini && cat > ~/.gemini/settings.json << EOF
@@ -220,7 +220,7 @@ Nebo použijte dashboard OmniRoute → **CLI Tools → KiloCode → Apply Config
---
### Pokračovat (rozšíření kódu VS)
### Continue (rozšíření kódu VS)
Upravit `~/.continue/config.yaml` :
@@ -286,28 +286,28 @@ Ovládací panel OmniRoute automatizuje konfiguraci většiny nástrojů:
## Dostupné koncové body API
Koncový bod | Popis | Použití pro
--- | --- | ---
`/v1/chat/completions` | Standardní chat (všichni poskytovatelé) | Všechny moderní nástroje
`/v1/responses` | API pro odpovědi (formát OpenAI) | Kodex, agentické pracovní postupy
`/v1/completions` | Doplňování starších textů | Starší nástroje používající `prompt:`
`/v1/embeddings` | Vkládání textu | RAG, vyhledávání
`/v1/images/generations` | Generování obrázků | DALL-E, Flux atd.
`/v1/audio/speech` | Převod textu na řeč | ElevenLabs, OpenAI TTS
`/v1/audio/transcriptions` | Převod řeči na text | Deepgram, AssemblyAI
| Koncový bod | Popis | Použití pro |
| -------------------------- | --------------------------------------- | ------------------------------------- |
| `/v1/chat/completions` | Standardní chat (všichni poskytovatelé) | Všechny moderní nástroje |
| `/v1/responses` | API pro odpovědi (formát OpenAI) | Kodex, agentické pracovní postupy |
| `/v1/completions` | Doplňování starších textů | Starší nástroje používající `prompt:` |
| `/v1/embeddings` | Vkládání textu | RAG, vyhledávání |
| `/v1/images/generations` | Generování obrázků | DALL-E, Flux atd. |
| `/v1/audio/speech` | Převod textu na řeč | ElevenLabs, OpenAI TTS |
| `/v1/audio/transcriptions` | Převod řeči na text | Deepgram, AssemblyAI |
---
## Odstraňování problémů
Chyba | Příčina | Opravit
--- | --- | ---
`Connection refused` | OmniRoute neběží | `pm2 start omniroute`
`401 Unauthorized` | Chybný klíč API | Zkontrolovat `/dashboard/api-manager`
`No combo configured` | Žádná aktivní routingová kombinace | Nastavení v `/dashboard/combos`
`invalid model` | Model není v katalogu | Použijte `auto` nebo zkontrolujte `/dashboard/providers`
CLI zobrazuje „není nainstalováno“ | Binární soubor není v cestě PATH | Zkontrolujte, `which <command>`
`kiro-cli: not found` | Není v PATH | `export PATH="$HOME/.local/bin:$PATH"`
| Chyba | Příčina | Opravit |
| ---------------------------------- | ---------------------------------- | -------------------------------------------------------- |
| `Connection refused` | OmniRoute neběží | `pm2 start omniroute` |
| `401 Unauthorized` | Chybný klíč API | Zkontrolovat `/dashboard/api-manager` |
| `No combo configured` | Žádná aktivní routingová kombinace | Nastavení v `/dashboard/combos` |
| `invalid model` | Model není v katalogu | Použijte `auto` nebo zkontrolujte `/dashboard/providers` |
| CLI zobrazuje „není nainstalováno“ | Binární soubor není v cestě PATH | Zkontrolujte, `which <command>` |
| `kiro-cli: not found` | Není v PATH | `export PATH="$HOME/.local/bin:$PATH"` |
---
+107 -107
View File
@@ -110,14 +110,14 @@ omniroute/
Jediný **zdroj pravdivých informací** pro všechny konfigurace poskytovatelů.
Soubor | Účel
--- | ---
`constants.ts` | Objekt `PROVIDERS` se základními URL adresami, přihlašovacími údaji OAuth (výchozí), záhlavími a výchozími systémovými výzvami pro každého poskytovatele. Definuje také `HTTP_STATUS` , `ERROR_TYPES` , `COOLDOWN_MS` , `BACKOFF_CONFIG` a `SKIP_PATTERNS` .
`credentialLoader.ts` | Načte externí přihlašovací údaje z `data/provider-credentials.json` a sloučí je s pevně zakódovanými výchozími hodnotami v `PROVIDERS` . Uchovává tajné údaje mimo kontrolu zdrojového kódu a zároveň zachovává zpětnou kompatibilitu.
`providerModels.ts` | Centrální registr modelů: mapuje aliasy poskytovatelů → ID modelů. Funkce jako `getModels()` , `getProviderByAlias()` .
`codexInstructions.ts` | Systémové instrukce vložené do požadavků Codexu (omezení úprav, pravidla sandboxu, zásady schvalování).
`defaultThinkingSignature.ts` | Výchozí „myšlenkové“ podpisy pro modely Claude a Gemini.
`ollamaModels.ts` | Definice schématu pro lokální Ollama modely (název, velikost, rodina, kvantizace).
| Soubor | Účel |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `constants.ts` | Objekt `PROVIDERS` se základními URL adresami, přihlašovacími údaji OAuth (výchozí), záhlavími a výchozími systémovými výzvami pro každého poskytovatele. Definuje také `HTTP_STATUS` , `ERROR_TYPES` , `COOLDOWN_MS` , `BACKOFF_CONFIG` a `SKIP_PATTERNS` . |
| `credentialLoader.ts` | Načte externí přihlašovací údaje z `data/provider-credentials.json` a sloučí je s pevně zakódovanými výchozími hodnotami v `PROVIDERS` . Uchovává tajné údaje mimo kontrolu zdrojového kódu a zároveň zachovává zpětnou kompatibilitu. |
| `providerModels.ts` | Centrální registr modelů: mapuje aliasy poskytovatelů → ID modelů. Funkce jako `getModels()` , `getProviderByAlias()` . |
| `codexInstructions.ts` | Systémové instrukce vložené do požadavků Codexu (omezení úprav, pravidla sandboxu, zásady schvalování). |
| `defaultThinkingSignature.ts` | Výchozí „myšlenkové“ podpisy pro modely Claude a Gemini. |
| `ollamaModels.ts` | Definice schématu pro lokální Ollama modely (název, velikost, rodina, kvantizace). |
#### Postup načítání přihlašovacích údajů
@@ -194,17 +194,17 @@ classDiagram
BaseExecutor <|-- GithubExecutor
```
Vykonavatel | Poskytovatel | Klíčové specializace
--- | --- | ---
`base.ts` | — | Abstraktní základ: tvorba URL adres, hlavičky, logika opakování, aktualizace přihlašovacích údajů
`default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Aktualizace generického tokenu OAuth pro standardní poskytovatele
`antigravity.ts` | Kód Google Cloud | Generování ID projektu/relace, záložní více URL adres, vlastní analýza opakovaných pokusů z chybových zpráv („reset po 2h7m23s“)
`cursor.ts` | IDE kurzoru | **Nejsložitější** : autorizace kontrolního součtu SHA-256, kódování požadavků Protobuf, analýza binárních EventStream → SSE odpovědí
`codex.ts` | Kodex OpenAI | Vkládá systémové instrukce, spravuje úrovně myšlení, odstraňuje nepodporované parametry
`gemini-cli.ts` | Rozhraní příkazového řádku Google Gemini | Vytvoření vlastní URL adresy ( `streamGenerateContent` ), aktualizace tokenu Google OAuth
`github.ts` | GitHub Copilot | Systém duálních tokenů (GitHub OAuth + Copilot token), napodobování hlaviček VSCode
`kiro.ts` | AWS CodeWhisperer | Binární parsování AWS EventStream, rámce událostí AMZN, odhad tokenů
`index.ts` | — | Továrna: název poskytovatele map → třída exekutoru s výchozím záložním nastavením
| Vykonavatel | Poskytovatel | Klíčové specializace |
| ---------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `base.ts` | — | Abstraktní základ: tvorba URL adres, hlavičky, logika opakování, aktualizace přihlašovacích údajů |
| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Aktualizace generického tokenu OAuth pro standardní poskytovatele |
| `antigravity.ts` | Kód Google Cloud | Generování ID projektu/relace, záložní více URL adres, vlastní analýza opakovaných pokusů z chybových zpráv („reset po 2h7m23s“) |
| `cursor.ts` | IDE kurzoru | **Nejsložitější** : autorizace kontrolního součtu SHA-256, kódování požadavků Protobuf, analýza binárních EventStream → SSE odpovědí |
| `codex.ts` | OpenAI Codex | Vkládá systémové instrukce, spravuje úrovně myšlení, odstraňuje nepodporované parametry |
| `gemini-cli.ts` | Google Gemini CLI | Vytvoření vlastní URL adresy ( `streamGenerateContent` ), aktualizace tokenu Google OAuth |
| `github.ts` | GitHub Copilot | Systém duálních tokenů (GitHub OAuth + Copilot token), napodobování hlaviček VSCode |
| `kiro.ts` | AWS CodeWhisperer | Binární parsování AWS EventStream, rámce událostí AMZN, odhad tokenů |
| `index.ts` | — | Továrna: název poskytovatele map → třída exekutoru s výchozím záložním nastavením |
---
@@ -212,12 +212,12 @@ Vykonavatel | Poskytovatel | Klíčové specializace
**Orchestrační vrstva** koordinuje překlad, provádění, streamování a zpracování chyb.
Soubor | Účel
--- | ---
`chatCore.ts` | **Centrální orchestrátor** (~600 řádků). Zvládá kompletní životní cyklus požadavku: detekce formátu → překlad → odeslání exekutoru → streamovaná/nestreamovaná odpověď → aktualizace tokenu → zpracování chyb → protokolování využití.
`responsesHandler.ts` | Adaptér pro OpenAI Responses API: převádí formát odpovědí → Dokončení chatu → odesílá do `chatCore` → převádí SSE zpět do formátu odpovědí.
`embeddings.ts` | Obslužná rutina generování embeddingu: řeší model embeddingu → poskytovatele, odesílá do API poskytovatele, vrací odpověď na embedding kompatibilní s OpenAI. Podporuje 6+ poskytovatelů.
`imageGeneration.ts` | Obslužná rutina generování obrázků: řeší model obrázku → poskytovatele, podporuje režimy kompatibilní s OpenAI, Gemini-image (Antigravity) a fallback (Nebius). Vrací obrázky v base64 nebo URL.
| Soubor | Účel |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chatCore.ts` | **Centrální orchestrátor** (~600 řádků). Zvládá kompletní životní cyklus požadavku: detekce formátu → překlad → odeslání exekutoru → streamovaná/nestreamovaná odpověď → aktualizace tokenu → zpracování chyb → protokolování využití. |
| `responsesHandler.ts` | Adaptér pro OpenAI Responses API: převádí formát odpovědí → Dokončení chatu → odesílá do `chatCore` → převádí SSE zpět do formátu odpovědí. |
| `embeddings.ts` | Obslužná rutina generování embeddingu: řeší model embeddingu → poskytovatele, odesílá do API poskytovatele, vrací odpověď na embedding kompatibilní s OpenAI. Podporuje 6+ poskytovatelů. |
| `imageGeneration.ts` | Obslužná rutina generování obrázků: řeší model obrázku → poskytovatele, podporuje režimy kompatibilní s OpenAI, Gemini-image (Antigravity) a fallback (Nebius). Vrací obrázky v base64 nebo URL. |
#### Životní cyklus požadavku (chatCore.ts)
@@ -262,22 +262,22 @@ sequenceDiagram
Obchodní logika, která podporuje obslužné rutiny a vykonavatele.
Soubor | Účel
--- | ---
`provider.ts` | **Detekce formátu** ( `detectFormat` ): analyzuje strukturu těla požadavku a identifikuje formáty Claude/OpenAI/Gemini/Antigravity/Responses (včetně heuristiky `max_tokens` pro Claude). Dále: tvorba URL, tvorba hlaviček, normalizace konfigurace thinking. Podporuje dynamické poskytovatele kompatibilní `openai-compatible-*` a `anthropic-compatible-*` .
`model.ts` | Analýza řetězců modelu ( `claude/model-name``{provider: "claude", model: "model-name"}` ), rozlišení aliasů s detekcí kolizí, sanitizace vstupu (odmítá průchod cestou/řídicí znaky) a rozlišení informací o modelu s podporou asynchronních metod pro získávání aliasů.
`accountFallback.ts` | Ovládání limitů rychlosti: exponenciální upomínka (1 s → 2 s → 4 s → max. 2 min), správa doby zpoždění účtu, klasifikace chyb (které chyby spouštějí fallback a které ne).
`tokenRefresh.ts` | Aktualizace tokenu OAuth pro **všechny poskytovatele** : Google (Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub (duální token OAuth + Copilot), Kiro (AWS SSO OIDC + sociální ověřování). Zahrnuje mezipaměť deduplikace promise za provozu a opakování s exponenciálním zpožděním.
`combo.ts` | **Kombinované modely** : řetězce záložních modelů. Pokud model A selže s chybou způsobilou pro záložní model, zkuste model B, poté C atd. Vrací skutečné stavové kódy upstreamu.
`usage.ts` | Načítá data o kvótách/využití z API poskytovatelů (kvóty GitHub Copilot, kvóty modelu Antigravity, limity rychlosti Codexu, rozpisy využití Kiro, nastavení Claude).
`accountSelector.ts` | Inteligentní výběr účtu s algoritmem bodování: pro výběr optimálního účtu pro každý požadavek se zohledňuje priorita, zdravotní stav, pozice v systému round robin a stav ochlazování.
`contextManager.ts` | Správa životního cyklu kontextu požadavku: vytváří a sleduje objekty kontextu pro každý požadavek s metadaty (ID požadavku, časová razítka, informace o poskytovateli) pro ladění a protokolování.
`ipFilter.ts` | Řízení přístupu založené na IP adrese: podporuje režimy povolených seznamů a blokovaných seznamů. Před zpracováním požadavků API ověřuje IP adresu klienta podle nakonfigurovaných pravidel.
`sessionManager.ts` | Sledování relací s otisky prstů klientů: sleduje aktivní relace pomocí hašovaných identifikátorů klientů, monitoruje počty požadavků a poskytuje metriky relací.
`signatureCache.ts` | Mezipaměť deduplikace na základě signatur požadavků: zabraňuje duplicitním požadavkům ukládáním nedávných signatur požadavků do mezipaměti a vrácením odpovědí z mezipaměti pro identické požadavky v rámci časového okna.
`systemPrompt.ts` | Globální vložení systémového výzvy: přidá konfigurovatelnou systémovou výzvu ke všem požadavkům s možností kompatibility pro jednotlivé poskytovatele.
`thinkingBudget.ts` | Správa rozpočtu tokenů uvažování: podporuje režimy průchodu, automatický (konfigurace strip thinking), vlastní (pevný rozpočet) a adaptivní (měřítko složitosti) pro řízení tokenů myšlení/uvažování.
`wildcardRouter.ts` | Směrování podle vzorů zástupných znaků: rozpoznává vzory zástupných znaků (např. `*/claude-*` ) na konkrétní páry poskytovatel/model na základě dostupnosti a priority.
| Soubor | Účel |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `provider.ts` | **Detekce formátu** ( `detectFormat` ): analyzuje strukturu těla požadavku a identifikuje formáty Claude/OpenAI/Gemini/Antigravity/Responses (včetně heuristiky `max_tokens` pro Claude). Dále: tvorba URL, tvorba hlaviček, normalizace konfigurace thinking. Podporuje dynamické poskytovatele kompatibilní `openai-compatible-*` a `anthropic-compatible-*` . |
| `model.ts` | Analýza řetězců modelu ( `claude/model-name``{provider: "claude", model: "model-name"}` ), rozlišení aliasů s detekcí kolizí, sanitizace vstupu (odmítá průchod cestou/řídicí znaky) a rozlišení informací o modelu s podporou asynchronních metod pro získávání aliasů. |
| `accountFallback.ts` | Ovládání limitů rychlosti: exponenciální upomínka (1 s → 2 s → 4 s → max. 2 min), správa doby zpoždění účtu, klasifikace chyb (které chyby spouštějí fallback a které ne). |
| `tokenRefresh.ts` | Aktualizace tokenu OAuth pro **všechny poskytovatele** : Google (Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub (duální token OAuth + Copilot), Kiro (AWS SSO OIDC + sociální ověřování). Zahrnuje mezipaměť deduplikace promise za provozu a opakování s exponenciálním zpožděním. |
| `combo.ts` | **Kombinované modely** : řetězce záložních modelů. Pokud model A selže s chybou způsobilou pro záložní model, zkuste model B, poté C atd. Vrací skutečné stavové kódy upstreamu. |
| `usage.ts` | Načítá data o kvótách/využití z API poskytovatelů (kvóty GitHub Copilot, kvóty modelu Antigravity, limity rychlosti Codexu, rozpisy využití Kiro, nastavení Claude). |
| `accountSelector.ts` | Inteligentní výběr účtu s algoritmem bodování: pro výběr optimálního účtu pro každý požadavek se zohledňuje priorita, zdravotní stav, pozice v systému round robin a stav ochlazování. |
| `contextManager.ts` | Správa životního cyklu kontextu požadavku: vytváří a sleduje objekty kontextu pro každý požadavek s metadaty (ID požadavku, časová razítka, informace o poskytovateli) pro ladění a protokolování. |
| `ipFilter.ts` | Řízení přístupu založené na IP adrese: podporuje režimy povolených seznamů a blokovaných seznamů. Před zpracováním požadavků API ověřuje IP adresu klienta podle nakonfigurovaných pravidel. |
| `sessionManager.ts` | Sledování relací s otisky prstů klientů: sleduje aktivní relace pomocí hašovaných identifikátorů klientů, monitoruje počty požadavků a poskytuje metriky relací. |
| `signatureCache.ts` | Mezipaměť deduplikace na základě signatur požadavků: zabraňuje duplicitním požadavkům ukládáním nedávných signatur požadavků do mezipaměti a vrácením odpovědí z mezipaměti pro identické požadavky v rámci časového okna. |
| `systemPrompt.ts` | Globální vložení systémového výzvy: přidá konfigurovatelnou systémovou výzvu ke všem požadavkům s možností kompatibility pro jednotlivé poskytovatele. |
| `thinkingBudget.ts` | Správa rozpočtu tokenů uvažování: podporuje režimy průchodu, automatický (konfigurace strip thinking), vlastní (pevný rozpočet) a adaptivní (měřítko složitosti) pro řízení tokenů myšlení/uvažování. |
| `wildcardRouter.ts` | Směrování podle vzorů zástupných znaků: rozpoznává vzory zástupných znaků (např. `*/claude-*` ) na konkrétní páry poskytovatel/model na základě dostupnosti a priority. |
#### Deduplikace obnovení tokenů
@@ -374,13 +374,13 @@ graph TD
end
```
Adresář | Soubory | Popis
--- | --- | ---
`request/` | 8 překladatelů | Převod těl požadavků mezi formáty. Každý soubor se při importu sám zaregistruje pomocí `register(from, to, fn)` .
`response/` | 7 překladatelů | Převádí bloky odpovědí streamovaných dat mezi formáty. Zpracovává typy událostí SSE, myšlenkové bloky a volání nástrojů.
`helpers/` | 6 pomocníků | Sdílené utility: `claudeHelper` (extrakce systémových prompts, thinking config), `geminiHelper` (mapování částí/obsahu), `openaiHelper` (filtrování formátů), `toolCallHelper` (generování ID, vkládání chybějících odpovědí), `maxTokensHelper` , `responsesApiHelper` .
`index.ts` | — | Překladový engine: `translateRequest()` , `translateResponse()` , správa stavu, registr.
`formats.ts` | — | Formátovací konstanty: `OPENAI` , `CLAUDE` , `GEMINI` , `ANTIGRAVITY` , `KIRO` , `CURSOR` , `OPENAI_RESPONSES` .
| Adresář | Soubory | Popis |
| ------------ | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `request/` | 8 překladatelů | Převod těl požadavků mezi formáty. Každý soubor se při importu sám zaregistruje pomocí `register(from, to, fn)` . |
| `response/` | 7 překladatelů | Převádí bloky odpovědí streamovaných dat mezi formáty. Zpracovává typy událostí SSE, myšlenkové bloky a volání nástrojů. |
| `helpers/` | 6 pomocníků | Sdílené utility: `claudeHelper` (extrakce systémových prompts, thinking config), `geminiHelper` (mapování částí/obsahu), `openaiHelper` (filtrování formátů), `toolCallHelper` (generování ID, vkládání chybějících odpovědí), `maxTokensHelper` , `responsesApiHelper` . |
| `index.ts` | — | Překladový engine: `translateRequest()` , `translateResponse()` , správa stavu, registr. |
| `formats.ts` | — | Formátovací konstanty: `OPENAI` , `CLAUDE` , `GEMINI` , `ANTIGRAVITY` , `KIRO` , `CURSOR` , `OPENAI_RESPONSES` . |
#### Klíčový design: Samoregistrující se pluginy
@@ -397,15 +397,15 @@ import "./request/claude-to-openai.js"; // ← self-registers
### 4.6 Nástroje ( `open-sse/utils/` )
Soubor | Účel
--- | ---
`error.ts` | Vytváření chybové odezvy (formát kompatibilní s OpenAI), parsování chyb v upstreamu, extrakce doby opakování Antigravity z chybových zpráv, streamování chyb SSE.
`stream.ts` | **SSE Transform Stream** — základní streamovací kanál. Dva režimy: `TRANSLATE` (plný překlad formátu) a `PASSTHROUGH` (normalizace + extrakce využití). Zpracovává ukládání bloků do vyrovnávací paměti, odhad využití a sledování délky obsahu. Instance kodéru/dekodéru pro každý stream se vyhýbají sdílenému stavu.
`streamHelpers.ts` | Nízkoúrovňové utility SSE: `parseSSELine` (tolerantní k bílým znakům), `hasValuableContent` (filtruje prázdné segmenty pro OpenAI/Claude/Gemini), `fixInvalidId` , `formatSSE` (serializace SSE s ohledem na formát s čištěním `perf_metrics` ).
`usageTracking.ts` | Extrakce využití tokenů z libovolného formátu (Claude/OpenAI/Gemini/Responses), odhad s oddělenými poměry znaků na token pro jednotlivé nástroje/zprávy, přidání vyrovnávací paměti (bezpečnostní rezerva 2000 tokenů), filtrování polí specifických pro formát, protokolování konzole s barvami ANSI.
`requestLogger.ts` | Protokolování požadavků na základě souborů (přihlášení pomocí `ENABLE_REQUEST_LOGS=true` ). Vytváří složky relací s očíslovanými soubory: `1_req_client.json``7_res_client.txt` . Veškeré I/O operace jsou asynchronní (aktivní a zapomenutý). Maskuje citlivé hlavičky.
`bypassHandler.ts` | Zachycuje specifické vzory z Claude CLI (extrakce názvu, zahřívání, počet) a vrací falešné odpovědi bez volání jakéhokoli poskytovatele. Podporuje streamování i nestreamování. Záměrně omezeno na rozsah Claude CLI.
`networkProxy.ts` | Rozpozná URL odchozí proxy pro daného poskytovatele s prioritou: konfigurace specifická pro poskytovatele → globální konfigurace → proměnné prostředí ( `HTTPS_PROXY` / `HTTP_PROXY` / `ALL_PROXY` ). Podporuje výjimky `NO_PROXY` . Ukládá konfiguraci do mezipaměti po dobu 30 sekund.
| Soubor | Účel |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `error.ts` | Vytváření chybové odezvy (formát kompatibilní s OpenAI), parsování chyb v upstreamu, extrakce doby opakování Antigravity z chybových zpráv, streamování chyb SSE. |
| `stream.ts` | **SSE Transform Stream** — základní streamovací kanál. Dva režimy: `TRANSLATE` (plný překlad formátu) a `PASSTHROUGH` (normalizace + extrakce využití). Zpracovává ukládání bloků do vyrovnávací paměti, odhad využití a sledování délky obsahu. Instance kodéru/dekodéru pro každý stream se vyhýbají sdílenému stavu. |
| `streamHelpers.ts` | Nízkoúrovňové utility SSE: `parseSSELine` (tolerantní k bílým znakům), `hasValuableContent` (filtruje prázdné segmenty pro OpenAI/Claude/Gemini), `fixInvalidId` , `formatSSE` (serializace SSE s ohledem na formát s čištěním `perf_metrics` ). |
| `usageTracking.ts` | Extrakce využití tokenů z libovolného formátu (Claude/OpenAI/Gemini/Responses), odhad s oddělenými poměry znaků na token pro jednotlivé nástroje/zprávy, přidání vyrovnávací paměti (bezpečnostní rezerva 2000 tokenů), filtrování polí specifických pro formát, protokolování konzole s barvami ANSI. |
| `requestLogger.ts` | Protokolování požadavků na základě souborů (přihlášení pomocí `ENABLE_REQUEST_LOGS=true` ). Vytváří složky relací s očíslovanými soubory: `1_req_client.json``7_res_client.txt` . Veškeré I/O operace jsou asynchronní (aktivní a zapomenutý). Maskuje citlivé hlavičky. |
| `bypassHandler.ts` | Zachycuje specifické vzory z Claude CLI (extrakce názvu, zahřívání, počet) a vrací falešné odpovědi bez volání jakéhokoli poskytovatele. Podporuje streamování i nestreamování. Záměrně omezeno na rozsah Claude CLI. |
| `networkProxy.ts` | Rozpozná URL odchozí proxy pro daného poskytovatele s prioritou: konfigurace specifická pro poskytovatele → globální konfigurace → proměnné prostředí ( `HTTPS_PROXY` / `HTTP_PROXY` / `ALL_PROXY` ). Podporuje výjimky `NO_PROXY` . Ukládá konfiguraci do mezipaměti po dobu 30 sekund. |
#### Streamovací kanál SSE
@@ -449,32 +449,32 @@ logs/
### 4.7 Aplikační vrstva ( `src/` )
Adresář | Účel
--- | ---
`src/app/` | Webové uživatelské rozhraní, trasy API, middleware Express, obslužné rutiny zpětných volání OAuth
`src/lib/` | Přístup k databázi ( `localDb.ts` , `usageDb.ts` ), ověřování, sdílení
`src/mitm/` | Nástroje proxy typu „man-in-the-middle“ pro zachycení provozu poskytovatelů
`src/models/` | Definice modelů databáze
`src/shared/` | Obálky kolem funkcí open-sse (provider, stream, error atd.)
`src/sse/` | Obslužné rutiny koncových bodů SSE, které propojují knihovnu open-sse s trasami Express
`src/store/` | Správa stavu aplikací
| Adresář | Účel |
| ------------- | ------------------------------------------------------------------------------------------------- |
| `src/app/` | Webové uživatelské rozhraní, trasy API, middleware Express, obslužné rutiny zpětných volání OAuth |
| `src/lib/` | Přístup k databázi ( `localDb.ts` , `usageDb.ts` ), ověřování, sdílení |
| `src/mitm/` | Nástroje proxy typu „man-in-the-middle“ pro zachycení provozu poskytovatelů |
| `src/models/` | Definice modelů databáze |
| `src/shared/` | Obálky kolem funkcí open-sse (provider, stream, error atd.) |
| `src/sse/` | Obslužné rutiny koncových bodů SSE, které propojují knihovnu open-sse s trasami Express |
| `src/store/` | Správa stavu aplikací |
#### Významné trasy API
Trasa | Metody | Účel
--- | --- | ---
`/api/provider-models` | ZÍSKAT/ODESLAT/SMAZAT | CRUD pro vlastní modely na poskytovatele
`/api/models/catalog` | ZÍSKAT | Agregovaný katalog všech modelů (chat, embedding, image, custom) seskupených podle poskytovatele
`/api/settings/proxy` | ZÍSKAT/VLOŽIT/ODSTRANIT | Konfigurace hierarchické odchozí proxy ( `global/providers/combos/keys` )
`/api/settings/proxy/test` | ZVEŘEJNIT | Ověřuje připojení proxy a vrací veřejnou IP adresu/latenci
`/v1/providers/[provider]/chat/completions` | ZVEŘEJNIT | Vyhrazené dokončování chatu pro jednotlivé poskytovatele s ověřováním modelu
`/v1/providers/[provider]/embeddings` | ZVEŘEJNIT | Vyhrazené vkládání pro jednotlivé poskytovatele s ověřováním modelu
`/v1/providers/[provider]/images/generations` | ZVEŘEJNIT | Vyhrazené generování obrázků pro každého poskytovatele s ověřováním modelu
`/api/settings/ip-filter` | ZÍSKAT/VLOŽIT | Správa povolených/blokovaných IP adres
`/api/settings/thinking-budget` | ZÍSKAT/VLOŽIT | Konfigurace rozpočtu tokenů zdůvodnění (průchozí/automatická/vlastní/adaptivní)
`/api/settings/system-prompt` | ZÍSKAT/VLOŽIT | Globální vložení systémového promptu pro všechny požadavky
`/api/sessions` | ZÍSKAT | Sledování a metriky aktivních relací
`/api/rate-limits` | ZÍSKAT | Stav limitu sazby na účet
| Trasa | Metody | Účel |
| --------------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------ |
| `/api/provider-models` | GET/POST/DELETE | CRUD pro vlastní modely na poskytovatele |
| `/api/models/catalog` | GET | Agregovaný katalog všech modelů (chat, embedding, image, custom) seskupených podle poskytovatele |
| `/api/settings/proxy` | GET/PUT/DELETE | Konfigurace hierarchické odchozí proxy ( `global/providers/combos/keys` ) |
| `/api/settings/proxy/test` | POST | Ověřuje připojení proxy a vrací veřejnou IP adresu/latenci |
| `/v1/providers/[provider]/chat/completions` | POST | Vyhrazené dokončování chatu pro jednotlivé poskytovatele s ověřováním modelu |
| `/v1/providers/[provider]/embeddings` | POST | Vyhrazené vkládání pro jednotlivé poskytovatele s ověřováním modelu |
| `/v1/providers/[provider]/images/generations` | POST | Vyhrazené generování obrázků pro každého poskytovatele s ověřováním modelu |
| `/api/settings/ip-filter` | GET/PUT | Správa povolených/blokovaných IP adres |
| `/api/settings/thinking-budget` | GET/PUT | Konfigurace rozpočtu tokenů zdůvodnění (průchozí/automatická/vlastní/adaptivní) |
| `/api/settings/system-prompt` | GET/PUT | Globální vložení systémového promptu pro všechny požadavky |
| `/api/sessions` | GET | Sledování a metriky aktivních relací |
| `/api/rate-limits` | GET | Stav limitu sazby na účet |
---
@@ -512,38 +512,38 @@ K hlášenému využití je přidána vyrovnávací paměť o kapacitě 2000 tok
## 6. Podporované formáty
Formát | Směr | Identifikátor
--- | --- | ---
Dokončení chatu OpenAI | zdroj + cíl | `openai`
API pro odpovědi OpenAI | zdroj + cíl | `openai-responses`
Antropic Claude | zdroj + cíl | `claude`
Google Gemini | zdroj + cíl | `gemini`
Rozhraní příkazového řádku Google Gemini | pouze cíl | `gemini-cli`
Antigravitace | zdroj + cíl | `antigravity`
AWS Kiro | pouze cíl | `kiro`
Kurzor | pouze cíl | `cursor`
| Formát | Směr | Identifikátor |
| ----------------------- | ----------- | ------------------ |
| OpenAI Chat Completions | zdroj + cíl | `openai` |
| OpenAI Responses API | zdroj + cíl | `openai-responses` |
| Anthropic Claude | zdroj + cíl | `claude` |
| Google Gemini | zdroj + cíl | `gemini` |
| Google Gemini CLI | jen cíl | `gemini-cli` |
| Antigravity | zdroj + cíl | `antigravity` |
| AWS Kiro | jen cíl | `kiro` |
| Cursor | jen cíl | `cursor` |
---
## 7. Podporovaní poskytovatelé
Poskytovatel | Metoda ověřování | Vykonavatel | Klíčové poznámky
--- | --- | --- | ---
Antropic Claude | Klíč API nebo OAuth | Výchozí | Používá hlavičku `x-api-key`
Google Gemini | Klíč API nebo OAuth | Výchozí | Používá hlavičku `x-goog-api-key`
Rozhraní příkazového řádku Google Gemini | OAuth | GeminiCLI | Používá koncový bod `streamGenerateContent`
Antigravitace | OAuth | Antigravitace | Záložní více URL adres, vlastní analýza opakovaných pokusů
OpenAI | Klíč API | Výchozí | Autorizace standardního nosiče
Kodex | OAuth | Kodex | Vkládá systémové instrukce, řídí myšlení
GitHub Copilot | OAuth + token Copilot | Github | Duální token, napodobování záhlaví VSCode
Kiro (AWS) | AWS SSO OIDC nebo sociální sítě | Kiro | Analýza binárního EventStreamu
IDE kurzoru | Autorizace kontrolního součtu | Kurzor | Kódování Protobuf, kontrolní součty SHA-256
Qwen | OAuth | Výchozí | Standardní ověřování
iFlow | OAuth (základní + nosič) | Výchozí | Duální hlavička pro autorizaci
OpenRouter | Klíč API | Výchozí | Autorizace standardního nosiče
GLM, Kimi, MiniMax | Klíč API | Výchozí | Kompatibilní s Claude, použijte `x-api-key`
`openai-compatible-*` | Klíč API | Výchozí | Dynamické: jakýkoli koncový bod kompatibilní s OpenAI
`anthropic-compatible-*` | Klíč API | Výchozí | Dynamický: jakýkoli koncový bod kompatibilní s Claude
| Poskytovatel | Metoda ověřování | Vykonavatel | Klíčové poznámky |
| ------------------------ | ------------------------ | ----------- | -------------------------------------------- |
| Anthropic Claude | API klíč nebo OAuth | Výchozí | Používá hlavičku `x-api-key` |
| Google Gemini | API klíč nebo OAuth | Výchozí | Používá hlavičku `x-goog-api-key` |
| Google Gemini CLI | OAuth | GeminiCLI | Používá koncový bod `streamGenerateContent` |
| Antigravity | OAuth | Antigravity | Záložní více URL, analýza opakovaných pokusů |
| OpenAI | API klíč | Výchozí | Autorizace standardního nosiče |
| Codex | OAuth | Codex | Vkládá systémové instrukce, řídí myšlení |
| GitHub Copilot | OAuth + Copilot token | Github | Duální token, napodobování záhlaví VSCode |
| Kiro (AWS) | AWS SSO OIDC nebo Social | Kiro | Analýza binárního EventStreamu |
| Cursor IDE | Checksum auth | Cursor | Kódování Protobuf, kontrolní součty SHA-256 |
| Qwen | OAuth | Výchozí | Standardní ověřování |
| iFlow | OAuth (Basic + Bearer) | Výchozí | Duální hlavička pro autorizaci |
| OpenRouter | API klíč | Výchozí | Autorizace standardního nosiče |
| GLM, Kimi, MiniMax | API klíč | Výchozí | Kompatibilní s Claude, použijte `x-api-key` |
| `openai-compatible-*` | API klíč | Výchozí | Dynamické: jakýkoli OpenAI kompatibilní |
| `anthropic-compatible-*` | API klíč | Výchozí | Dynamické: jakýkoli Claude kompatibilní |
---
+67 -137
View File
@@ -18,6 +18,38 @@ _Váš univerzální API proxy jeden endpoint, více než 44 poskytovatelů,
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
## 🖼️ Hlavní ovládací panel
<div align="center"> <img src="./docs/screenshots/MainOmniRoute.png" alt="Řídicí panel OmniRoute" width="800"> </div>
@@ -58,9 +90,9 @@ _Připojte libovolný nástroj IDE nebo CLI s umělou inteligencí přes OmniRou
</tr>
<tr>
<td align="center" width="110"> <a href="https://github.com/anomalyco/opencode"><img src="./public/providers/opencode.svg" alt="OpenCode" width="48"><br><b>OpenCode</b></a><br> <sub>⭐ 106 tisíc</sub> </td>
<td align="center" width="110"> <a href="https://github.com/openai/codex"><img src="./public/providers/codex.png" alt="CLI Codexu" width="48"><br><b>CLI Codexu</b></a><br> <sub>⭐ 60,8 tisíc</sub> </td>
<td align="center" width="110"> <a href="https://github.com/openai/codex"><img src="./public/providers/codex.png" alt="Codex CLI" width="48"><br><b>Codex CLI</b></a><br> <sub>⭐ 60,8 tisíc</sub> </td>
<td align="center" width="110"> <a href="https://github.com/anthropics/claude-code"><img src="./public/providers/claude.png" alt="Claude Code" width="48"><br><b>Claude Code</b></a><br> <sub>⭐ 67,3 tisíc</sub> </td>
<td align="center" width="110"> <a href="https://github.com/google-gemini/gemini-cli"><img src="./public/providers/gemini-cli.png" alt="Rozhraní příkazového řádku Gemini" width="48"><br> <b>Rozhraní příkazového řádku Gemini</b></a><br> <sub>⭐ 94,7 tisíc</sub> </td>
<td align="center" width="110"> <a href="https://github.com/google-gemini/gemini-cli"><img src="./public/providers/gemini-cli.png" alt="Gemini CLI" width="48"><br> <b>Gemini CLI</b></a><br> <sub>⭐ 94,7 tisíc</sub> </td>
<td align="center" width="110"> <a href="https://github.com/Kilo-Org/kilocode"><img src="./public/providers/kilocode.png" alt="Kilo kód" width="48"><br><b>Kilo kód</b></a><br> <sub>⭐ 15,5 tisíc</sub> </td>
</tr>
</table>
@@ -165,7 +197,7 @@ OpenAI používá jeden formát, Claude (Anthropic) jiný a Gemini ještě třet
**Jak to OmniRoute řeší:**
- **Sjednocený koncový bod** — Jeden `http://localhost:20128/v1` slouží jako proxy pro všech 44+ poskytovatelů.
- **Sjednocený koncový bod** — Jeden `http://localhost:20128/v1` slouží jako proxy pro všech 67+ poskytovatelů.
- **Překlad formátu** — Automatický a transparentní: OpenAI ↔ Claude ↔ Gemini ↔ Responses API
- **Sanitizace odpovědí** — Odstraňuje nestandardní pole ( `x_groq` , `usage_breakdown` , `service_tier` ), která porušují OpenAI SDK v1.83+
- **Normalizace rolí** — Převádí `developer``system` pro poskytovatele bez OpenAI; `system``user` pro GLM/ERNIE
@@ -799,29 +831,29 @@ Po minimalizaci se OmniRoute nachází v systémové liště a nabízí rychlé
## 💰 Přehled cen
| Úroveň | Poskytovatel | Náklady | Obnovení kvóty | Nejlepší pro |
| --------------------------------- | -------------------------------- | ------------------------------------ | ------------------------------------------ | --------------------------------------------------------- |
| **💳 PŘEDPLATNÉ** | Claude Code (profesionál) | 20 dolarů měsíčně | 5 hodin + týdně | Již přihlášen/a k odběru |
| Kodex (Plus/Pro) | 20200 USD/měsíc | 5 hodin + týdně | Uživatelé OpenAI |
| Rozhraní příkazového řádku Gemini | **UVOLNIT** | 180 tisíc měsíčně + 1 tisíc denně | Každý! |
| GitHub Copilot | 1019 USD/měsíc | Měsíční | Uživatelé GitHubu |
| **🔑 KLÍČ API** | NVIDIA NIM | **ZDARMA** (vývoj navždy) | ~40 ot./min | 70+ otevřených modelů |
| Mozky | **ZDARMA** (1 milion tok/den) | 60 000 otáček za minutu / 30 ot./min | Nejrychlejší na světě |
| Groq | **ZDARMA** (30 ot./min.) | 14,4 tisíc otáček za minutu | Ultrarychlá lama/gema |
| DeepSeek V3.2 | 0,27/1,10 USD za 1 milion | Žádný | Nejlepší zdůvodnění ceny a kvality |
| xAI Grok-4 Rychlý | **0,20/0,50 USD za 1 milion** 🆕 | Žádný | Nejrychlejší + volání nástroje, ultranízké |
| xAI Grok-4 (standardní) | 0,20/1,50 USD za 1 milion 🆕 | Žádný | Vlajková loď Reasoning od xAI |
| Mistral | Zkušební verze zdarma + placené | Omezená sazba | Evropská umělá inteligence |
| OpenRouter | Platba za použití | Žádný | Více než 100 modelů agregováno. |
| **💰 LEVNÉ** | GLM-5 (přes Z.AI) 🆕 | 0,5 USD/1 milion | Denně v 10:00 | Výstup 128 tisíc obrazových bodů, nejnovější vlajková loď |
| GLM-4.7 | 0,6 USD/1 milion | Denně v 10:00 | Záloha rozpočtu |
| MiniMax M2.5 🆕 | Vstup 0,3 USD/1 milion | 5hodinové válcování | Úvaha + agentní úkoly |
| MiniMax M2.1 | 0,2 USD/1 milion | 5hodinové válcování | Nejlevnější varianta |
| Kimi K2.5 (Moonshot API) 🆕 | Platba za použití | Žádný | Přímý přístup k Moonshot API |
| Kimi K2 | 9 dolarů měsíčně bez závazků | 10 milionů tokenů/měsíc | Předvídatelné náklady |
| **🆓 ZDARMA** | iFlow | **0 dolarů** | Neomezený | 5 modelů neomezeně |
| Qwen | **0 dolarů** | Neomezený | 4 modely neomezeně |
| Kiro | **0 dolarů** | Neomezený | Claude Sonnet/Haiku (tvorce AWS) |
| Úroveň | Poskytovatel | Náklady | Obnovení kvóty | Nejlepší pro |
| --------------------------- | -------------------------------- | ------------------------------------ | ------------------------------------------ | --------------------------------------------------------- |
| **💳 PŘEDPLATNÉ** | Claude Code (profesionál) | 20 dolarů měsíčně | 5 hodin + týdně | Již přihlášen/a k odběru |
| Kodex (Plus/Pro) | 20200 USD/měsíc | 5 hodin + týdně | Uživatelé OpenAI |
| Gemini CLI | **UVOLNIT** | 180 tisíc měsíčně + 1 tisíc denně | Každý! |
| GitHub Copilot | 1019 USD/měsíc | Měsíční | Uživatelé GitHubu |
| **🔑 KLÍČ API** | NVIDIA NIM | **ZDARMA** (vývoj navždy) | ~40 ot./min | 70+ otevřených modelů |
| Mozky | **ZDARMA** (1 milion tok/den) | 60 000 otáček za minutu / 30 ot./min | Nejrychlejší na světě |
| Groq | **ZDARMA** (30 ot./min.) | 14,4 tisíc otáček za minutu | Ultrarychlá lama/gema |
| DeepSeek V3.2 | 0,27/1,10 USD za 1 milion | Žádný | Nejlepší zdůvodnění ceny a kvality |
| xAI Grok-4 Rychlý | **0,20/0,50 USD za 1 milion** 🆕 | Žádný | Nejrychlejší + volání nástroje, ultranízké |
| xAI Grok-4 (standardní) | 0,20/1,50 USD za 1 milion 🆕 | Žádný | Vlajková loď Reasoning od xAI |
| Mistral | Zkušební verze zdarma + placené | Omezená sazba | Evropská umělá inteligence |
| OpenRouter | Platba za použití | Žádný | Více než 100 modelů agregováno. |
| **💰 LEVNÉ** | GLM-5 (přes Z.AI) 🆕 | 0,5 USD/1 milion | Denně v 10:00 | Výstup 128 tisíc obrazových bodů, nejnovější vlajková loď |
| GLM-4.7 | 0,6 USD/1 milion | Denně v 10:00 | Záloha rozpočtu |
| MiniMax M2.5 🆕 | Vstup 0,3 USD/1 milion | 5hodinové válcování | Úvaha + agentní úkoly |
| MiniMax M2.1 | 0,2 USD/1 milion | 5hodinové válcování | Nejlevnější varianta |
| Kimi K2.5 (Moonshot API) 🆕 | Platba za použití | Žádný | Přímý přístup k Moonshot API |
| Kimi K2 | 9 dolarů měsíčně bez závazků | 10 milionů tokenů/měsíc | Předvídatelné náklady |
| **🆓 ZDARMA** | iFlow | **0 dolarů** | Neomezený | 5 modelů neomezeně |
| Qwen | **0 dolarů** | Neomezený | 4 modely neomezeně |
| Kiro | **0 dolarů** | Neomezený | Claude Sonnet/Haiku (tvorce AWS) |
> 🆕 **Přidány nové modely (březen 2026):** řada Grok-4 Fast za 0,20 USD/0,50 USD/M (benchmarkováno na 1143 ms o 30 % rychlejší než Gemini 2.5 Flash), GLM-5 přes Z.AI s výstupem 128K, uvažování MiniMax M2.5, aktualizované ceny DeepSeek V3.2, Kimi K2.5 přes Moonshot Direct API.
@@ -951,31 +983,6 @@ Pak v `/dashboard/media` → záložka **Přepis** : nahrajte libovolný zvukov
OmniRoute v2.0 je navržen jako operační platforma, nikoli pouze jako proxy pro relé.
### 🆕 Nové — Vylepšení inspirovaná ClawRouterem (březen 2026)
| Funkce | Co to dělá |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| ⚡ **Grok-4 Rychlá rodina** | Modely xAI za 0,20 USD/0,50 USD/M v benchmarku 1143 ms (o 30 % rychlejší než Gemini 2.5 Flash) |
| 🧠 **GLM-5 přes Z.AI** | 128 tisíc výstupních dat, 0,5 USD/1 milion USD nejnovější vlajková loď rodiny GLM |
| 🔮 **MiniMax M2.5** | Úvaha + agentní úkoly za 0,30 USD/1 milion významný upgrade oproti M2.1 |
| 🎯 **Příznak volání nástroje pro každý model** | `toolCalling: true/false` v registru — AutoCombo přeskakuje modely, které nepodporují nástroje. |
| 🌍 **Detekce vícejazyčného záměru** | Klíčová slova PT/ZH/ES/AR v bodování AutoCombo lepší výběr modelu pro neanglický obsah |
| 📊 **Záložní metody řízené benchmarkem** | Skutečná latence p95 z živých požadavků poskytuje kombinované skóre AutoCombo se učí ze skutečných dat |
| 🔁 **Požádat o deduplikaci** | Okno pro deduplikaci na základě hashování obsahu bezpečné pro více agentů, zabraňuje duplicitním platbám |
| 🔌 **Strategie pro zásuvné routery** | Rozšiřitelné rozhraní `RouterStrategy` přidejte si vlastní logiku směrování jako pluginy |
### 🚀 Předchozí verze v2.0.9+ — Hřiště, otisky prstů v CLI a ACP
| Funkce | Co to dělá |
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Modelové hřiště** | Stránka řídicího panelu pro přímé testování libovolného modelu selektory poskytovatele/modelu/koncového bodu, editor Monaco, streamování, přerušení, načasování |
| 🔏 **Porovnávání otisků prstů v CLI** | Řazení hlaviček/těl serveru podle poskytovatele tak, aby odpovídalo nativním podpisům CLI přepínání pro jednotlivé poskytovatele v Nastavení &gt; Zabezpečení. **Vaše IP adresa proxy serveru je zachována.** |
| 🤝 **Podpora ACP (Agent Client Protocol)** | Vyhledávání agentů CLI (Codex, Claude, Goose, Gemini CLI, OpenClaw + 9 dalších), generátor procesů, koncový bod `/api/acp/agents` |
| 🤖 **Řídicí panel agentů ACP** | Ladění Stránka Agenti — mřížka 14 agentů se stavem instalace, verzí a formulářem pro vlastní agenta pro libovolný nástroj CLI. Uživatelé **OpenCode** získají tlačítko „Stáhnout opencode.json“, které automaticky vygeneruje konfiguraci připravenou k použití se všemi dostupnými modely. |
| 🔧 **Směrování `apiFormat` pro vlastní model** | Vlastní modely s `apiFormat: "responses"` nyní správně směrují do překladače Responses API. |
| 🏢 **Izolace pracovního prostoru Codexu** | Více pracovních prostorů Codexu na jeden e-mail OAuth správně odděluje připojení podle ID pracovního prostoru |
| 🔄 **Automatická aktualizace elektronů** | Desktopová aplikace kontroluje aktualizace + automaticky se instaluje po restartu |
### 🤖 Operace s agenty a protokoly (v2.0)
| Funkce | Co to dělá |
@@ -1439,7 +1446,7 @@ Settings → Models → Advanced:
Pro konfiguraci jedním kliknutím použijte stránku **Nástroje CLI** na řídicím panelu nebo ručně upravte soubor `~/.claude/settings.json` .
### CLI Codexu
### Codex CLI
```bash
export OPENAI_BASE_URL="http://localhost:20128"
@@ -1676,94 +1683,17 @@ Pokud si teď nechcete nastavovat vlastní přihlašovací údaje, můžete stá
---
<details>
<summary><b>🇧🇷 Versão em Português</b></summary>
</details>
#### Dočasné řešení (bez vlastních přihlašovacích údajů)
#### Pokud používáte OAuth pro Antigravity / Gemini CLI?
Chcete-li získat přístup k přihlašovacím údajům bez vlastní konfigurace, můžete použít následující postup:
Ověřeno **Antigravity** a **Gemini CLI** pomocí **Google OAuth 2.0** pro autenticitu. O Google exige que a `redirect_uri` usada no fluxo OAuth seja **exatamente** uma das URIs pre-cadastradas no Google Cloud Console to use.
1. OmniRoute otevře URL autorizace Google
2. Po autorizaci se Google pokusí přesměrovat na `localhost` (což selže na vzdáleném serveru)
3. **Zkopírujte celou URL adresu** z adresního řádku prohlížeče
4. Vložte tuto URL adresu do pole zobrazeného v modálním okně připojení OmniRoute
5. Klikněte na **„Připojit"**
Jako credenciais OAuth embutidas no OmniRoute estão cadastradas **apenas para `localhost`** . Quando você acessa o OmniRoute em um servidor remote (ex: `https://omniroute.meuservidor.com` ), o Google rejeita a autenticação com:
```
Error 400: redirect_uri_mismatch
```
#### Řešení: Nakonfigurujte souas próprias credenciais OAuth
Você precisa criar um **OAuth 2.0 Client ID** no Google Cloud Console com a URI do seu server.
#### Přejít na přejezd
**1. Přístup ke službě Google Cloud Console**
Abra: [https://console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials)
**2. Crie um novo OAuth 2.0 Client ID**
- Klikněte na **„+ Vytvořit přihlašovací údaje“** → **„ID klienta OAuth“**
- Typ aplikace: **"Webová aplikace"**
- Název: escolha qualquer nome (např.: `OmniRoute Remote` )
**3. Adicione jako autorizované URI pro přesměrování**
Žádné pole **"URI autorizovaného přesměrování"** , adicione:
```
https://seu-servidor.com/callback
```
> Substitua `seu-servidor.com` pelo domínio ou IP do seu servidor (včetně portu se necessário, např.: `http://45.33.32.156:20128/callback` ).
**4. Uložte a kopii jako credenciais**
Após criar, o Google Mostrará o **Client ID** eo **Client Secret** .
**5. Nakonfigurujte jako variáveis de ambiente**
No seu `.env` (ou nas variáveis de ambiente do Docker):
```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. Reinicie o OmniRoute**
```bash
# Se usando npm:
npm run dev
# Se usando Docker:
docker restart omniroute
```
**7. Připojte se znovu**
Řídicí panel → Poskytovatelé → Antigravity (nebo Gemini CLI) → OAuth
Agora nebo Google redirecionará corretamente para `https://seu-servidor.com/callback` ea autenticação funcionará.
---
#### Řešení temporário (sem configurar credenciais próprias)
Chcete-li získat přístup k kriterii pověření, můžete použít adresu **URL** :
1. O OmniRoute abrirá a URL autorização Google
2. Após você autorizar, nebo Google tentará redirecionar para `localhost` (que falha no servidor remoto)
3. **Zkopírujte úplnou** adresu URL prohlížeče do svého prohlížeče (mesmo que a pagina não carregue)
4. Cole essa URL no campo que aparece no modal de conexão do OmniRoute
5. Klikněte na **„Připojit se“**
> Toto řešení funguje na základě autorizačního kódu na adrese URL a nezávislého přesměrování přesměrování nebo jiného.
> Toto řešení funguje, protože autorizační kód v URL adrese je platný bez ohledu na načtení přesměrovací stránky.
---
+112 -118
View File
@@ -20,30 +20,30 @@ Kompletní průvodce konfigurací poskytovatelů, vytvářením kombinací, inte
## 💰 Přehled cen
Úroveň | Poskytovatel | Náklady | Obnovení kvóty | Nejlepší pro
--- | --- | --- | --- | ---
**💳 PŘEDPLATNÉ** | Claude Code (profesionál) | 20 dolarů měsíčně | 5 hodin + týdně | Již přihlášen/a k odběru
| Kodex (Plus/Pro) | 20200 USD/měsíc | 5 hodin + týdně | Uživatelé OpenAI
| Rozhraní příkazového řádku Gemini | **UVOLNIT** | 180 tisíc měsíčně + 1 tisíc denně | Každý!
| GitHub Copilot | 1019 USD/měsíc | Měsíční | Uživatelé GitHubu
**🔑 KLÍČ API** | Hluboké vyhledávání | Platba za použití | Žádný | Laciné uvažování
| Groq | Platba za použití | Žádný | Ultrarychlá inference
| xAI (Grok) | Platba za použití | Žádný | Grok 4 uvažování
| Mistral | Platba za použití | Žádný | Modely hostované v EU
| Zmatek | Platba za použití | Žádný | Rozšířené vyhledávání
| Společně s umělou inteligencí | Platba za použití | Žádný | Modely s otevřeným zdrojovým kódem
| Ohňostroj s umělou inteligencí | Platba za použití | Žádný | Rychlé snímky FLUX
| Mozky | Platba za použití | Žádný | Rychlost v měřítku destičky
| Soudržný | Platba za použití | Žádný | Příkaz R+ RAG
| NVIDIA NIM | Platba za použití | Žádný | Podnikové modely
**💰 LEVNÉ** | GLM-4.7 | 0,6 USD/1 milion | Denně v 10:00 | Záloha rozpočtu
| MiniMax M2.1 | 0,2 USD/1 milion | 5hodinové válcování | Nejlevnější varianta
| Kimi K2 | 9 dolarů měsíčně bez závazků | 10 milionů tokenů/měsíc | Předvídatelné náklady
**🆓 ZDARMA** | iFlow | 0 dolarů | Neomezený | 8 modelů zdarma
| Qwen | 0 dolarů | Neomezený | 3 modely zdarma
| Kiro | 0 dolarů | Neomezený | Claude zdarma
| Úroveň | Poskytovatel | Náklady | Obnovení kvóty | Nejlepší pro |
| ----------------- | ----------------- | ---------------- | ------------------- | -------------------------- |
| **💳 PŘEDPLATNÉ** | Claude Code (pro) | 20 USD měsíc | 5h + týdně | Již přihlášené |
| | Kodex (Plus/Pro) | 20200 USD/měsíc | 5h + týdně | Uživatele OpenAI |
| | Gemini CLI | **ZDARMA** | 180K/mo + 1K/den | Každého! |
| | GitHub Copilot | 1019 USD/měsíc | Měsíční | Uživatele GitHubu |
| **🔑 KLÍČ API** | DeepSeek | Dle užití | Žádné | Laciné uvažování |
| | Groq | Dle užití | Žádné | Ultrarychlá inference |
| | xAI (Grok) | Dle užití | Žádné | Grok 4 uvažování |
| | Mistral | Dle užití | Žádné | Modely hostované v EU |
| | Perplexity | Dle užití | Žádné | Rozšířené vyhledávání |
| | Together AI | Dle užití | Žádné | Open Source modely |
| | Fireworks AI | Dle užití | Žádné | Rychlé FLUX obrázky |
| | Cerebras | Dle užití | Žádné | Rychlost destičkového čipu |
| | Cohere | Dle užití | Žádné | Command R+ RAG |
| | NVIDIA NIM | Dle užití | Žádné | Podnikové modely |
| **💰 LEVNÉ** | GLM-4.7 | $0.6/1M | Denně 10:00 | Levná záloha |
| | MiniMax M2.1 | $0.2/1M | 5hodinové válcování | Nejlevnější varianta |
| | Kimi K2 | 9 USD měsíc | 10M tokens/měsíc | Předvídatelné náklady |
| **🆓 ZDARMA** | iFlow | $0 | Neomezený | 8 modelů zdarma |
| | Qwen | $0 | Neomezený | 3 modely zdarma |
| | Kiro | $0 | Neomezený | Claude zdarma |
**💡 Tip pro profesionály:** Začněte s kombinací Gemini CLI (180 tisíc zdarma/měsíc) + iFlow (neomezeně zdarma) = 0 dolarů!
**💡 Pro Tip:** Začněte s kombinací Gemini CLI (180K zdarma/měsíc) + iFlow (neomezeně zdarma) = $0!
---
@@ -271,7 +271,7 @@ Upravit `~/.claude/config.json` :
}
```
### CLI Codexu
### Codex CLI
```bash
export OPENAI_BASE_URL="http://localhost:20128"
@@ -335,7 +335,7 @@ omniroute
omniroute --port 3000
```
Rozhraní příkazového řádku automaticky načte `.env` z adresáře `~/.omniroute/.env` nebo `./.env` .
CLI automaticky načte `.env` z adresáře `~/.omniroute/.env` nebo `./.env` .
### Nasazení VPS
@@ -407,23 +407,23 @@ Informace o režimu integrovaném s hostitelem s binárními soubory CLI nalezne
### Proměnné prostředí
Proměnná | Výchozí | Popis
--- | --- | ---
`JWT_SECRET` | `omniroute-default-secret-change-me` | Tajný klíč podpisu JWT ( **změna v produkčním prostředí** )
`INITIAL_PASSWORD` | `123456` | První přihlašovací heslo
`DATA_DIR` | `~/.omniroute` | Datový adresář (db, využití, protokoly)
`PORT` | výchozí nastavení rámce | Servisní port ( `20128` v příkladech)
`HOSTNAME` | výchozí nastavení rámce | Vázat hostitele (Docker má výchozí hodnotu `0.0.0.0` )
`NODE_ENV` | výchozí nastavení za běhu | Nastavení `production` pro nasazení
`BASE_URL` | `http://localhost:20128` | Interní základní URL na straně serveru
`CLOUD_URL` | `https://omniroute.dev` | Základní adresa URL koncového bodu synchronizace s cloudem
`API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | Tajný klíč HMAC pro generované klíče API
`REQUIRE_API_KEY` | `false` | Vynutit klíč rozhraní Bearer API na `/v1/*`
`ENABLE_REQUEST_LOGS` | `false` | Povoluje protokolování požadavků/odpovědí
`AUTH_COOKIE_SECURE` | `false` | Vynutit soubor cookie `Secure` ověřování (za reverzní proxy HTTPS)
`OMNIROUTE_MEMORY_MB` | `512` | Limit haldy Node.js v MB
`PROMPT_CACHE_MAX_SIZE` | `50` | Maximální počet položek mezipaměti výzev
`SEMANTIC_CACHE_MAX_SIZE` | `100` | Maximální počet položek sémantické mezipaměti
| Proměnná | Výchozí | Popis |
| ------------------------- | ------------------------------------ | ------------------------------------------------------------------ |
| `JWT_SECRET` | `omniroute-default-secret-change-me` | Tajný klíč podpisu JWT ( **změna v produkčním prostředí** ) |
| `INITIAL_PASSWORD` | `123456` | První přihlašovací heslo |
| `DATA_DIR` | `~/.omniroute` | Datový adresář (db, využití, protokoly) |
| `PORT` | výchozí nastavení rámce | Servisní port ( `20128` v příkladech) |
| `HOSTNAME` | výchozí nastavení rámce | Vázat hostitele (Docker má výchozí hodnotu `0.0.0.0` ) |
| `NODE_ENV` | výchozí nastavení za běhu | Nastavení `production` pro nasazení |
| `BASE_URL` | `http://localhost:20128` | Interní základní URL na straně serveru |
| `CLOUD_URL` | `https://omniroute.dev` | Základní adresa URL koncového bodu synchronizace s cloudem |
| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | Tajný klíč HMAC pro generované klíče API |
| `REQUIRE_API_KEY` | `false` | Vynutit klíč rozhraní Bearer API na `/v1/*` |
| `ENABLE_REQUEST_LOGS` | `false` | Povoluje protokolování požadavků/odpovědí |
| `AUTH_COOKIE_SECURE` | `false` | Vynutit soubor cookie `Secure` ověřování (za reverzní proxy HTTPS) |
| `OMNIROUTE_MEMORY_MB` | `512` | Limit haldy Node.js v MB |
| `PROMPT_CACHE_MAX_SIZE` | `50` | Maximální počet položek mezipaměti výzev |
| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Maximální počet položek sémantické mezipaměti |
Úplný přehled proměnných prostředí naleznete v souboru [README](../README.md) .
@@ -439,7 +439,7 @@ Proměnná | Výchozí | Popis
**Codex ( `cx/` )** — Plus/Pro: `cx/gpt-5.2-codex` , `cx/gpt-5.1-codex-max`
**Rozhraní příkazového řádku Gemini ( `gc/` )** — ZDARMA: `gc/gemini-3-flash-preview` , `gc/gemini-2.5-pro`
**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`
@@ -473,9 +473,6 @@ Proměnná | Výchozí | Popis
**NVIDIA NIM ( `nvidia/` )** : `nvidia/nvidia/llama-3.3-70b-instruct`
---
## 🧩 Pokročilé funkce
@@ -552,12 +549,12 @@ Vrátí modely seskupené podle poskytovatele s typy ( `chat` , `embedding` , `i
Přístup přes **Dashboard → Translator** . Ladění a vizualizace toho, jak OmniRoute překládá požadavky API mezi poskytovateli.
Režim | Účel
--- | ---
**Dětské hřiště** | Vyberte zdrojový/cílový formát, vložte požadavek a okamžitě si prohlédněte přeložený výstup
**Tester chatu** | Odesílejte zprávy živého chatu přes proxy a kontrolujte celý cyklus požadavku/odpovědi
**Zkušební stolice** | Spusťte dávkové testy napříč různými kombinacemi formátů pro ověření správnosti překladu
**Živý monitor** | Sledujte překlady v reálném čase, jak požadavky procházejí proxy serverem
| Režim | Účel |
| -------------------- | ------------------------------------------------------------------------------------------- |
| **Dětské hřiště** | Vyberte zdrojový/cílový formát, vložte požadavek a okamžitě si prohlédněte přeložený výstup |
| **Tester chatu** | Odesílejte zprávy živého chatu přes proxy a kontrolujte celý cyklus požadavku/odpovědi |
| **Zkušební stolice** | Spusťte dávkové testy napříč různými kombinacemi formátů pro ověření správnosti překladu |
| **Živý monitor** | Sledujte překlady v reálném čase, jak požadavky procházejí proxy serverem |
**Případy použití:**
@@ -571,14 +568,14 @@ Režim | Účel
Konfigurace přes **Dashboard → Nastavení → Routing** .
Strategie | Popis
--- | ---
**Nejprve vyplňte** | Používá účty podle priority primární účet zpracovává všechny požadavky, dokud není k dispozici.
**Round Robin** | Cykluje mezi všemi účty s nastavitelným trvalým limitem (výchozí: 3 volání na účet)
**P2C (Síla dvou možností)** | Vybere 2 náhodné účty a nasměruje je k tomu zdravějšímu vyvažuje zátěž s povědomím o zdraví
**Náhodný** | Náhodně vybere účet pro každý požadavek pomocí Fisher-Yatesova náhodného výběru.
**Nejméně používané** | Směruje k účtu s nejstarším časovým razítkem `lastUsedAt` a rovnoměrně rozděluje provoz.
**Optimalizované náklady** | Směruje k účtu s nejnižší prioritou a optimalizuje pro poskytovatele s nejnižšími náklady.
| Strategie | Popis |
| ---------------------------- | ------------------------------------------------------------------------------------------------- |
| **Nejprve vyplňte** | Používá účty podle priority primární účet zpracovává všechny požadavky, dokud není k dispozici. |
| **Round Robin** | Cykluje mezi všemi účty s nastavitelným trvalým limitem (výchozí: 3 volání na účet) |
| **P2C (Síla dvou možností)** | Vybere 2 náhodné účty a nasměruje je k tomu zdravějšímu vyvažuje zátěž s povědomím o zdraví |
| **Náhodný** | Náhodně vybere účet pro každý požadavek pomocí Fisher-Yatesova náhodného výběru. |
| **Nejméně používané** | Směruje k účtu s nejstarším časovým razítkem `lastUsedAt` a rovnoměrně rozděluje provoz. |
| **Optimalizované náklady** | Směruje k účtu s nejnižší prioritou a optimalizuje pro poskytovatele s nejnižšími náklady. |
#### Aliasy zástupných znaků modelů
@@ -611,24 +608,21 @@ Konfigurace přes **Dashboard → Settings → Resilience** .
OmniRoute implementuje odolnost na úrovni poskytovatele se čtyřmi komponentami:
1. **Profily poskytovatelů** Konfigurace pro jednotlivé poskytovatele pro:
- Práh selhání (počet selhání před otevřením)
- Doba zchlazení
- Citlivost detekce limitu frekvence
- Exponenciální backoff parametry
- Práh selhání (počet selhání před otevřením)
- Doba zchlazení
- Citlivost detekce limitu frekvence
- Exponenciální backoff parametry
2. **Upravitelné limity rychlosti** Výchozí nastavení na úrovni systému konfigurovatelná na řídicím panelu:
- **Požadavky za minutu (RPM)** — Maximální počet požadavků za minutu na účet
- **Minimální doba mezi požadavky** — Minimální mezera v milisekundách mezi požadavky
- **Max. počet souběžných požadavků** — Maximální počet souběžných požadavků na účet
- Klikněte na **Upravit** pro úpravu a poté **na Uložit** nebo **Zrušit** . Hodnoty se ukládají prostřednictvím rozhraní API pro odolnost.
- **Požadavky za minutu (RPM)** — Maximální počet požadavků za minutu na účet
- **Minimální doba mezi požadavky** — Minimální mezera v milisekundách mezi požadavky
- **Max. počet souběžných požadavků** — Maximální počet souběžných požadavků na účet
- Klikněte na **Upravit** pro úpravu a poté **na Uložit** nebo **Zrušit** . Hodnoty se ukládají prostřednictvím rozhraní API pro odolnost.
3. **Jistič** Sleduje poruchy u jednotlivých poskytovatelů a automaticky rozpojuje obvod, když je dosaženo prahové hodnoty:
- **ZAVŘENO** (v pořádku) Požadavky probíhají normálně.
- **OTEVŘENO**Poskytovatel je dočasně zablokován po opakovaných selháních
- **HALF_OPEN** — Testování, zda se poskytovatel zotavil
- **ZAVŘENO** (v pořádku) Požadavky probíhají normálně.
- **OTEVŘENO** — Poskytovatel je dočasně zablokován po opakovaných selháních
- **HALF_OPEN**Testování, zda se poskytovatel zotavil
4. **Zásady a uzamčené identifikátory** Zobrazuje stav jističe a uzamčené identifikátory s možností vynuceného odemčení.
@@ -642,11 +636,11 @@ OmniRoute implementuje odolnost na úrovni poskytovatele se čtyřmi komponentam
Správa záloh databáze se provádí v **nabídce Ovládací panel → Nastavení → Systém a úložiště** .
Akce | Popis
--- | ---
**Exportovat databázi** | Stáhne aktuální databázi SQLite jako soubor `.sqlite`
**Exportovat vše (.tar.gz)** | Stáhne kompletní zálohu včetně: databáze, nastavení, kombinací, připojení k poskytovatelům (bez přihlašovacích údajů) a metadat klíče API.
**Importovat databázi** | Nahrajte soubor `.sqlite` , který nahradí aktuální databázi. Záloha před importem se vytvoří automaticky.
| Akce | Popis |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| **Exportovat databázi** | Stáhne aktuální databázi SQLite jako soubor `.sqlite` |
| **Exportovat vše (.tar.gz)** | Stáhne kompletní zálohu včetně: databáze, nastavení, kombinací, připojení k poskytovatelům (bez přihlašovacích údajů) a metadat klíče API. |
| **Importovat databázi** | Nahrajte soubor `.sqlite` , který nahradí aktuální databázi. Záloha před importem se vytvoří automaticky. |
```bash
# API: Export database
@@ -674,13 +668,13 @@ curl -X POST http://localhost:20128/api/db-backups/import \
Stránka nastavení je pro snadnou navigaci uspořádána do 5 záložek:
Záložka | Obsah
--- | ---
**Zabezpečení** | Nastavení přihlášení/hesla, řízení přístupu k IP adrese, autorizace API pro `/models` a blokování poskytovatelů
**Směrování** | Globální strategie směrování (6 možností), aliasy zástupných znaků, záložní řetězce, kombinované výchozí hodnoty
**Odolnost** | Profily poskytovatelů, upravitelné limity sazeb, stav jističů, zásady a uzamčené identifikátory
**Umělá inteligence** | Konfigurace rozpočtu promyšleného projektu, globální vkládání promptu do systému, statistiky mezipaměti promptu
**Moderní** | Globální konfigurace proxy (HTTP/SOCKS5)
| Záložka | Obsah |
| --------------------- | ---------------------------------------------------------------------------------------------------------------- |
| **Zabezpečení** | Nastavení přihlášení/hesla, řízení přístupu k IP adrese, autorizace API pro `/models` a blokování poskytovatelů |
| **Směrování** | Globální strategie směrování (6 možností), aliasy zástupných znaků, záložní řetězce, kombinované výchozí hodnoty |
| **Odolnost** | Profily poskytovatelů, upravitelné limity sazeb, stav jističů, zásady a uzamčené identifikátory |
| **Umělá inteligence** | Konfigurace rozpočtu promyšleného projektu, globální vkládání promptu do systému, statistiky mezipaměti promptu |
| **Moderní** | Globální konfigurace proxy (HTTP/SOCKS5) |
---
@@ -688,10 +682,10 @@ Záložka | Obsah
Přístup přes **Dashboard → Náklady** .
Záložka | Účel
--- | ---
**Rozpočet** | Nastavte limity útrat pro každý klíč API s denními/týdenními/měsíčními rozpočty a sledováním v reálném čase
**Ceny** | Zobrazení a úprava cenových položek modelu cena za 1000 vstupních/výstupních tokenů na poskytovatele
| Záložka | Účel |
| ------------ | ----------------------------------------------------------------------------------------------------------- |
| **Rozpočet** | Nastavte limity útrat pro každý klíč API s denními/týdenními/měsíčními rozpočty a sledováním v reálném čase |
| **Ceny** | Zobrazení a úprava cenových položek modelu cena za 1000 vstupních/výstupních tokenů na poskytovatele |
```bash
# API: Set a budget
@@ -733,14 +727,14 @@ Podporované zvukové formáty: `mp3` , `wav` , `m4a` , `flac` , `ogg` , `webm`
Nastavte vyvažování jednotlivých kombinací v **nabídce Dashboard → Kombinace → Vytvořit/Upravit → Strategie** .
Strategie | Popis
--- | ---
**Round-Robin** | Postupně prochází modely
**Přednost** | Vždy se pokusí o první model; vrací se pouze v případě chyby.
**Náhodný** | Pro každý požadavek vybere náhodný model z komba
**Vážené** | Trasy proporcionálně na základě přiřazených vah pro každý model
**Nejméně používané** | Směruje k modelu s nejmenším počtem nedávných požadavků (používá kombinované metriky)
**Optimalizované z hlediska nákladů** | Trasy k nejlevnějšímu dostupnému modelu (používá ceník)
| Strategie | Popis |
| ------------------------------------- | ------------------------------------------------------------------------------------- |
| **Round-Robin** | Postupně prochází modely |
| **Přednost** | Vždy se pokusí o první model; vrací se pouze v případě chyby. |
| **Náhodný** | Pro každý požadavek vybere náhodný model z komba |
| **Vážené** | Trasy proporcionálně na základě přiřazených vah pro každý model |
| **Nejméně používané** | Směruje k modelu s nejmenším počtem nedávných požadavků (používá kombinované metriky) |
| **Optimalizované z hlediska nákladů** | Trasy k nejlevnějšímu dostupnému modelu (používá ceník) |
Globální výchozí hodnoty kombinací lze nastavit v **nabídce Dashboard → Settings → Routing → Combo Defaults** .
@@ -750,14 +744,14 @@ Globální výchozí hodnoty kombinací lze nastavit v **nabídce Dashboard →
Přístup přes **Dashboard → Stav** . Přehled stavu systému v reálném čase se 6 kartami:
Karta | Co to ukazuje
--- | ---
**Stav systému** | Doba provozuschopnosti, verze, využití paměti, datový adresář
**Zdraví poskytovatelů** | Stav jističe podle dodavatele (Zapnuto/Vypnuto/Napůl vypnuto)
**Limity sazeb** | Aktivní limit rychlosti cooldownů na účet se zbývajícím časem
**Aktivní výluky** | Poskytovatelé dočasně blokovaní politikou uzamčení
**Mezipaměť podpisů** | Statistiky mezipaměti pro deduplikaci (aktivní klíče, míra zásahů)
**Telemetrie latence** | Agregace latence p50/p95/p99 na poskytovatele
| Karta | Co to ukazuje |
| ------------------------ | ------------------------------------------------------------------ |
| **Stav systému** | Doba provozuschopnosti, verze, využití paměti, datový adresář |
| **Zdraví poskytovatelů** | Stav jističe podle dodavatele (Zapnuto/Vypnuto/Napůl vypnuto) |
| **Limity sazeb** | Aktivní limit rychlosti cooldownů na účet se zbývajícím časem |
| **Aktivní výluky** | Poskytovatelé dočasně blokovaní politikou uzamčení |
| **Mezipaměť podpisů** | Statistiky mezipaměti pro deduplikaci (aktivní klíče, míra zásahů) |
| **Telemetrie latence** | Agregace latence p50/p95/p99 na poskytovatele |
**Tip pro profesionály:** Stránka Zdraví se automaticky obnovuje každých 10 sekund. Pomocí karty jističe můžete zjistit, kteří poskytovatelé mají problémy.
@@ -795,20 +789,20 @@ Výstup → `electron/dist-electron/`
### Klíčové vlastnosti
Funkce | Popis
--- | ---
**Připravenost serveru** | Před zobrazením okna se dotazuje server (žádná prázdná obrazovka)
**Systémový zásobník** | Minimalizovat do zásobníku, změnit port, ukončit menu v zásobníku
**Správa přístavů** | Změna portu serveru z panelu úloh (automatické restartování serveru)
**Zásady zabezpečení obsahu** | Omezující CSP prostřednictvím záhlaví relace
**Jedna instance** | V daném okamžiku může běžet pouze jedna instance aplikace
**Offline režim** | Dodávaný server Next.js funguje bez internetu
| Funkce | Popis |
| ----------------------------- | -------------------------------------------------------------------- |
| **Připravenost serveru** | Před zobrazením okna se dotazuje server (žádná prázdná obrazovka) |
| **Systémový zásobník** | Minimalizovat do zásobníku, změnit port, ukončit menu v zásobníku |
| **Správa přístavů** | Změna portu serveru z panelu úloh (automatické restartování serveru) |
| **Zásady zabezpečení obsahu** | Omezující CSP prostřednictvím záhlaví relace |
| **Jedna instance** | V daném okamžiku může běžet pouze jedna instance aplikace |
| **Offline režim** | Dodávaný server Next.js funguje bez internetu |
### Proměnné prostředí
Proměnná | Výchozí | Popis
--- | --- | ---
`OMNIROUTE_PORT` | `20128` | Port serveru
`OMNIROUTE_MEMORY_MB` | `512` | Limit haldy Node.js (6416384 MB)
| Proměnná | Výchozí | Popis |
| --------------------- | ------- | --------------------------------- |
| `OMNIROUTE_PORT` | `20128` | Port serveru |
| `OMNIROUTE_MEMORY_MB` | `512` | Limit haldy Node.js (6416384 MB) |
📖 Úplná dokumentace: [`electron/README.md`](../electron/README.md)
+32 -67
View File
@@ -8,73 +8,6 @@ _Din universelle API-proxy — ét slutpunkt, 36+ udbydere, ingen nedetid. Nu me
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
<div align="center">
[![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)
[![Licens](https://img.shields.io/github/license/diegosouzapw/OmniRoute)](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
[![Websted](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)
[🌐 Hjemmeside](https://omniroute.online) • [🚀 Hurtig start](#-quick-start) • [💡 Funktioner](#-key-features) • [📖 Docs](#-documentation) • [💡 Priser](#-pricing-at-a-glance) • [💬 WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
</div>
🌐 **Tilgængelig på:** 🇺🇸 [engelsk](../../README.md) | 🇧🇷 [Português (Brasil)](../pt-BR/README.md) | 🇪🇸 [Español](../es/README.md) | 🇫🇷 [Français](../fr/README.md) | 🇮🇹 [Italiano](../it/README.md) | 🇷🇺 [Русский](../ru/README.md) | 🇨🇳 [中文 (简体)](../zh-CN/README.md) | 🇩🇪 [Tysk](../de/README.md) | 🇮🇳 [हिन्दी](../in/README.md) | 🇹🇭 [ไทย](../th/README.md) | 🇺🇦 [Українська](../uk-UA/README.md) | 🇸🇦 [العربية](../ar/README.md) | 🇯🇵 [日本語](../ja/README.md) | 🇻🇳 [Tiếng Việt](../vi/README.md) | 🇧🇬 [Български](../bg/README.md) | 🇩🇰 [Dansk](../da/README.md) | 🇫🇮 [Suomi](../fi/README.md) | 🇮🇱 [engelsk](../he/README.md) | 🇭🇺 [Magyar](../hu/README.md) | 🇮🇩 [Bahasa Indonesien](../id/README.md) | 🇰🇷 [한국어](../ko/README.md) | 🇲🇾 [Bahasa Melayu](../ms/README.md) | 🇳🇱 [Nederlands](../nl/README.md) | 🇳🇴 [norsk](../no/README.md) | 🇵🇹 [Português (Portugal)](../pt/README.md) | 🇷🇴 [Română](../ro/README.md) | 🇵🇱 [Polski](../pl/README.md) | 🇸🇰 [Slovenčina](../sk/README.md) | 🇸🇪 [Svenska](../sv/README.md) | 🇵🇭 [filippinsk](../phi/README.md)
---
## 🖼️ Hovedbetjeningspanel
<div align="center">
<img src="./docs/screenshots/MainOmniRoute.png" alt="OmniRoute Dashboard" width="800"/>
</div>
---
## 📸 Dashboard Preview
<details>
<summary><b>Klik for at se skærmbilleder af dashboard</b></summary>
| Side | Skærmbillede |
| ----------------- | --------------------------------------------------- |
| **Udbydere** | ![Udbydere](docs/screenshots/01-providers.png) |
| **Komboer** | ![Combos](docs/screenshots/02-combos.png) |
| **Analyse** | ![Analytics](docs/screenshots/03-analytics.png) |
| **Sundhed** | ![Sundhed](docs/screenshots/04-health.png) |
| **Oversætter** | ![Oversætter](docs/screenshots/05-translator.png) |
| **Indstillinger** | ![Indstillinger](docs/screenshots/06-settings.png) |
| **CLI-værktøjer** | ![CLI-værktøjer](docs/screenshots/07-cli-tools.png) |
| **Brugslogfiler** | ![Brug](docs/screenshots/08-usage.png) |
| **Endpunkt** | ![Endpoint](docs/screenshots/09-endpoint.png) |
</details>
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Gratis AI-udbyder til dine foretrukne kodningsagenter
_Tilslut ethvert AI-drevet IDE- eller CLI-værktøj gennem OmniRoute - gratis API-gateway til ubegrænset kodning._
@@ -159,6 +92,38 @@ _Tilslut ethvert AI-drevet IDE- eller CLI-værktøj gennem OmniRoute - gratis AP
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
## 🤔 Hvorfor OmniRoute?
**Stop med at spilde penge og nå grænser:**
+32 -67
View File
@@ -8,61 +8,6 @@ _Ihr universeller API-Proxy ein Endpunkt, mehr als 36 Anbieter, keine Ausfal
---
### 🆕 Neu in v2.7.0
- **Erweiterbare RouterStrategy** — Regeln-, Kosten- und Latenzstrategien
- **Mehrsprachige Absichtserkennung** — Routing-Scoring in 30+ Sprachen
- **Anfrage-Deduplizierung** — doppelte API-Aufrufe per Content-Hash vermeiden
- **Neue Anbieter:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Aktualisierte Preise:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
<div align="center">
[![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)
[![Lizenz](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) • [🚀 Schnellstart](#-quick-start) • [💡 Funktionen](#-key-features) • [📖 Dokumente](#-documentation) • [💰 Preise](#-pricing-at-a-glance) • [💬 WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
</div>
🌐 **Verfügbar in:** 🇺🇸 [Englisch](../../README.md) | 🇧🇷 [Português (Brasilien)](../pt-BR/README.md) | 🇪🇸 [Español](../es/README.md) | 🇫🇷 [Français](../fr/README.md) | 🇮🇹 [Italienisch](../it/README.md) | 🇷🇺 [Русский](../ru/README.md) | 🇨🇳 [中文 (简体)](../zh-CN/README.md) | 🇩🇪 [Deutsch](../de/README.md) | 🇮🇳 [हिन्दी](../in/README.md) | 🇹🇭 [ไทย](../th/README.md) | 🇺🇦 [Українська](../uk-UA/README.md) | 🇸🇦 [العربية](../ar/README.md) | 🇯🇵 [日本語](../ja/README.md) | 🇻🇳 [Tiếng Việt](../vi/README.md) | 🇧🇬 [Български](../bg/README.md) | 🇩🇰 [Dänisch](../da/README.md) | 🇫🇮 [Suomi](../fi/README.md) | 🇮🇱 [עברית](../he/README.md) | 🇭🇺 [Magyar](../hu/README.md) | 🇮🇩 [Bahasa Indonesia](../id/README.md) | 🇰🇷 [한국어](../ko/README.md) | 🇲🇾 [Bahasa Melayu](../ms/README.md) | 🇳🇱 [Niederlande](../nl/README.md) | 🇳🇴 [Norsk](../no/README.md) | 🇵🇹 [Português (Portugal)](../pt/README.md) | 🇷🇴 [Română](../ro/README.md) | 🇵🇱 [Polski](../pl/README.md) | 🇸🇰 [Slovenčina](../sk/README.md) | 🇸🇪 [Svenska](../sv/README.md) | 🇵🇭 [Philippinisch](../phi/README.md)
---
## 🖼️ Haupt-Dashboard
<div align="center">
<img src="./docs/screenshots/MainOmniRoute.png" alt="OmniRoute Dashboard" width="800"/>
</div>
---
## 📸 Dashboard-Vorschau
<details>
<summary><b>Klicken Sie hier, um Dashboard-Screenshots anzuzeigen</b></summary>
| Seite | Screenshot |
| ---------------------- | -------------------------------------------------- |
| **Anbieter** | ![Anbieter](docs/screenshots/01-providers.png) |
| **Kombinationen** | ![Combos](docs/screenshots/02-combos.png) |
| **Analytik** | ![Analytics](docs/screenshots/03-analytics.png) |
| **Gesundheit** | ![Gesundheit](docs/screenshots/04-health.png) |
| **Übersetzer** | ![Übersetzer](docs/screenshots/05-translator.png) |
| **Einstellungen** | ![Einstellungen](docs/screenshots/06-settings.png) |
| **CLI-Tools** | ![CLI-Tools](docs/screenshots/07-cli-tools.png) |
| **Nutzungsprotokolle** | ![Verwendung](docs/screenshots/08-usage.png) |
| **Endpunkt** | ![Endpunkt](docs/screenshots/09-endpoint.png) |
</details>
---
### 🤖 Kostenloser KI-Anbieter für Ihre bevorzugten Programmieragenten
_Verbinden Sie jedes KI-gestützte IDE- oder CLI-Tool über OmniRoute kostenloses API-Gateway für unbegrenzte Codierung._
@@ -147,6 +92,38 @@ _Verbinden Sie jedes KI-gestützte IDE- oder CLI-Tool über OmniRoute kosten
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
## 🤔 Warum OmniRoute?
**Hören Sie auf, Geld zu verschwenden und an Grenzen zu stoßen:**
@@ -890,18 +867,6 @@ Wenn OmniRoute minimiert ist, befindet es sich mit schnellen Aktionen in Ihrer T
OmniRoute v2.0 ist als Betriebsplattform konzipiert und nicht nur als Relay-Proxy.
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Agenten- und Protokolloperationen (v2.0)| Funktion | Was es tut |
| ------------------------------------ | -------------------------------------------------------------------------------- |
+32 -22
View File
@@ -11,28 +11,6 @@ _Tu proxy de API universal — un endpoint, 36+ proveedores, cero tiempo de inac
---
### 🆕 Novedades en v2.7.0
- **RouterStrategy enchufable** — estrategias de reglas, costo y latencia
- **Detección de intención multilingüe** — puntuación de enrutamiento en 30+ idiomas
- **Deduplicación de solicitudes** — evita llamadas duplicadas por hash de contenido
- **Nuevos proveedores:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Precios actualizados:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Proveedor de IA Gratuito para tus agentes de programación favoritos
_Conecta cualquier IDE o herramienta CLI con IA a través de OmniRoute — gateway de API gratuito para programación ilimitada._
@@ -118,6 +96,38 @@ _Conecta cualquier IDE o herramienta CLI con IA a través de OmniRoute — gatew
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _Universaali API-välityspalvelin yksi päätepiste, yli 36 palveluntarjoaja
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Ilmainen AI Provider suosikkikoodaajillesi
_Yhdistä mikä tahansa tekoälyllä toimiva IDE- tai CLI-työkalu OmniRouten kautta ilmainen API-yhdyskäytävä rajoittamattomaan koodaukseen._
@@ -118,6 +96,38 @@ _Yhdistä mikä tahansa tekoälyllä toimiva IDE- tai CLI-työkalu OmniRouten ka
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _Votre proxy API universel — un endpoint, 36+ fournisseurs, zéro temps d'arr
---
### 🆕 Nouveautés dans v2.7.0
- **RouterStrategy extensible** — stratégies de règles, coût et latence
- **Détection d'intention multilingue** — scoring de routage en 30+ langues
- **Déduplication des requêtes** — évite les appels dupliqués via hash de contenu
- **Nouveaux fournisseurs :** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Tarifs mis à jour :** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Fournisseur IA gratuit pour vos agents de programmation préférés
_Connectez n'importe quel IDE ou outil CLI alimenté par l'IA via OmniRoute — passerelle API gratuite pour un codage illimité._
@@ -118,6 +96,38 @@ _Connectez n'importe quel IDE ou outil CLI alimenté par l'IA via OmniRoute —
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _שרת ה-API האוניברסלי שלך - נקודת קצה אחת, 36+ ספ
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 ספק AI בחינם עבור סוכני הקידוד המועדפים עליך
_חבר כל כלי IDE או CLI המופעל על ידי AI דרך OmniRoute - שער API בחינם לקידוד בלתי מוגבל._
@@ -118,6 +96,38 @@ _חבר כל כלי IDE או CLI המופעל על ידי AI דרך OmniRoute -
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _Az univerzális API-proxy egy végpont, 36+ szolgáltató, nulla állásid
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Ingyenes mesterséges intelligencia szolgáltató kedvenc kódoló ügynökei számára
_Csatlakoztasson bármilyen mesterséges intelligencia-alapú IDE-t vagy CLI-eszközt az OmniRoute-on keresztül ingyenes API-átjáró a korlátlan kódoláshoz._
@@ -118,6 +96,38 @@ _Csatlakoztasson bármilyen mesterséges intelligencia-alapú IDE-t vagy CLI-esz
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _Proksi API universal Anda — satu titik akhir, 36+ penyedia, tanpa waktu henti
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Penyedia AI gratis untuk agen coding favorit Anda
_Hubungkan alat IDE atau CLI apa pun yang didukung AI melalui OmniRoute — gerbang API gratis untuk pengkodean tanpa batas._
@@ -118,6 +96,38 @@ _Hubungkan alat IDE atau CLI apa pun yang didukung AI melalui OmniRoute — gerb
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -13,28 +13,6 @@ _आपका सार्वभौमिक एपीआई प्रॉक्
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 आपके पसंदीदा कोडिंग एजेंटों के लिए निःशुल्क एआई प्रदाता
_OmniRoute के माध्यम से किसी भी AI-संचालित IDE या CLI टूल को कनेक्ट करें - असीमित कोडिंग के लिए निःशुल्क API गेटवे।_
@@ -43,6 +21,38 @@ _OmniRoute के माध्यम से किसी भी AI-संचा
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+33 -23
View File
@@ -5,34 +5,12 @@
### Non smettere mai di programmare. Routing intelligente verso **modelli IA GRATUITI e economici** con fallback automatico.
_Il tuo proxy API universale — un endpoint, 36+ provider, zero downtime._
_Il tuo proxy API universale — un endpoint, 67+ provider, zero downtime._
**Chat Completions • Embeddings • Generazione Immagini • Audio • Reranking • 100% TypeScript**
---
### 🆕 Novità in v2.7.0
- **RouterStrategy estensibile** — strategie per regole, costo e latenza
- **Rilevamento intento multilingue** — scoring di routing in 30+ lingue
- **Deduplicazione richieste** — evita chiamate duplicate tramite hash del contenuto
- **Nuovi provider:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Prezzi aggiornati:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Provider IA gratuito per i tuoi agenti di programmazione preferiti
_Connetti qualsiasi IDE o strumento CLI con IA tramite OmniRoute — gateway API gratuito per programmazione illimitata._
@@ -118,6 +96,38 @@ _Connetti qualsiasi IDE o strumento CLI con IA tramite OmniRoute — gateway API
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _ユニバーサル API プロキシ — 1 つのエンドポイント、36 以
---
### 🆕 v2.7.0 の新機能
- **プラガブル RouterStrategy** — ルール・コスト・レイテンシ戦略をサポート
- **多言語インテント検出** — 30以上の言語でルーティングスコアリング
- **リクエスト重複排除** — コンテンツハッシュで重複 API 呼び出しを防止
- **新しいプロバイダー:** Grok-4 Fast (xAI)、GLM-5 / Z.AI、MiniMax M2.5、Kimi K2.5
- **価格更新:** Grok-4 Fast $0.20/$0.50/M、GLM-5 $0.50/M、MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 お気に入りのコーディング エージェント向けの無料 AI プロバイダー
_AI を活用した IDE または CLI ツールを、無制限のコーディングのための無料 API ゲートウェイである OmniRoute 経由で接続します。_
@@ -118,6 +96,38 @@ _AI を活用した IDE または CLI ツールを、無制限のコーディン
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _범용 API 프록시 — 하나의 엔드포인트, 36개 이상의 공급자,
---
### 🆕 v2.7.0 새로운 기능
- **플러그형 RouterStrategy** — 규칙, 비용, 지연 전략 지원
- **다국어 의도 감지** — 30개 이상 언어로 라우팅 스코어링
- **요청 중복 제거** — 콘텐츠 해시로 중복 API 호출 방지
- **새 공급자:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **가격 업데이트:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 좋아하는 코딩 에이전트를 위한 무료 AI 제공업체
_무제한 코딩을 위한 무료 API 게이트웨이인 OmniRoute를 통해 AI 기반 IDE 또는 CLI 도구를 연결하세요._
@@ -118,6 +96,38 @@ _무제한 코딩을 위한 무료 API 게이트웨이인 OmniRoute를 통해 AI
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _Proksi API universal anda — satu titik akhir, 36+ pembekal, masa henti sifar.
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Pembekal AI percuma untuk ejen pengekodan kegemaran anda
_Sambungkan mana-mana alat IDE atau CLI berkuasa AI melalui OmniRoute — get laluan API percuma untuk pengekodan tanpa had._
@@ -118,6 +96,38 @@ _Sambungkan mana-mana alat IDE atau CLI berkuasa AI melalui OmniRoute — get la
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+33 -23
View File
@@ -11,28 +11,6 @@ _Uw universele API-proxy: één eindpunt, meer dan 36 providers, geen downtime._
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Gratis AI-provider voor uw favoriete codeeragenten
_Verbind elke AI-aangedreven IDE- of CLI-tool via OmniRoute: gratis API-gateway voor onbeperkte codering._
@@ -118,6 +96,38 @@ _Verbind elke AI-aangedreven IDE- of CLI-tool via OmniRoute: gratis API-gateway
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
@@ -246,7 +256,7 @@ OpenAI gebruikt het ene formaat, Claude (Anthropic) gebruikt een ander, Gemini n
**Hoe OmniRoute het oplost:**
- **Unified Endpoint** — Eén enkele `http://localhost:20128/v1` dient als proxy voor alle 36+ providers
- **Unified Endpoint** — Eén enkele `http://localhost:20128/v1` dient als proxy voor alle 67+ providers
- **Formatvertaling** — Automatisch en transparant: OpenAI ↔ Claude ↔ Gemini ↔ Responses API
- **Response Sanitization** — Verwijdert niet-standaardvelden (`x_groq`, `usage_breakdown`, `service_tier`) die OpenAI SDK v1.83+ breken
- **Rolnormalisatie** — Converteert `developer``system` voor niet-OpenAI-providers; `system``user` voor GLM/ERNIE
+32 -22
View File
@@ -11,28 +11,6 @@ _Din universelle API-proxy ett endepunkt, 36+ leverandører, null nedetid._
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Gratis AI-leverandør for dine favorittkodeagenter
_Koble til ethvert AI-drevet IDE- eller CLI-verktøy gjennom OmniRoute gratis API-gateway for ubegrenset koding._
@@ -118,6 +96,38 @@ _Koble til ethvert AI-drevet IDE- eller CLI-verktøy gjennom OmniRoute grati
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+35 -25
View File
@@ -5,34 +5,12 @@
### 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._
_Iyong unibersal na API proxy — isang endpoint, 67+ provider, zero downtime._
**Mga Pagkumpleto ng Chat • Mga Pag-embed • Pagbuo ng Imahe • Audio • Pag-rerank • 100% TypeScript**
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Libreng AI Provider para sa iyong mga paboritong coding agent
_Ikonekta ang anumang AI-powered IDE o CLI tool sa pamamagitan ng OmniRoute — libreng API gateway para sa walang limitasyong coding._
@@ -118,6 +96,38 @@ _Ikonekta ang anumang AI-powered IDE o CLI tool sa pamamagitan ng OmniRoute —
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
@@ -246,7 +256,7 @@ Gumagamit ang OpenAI ng isang format, gumagamit si Claude (Anthropic) ng isa pa,
**Paano ito niresolba ng OmniRoute:**
- **Pinag-isang Endpoint** — Isang `http://localhost:20128/v1` ang nagsisilbing proxy para sa lahat ng 36+ provider
- **Pinag-isang Endpoint** — Isang `http://localhost:20128/v1` ang nagsisilbing proxy para sa lahat ng 67+ provider
- **Format Translation** — Awtomatiko at transparent: OpenAI ↔ Claude ↔ Gemini ↔ Responses API
- **Response Sanitization** — Tinatanggal ang mga hindi karaniwang field (`x_groq`, `usage_breakdown`, `service_tier`) na sumisira sa OpenAI SDK v1.83+
- **Role Normalization** — Kino-convert ang `developer``system` para sa mga provider na hindi OpenAI; `system``user` para sa GLM/ERNIE
@@ -331,7 +341,7 @@ Gumagamit ang mga developer ng Cursor, Claude Code, Codex CLI, OpenClaw, Gemini
- **CLI Tools Dashboard** — Nakatuon na page na may isang-click na setup para sa Claude Code, Codex CLI, OpenClaw, Kilo Code, Antigravity, Cline
- **GitHub Copilot Config Generator** — Bumubuo ng `chatLanguageModels.json` para sa VS Code na may maramihang pagpili ng modelo
- **Onboarding Wizard** — May gabay na 4-step na pag-setup para sa mga unang beses na user
- **Isang endpoint, lahat ng modelo** — I-configure ang `http://localhost:20128/v1` nang isang beses, i-access ang 36+ provider
- **Isang endpoint, lahat ng modelo** — I-configure ang `http://localhost:20128/v1` nang isang beses, i-access ang 67+ provider
</details>
+32 -22
View File
@@ -11,28 +11,6 @@ _Twój uniwersalny serwer proxy API — jeden punkt końcowy, ponad 36 dostawcó
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Bezpłatny dostawca AI dla Twoich ulubionych agentów kodujących
_Połącz dowolne narzędzie IDE lub CLI oparte na sztucznej inteligencji poprzez OmniRoute — bezpłatną bramę API dla nieograniczonego kodowania._
@@ -118,6 +96,38 @@ _Połącz dowolne narzędzie IDE lub CLI oparte na sztucznej inteligencji poprze
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _Seu proxy de API universal — um endpoint, 36+ provedores, zero tempo de inati
---
### 🆕 Novidades na v2.7.0
- **RouterStrategy plugável** — estratégias de regras, custo e latência
- **Detecção de intenção multilíngue** — scoring de roteamento em 30+ idiomas
- **Deduplicação de requisições** — evita chamadas duplicadas por hash de conteúdo
- **Novos provedores:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Preços atualizados:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Provedor de IA Gratuito para seus agentes de programação favoritos
_Conecte qualquer IDE ou ferramenta CLI com IA através do OmniRoute — gateway de API gratuito para programação ilimitada._
@@ -118,6 +96,38 @@ _Conecte qualquer IDE ou ferramenta CLI com IA através do OmniRoute — gateway
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _Seu proxy de API universal — um endpoint, mais de 36 provedores, tempo de ina
---
### 🆕 Novidades na v2.7.0
- **RouterStrategy extensível** — estratégias de regras, custo e latência
- **Deteção de intenção multilíngue** — scoring de encaminhamento em 30+ idiomas
- **Deduplicação de pedidos** — evita chamadas duplicadas por hash de conteúdo
- **Novos fornecedores:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Preços atualizados:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Provedor de IA gratuito para seus agentes de codificação favoritos
_Conecte qualquer ferramenta IDE ou CLI com tecnologia de IA por meio do OmniRoute - gateway de API gratuito para codificação ilimitada._
@@ -118,6 +96,38 @@ _Conecte qualquer ferramenta IDE ou CLI com tecnologia de IA por meio do OmniRou
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _Proxy-ul dvs. universal API - un punct final, peste 36 de furnizori, zero timpi
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Furnizor AI gratuit pentru agenții tăi preferați de codare
_Conectați orice instrument IDE sau CLI alimentat de AI prin OmniRoute — gateway API gratuit pentru codare nelimitată._
@@ -118,6 +96,38 @@ _Conectați orice instrument IDE sau CLI alimentat de AI prin OmniRoute — gate
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+35 -25
View File
@@ -11,28 +11,6 @@ _Ваш универсальный API-прокси — одна точка до
---
### 🆕 Новое в v2.7.0
- **Подключаемая RouterStrategy** — стратегии по правилам, стоимости и задержке
- **Многоязычное распознавание намерений** — маршрутизация на 30+ языках
- **Дедупликация запросов** — устранение дублей по хэшу содержимого
- **Новые провайдеры:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Обновлённые цены:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Бесплатный AI-провайдер для ваших любимых агентов программирования
_Подключайте любую IDE или CLI-инструмент с AI через OmniRoute — бесплатный API gateway для неограниченного программирования._
@@ -118,6 +96,38 @@ _Подключайте любую IDE или CLI-инструмент с AI ч
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
@@ -376,7 +386,7 @@ Claude Code, Codex, Gemini CLI, Copilot — все используют OAuth 2.
- **Панель управления унифицированными журналами** — 4 вкладки: журналы запросов, журналы прокси, журналы аудита, консоль.
- **Консольный просмотр журнала** — просмотрщик в режиме терминала в режиме реального времени с уровнями с цветовой кодировкой, автоматической прокруткой, поиском и фильтрацией.
- **Журналы прокси-сервера SQLite** — постоянные журналы, сохраняющиеся после перезапуска сервера.
- **Площадка переводчика** — 4 режима отладки: Площадка (перевод формата), Тестер чата (туда и обратно), Тестовый стенд (пакетный), Мониторинг в реальном времени (в режиме реального времени).
- **Площадка транслятора (Translator Playground)** — 4 режима отладки: Площадка (перевод формата), Тестер чата (туда и обратно), Тестовый стенд (пакетный), Мониторинг в реальном времени (в режиме реального времени).
- **Запрос телеметрии** — задержка p50/p95/p99 + отслеживание X-Request-Id
- **Журналирование на основе файлов с ротацией** — перехватчик консоли записывает все в журнал JSON с ротацией на основе размера.
@@ -441,7 +451,7 @@ Claude Code, Codex, Gemini CLI, Copilot — все используют OAuth 2.
- **Оценки LLM** — тестирование золотого набора с 10 предварительно загруженными вариантами, охватывающими приветствия, математику, географию, генерацию кода, соответствие JSON, перевод, уценку, отказ от безопасности.
- **4 стратегии сопоставления**`exact`, `contains`, `regex`, `custom` (функция JS)
- **Тестовый стенд Translator Playground** — пакетное тестирование с несколькими входными данными и ожидаемыми результатами, сравнение между поставщиками.
- **Тестовый стенд (Testbed)** — пакетное тестирование с несколькими входными данными и ожидаемыми результатами, сравнение между поставщиками.
- **Тестер чата** — полный цикл с визуальным отображением ответов.
- **Живой монитор** — поток всех запросов, проходящих через прокси, в реальном времени.
@@ -1006,7 +1016,7 @@ OmniRoute включает встроенный фреймворк оценки
- Приветствия, математика, география, генерация кода
- Соответствие формату JSON, перевод, markdown
- Отказ от небезопасного контента, подсчёт, булева логика
- Отказ от небезопасного контента (Safety refusal), подсчёт, булева логика
### Стратегии оценки
+32 -22
View File
@@ -11,28 +11,6 @@ _Váš univerzálny proxy server API jeden koncový bod, 36+ poskytovateľov
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Bezplatný poskytovateľ AI pre vašich obľúbených kódovacích agentov
_Pripojte akýkoľvek nástroj IDE alebo CLI poháňaný AI cez OmniRoute bezplatnú bránu API pre neobmedzené kódovanie._
@@ -118,6 +96,38 @@ _Pripojte akýkoľvek nástroj IDE alebo CLI poháňaný AI cez OmniRoute be
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _Din universella API-proxy — en slutpunkt, 36+ leverantörer, noll driftstopp.
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Gratis AI-leverantör för dina favoritkodningsagenter
_Anslut alla AI-drivna IDE- eller CLI-verktyg via OmniRoute — gratis API-gateway för obegränsad kodning._
@@ -118,6 +96,38 @@ _Anslut alla AI-drivna IDE- eller CLI-verktyg via OmniRoute — gratis API-gatew
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _พร็อกซี API สากลของคุณ — จุดสิ้
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 ผู้ให้บริการ AI ฟรีสำหรับตัวแทนการเขียนโค้ดที่คุณชื่นชอบ
_เชื่อมต่อเครื่องมือ IDE หรือ CLI ที่ขับเคลื่อนด้วย AI ผ่าน OmniRoute — เกตเวย์ API ฟรีสำหรับการเข้ารหัสไม่จำกัด_
@@ -118,6 +96,38 @@ _เชื่อมต่อเครื่องมือ IDE หรือ CLI
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _Ваш універсальний API-проксі — одна кінцева
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Безкоштовний постачальник AI для ваших улюблених агентів кодування
_Підключіть будь-який інструмент IDE або CLI на основі штучного інтелекту через OmniRoute — безкоштовний шлюз API для необмеженого програмування._
@@ -118,6 +96,38 @@ _Підключіть будь-який інструмент IDE або CLI на
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _Proxy API phổ quát của bạn — một điểm cuối, hơn 36 nhà cung c
---
### 🆕 What's New in v2.7.0
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
- **Multilingual intent detection** — routing scoring in 30+ languages
- **Request deduplication** — prevent duplicate API calls via content hash
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 Nhà cung cấp AI miễn phí cho các tác nhân mã hóa yêu thích của bạn
_Kết nối mọi công cụ IDE hoặc CLI được hỗ trợ bởi AI thông qua OmniRoute — cổng API miễn phí để mã hóa không giới hạn._
@@ -118,6 +96,38 @@ _Kết nối mọi công cụ IDE hoặc CLI được hỗ trợ bởi AI thông
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+32 -22
View File
@@ -11,28 +11,6 @@ _您的通用 API 代理 — 一个端点,36+ 提供商,零停机时间。_
---
### 🆕 v2.7.0 新功能
- **可插拔 RouterStrategy** — 支持规则、成本和延迟策略
- **多语言意图检测** — 支持 30+ 语言的路由评分
- **请求去重** — 基于内容哈希避免重复 API 调用
- **新增提供商:** Grok-4 Fast (xAI)、GLM-5 / Z.AI、MiniMax M2.5、Kimi K2.5
- **价格更新:** Grok-4 Fast $0.20/$0.50/MGLM-5 $0.50/MMiniMax M2.5 $0.30/M
---
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
| Feature | What It Does |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
### 🤖 为您最爱的编程代理提供免费 AI
_通过 OmniRoute 连接任何 AI 驱动的 IDE 或 CLI 工具 — 免费 API 网关,无限编程。_
@@ -118,6 +96,38 @@ _通过 OmniRoute 连接任何 AI 驱动的 IDE 或 CLI 工具 — 免费 API
---
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
### 🆕 What's New in v3.0.0
| Area | Change |
| --- | --- |
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection |
| ✅ **Route Validation** | All 176 API routes validated with Zod schemas + `validateBody()` |
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streams (#585) |
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement |
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback |
| 🔄 **Model Auto-Sync** | 24h scheduler refreshes model lists for 16 providers |
| 🌐 **OpenCode Zen/Go** | Two new providers: free tier + subscription tier |
| 🔧 **926 Tests** | Full test suite passes with 0 failures |
---
[![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)
+1 -1
View File
@@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: OmniRoute API
version: 3.0.0-rc.10
version: 3.0.1
description: |
OmniRoute is a local-first AI API proxy router. It provides an OpenAI-compatible
endpoint that routes requests to multiple AI providers with load balancing,
+1
View File
@@ -29,6 +29,7 @@ const eslintConfig = [
ignores: [
// Next.js build output
".next/**",
"src/.next/**",
"out/**",
"build/**",
"next-env.d.ts",
+87 -79
View File
@@ -1,6 +1,6 @@
# OmniRoute
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 36+ AI providers — all through a single OpenAI-compatible endpoint.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 67+ AI providers — all through a single OpenAI-compatible endpoint.
## Overview
@@ -8,19 +8,19 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
**Key value:** One endpoint (`http://localhost:20128/v1`), unlimited models, zero downtime, minimal cost.
**Current version:** 2.0.13
**Current version:** 3.0.0
## Tech Stack
- **Runtime:** Node.js >= 18
- **Framework:** Next.js 16 (App Router) with TypeScript
- **Framework:** Next.js 16 (App Router) with TypeScript 5.9
- **Database:** SQLite via better-sqlite3 (local, zero-config)
- **State management:** Zustand (client), lowdb (server JSON persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics
- **State management:** Zustand (client), SQLite (server persistence)
- **UI:** React 19, Tailwind CSS 4, Recharts for analytics, @lobehub/icons for 130+ provider SVG icons
- **Auth:** OAuth 2.0 (PKCE) for providers, bcrypt for local user auth
- **Background jobs:** Custom token health check scheduler
- **Background jobs:** Custom token health check scheduler, 24h model auto-sync
- **Streaming:** Server-Sent Events (SSE) for real-time proxy responses
- **Proxy engine:** Custom pipeline with format translation, circuit breaker, rate limiting
- **Proxy engine:** Custom pipeline with format translation, circuit breaker, rate limiting, auto-combo engine
- **i18n:** next-intl with 30 languages
- **Package:** Published on npm (`omniroute`) and Docker Hub (`diegosouzapw/omniroute`)
@@ -35,14 +35,14 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ │ ├── agents/ # ACP Agents dashboard (CLI agent detection + custom agents)
│ │ │ ├── analytics/ # Usage analytics and charts
│ │ │ ├── api-manager/ # API key management
│ │ │ ├── cli-tools/ # CLI tool configuration (Claude, Codex, Gemini, etc.)
│ │ │ ├── combos/ # Model combo management
│ │ │ ├── costs/ # Cost tracking
│ │ │ ├── endpoint/ # Endpoint info and cloud proxy
│ │ │ ├── health/ # System health monitoring
│ │ │ ├── cli-tools/ # CLI tool configuration (Claude Code, Codex, Gemini CLI, etc.)
│ │ │ ├── combos/ # Model combo management (9 strategies + 4 templates)
│ │ │ ├── costs/ # Cost tracking per provider/model
│ │ │ ├── endpoint/ # Unified: Endpoint Proxy, MCP, A2A, API Endpoints tabs
│ │ │ ├── health/ # System health (uptime, circuit breakers, latency)
│ │ │ ├── limits/ # Rate limits dashboard
│ │ │ ├── logs/ # Request logs viewer
│ │ │ ├── media/ # Image/video/music generation
│ │ │ ├── logs/ # Request, Proxy, Audit, Console logs (tabbed)
│ │ │ ├── media/ # Image/video/music generation + transcription
│ │ │ ├── playground/ # Model playground (Monaco editor, streaming)
│ │ │ ├── providers/ # Provider management (OAuth + API key + free)
│ │ │ ├── settings/ # Settings tabs (General, Appearance, Security, Routing, Resilience, Advanced)
@@ -51,7 +51,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ ├── api/ # REST API endpoints
│ │ │ ├── v1/ # OpenAI-compatible API (chat, models, embeddings, images, audio)
│ │ │ ├── acp/ # ACP agent management API
│ │ │ ├── oauth/ # OAuth flows per provider (authorize, exchange, callback)
│ │ │ ├── oauth/ # OAuth flows per provider
│ │ │ ├── providers/ # Provider CRUD and batch testing
│ │ │ ├── models/ # Dashboard model listing and aliases
│ │ │ ├── combos/ # Combo CRUD (multi-model fallback chains)
@@ -59,131 +59,143 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
│ │ └── login/ # Login page
│ ├── domain/ # Domain types and business logic interfaces
│ ├── i18n/ # Internationalization
│ │ └── messages/ # 30 language JSON files (ar, bg, cs, da, de, en, es, fi, fr, he, hu, id, in, it, ja, ko, ms, nl, no, phi, pl, pt, pt-BR, ro, ru, sk, sv, th, uk-UA, vi, zh-CN)
│ │ └── messages/ # 30 language JSON files
│ ├── lib/ # Core libraries
│ │ ├── acp/ # ACP agent registry and manager (14 built-in agents + custom)
│ │ ├── db/ # SQLite database layer (providers, combos, prompts, logs)
│ │ ├── a2a/ # Agent-to-Agent v0.3 protocol server
│ │ ├── acp/ # ACP agent registry and manager (14 built-in + custom)
│ │ ├── db/ # SQLite database layer (core, providers, models, combos, apiKeys, settings, backup)
│ │ ├── oauth/ # OAuth providers, services, and utilities
│ │ │ ├── providers/ # Provider-specific OAuth configs (GitHub, Google, Claude, etc.)
│ │ │ ├── constants/ # Default OAuth credentials (overridable via env)
│ │ │ ├── providers/ # Provider-specific OAuth configs
│ │ │ ├── services/ # Provider-specific token exchange logic
│ │ │ └── utils/ # PKCE, callback server, token helpers
│ │ ├── cloudSync.ts # Cloud sync via Cloudflare Workers
│ │ ├── tokenHealthCheck.ts # Background OAuth token refresh scheduler
│ │ └── localDb.ts # Unified database access layer
│ │ └── localDb.ts # Unified re-export layer for all DB modules
│ ├── shared/ # Shared utilities, components, and constants
│ │ ├── components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, etc.)
│ │ ├── constants/ # Provider definitions, model lists, pricing
│ │ ├── validation/ # Zod schemas (settings, providers, etc.)
│ │ ├── components/ # Reusable UI components (Card, Badge, Button, Modal, Sidebar, ProviderIcon, etc.)
│ │ ├── constants/ # Provider definitions, model lists, pricing, upstream headers
│ │ ├── validation/ # Zod schemas (settings, providers, routes)
│ │ └── utils/ # Helpers (auth, CORS, error codes, machine ID)
│ ├── sse/ # SSE proxy pipeline
│ │ ├── services/ # Auth resolution, format translation, response handling
│ │ └── middleware/ # Rate limiting, circuit breaker, caching, idempotency
│ ├── store/ # Zustand client-side stores (theme, providers, etc.)
── types/ # TypeScript type definitions
│ ├── proxy.ts # Main proxy request handler
│ └── server-init.ts # Server initialization (DB, health checks)
── types/ # TypeScript type definitions
├── open-sse/ # Standalone SSE server (npm workspace)
│ ├── config/ # Model registries (embedding, image, audio, rerank, moderation, CLI fingerprints)
│ ├── handlers/ # Request handlers per API type
│ ├── mcp-server/ # Built-in MCP server (16 tools, audit logging, scope auth)
── translators/ # Format translators (OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama)
├── tests/ # Test suites
│ ├── handlers/ # Request handlers per API type (chat, responses, embeddings, images, audio, search)
│ ├── mcp-server/ # Built-in MCP server (16 tools, 3 transports: stdio/SSE/streamable-HTTP)
── services/ # Auto-combo engine (6-factor scoring, 4 mode packs, bandit exploration)
│ └── translator/ # Format translators (OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama ↔ DeepSeek)
├── tests/ # Test suites (926 assertions)
│ ├── unit/ # Unit tests (32+ test files)
│ └── integration/ # Integration tests
├── docs/ # Documentation (with 29-language i18n subdirectories)
│ ├── i18n/ # Translated docs (ar, bg, cs, da, de, es, fi, fr, he, hu, id, in, it, ja, ko, ms, nl, no, phi, pl, pt, pt-BR, ro, ru, sk, sv, th, uk-UA, vi, zh-CN)
├── docs/ # Documentation
│ ├── i18n/ # 30-language translated READMEs
│ ├── screenshots/ # Dashboard screenshots
│ ├── a2a-server.md # A2A agent protocol documentation
│ ├── auto-combo.md # Auto-combo engine (6-factor scoring)
│ └── mcp-server.md # MCP server (16 tools)
├── electron/ # Electron desktop app
├── bin/ # CLI entry points (omniroute, reset-password)
└── .env.example # Environment variable template
```
## Key Features (v2.0.13)
## Key Features (v3.0.0)
### Core Proxy
- **36+ AI providers** with automatic format translation
- **67+ AI providers** with automatic format translation
- **6 routing strategies**: priority, weighted, round-robin, random, least-used, cost-optimized
- **4-tier fallback**: Subscription → API Key → Cheap → Free
- **Auto-combo engine**: Self-healing routing optimization with 6-factor scoring, bandit exploration, progressive cooldown
- **Semantic caching** with cache hit/miss headers
- **Idempotency** with configurable dedup window
- **Circuit breaker** per provider with configurable thresholds
- **Provider Icons**: 130+ provider logos via `@lobehub/icons` (SVG) with PNG fallback
- **Model Auto-Sync**: 24h scheduler refreshes model lists for 16 providers
- **Registered Keys API**: Auto-provision API keys via `POST /api/v1/registered-keys` with quota enforcement
- **926 tests** with 0 failures
### Anti-Ban Protection
### Security
- **CodeQL security**: Fixed 10+ CodeQL alerts (polynomial-redos, insecure-randomness, shell-injection)
- **Route validation**: All 176 API routes validated with Zod schemas + `validateBody()`
- **omniModel tag sanitization**: Internal `<omniModel>` tags never leak to clients in SSE streams
- **TLS Fingerprint Spoofing** — Browser-like TLS fingerprint to reduce bot detection
- **CLI Fingerprint Matching** — Per-provider request signature matching (headers/body ordering) to match native CLI tools. Proxy IP is preserved.
- **CLI Fingerprint Matching** — Per-provider request signature matching
### Dashboard Pages
- **Providers** — OAuth, API key, and free provider management
- **Combos** — Multi-model fallback chain builder with templates
- **Providers** — OAuth, API key, and free provider management with ProviderIcon SVG icons
- **Combos** — Multi-model combo builder with 4 templates (Free Stack, High Availability, Cost Saver, Balanced) + 9 strategies
- **Analytics** — Token consumption, cost, heatmaps, distributions
- **Health** — Uptime, memory, latency percentiles, circuit breakers
- **Logs** — Real-time request log viewer with filtering
- **Logs** — Request, Proxy, Audit, Console (tabbed)
- **Costs** — Cost tracking per provider/model
- **Limits** — Rate limit monitoring
- **CLI Tools** — One-click configuration for 10+ AI CLI tools
- **CLI Agents** — Grid of 14 built-in agents with install detection + custom agent registration
- **CLI Agents** — Grid of 14+ built-in agents with ProviderIcon and install detection + custom agent registration
- **Playground** — Test any model with Monaco editor, streaming responses
- **Media** — Image/video/music generation (DALL-E, FLUX, AnimateDiff, etc.)
- **Media** — Image/video/music generation (DALL-E, FLUX, etc.) + audio transcription (up to 2GB files)
- **Translator** — Format debugging: playground, chat tester, test bench, live monitor
- **Settings** — General, Appearance (7 color themes), Security (TLS/CLI fingerprint, IP filter), Routing, Resilience, Advanced
- **Endpoint** — Unified API endpoint info + cloud proxy
### Sidebar Organization
- **Main**: Home, Endpoints, API Manager, Providers, Combos, Costs, Analytics, Limits
- **CLI**: Tools, Agents
- **Debug**: Translator, Playground, Media
- **System**: Health, Logs, Settings
- **Help**: Docs, Issues
- **Endpoint** — Unified: Endpoint Proxy, MCP Server, A2A Server, API Endpoints (tabbed)
### Protocol Support
- **OpenAI-compatible** — `/v1/chat/completions`, `/v1/models`, `/v1/embeddings`, `/v1/images/generations`, `/v1/audio/transcriptions`
- **OpenAI-compatible** — `/v1/chat/completions`, `/v1/models`, `/v1/embeddings`, `/v1/images/generations`, `/v1/audio/transcriptions`, `/v1/audio/speech`
- **Anthropic** — `/v1/messages`, `/v1/messages/count_tokens`
- **OpenAI Responses** — `/v1/responses`
- **Gemini** — `/v1beta/models`, `/v1beta/models/{...path}`
- **Ollama** — `/v1/api/chat`, `/api/tags`
- **MCP** — 16-tool MCP server with scope-based auth
- **A2A** — Agent-to-Agent protocol (smart-routing, quota-management skills)
- **MCP** — 16-tool MCP server with scope-based auth (3 transports: stdio, SSE, streamable HTTP)
- **A2A** — Agent-to-Agent v0.3 protocol (JSON-RPC 2.0, smart-routing + quota-management skills)
- **ACP** — Agent detection, custom agent registry
### MCP Server (16 Tools)
| Category | Tools |
|-----------|-------|
| Essential | `get_health`, `list_combos`, `get_combo_metrics`, `switch_combo`, `check_quota`, `route_request`, `cost_report`, `list_models_catalog` |
| Advanced | `simulate_route`, `set_budget_guard`, `set_resilience_profile`, `test_combo`, `get_provider_metrics`, `best_combo_for_task`, `explain_route`, `get_session_snapshot` |
### Internationalization
- 30 languages for UI (sidebar, settings, agents, and all dashboard pages)
- 30 READMEs (root README.md + 29 translated README.*.md)
- 29 translated doc sets in docs/i18n/
- 30 languages for UI (all dashboard pages)
- 30 translated READMEs in docs/i18n/
- Language switcher in documentation
## Key Architectural Decisions
1. **OpenAI-compatible API surface:** All incoming requests follow the OpenAI API format (`/v1/chat/completions`, `/v1/models`, etc.). This makes OmniRoute a drop-in replacement for any tool that supports custom OpenAI endpoints.
1. **OpenAI-compatible API surface:** All incoming requests follow the OpenAI API format. This makes OmniRoute a drop-in replacement for any tool that supports custom OpenAI endpoints.
2. **Provider abstraction via format translators:** Each AI provider (Claude, Gemini, etc.) has a translator in `open-sse/translators/` that converts between the OpenAI format and the provider's native format. This happens transparently.
2. **Provider abstraction via format translators:** Each AI provider has a translator in `open-sse/translator/` that converts between OpenAI format and the provider's native format transparently.
3. **Connection-based provider model:** Providers are stored as "connections" in SQLite. Each connection has an `id`, `provider`, `authType` (oauth/apikey/free), `isActive` flag, and credentials. Multiple connections per provider are supported for multi-account rotation.
3. **Connection-based provider model:** Providers are stored as "connections" in SQLite. Each connection has an `id`, `provider`, `authType` (oauth/apikey/free), `isActive` flag, and credentials. Multiple connections per provider for multi-account rotation.
4. **Combo system for fallback:** Users create "combos" — ordered lists of `provider/model` pairs. The proxy tries each in order until one succeeds. Supports 6 strategies.
4. **Combo system for fallback:** Users create "combos" — ordered lists of `provider/model` pairs. The proxy tries each in order until one succeeds. Supports 9 strategies including auto-combo with self-healing.
5. **SSE proxy pipeline (`src/sse/`):** The proxy pipeline is middleware-based: request → auth resolution → rate limiting → circuit breaker → format translation → upstream call → response translation → SSE streaming back to client.
5. **SSE proxy pipeline:** The proxy pipeline is middleware-based: request → auth resolution → rate limiting → circuit breaker → format translation → upstream call → response translation → SSE streaming back to client.
6. **SQLite for persistence:** All state (providers, combos, logs, settings) is stored in a single SQLite database file at `data/omniroute.db`. This keeps the app self-contained and zero-config.
6. **SQLite for persistence:** All state (providers, combos, logs, settings, API keys) stored in a single SQLite database. All DB operations go through `src/lib/db/` modules, never raw SQL in routes.
7. **OAuth with PKCE:** OAuth flows use PKCE for security. A local callback server handles the redirect. Token refresh is handled by a background job (`tokenHealthCheck.ts`).
7. **OAuth with PKCE:** OAuth flows use PKCE for security. Token refresh handled by background job (`tokenHealthCheck.ts`).
8. **ACP Agent Registry:** 14 built-in CLI agents with dynamic detection and a 60-second cache. Custom agents can be added via dashboard or API, stored in settings DB.
8. **ProviderIcon component:** Unified icon system using `@lobehub/icons` (130+ SVG) with PNG fallback and generic icon fallback chain. Used on providers, dashboard, and agents pages.
9. **DB architecture:** `localDb.ts` is a re-export layer only — real logic lives in `src/lib/db/` modules (core, providers, models, combos, apiKeys, settings, backup).
10. **Upstream headers:** Custom headers merged in executors after default auth; same header name replaces executor value. Forbidden header names in `src/shared/constants/upstreamHeaders.ts`.
## Main Flows
### Proxy Request Flow
1. Client sends OpenAI-format request to `/v1/chat/completions`
2. API key validation (`src/shared/utils/apiAuth.ts`)
2. API key validation
3. Model resolution: direct model or combo lookup
4. For combos: iterate through models in fallback order
4. For combos: iterate through models with selected strategy
5. Auth resolution: get credentials for the target provider
6. Format translation: OpenAI → provider native format
7. CLI fingerprint matching (if enabled for provider)
8. Upstream request with circuit breaker and rate limiting
9. Response translation: provider → OpenAI format
10. SSE streaming back to client
10. omniModel tag sanitization (strip internal tags)
11. SSE streaming back to client
### OAuth Flow
1. Dashboard initiates `/api/oauth/[provider]/authorize`
@@ -192,31 +204,27 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
4. Tokens stored as a provider connection in SQLite
5. Background job refreshes tokens before expiry
### Model Listing
- `/api/models` — Dashboard endpoint, lists all defined models with aliases
- `/v1/models` — OpenAI-compatible endpoint, lists only models from active providers
## Important Notes for LLMs
1. **Two model endpoints exist:** `/api/models` (dashboard, all models) and `/v1/models` (OpenAI-compatible, active only). Don't confuse them.
1. **Two model endpoints exist:** `/api/models` (dashboard, all models) and `/v1/models` (OpenAI-compatible, active only).
2. **Provider IDs vs aliases:** Providers have both an ID (`claude`, `github`) and a short alias (`cc`, `gh`). Models are referenced as `alias/model-name` (e.g., `cc/claude-opus-4-6`).
3. **The `open-sse/` directory is a separate npm workspace** with its own config, handlers, and translators. It handles the actual SSE streaming and format translation.
3. **The `open-sse/` directory is a separate npm workspace** with its own config, handlers, and translators.
4. **Environment variables:** All configuration is in `.env` (from `.env.example`). Key vars: `PORT`, `NEXT_PUBLIC_BASE_URL`, `API_KEY`, `ADMIN_PASSWORD`.
5. **Database migrations:** SQLite schema is managed inline in `src/lib/db/core.ts` and `src/lib/db/providers.ts`. No migration framework — schema changes are applied on startup.
5. **Database layer:** Operations go through `src/lib/db/` modules. `localDb.ts` is re-exports only — add new functions to the proper `db/*.ts` module.
6. **Tests use Node.js built-in test runner:** Run `npm test` or `node --test tests/unit/*.test.mjs`. Playwright is used for E2E tests.
6. **Tests use Node.js built-in test runner:** 926 assertions across 32+ test files. Run `npm test`.
7. **The proxy pipeline is in `src/sse/`**, not in `src/app/api/v1/`. The API routes in `src/app/api/v1/` delegate to the SSE server running on a separate Express instance.
7. **MCP and A2A pages are embedded as tabs inside `/dashboard/endpoint`**, not standalone routes.
8. **Sidebar sections:** Main nav, CLI (Tools + Agents), Debug (Translator + Playground + Media), System (Health + Logs + Settings), Help (Docs + Issues).
8. **ACP agents** are in `src/lib/acp/registry.ts` (14 built-in) with a 60s detection cache. Custom agents stored via settings DB.
9. **ACP agents** are in `src/lib/acp/registry.ts` (14 built-in) with a 60s detection cache. Custom agents stored via `src/shared/validation/settingsSchemas.ts`.
9. **Auto-combo engine** in `open-sse/services/autoCombo/` — 6-factor scoring, 4 mode packs, bandit exploration, progressive cooldown.
10. **CLI fingerprint configs** are in `open-sse/config/cliFingerprints.ts`. They match native CLI request patterns per provider.
10. **Docker:** Dockerfile has two targets: `runner-base` and `runner-cli`. `docker-compose.yml` for dev (3 profiles), `docker-compose.prod.yml` for production (port 20130).
## Links
+4
View File
@@ -13,8 +13,11 @@ const nextConfig = {
},
output: "standalone",
serverExternalPackages: [
"pino",
"pino-pretty",
"thread-stream",
"better-sqlite3",
"keytar",
"zod",
"child_process",
"fs",
@@ -68,6 +71,7 @@ const nextConfig = {
const KNOWN_EXTERNALS = new Set([
"better-sqlite3",
"keytar",
"zod",
"pino",
"pino-pretty",
+20 -6
View File
@@ -16,6 +16,7 @@
import { readFileSync, existsSync } from "fs";
import { join } from "path";
import { resolveDataDir } from "../../src/lib/dataPaths";
// Fields that can be overridden per provider
const CREDENTIAL_FIELDS = ["clientId", "clientSecret", "tokenUrl", "authUrl", "refreshUrl"];
@@ -25,13 +26,21 @@ const CONFIG_TTL_MS = 60_000;
let lastLoadTime = 0;
let cachedProviders = null;
// Survives Next.js dev HMR: module-level cache resets but process is the same (V4 pattern).
type CredGlobals = typeof globalThis & { __omnirouteCredNoFileLogged?: boolean };
function credGlobals(): CredGlobals {
return globalThis as CredGlobals;
}
/**
* Resolve the path to provider-credentials.json
* Priority: DATA_DIR env ./data (project root)
* Resolves the path to provider-credentials.json using the application's
* data directory. Delegates to resolveDataDir() which handles DATA_DIR env,
* platform-specific defaults, and fallback logic.
*
* previous: Priority: DATA_DIR env ./data (project root)
*/
function resolveCredentialsPath() {
const dataDir = process.env.DATA_DIR || join(process.cwd(), "data");
return join(dataDir, "provider-credentials.json");
return join(resolveDataDir(), "provider-credentials.json");
}
/**
@@ -51,8 +60,9 @@ export function loadProviderCredentials(providers) {
const credPath = resolveCredentialsPath();
if (!existsSync(credPath)) {
if (!cachedProviders) {
if (!credGlobals().__omnirouteCredNoFileLogged) {
console.log("[CREDENTIALS] No external credentials file found, using defaults.");
credGlobals().__omnirouteCredNoFileLogged = true;
}
cachedProviders = providers;
lastLoadTime = Date.now();
@@ -93,7 +103,11 @@ export function loadProviderCredentials(providers) {
`[CREDENTIALS] ${isReload ? "Reloaded" : "Loaded"} external credentials: ${overrideCount} field(s) from ${credPath}`
);
} catch (err) {
console.log(`[CREDENTIALS] Error reading credentials file: ${err.message}. Using defaults.`);
const reason =
err instanceof SyntaxError
? "Invalid JSON format"
: (err as NodeJS.ErrnoException).code || "read error";
console.log(`[CREDENTIALS] Error reading credentials file (${reason}). Using defaults.`);
}
cachedProviders = providers;
+18 -1
View File
@@ -16,6 +16,8 @@ export interface RegistryModel {
toolCalling?: boolean;
targetFormat?: string;
unsupportedParams?: readonly string[];
/** Maximum context window in tokens */
contextLength?: number;
}
// Reasoning models reject temperature, top_p, penalties, logprobs, n.
@@ -65,6 +67,8 @@ export interface RegistryEntry {
chatPath?: string;
clientVersion?: string;
passthroughModels?: boolean;
/** Default context window for all models in this provider (can be overridden per-model) */
defaultContextLength?: number;
}
interface LegacyProvider {
@@ -137,6 +141,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
urlSuffix: "?beta=true",
authType: "oauth",
authHeader: "x-api-key",
defaultContextLength: 200000,
headers: {
"Anthropic-Version": "2023-06-01",
"Anthropic-Beta":
@@ -180,6 +185,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
},
authType: "apikey",
authHeader: "x-goog-api-key",
defaultContextLength: 1000000,
oauth: {
clientIdEnv: "GEMINI_OAUTH_CLIENT_ID",
clientIdDefault: "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com",
@@ -216,6 +222,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
},
authType: "oauth",
authHeader: "bearer",
defaultContextLength: 1000000,
oauth: {
clientIdEnv: "GEMINI_CLI_OAUTH_CLIENT_ID",
clientIdDefault: "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com",
@@ -247,6 +254,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
baseUrl: "https://chatgpt.com/backend-api/codex/responses",
authType: "oauth",
authHeader: "bearer",
defaultContextLength: 400000,
headers: {
Version: "0.92.0",
"Openai-Beta": "responses=experimental",
@@ -399,6 +407,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
responsesBaseUrl: "https://api.githubcopilot.com/responses",
authType: "oauth",
authHeader: "bearer",
defaultContextLength: 128000,
headers: {
"copilot-integration-id": "vscode-chat",
"editor-version": "vscode/1.110.0",
@@ -447,6 +456,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
baseUrl: "https://codewhisperer.us-east-1.amazonaws.com/generateAssistantResponse",
authType: "oauth",
authHeader: "bearer",
defaultContextLength: 200000,
headers: {
"Content-Type": "application/json",
Accept: "application/vnd.amazon.eventstream",
@@ -473,6 +483,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
chatPath: "/aiserver.v1.ChatService/StreamUnifiedChatWithTools",
authType: "oauth",
authHeader: "bearer",
defaultContextLength: 200000,
headers: {
"connect-accept-encoding": "gzip",
"connect-protocol-version": "1",
@@ -501,6 +512,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
baseUrl: "https://api.openai.com/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 128000,
models: [
{ id: "gpt-4o", name: "GPT-4o" },
{ id: "gpt-4o-mini", name: "GPT-4o Mini" },
@@ -522,6 +534,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
urlSuffix: "?beta=true",
authType: "apikey",
authHeader: "x-api-key",
defaultContextLength: 200000,
headers: {
"Anthropic-Version": "2023-06-01",
},
@@ -548,6 +561,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
authType: "apikey",
authHeader: "Authorization",
authPrefix: "Bearer",
defaultContextLength: 200000,
models: [
{ id: "glm-5", name: "GLM-5" },
{ id: "kimi-k2.5", name: "Kimi K2.5" },
@@ -565,6 +579,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
authType: "apikey",
authHeader: "Authorization",
authPrefix: "Bearer",
defaultContextLength: 200000,
models: [
{ id: "minimax-m2.5-free", name: "MiniMax M2.5 Free" },
{ id: "big-pickle", name: "Big Pickle" },
@@ -580,6 +595,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
baseUrl: "https://openrouter.ai/api/v1/chat/completions",
authType: "apikey",
authHeader: "bearer",
defaultContextLength: 128000,
headers: {
"HTTP-Referer": "https://endpoint-proxy.local",
"X-Title": "Endpoint Proxy",
@@ -593,6 +609,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
format: "claude",
executor: "default",
baseUrl: "https://api.z.ai/api/anthropic/v1/messages",
defaultContextLength: 200000,
urlSuffix: "?beta=true",
authType: "apikey",
authHeader: "x-api-key",
@@ -1353,7 +1370,7 @@ export const REGISTRY: Record<string, RegistryEntry> = {
{ id: "qwen/qwen3-32b", name: "Qwen3 32B (Puter)" },
{ id: "qwen/qwen3-coder", name: "Qwen3 Coder 480B (Puter)" },
],
passthroughModels: true, // 500+ models available — users can type any Puter model ID
passthroughModels: true, // 500+ models available — users can type arbitrary Puter model IDs
},
"cloudflare-ai": {
+3 -2
View File
@@ -1,5 +1,5 @@
import crypto from "crypto";
import { BaseExecutor } from "./base.ts";
import { BaseExecutor, mergeUpstreamExtraHeaders } from "./base.ts";
import { PROVIDERS, OAUTH_ENDPOINTS, HTTP_STATUS } from "../config/constants.ts";
const MAX_RETRY_AFTER_MS = 10000;
@@ -198,7 +198,7 @@ export class AntigravityExecutor extends BaseExecutor {
return totalMs > 0 ? totalMs : null;
}
async execute({ model, body, stream, credentials, signal, log }) {
async execute({ model, body, stream, credentials, signal, log, upstreamExtraHeaders }) {
const fallbackCount = this.getFallbackCount();
let lastError = null;
let lastStatus = 0;
@@ -208,6 +208,7 @@ export class AntigravityExecutor extends BaseExecutor {
for (let urlIndex = 0; urlIndex < fallbackCount; urlIndex++) {
const url = this.buildUrl(model, stream, urlIndex);
const headers = this.buildHeaders(credentials, stream);
mergeUpstreamExtraHeaders(headers, upstreamExtraHeaders);
const transformedBody = this.transformRequest(model, body, stream, credentials);
// Initialize retry counter for this URL
+28 -2
View File
@@ -58,8 +58,23 @@ export type ExecuteInput = {
signal?: AbortSignal | null;
log?: ExecutorLog | null;
extendedContext?: boolean;
/** Merged after auth + CLI fingerprint headers (values override same-named defaults). */
upstreamExtraHeaders?: Record<string, string> | null;
};
/** Apply model-level extra upstream headers (e.g. Authentication, X-Custom-Auth). */
export function mergeUpstreamExtraHeaders(
headers: Record<string, string>,
extra?: Record<string, string> | null
): void {
if (!extra) return;
for (const [k, v] of Object.entries(extra)) {
if (typeof k === "string" && k.length > 0 && typeof v === "string") {
headers[k] = v;
}
}
}
function mergeAbortSignals(primary: AbortSignal, secondary: AbortSignal): AbortSignal {
const controller = new AbortController();
@@ -204,7 +219,16 @@ export class BaseExecutor {
return { status: response.status, message: bodyText || `HTTP ${response.status}` };
}
async execute({ model, body, stream, credentials, signal, log, extendedContext }: ExecuteInput) {
async execute({
model,
body,
stream,
credentials,
signal,
log,
extendedContext,
upstreamExtraHeaders,
}: ExecuteInput) {
const fallbackCount = this.getFallbackCount();
let lastError: unknown = null;
let lastStatus = 0;
@@ -258,6 +282,8 @@ export class BaseExecutor {
bodyString = fingerprinted.bodyString;
}
mergeUpstreamExtraHeaders(finalHeaders, upstreamExtraHeaders);
const fetchOptions: RequestInit = {
method: "POST",
headers: finalHeaders,
@@ -289,7 +315,7 @@ export class BaseExecutor {
continue;
}
return { response, url, headers, transformedBody };
return { response, url, headers: finalHeaders, transformedBody };
} catch (error) {
// Distinguish timeout errors from other abort errors
const err = error instanceof Error ? error : new Error(String(error));
+3 -2
View File
@@ -20,7 +20,7 @@ declare const EdgeRuntime: string | undefined;
* @see cursorProtobuf.js for Protobuf encoding/decoding utilities
*/
import { BaseExecutor } from "./base.ts";
import { BaseExecutor, mergeUpstreamExtraHeaders } from "./base.ts";
import { PROVIDERS, HTTP_STATUS } from "../config/constants.ts";
import {
generateCursorBody,
@@ -363,9 +363,10 @@ export class CursorExecutor extends BaseExecutor {
});
}
async execute({ model, body, stream, credentials, signal, log }) {
async execute({ model, body, stream, credentials, signal, log, upstreamExtraHeaders }) {
const url = this.buildUrl();
const headers = this.buildHeaders(credentials);
mergeUpstreamExtraHeaders(headers, upstreamExtraHeaders);
const transformedBody = this.transformRequest(model, body, stream, credentials);
try {
+11 -1
View File
@@ -1,5 +1,6 @@
import {
BaseExecutor,
mergeUpstreamExtraHeaders,
type ExecuteInput,
type ExecutorLog,
type ProviderCredentials,
@@ -89,9 +90,18 @@ export class KiroExecutor extends BaseExecutor {
/**
* Custom execute for Kiro - handles AWS EventStream binary response
*/
async execute({ model, body, stream, credentials, signal, log }: ExecuteInput) {
async execute({
model,
body,
stream,
credentials,
signal,
log,
upstreamExtraHeaders,
}: ExecuteInput) {
const url = this.buildUrl(model, stream, 0);
const headers = this.buildHeaders(credentials, stream);
mergeUpstreamExtraHeaders(headers, upstreamExtraHeaders);
const transformedBody = this.transformRequest(model, body, stream, credentials);
const response = await fetch(url, {
+77 -13
View File
@@ -1,5 +1,5 @@
import { getCorsOrigin } from "../utils/cors.ts";
import { detectFormat, getTargetFormat } from "../services/provider.ts";
import { detectFormatFromEndpoint, getTargetFormat } from "../services/provider.ts";
import { translateRequest, needsTranslation } from "../translator/index.ts";
import { FORMATS } from "../translator/formats.ts";
import {
@@ -26,7 +26,11 @@ import {
appendRequestLog,
saveCallLog,
} from "@/lib/usageDb";
import { getModelNormalizeToolCallId, getModelPreserveOpenAIDeveloperRole } from "@/lib/localDb";
import {
getModelNormalizeToolCallId,
getModelPreserveOpenAIDeveloperRole,
getModelUpstreamExtraHeaders,
} from "@/lib/localDb";
import { getExecutor } from "../executors/index.ts";
import {
parseCodexQuotaHeaders,
@@ -76,7 +80,8 @@ export function shouldUseNativeCodexPassthrough({
if (provider !== "codex") return false;
if (sourceFormat !== FORMATS.OPENAI_RESPONSES) return false;
const normalizedEndpoint = String(endpointPath || "").replace(/\/+$/, "");
return /(?:^|\/)responses(?:\/.*)?$/i.test(normalizedEndpoint);
const segments = normalizedEndpoint.split("/");
return segments.includes("responses");
}
/**
@@ -216,9 +221,10 @@ export async function handleChatCore({
credentials.connectionId = connectionId;
}
const sourceFormat = detectFormat(body);
const endpointPath = String(clientRawRequest?.endpoint || "");
const isResponsesEndpoint = /(?:^|\/)responses(?:\/.*)?$/i.test(endpointPath);
const sourceFormat = detectFormatFromEndpoint(body, endpointPath);
const isResponsesEndpoint =
/\/responses(?=\/|$)/i.test(endpointPath) || /^responses(?=\/|$)/i.test(endpointPath);
const nativeCodexPassthrough = shouldUseNativeCodexPassthrough({
provider,
sourceFormat,
@@ -280,6 +286,23 @@ export async function handleChatCore({
const modelTargetFormat = getModelTargetFormat(alias, resolvedModel);
const targetFormat = modelTargetFormat || getTargetFormat(provider);
// Primary path: merge client model id + alias target so config on either key applies; resolved
// id wins on same header name. T5 family fallback uses only (nextModel, resolveModelAlias(next))
// so A-model headers are not sent to B — see buildUpstreamHeadersForExecute.
const buildUpstreamHeadersForExecute = (modelToCall: string): Record<string, string> => {
if (modelToCall === effectiveModel) {
return {
...getModelUpstreamExtraHeaders(provider || "", model || "", sourceFormat),
...getModelUpstreamExtraHeaders(provider || "", resolvedModel || "", sourceFormat),
};
}
const r = resolveModelAlias(modelToCall);
return {
...getModelUpstreamExtraHeaders(provider || "", modelToCall || "", sourceFormat),
...getModelUpstreamExtraHeaders(provider || "", r || "", sourceFormat),
};
};
// Default to false unless client explicitly sets stream: true (OpenAI spec compliant)
const acceptHeader =
clientRawRequest?.headers && typeof clientRawRequest.headers.get === "function"
@@ -332,11 +355,42 @@ export async function handleChatCore({
translatedBody = { ...body, _nativeCodexPassthrough: true };
log?.debug?.("FORMAT", "native codex passthrough enabled");
} else if (isClaudePassthrough) {
// Claude-to-Claude passthrough: forward body completely untouched.
// No translation, no field stripping, no thinking normalization.
// We are just a gateway -- do not interfere with the request in the slightest.
translatedBody = { ...body };
log?.debug?.("FORMAT", "claude->claude passthrough -- forwarding untouched");
// Claude OAuth expects the same Claude Code prompt + structural normalization
// as the OpenAI-compatible chat path. Round-trip through OpenAI to reuse the
// working Claude translator instead of forwarding raw Messages payloads.
const normalizeToolCallId = getModelNormalizeToolCallId(
provider || "",
model || "",
sourceFormat
);
const preserveDeveloperRole = getModelPreserveOpenAIDeveloperRole(
provider || "",
model || "",
sourceFormat
);
translatedBody = translateRequest(
FORMATS.CLAUDE,
FORMATS.OPENAI,
model,
{ ...body },
stream,
credentials,
provider,
reqLogger,
{ normalizeToolCallId, preserveDeveloperRole }
);
translatedBody = translateRequest(
FORMATS.OPENAI,
FORMATS.CLAUDE,
model,
translatedBody,
stream,
credentials,
provider,
reqLogger,
{ normalizeToolCallId, preserveDeveloperRole }
);
log?.debug?.("FORMAT", "claude->openai->claude normalized passthrough");
} else {
translatedBody = { ...body };
@@ -562,6 +616,7 @@ export async function handleChatCore({
signal: streamController.signal,
log,
extendedContext,
upstreamExtraHeaders: buildUpstreamHeadersForExecute(modelToCall),
})
);
@@ -693,16 +748,19 @@ export async function handleChatCore({
await onCredentialsRefreshed(newCredentials);
}
// Retry with new credentials
// Retry with new credentials — model + extra headers follow translatedBody.model so they
// stay aligned if this block ever runs after a path that mutates body.model (e.g. fallback).
try {
const retryModelId = String(translatedBody.model || effectiveModel);
const retryResult = await executor.execute({
model,
model: retryModelId,
body: translatedBody,
stream,
credentials: getExecutionCredentials(),
signal: streamController.signal,
log,
extendedContext,
upstreamExtraHeaders: buildUpstreamHeadersForExecute(retryModelId),
});
if (retryResult.response.ok) {
@@ -1010,8 +1068,14 @@ export async function handleChatCore({
}
// Translate response to client's expected format (usually OpenAI)
// Pass toolNameMap so Claude OAuth proxy_ prefix is stripped in tool_use blocks (#605)
let translatedResponse = needsTranslation(targetFormat, sourceFormat)
? translateNonStreamingResponse(responseBody, targetFormat, sourceFormat)
? translateNonStreamingResponse(
responseBody,
targetFormat,
sourceFormat,
toolNameMap as Map<string, string> | null
)
: responseBody;
// T26: Strip markdown code blocks if provider format is Claude
+24 -8
View File
@@ -1081,6 +1081,21 @@ async function handleComfyUIImageGeneration({ model, provider, providerConfig, b
}
}
type Imagen3ImageGenArgs = {
model: string;
provider: string;
providerConfig: { baseUrl: string };
body: { prompt?: string; size?: string; n?: number };
credentials: { apiKey?: string; accessToken?: string };
log?: { info?: (tag: string, msg: string) => void; error?: (tag: string, msg: string) => void } | null;
};
type Imagen3NormalizedImage = {
b64_json?: unknown;
url?: unknown;
revised_prompt?: string;
};
/**
* Handle Imagen 3 image generation
*/
@@ -1091,7 +1106,7 @@ async function handleImagen3ImageGeneration({
body,
credentials,
log,
}: any) {
}: Imagen3ImageGenArgs) {
const startTime = Date.now();
const token = credentials.apiKey || credentials.accessToken;
const aspectRatio = mapImageSize(body.size);
@@ -1142,11 +1157,11 @@ async function handleImagen3ImageGeneration({
const data = await response.json();
// Normalize response to OpenAI format
const images: any[] = [];
const images: Imagen3NormalizedImage[] = [];
if (Array.isArray(data.images)) {
images.push(
...data.images.map((img: any) => ({
b64_json: img.image || img.b64_json || img.url || img,
...data.images.map((img: Record<string, unknown>) => ({
b64_json: img.image ?? img.b64_json ?? img.url ?? img,
revised_prompt: body.prompt,
}))
);
@@ -1174,8 +1189,9 @@ async function handleImagen3ImageGeneration({
success: true,
data: { created: data.created || Math.floor(Date.now() / 1000), data: images },
};
} catch (err: any) {
if (log) log.error("IMAGE", `${provider} fetch error: ${err.message}`);
} catch (err: unknown) {
const errMsg = err instanceof Error ? err.message : String(err);
if (log) log.error("IMAGE", `${provider} fetch error: ${errMsg}`);
saveCallLog({
method: "POST",
@@ -1184,9 +1200,9 @@ async function handleImagen3ImageGeneration({
model: `${provider}/${model}`,
provider,
duration: Date.now() - startTime,
error: err.message,
error: errMsg,
}).catch(() => {});
return { success: false, status: 502, error: `Image provider error: ${err.message}` };
return { success: false, status: 502, error: `Image provider error: ${errMsg}` };
}
}
+13 -3
View File
@@ -68,11 +68,14 @@ function findBestMessageText(output: unknown[]): {
/**
* Translate non-streaming response to OpenAI format
* Handles different provider response formats (Gemini, Claude, etc.)
*
* @param toolNameMap - Optional Map<prefixedName, originalName> for Claude OAuth tool name stripping
*/
export function translateNonStreamingResponse(
responseBody: unknown,
targetFormat: string,
sourceFormat: string
sourceFormat: string,
toolNameMap?: Map<string, string> | null
): unknown {
// If already in source format (usually OpenAI), return as-is
if (targetFormat === sourceFormat || targetFormat === FORMATS.OPENAI) {
@@ -122,11 +125,14 @@ export function translateNonStreamingResponse(
typeof itemObj.arguments === "string"
? itemObj.arguments
: JSON.stringify(itemObj.arguments || {});
const rawName = toString(itemObj.name);
// Strip Claude OAuth proxy_ prefix using toolNameMap (mirrors tool_use fix for #605)
const resolvedName = toolNameMap?.get(rawName) ?? rawName;
toolCalls.push({
id: callId,
type: "function",
function: {
name: toString(itemObj.name),
name: resolvedName,
arguments: fnArgs,
},
});
@@ -334,11 +340,15 @@ export function translateNonStreamingResponse(
} else if (blockObj.type === "thinking") {
thinkingContent += toString(blockObj.thinking);
} else if (blockObj.type === "tool_use") {
// Strip Claude OAuth tool name prefix (proxy_) using the map from request translation.
// Fallback to raw name if block wasn't prefixed (disableToolPrefix path).
const rawName = toString(blockObj.name);
const strippedName = toolNameMap?.get(rawName) ?? rawName;
toolCalls.push({
id: toString(blockObj.id, `call_${Date.now()}_${toolCalls.length}`),
type: "function",
function: {
name: toString(blockObj.name),
name: strippedName,
arguments: JSON.stringify(blockObj.input || {}),
},
});
+9 -2
View File
@@ -23,12 +23,19 @@ export function parseSSEToOpenAIResponse(rawSSE, fallbackModel) {
const first = chunks[0];
const contentParts = [];
const reasoningParts = [];
const accumulatedToolCalls = new Map<string, any>();
type AccumulatedToolCall = {
id: string | null;
index: number;
type: string;
function: { name: string; arguments: string };
};
const accumulatedToolCalls = new Map<string, AccumulatedToolCall>();
let unknownToolCallSeq = 0;
let finishReason = "stop";
let usage = null;
const getToolCallKey = (toolCall: any) => {
const getToolCallKey = (toolCall: Record<string, unknown>) => {
if (toolCall?.id) return `id:${toolCall.id}`;
if (Number.isInteger(toolCall?.index)) return `idx:${toolCall.index}`;
unknownToolCallSeq += 1;
+1
View File
@@ -36,6 +36,7 @@ export {
// Services
export {
detectFormat,
detectFormatFromEndpoint,
getProviderConfig,
buildProviderUrl,
buildProviderHeaders,
+182 -52
View File
@@ -1,5 +1,5 @@
/**
* MCP HTTP Transport Layer Singleton server + SSE/Streamable HTTP handlers.
* MCP HTTP Transport Layer session-aware handlers for SSE and Streamable HTTP.
*
* Runs the MCP server **inside** the Next.js process so it can be toggled
* from the dashboard without requiring `omniroute --mcp`.
@@ -14,58 +14,188 @@ import { createMcpServer } from "./server.ts";
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
// ────── Singleton ──────────────────────────────────────────
let _sseServer: McpServer | null = null;
let _sseTransport: WebStandardStreamableHTTPServerTransport | null = null;
let _sseStartedAt: number | null = null;
let _server: McpServer | null = null;
let _transport: WebStandardStreamableHTTPServerTransport | null = null;
let _startedAt: number | null = null;
let _activeTransportMode: "sse" | "streamable-http" | null = null;
type StreamableSession = {
sessionId: string;
server: McpServer;
transport: WebStandardStreamableHTTPServerTransport;
startedAt: number;
};
function ensureServer(mode: "sse" | "streamable-http"): {
const _streamableSessions = new Map<string, StreamableSession>();
function closeSseTransport(): void {
if (_sseTransport) {
try {
_sseTransport.close();
} catch {
// ignore shutdown errors
}
}
_sseServer = null;
_sseTransport = null;
_sseStartedAt = null;
}
function closeStreamableSession(sessionId: string): void {
const session = _streamableSessions.get(sessionId);
if (!session) {
return;
}
try {
session.transport.close();
} catch {
// ignore shutdown errors
}
_streamableSessions.delete(sessionId);
}
function closeAllStreamableSessions(): void {
for (const sessionId of _streamableSessions.keys()) {
closeStreamableSession(sessionId);
}
}
function ensureSseServer(): {
server: McpServer;
transport: WebStandardStreamableHTTPServerTransport;
} {
if (_server && _transport && _activeTransportMode === mode) {
return { server: _server, transport: _transport };
if (_sseServer && _sseTransport) {
return { server: _sseServer, transport: _sseTransport };
}
// Shutdown previous if switching modes
if (_transport) {
try { _transport.close(); } catch { /* ignore */ }
}
closeAllStreamableSessions();
_server = createMcpServer();
_transport = new WebStandardStreamableHTTPServerTransport({
_sseServer = createMcpServer();
_sseTransport = new WebStandardStreamableHTTPServerTransport({
sessionIdGenerator: () => randomUUID(),
});
_activeTransportMode = mode;
_startedAt = Date.now();
_sseStartedAt = Date.now();
// Connect server to transport (fire-and-forget, will be ready by first request)
void _server.connect(_transport);
void _sseServer.connect(_sseTransport);
console.log(`[MCP] HTTP transport started (${mode})`);
return { server: _server, transport: _transport };
console.log("[MCP] HTTP transport started (sse)");
return { server: _sseServer, transport: _sseTransport };
}
// ────── Streamable HTTP Handler ────────────────────────────
function createStreamableSession(): StreamableSession {
closeSseTransport();
const sessionId = randomUUID();
const server = createMcpServer();
const transport = new WebStandardStreamableHTTPServerTransport({
sessionIdGenerator: () => sessionId,
});
const session = {
sessionId,
server,
transport,
startedAt: Date.now(),
};
void server.connect(transport);
_streamableSessions.set(sessionId, session);
console.log(`[MCP] HTTP transport started (streamable-http:${sessionId})`);
return session;
}
async function isInitializeRequest(request: Request): Promise<boolean> {
if (request.method !== "POST") {
return false;
}
try {
const body = (await request.clone().json()) as { method?: unknown };
return body?.method === "initialize";
} catch {
return false;
}
}
function errorResponse(message: string, code: number, status = 400): Response {
return new Response(
JSON.stringify({
jsonrpc: "2.0",
error: { code, message },
id: null,
}),
{
status,
headers: { "Content-Type": "application/json" },
}
);
}
function withSessionHeader(response: Response, sessionId: string): Response {
if (response.headers.get("mcp-session-id")) {
return response;
}
const headers = new Headers(response.headers);
headers.set("mcp-session-id", sessionId);
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers,
});
}
async function handleStreamableRequest(request: Request): Promise<Response> {
const sessionId = request.headers.get("mcp-session-id");
if (sessionId) {
const session = _streamableSessions.get(sessionId);
if (!session) {
return errorResponse("Bad Request: Unknown Mcp-Session-Id header", -32000);
}
try {
const response = await session.transport.handleRequest(request);
if (request.method === "DELETE") {
closeStreamableSession(sessionId);
}
return withSessionHeader(response, sessionId);
} catch (err) {
console.error("[MCP] Streamable HTTP error:", err);
if (request.method === "DELETE") {
closeStreamableSession(sessionId);
}
return new Response(JSON.stringify({ error: "MCP transport error" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
}
if (!(await isInitializeRequest(request))) {
return errorResponse("Bad Request: Mcp-Session-Id header is required", -32000);
}
const session = createStreamableSession();
try {
const response = await session.transport.handleRequest(request);
return withSessionHeader(response, session.sessionId);
} catch (err) {
closeStreamableSession(session.sessionId);
console.error("[MCP] Streamable HTTP error:", err);
return new Response(JSON.stringify({ error: "MCP transport error" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
}
/**
* Handle Streamable HTTP requests (POST / GET / DELETE).
* Used by the Next.js route at /api/mcp/stream.
*/
export async function handleMcpStreamableHTTP(request: Request): Promise<Response> {
const { transport } = ensureServer("streamable-http");
try {
return await transport.handleRequest(request);
} catch (err) {
console.error("[MCP] Streamable HTTP error:", err);
return new Response(
JSON.stringify({ error: "MCP transport error" }),
{ status: 500, headers: { "Content-Type": "application/json" } },
);
}
return handleStreamableRequest(request);
}
/**
@@ -74,47 +204,47 @@ export async function handleMcpStreamableHTTP(request: Request): Promise<Respons
* and POST for messages (the Streamable HTTP transport supports both patterns).
*/
export async function handleMcpSSE(request: Request): Promise<Response> {
const { transport } = ensureServer("sse");
const { transport } = ensureSseServer();
try {
return await transport.handleRequest(request);
} catch (err) {
console.error("[MCP] SSE error:", err);
return new Response(
JSON.stringify({ error: "MCP SSE transport error" }),
{ status: 500, headers: { "Content-Type": "application/json" } },
);
return new Response(JSON.stringify({ error: "MCP SSE transport error" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
}
// ────── Status & Lifecycle ─────────────────────────────────
export function getMcpHttpStatus(): {
online: boolean;
transport: string | null;
startedAt: number | null;
uptime: string | null;
} {
const online = _transport !== null && _activeTransportMode !== null;
const streamableStartedAt =
_streamableSessions.size > 0
? Math.min(...Array.from(_streamableSessions.values(), (session) => session.startedAt))
: null;
const startedAt = streamableStartedAt ?? _sseStartedAt;
const transport = _streamableSessions.size > 0 ? "streamable-http" : _sseTransport ? "sse" : null;
const online = transport !== null;
return {
online,
transport: _activeTransportMode,
startedAt: _startedAt,
uptime: _startedAt ? `${Math.floor((Date.now() - _startedAt) / 1000)}s` : null,
transport,
startedAt,
uptime: startedAt ? `${Math.floor((Date.now() - startedAt) / 1000)}s` : null,
};
}
export function shutdownMcpHttp(): void {
if (_transport) {
try { _transport.close(); } catch { /* ignore */ }
}
_server = null;
_transport = null;
_activeTransportMode = null;
_startedAt = null;
closeSseTransport();
closeAllStreamableSessions();
console.log("[MCP] HTTP transport shutdown");
}
export function isMcpHttpActive(): boolean {
return _transport !== null;
return _sseTransport !== null || _streamableSessions.size > 0;
}
+3 -3
View File
@@ -57,7 +57,7 @@ export const TaskInputSchema = z.object({
role: z
.enum(["coding", "review", "planning", "analysis", "debugging", "documentation"])
.optional(),
metadata: z.record(z.unknown()).optional(),
metadata: z.record(z.string(), z.unknown()).optional(),
});
export const CostEnvelopeSchema = z.object({
@@ -120,7 +120,7 @@ export type PolicyVerdict = z.infer<typeof PolicyVerdictSchema>;
export const JsonRpcRequestSchema = z.object({
jsonrpc: z.literal("2.0"),
method: z.enum(["message/send", "message/stream", "tasks/get", "tasks/cancel"]),
params: z.record(z.unknown()),
params: z.record(z.string(), z.unknown()),
id: z.union([z.string(), z.number()]),
});
@@ -151,7 +151,7 @@ export const MessageSendParamsSchema = z.object({
message: z.object({
role: z.string().default("user"),
content: z.string(),
metadata: z.record(z.unknown()).optional(),
metadata: z.record(z.string(), z.unknown()).optional(),
}),
config: z
.object({
+2 -2
View File
@@ -435,7 +435,7 @@ async function handleListModelsCatalog(args: { provider?: string; capability?: s
let path = "/v1/models";
let isProviderSpecific = false;
let source = "local_catalog";
let warning = undefined;
let warning: string | undefined;
if (args.provider && !args.capability) {
// Use direct provider fetch to get real-time API status
@@ -451,7 +451,7 @@ async function handleListModelsCatalog(args: { provider?: string; capability?: s
const raw = toRecord(await omniRouteFetch(path));
// If we used the direct provider endpoint
let rawModels = [];
let rawModels: unknown[] = [];
if (isProviderSpecific) {
rawModels = Array.isArray(raw.models) ? raw.models : [];
source = typeof raw.source === "string" ? raw.source : "api";
+2 -1
View File
@@ -7,6 +7,7 @@
import fs from "fs";
import path from "path";
import { resolveDataDir } from "../../../src/lib/dataPaths";
export interface AdaptationState {
comboId: string;
@@ -23,7 +24,7 @@ export interface AdaptationState {
lastUpdated: string;
}
const PERSISTENCE_DIR = path.join(process.cwd(), "data");
const PERSISTENCE_DIR = resolveDataDir();
const STATE_FILE = path.join(PERSISTENCE_DIR, "auto_combo_state.json");
let stateCache = new Map<string, AdaptationState>();
+25 -2
View File
@@ -522,10 +522,33 @@ export async function handleComboChat({
},
});
const transformedStream = res.body.pipeThrough(transform);
// FIX #585: Sanitize outbound stream — strip <omniModel> tags from
// visible content so they don't leak to the user. The tag is still
// present in the full response for round-trip context pinning, but
// we clean it from each SSE chunk's content field before delivery.
const sanitize = new TransformStream({
transform(chunk, controller) {
const text = decoder.decode(chunk, { stream: true });
// Only run replacement if the chunk actually contains the tag
if (text.includes("<omniModel>")) {
const cleaned = text.replace(
/(?:\\\\n|\\n)?<omniModel>[^<]+<\/omniModel>(?:\\\\n|\\n)?/g,
""
);
controller.enqueue(encoder.encode(cleaned));
} else {
controller.enqueue(chunk);
}
},
});
const transformedStream = res.body.pipeThrough(transform).pipeThrough(sanitize);
// Add model info as response header for clients that support it
const headers = new Headers(res.headers);
headers.set("X-OmniRoute-Model", modelStr);
return new Response(transformedStream, {
status: res.status,
headers: res.headers,
headers,
});
}
: handleSingleModel;
+39 -5
View File
@@ -5,14 +5,34 @@
* 3 layers: trim tool messages, compress thinking, aggressive purification.
*/
// Default token limits per provider (rough estimates based on model context windows)
const DEFAULT_LIMITS = {
import { REGISTRY } from "../config/providerRegistry.ts";
// Default token limits per provider (fallbacks when not in registry)
const DEFAULT_LIMITS: Record<string, number> = {
claude: 200000,
openai: 128000,
gemini: 1000000,
codex: 400000,
default: 128000,
};
// Environment variable overrides (highest priority)
function getEnvOverride(provider: string): number | null {
const envKey = `CONTEXT_LENGTH_${provider.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`;
const envValue = process.env[envKey];
if (envValue) {
const parsed = parseInt(envValue, 10);
if (!isNaN(parsed) && parsed > 0) return parsed;
}
// Global override
const globalValue = process.env.CONTEXT_LENGTH_DEFAULT;
if (globalValue) {
const parsed = parseInt(globalValue, 10);
if (!isNaN(parsed) && parsed > 0) return parsed;
}
return null;
}
// Rough chars-per-token ratio for quick estimation
const CHARS_PER_TOKEN = 4;
@@ -27,9 +47,20 @@ export function estimateTokens(text) {
/**
* Get token limit for a provider/model combination
* Priority: Env override > Registry defaultContextLength > DEFAULT_LIMITS
*/
export function getTokenLimit(provider, model = null) {
// Check if model has a known limit
// 1. Check environment variable override first
const envOverride = getEnvOverride(provider);
if (envOverride) return envOverride;
// 2. Check registry for provider default
const registryEntry = REGISTRY[provider];
if (registryEntry?.defaultContextLength) {
return registryEntry.defaultContextLength;
}
// 3. Check if model name hints at a known limit
if (model) {
const lower = model.toLowerCase();
if (lower.includes("claude")) return DEFAULT_LIMITS.claude;
@@ -38,10 +69,13 @@ export function getTokenLimit(provider, model = null) {
lower.includes("gpt") ||
lower.includes("o1") ||
lower.includes("o3") ||
lower.includes("o4")
lower.includes("o4") ||
lower.includes("codex")
)
return DEFAULT_LIMITS.openai;
return DEFAULT_LIMITS.codex;
}
// 4. Fallback to DEFAULT_LIMITS or default
return DEFAULT_LIMITS[provider] || DEFAULT_LIMITS.default;
}
+2 -2
View File
@@ -242,8 +242,8 @@ export async function getModelInfoCore(modelStr, aliasesOrGetter) {
// FIX #73: Models like claude-haiku-4-5-20251001 sent without provider prefix
// would incorrectly route to OpenAI. Use heuristic prefix detection first.
if (/^claude-/i.test(modelId)) {
// Claude models → Antigravity (Anthropic) provider
return { provider: "antigravity", model: modelId, extendedContext };
// Claude models → Anthropic provider (canonical source for Claude models)
return { provider: "anthropic", model: modelId, extendedContext };
}
if (/^gemini-/i.test(modelId) || /^gemma-/i.test(modelId)) {
// Gemini/Gemma models → Gemini provider
+21
View File
@@ -35,6 +35,27 @@ function buildAnthropicCompatibleUrl(baseUrl) {
return `${normalized}/messages`;
}
// Detect request format from endpoint first when the route is known.
// This avoids ambiguous bodies like OpenAI /chat/completions requests that also
// contain max_tokens or Claude model names.
export function detectFormatFromEndpoint(body, endpointPath = "") {
const path = String(endpointPath || "");
if (/\/responses(?=\/|$)/i.test(path) || /^responses(?=\/|$)/i.test(path)) {
return "openai-responses";
}
if (/\/messages(?=\/|$)/i.test(path) || /^messages(?=\/|$)/i.test(path)) {
return "claude";
}
if (/\/(?:chat\/completions|completions)(?=\/|$)/i.test(path) || /^(?:chat\/completions|completions)(?=\/|$)/i.test(path)) {
return "openai";
}
return detectFormat(body);
}
// Detect request format from body structure
export function detectFormat(body) {
// OpenAI Responses API:
+22 -9
View File
@@ -86,7 +86,8 @@ function toDisplayLabel(value: string): string {
.filter(Boolean)
.map((part) => {
if (/^pro\+$/i.test(part)) return "Pro+";
if (/^[a-z]{2,}$/.test(part)) return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
if (/^[a-z]{2,}$/.test(part))
return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
return part;
})
.join(" ")
@@ -200,7 +201,9 @@ async function getGitHubUsage(accessToken, providerSpecificData) {
if (dataRecord.quota_snapshots) {
// Paid plan format
const snapshots = toRecord(dataRecord.quota_snapshots);
const resetAt = parseResetTime(getFieldValue(dataRecord, "quota_reset_date", "quotaResetDate"));
const resetAt = parseResetTime(
getFieldValue(dataRecord, "quota_reset_date", "quotaResetDate")
);
const premiumQuota = formatGitHubQuotaSnapshot(snapshots.premium_interactions, resetAt);
const chatQuota = formatGitHubQuotaSnapshot(snapshots.chat, resetAt);
const completionsQuota = formatGitHubQuotaSnapshot(snapshots.completions, resetAt);
@@ -225,7 +228,11 @@ async function getGitHubUsage(accessToken, providerSpecificData) {
// Free/limited plan format
const monthlyQuotas = toRecord(dataRecord.monthly_quotas);
const usedQuotas = toRecord(dataRecord.limited_user_quotas);
const resetDate = getFieldValue(dataRecord, "limited_user_reset_date", "limitedUserResetDate");
const resetDate = getFieldValue(
dataRecord,
"limited_user_reset_date",
"limitedUserResetDate"
);
const resetAt = parseResetTime(resetDate);
const quotas: Record<string, UsageQuota> = {};
@@ -327,11 +334,7 @@ function inferGitHubPlanName(data: JsonRecord, premiumQuota: UsageQuota | null):
toNumber(getFieldValue(monthlyQuotas, "premium_interactions", "premiumInteractions"), 0);
const chatTotal = toNumber(getFieldValue(monthlyQuotas, "chat", "chat"), 0);
if (
combined.includes("PRO+") ||
combined.includes("PRO_PLUS") ||
combined.includes("PROPLUS")
) {
if (combined.includes("PRO+") || combined.includes("PRO_PLUS") || combined.includes("PROPLUS")) {
return "Copilot Pro+";
}
if (combined.includes("ENTERPRISE")) return "Copilot Enterprise";
@@ -655,8 +658,18 @@ async function getClaudeUsage(accessToken) {
}
}
// Try to extract plan tier from the OAuth response
const planRaw =
typeof data.tier === "string"
? data.tier
: typeof data.plan === "string"
? data.plan
: typeof data.subscription_type === "string"
? data.subscription_type
: null;
return {
plan: "Claude Code",
plan: planRaw || "Claude Code",
quotas,
extraUsage: data.extra_usage ?? null,
};
@@ -40,6 +40,7 @@ export function createResponsesLogger(model, logsDir = null) {
const timestamp = new Date().toISOString().replace(/[:.]/g, "").slice(0, 15);
const uniqueId = Math.random().toString(36).slice(2, 8);
const baseDir = logsDir || (typeof process !== "undefined" ? process.cwd() : ".");
// previous: const baseDir = logsDir || resolveDataDir(); — reverted in #555 for Workers compat
const logDir = path.join(baseDir, "logs", `responses_${model}_${timestamp}_${uniqueId}`);
try {
+1 -1
View File
@@ -144,7 +144,7 @@ export function translateRequest(
}
// Final step: prepare request for Claude format endpoints
if (targetFormat === FORMATS.CLAUDE && sourceFormat !== FORMATS.CLAUDE) {
if (targetFormat === FORMATS.CLAUDE) {
result = prepareClaudeRequest(result, provider);
}
@@ -29,7 +29,7 @@ type ClaudeTool = {
/**
* T02: Recursively strips empty text blocks from content arrays.
* Anthropic returns 400 "text content blocks must be non-empty" if any
* Anthropic returns 400 "text content blocks must be non-empty" when a
* text block has text: "". Must also recurse into nested tool_result.content.
* Ref: sub2api PR #1212
*/
@@ -259,11 +259,19 @@ export function openaiToClaudeRequest(model, body, stream) {
toolNameMap.set(toolName, originalName);
}
// Normalize input_schema: Anthropic requires `properties` when type is "object" (#595).
// MCP tools (e.g. pencil, computer_use) may omit properties on object-type schemas.
const rawSchema: Record<string, unknown> =
toolData.parameters || toolData.input_schema || { type: "object", properties: {}, required: [] };
const normalizedSchema =
rawSchema.type === "object" && !rawSchema.properties
? { ...rawSchema, properties: {} }
: rawSchema;
return {
name: toolName,
description: toolData.description || "",
input_schema: toolData.parameters ||
toolData.input_schema || { type: "object", properties: {}, required: [] },
input_schema: normalizedSchema,
};
});
+2 -4
View File
@@ -16,10 +16,8 @@ async function ensureNodeModules() {
try {
fs = await import("fs");
path = await import("path");
LOGS_DIR = path.join(
typeof process !== "undefined" && process.cwd ? process.cwd() : ".",
"logs"
);
const { resolveDataDir } = await import("../../src/lib/dataPaths");
LOGS_DIR = path.join(resolveDataDir(), "logs");
} catch {
// Running in non-Node environment (Worker, Browser, etc.)
}
+10 -6
View File
@@ -57,6 +57,8 @@ type TranslateState = ReturnType<typeof initState> & {
accumulatedContent?: string;
};
type UsageTokenRecord = Record<string, number>;
function getOpenAIIntermediateChunks(value: unknown): unknown[] {
if (!value || typeof value !== "object") return [];
const candidate = (value as JsonRecord)._openaiIntermediate;
@@ -108,7 +110,9 @@ export function createSSEStream(options: StreamOptions = {}) {
} = options;
let buffer = "";
let usage = null;
let usage: UsageTokenRecord | null = null;
/** Passthrough (OpenAI CC shape): saw tool_calls in stream before finish_reason */
let passthroughHasToolCalls = false;
// State for translate mode (accumulatedContent for call log response body)
const state: TranslateState | null =
@@ -223,9 +227,9 @@ export function createSSEStream(options: StreamOptions = {}) {
if (extracted) {
// Non-destructive merge: never overwrite a positive value with 0
// message_start carries input_tokens, message_delta carries output_tokens;
if (!usage) usage = {} as any;
const u = usage as Record<string, number>;
const eu = extracted as Record<string, number>;
if (!usage) usage = {};
const u = usage;
const eu = extracted as UsageTokenRecord;
if (eu.prompt_tokens > 0) u.prompt_tokens = eu.prompt_tokens;
if (eu.completion_tokens > 0) u.completion_tokens = eu.completion_tokens;
if (eu.total_tokens > 0) u.total_tokens = eu.total_tokens;
@@ -266,7 +270,7 @@ export function createSSEStream(options: StreamOptions = {}) {
// T18: Track if we saw tool calls
if (delta?.tool_calls && delta.tool_calls.length > 0) {
(state as any).passthroughHasToolCalls = true;
passthroughHasToolCalls = true;
}
const content = delta?.content || delta?.reasoning_content;
@@ -288,7 +292,7 @@ export function createSSEStream(options: StreamOptions = {}) {
// T18: Normalize finish_reason to 'tool_calls' if tool calls were used
if (
isFinishChunk &&
(state as any).passthroughHasToolCalls &&
passthroughHasToolCalls &&
parsed.choices[0].finish_reason !== "tool_calls"
) {
parsed.choices[0].finish_reason = "tool_calls";
+1 -1
View File
@@ -140,7 +140,7 @@ export function createDisconnectAwareStream(transformStream, streamController) {
const errorMsg = error instanceof Error ? error.message : "Upstream stream error";
const statusCode =
typeof error === "object" && error !== null && "statusCode" in error
? (error as any).statusCode
? Number((error as { statusCode?: unknown }).statusCode) || 500
: 500;
const errorEvent = {
+206 -157
View File
@@ -1,12 +1,12 @@
{
"name": "omniroute",
"version": "3.0.0-rc.10",
"version": "3.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "omniroute",
"version": "3.0.0-rc.10",
"version": "3.0.1",
"hasInstallScript": true,
"license": "MIT",
"workspaces": [
@@ -26,6 +26,7 @@
"http-proxy-middleware": "^3.0.5",
"https-proxy-agent": "^8.0.0",
"jose": "^6.1.3",
"keytar": "^7.9.0",
"lowdb": "^7.0.1",
"monaco-editor": "^0.55.1",
"next": "^16.0.10",
@@ -55,6 +56,7 @@
"@tailwindcss/postcss": "^4.1.18",
"@types/bcryptjs": "^3.0.0",
"@types/better-sqlite3": "^7.6.13",
"@types/keytar": "^4.4.0",
"@types/node": "^25.2.3",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
@@ -1785,6 +1787,9 @@
"cpu": [
"arm"
],
"libc": [
"glibc"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -1801,6 +1806,9 @@
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -1817,6 +1825,9 @@
"cpu": [
"ppc64"
],
"libc": [
"glibc"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -1833,6 +1844,9 @@
"cpu": [
"riscv64"
],
"libc": [
"glibc"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -1849,6 +1863,9 @@
"cpu": [
"s390x"
],
"libc": [
"glibc"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -1881,6 +1898,9 @@
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
@@ -1913,6 +1933,9 @@
"cpu": [
"arm"
],
"libc": [
"glibc"
],
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -1935,6 +1958,9 @@
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -1957,6 +1983,9 @@
"cpu": [
"ppc64"
],
"libc": [
"glibc"
],
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -1979,6 +2008,9 @@
"cpu": [
"riscv64"
],
"libc": [
"glibc"
],
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -2001,6 +2033,9 @@
"cpu": [
"s390x"
],
"libc": [
"glibc"
],
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -2045,6 +2080,9 @@
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "Apache-2.0",
"optional": true,
"os": [
@@ -2554,28 +2592,32 @@
}
},
"node_modules/@napi-rs/wasm-runtime": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz",
"integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==",
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz",
"integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@emnapi/core": "^1.4.3",
"@emnapi/runtime": "^1.4.3",
"@tybys/wasm-util": "^0.10.0"
"@emnapi/core": "^1.7.1",
"@emnapi/runtime": "^1.7.1",
"@tybys/wasm-util": "^0.10.1"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Brooooooklyn"
}
},
"node_modules/@next/env": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.10.tgz",
"integrity": "sha512-8tuaQkyDVgeONQ1MeT9Mkk8pQmZapMKFh5B+OrFUlG3rVmYTXcXlBetBgTurKXGaIZvkoqRT9JL5K3phXcgang==",
"version": "16.1.7",
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.7.tgz",
"integrity": "sha512-rJJbIdJB/RQr2F1nylZr/PJzamvNNhfr3brdKP6s/GW850jbtR70QlSfFselvIBbcPUOlQwBakexjFzqLzF6pg==",
"license": "MIT"
},
"node_modules/@next/eslint-plugin-next": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.0.10.tgz",
"integrity": "sha512-b2NlWN70bbPLmfyoLvvidPKWENBYYIe017ZGUpElvQjDytCWgxPJx7L9juxHt0xHvNVA08ZHJdOyhGzon/KJuw==",
"version": "16.1.6",
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.1.6.tgz",
"integrity": "sha512-/Qq3PTagA6+nYVfryAtQ7/9FEr/6YVyvOtl6rZnGsbReGLf0jZU6gkpr1FuChAQpvV46a78p4cmHOVP8mbfSMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2583,9 +2625,9 @@
}
},
"node_modules/@next/swc-darwin-arm64": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.10.tgz",
"integrity": "sha512-4XgdKtdVsaflErz+B5XeG0T5PeXKDdruDf3CRpnhN+8UebNa5N2H58+3GDgpn/9GBurrQ1uWW768FfscwYkJRg==",
"version": "16.1.7",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.7.tgz",
"integrity": "sha512-b2wWIE8sABdyafc4IM8r5Y/dS6kD80JRtOGrUiKTsACFQfWWgUQ2NwoUX1yjFMXVsAwcQeNpnucF2ZrujsBBPg==",
"cpu": [
"arm64"
],
@@ -2599,9 +2641,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.10.tgz",
"integrity": "sha512-spbEObMvRKkQ3CkYVOME+ocPDFo5UqHb8EMTS78/0mQ+O1nqE8toHJVioZo4TvebATxgA8XMTHHrScPrn68OGw==",
"version": "16.1.7",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.7.tgz",
"integrity": "sha512-zcnVaaZulS1WL0Ss38R5Q6D2gz7MtBu8GZLPfK+73D/hp4GFMrC2sudLky1QibfV7h6RJBJs/gOFvYP0X7UVlQ==",
"cpu": [
"x64"
],
@@ -2615,9 +2657,9 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.10.tgz",
"integrity": "sha512-uQtWE3X0iGB8apTIskOMi2w/MKONrPOUCi5yLO+v3O8Mb5c7K4Q5KD1jvTpTF5gJKa3VH/ijKjKUq9O9UhwOYw==",
"version": "16.1.7",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.7.tgz",
"integrity": "sha512-2ant89Lux/Q3VyC8vNVg7uBaFVP9SwoK2jJOOR0L8TQnX8CAYnh4uctAScy2Hwj2dgjVHqHLORQZJ2wH6VxhSQ==",
"cpu": [
"arm64"
],
@@ -2634,9 +2676,9 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.10.tgz",
"integrity": "sha512-llA+hiDTrYvyWI21Z0L1GiXwjQaanPVQQwru5peOgtooeJ8qx3tlqRV2P7uH2pKQaUfHxI/WVarvI5oYgGxaTw==",
"version": "16.1.7",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.7.tgz",
"integrity": "sha512-uufcze7LYv0FQg9GnNeZ3/whYfo+1Q3HnQpm16o6Uyi0OVzLlk2ZWoY7j07KADZFY8qwDbsmFnMQP3p3+Ftprw==",
"cpu": [
"arm64"
],
@@ -2653,15 +2695,12 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.10.tgz",
"integrity": "sha512-AK2q5H0+a9nsXbeZ3FZdMtbtu9jxW4R/NgzZ6+lrTm3d6Zb7jYrWcgjcpM1k8uuqlSy4xIyPR2YiuUr+wXsavA==",
"version": "16.1.7",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.7.tgz",
"integrity": "sha512-KWVf2gxYvHtvuT+c4MBOGxuse5TD7DsMFYSxVxRBnOzok/xryNeQSjXgxSv9QpIVlaGzEn/pIuI6Koosx8CGWA==",
"cpu": [
"x64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -2672,15 +2711,12 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.10.tgz",
"integrity": "sha512-1TDG9PDKivNw5550S111gsO4RGennLVl9cipPhtkXIFVwo31YZ73nEbLjNC8qG3SgTz/QZyYyaFYMeY4BKZR/g==",
"version": "16.1.7",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.7.tgz",
"integrity": "sha512-HguhaGwsGr1YAGs68uRKc4aGWxLET+NevJskOcCAwXbwj0fYX0RgZW2gsOCzr9S11CSQPIkxmoSbuVaBp4Z3dA==",
"cpu": [
"x64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -2691,9 +2727,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.10.tgz",
"integrity": "sha512-aEZIS4Hh32xdJQbHz121pyuVZniSNoqDVx1yIr2hy+ZwJGipeqnMZBJHyMxv2tiuAXGx6/xpTcQJ6btIiBjgmg==",
"version": "16.1.7",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.7.tgz",
"integrity": "sha512-S0n3KrDJokKTeFyM/vGGGR8+pCmXYrjNTk2ZozOL1C/JFdfUIL9O1ATaJOl5r2POe56iRChbsszrjMAdWSv7kQ==",
"cpu": [
"arm64"
],
@@ -2707,9 +2743,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.10.tgz",
"integrity": "sha512-E+njfCoFLb01RAFEnGZn6ERoOqhK1Gl3Lfz1Kjnj0Ulfu7oJbuMyvBKNj/bw8XZnenHDASlygTjZICQW+rYW1Q==",
"version": "16.1.7",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.7.tgz",
"integrity": "sha512-mwgtg8CNZGYm06LeEd+bNnOUfwOyNem/rOiP14Lsz+AnUY92Zq/LXwtebtUiaeVkhbroRCQ0c8GlR4UT1U+0yg==",
"cpu": [
"x64"
],
@@ -2928,6 +2964,9 @@
"cpu": [
"arm"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -2948,6 +2987,9 @@
"cpu": [
"arm"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -2968,6 +3010,9 @@
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -2988,6 +3033,9 @@
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -4882,6 +4930,9 @@
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -4899,6 +4950,9 @@
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -4916,6 +4970,9 @@
"ppc64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -4933,6 +4990,9 @@
"s390x"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -5010,23 +5070,6 @@
"node": ">=14.0.0"
}
},
"node_modules/@rolldown/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz",
"integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@emnapi/core": "^1.7.1",
"@emnapi/runtime": "^1.7.1",
"@tybys/wasm-util": "^0.10.1"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Brooooooklyn"
}
},
"node_modules/@rolldown/binding-win32-arm64-msvc": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.9.tgz",
@@ -5253,6 +5296,9 @@
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
@@ -5269,6 +5315,9 @@
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
@@ -5515,6 +5564,9 @@
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -5532,6 +5584,9 @@
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -5605,70 +5660,6 @@
"node": ">=14.0.0"
}
},
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
"version": "1.8.1",
"dev": true,
"inBundle": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@emnapi/wasi-threads": "1.1.0",
"tslib": "^2.4.0"
}
},
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
"version": "1.8.1",
"dev": true,
"inBundle": true,
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
"version": "1.1.0",
"dev": true,
"inBundle": true,
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
"version": "1.1.1",
"dev": true,
"inBundle": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@emnapi/core": "^1.7.1",
"@emnapi/runtime": "^1.7.1",
"@tybys/wasm-util": "^0.10.1"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Brooooooklyn"
}
},
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
"version": "0.10.1",
"dev": true,
"inBundle": true,
"license": "MIT",
"optional": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
"version": "2.8.1",
"dev": true,
"inBundle": true,
"license": "0BSD",
"optional": true
},
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz",
@@ -6122,6 +6113,13 @@
"license": "MIT",
"peer": true
},
"node_modules/@types/keytar": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@types/keytar/-/keytar-4.4.0.tgz",
"integrity": "sha512-cq/NkUUy6rpWD8n7PweNQQBpw2o0cf5v6fbkUVEpOB9VzzIvyPvSEId1/goIj+MciW2v1Lw5mRimKO01XgE9EA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/mdast": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
@@ -6607,6 +6605,9 @@
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -6621,6 +6622,9 @@
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -6635,6 +6639,9 @@
"ppc64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -6649,6 +6656,9 @@
"riscv64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -6663,6 +6673,9 @@
"riscv64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -6677,6 +6690,9 @@
"s390x"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -6728,6 +6744,19 @@
"node": ">=14.0.0"
}
},
"node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
"version": "0.2.12",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz",
"integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@emnapi/core": "^1.4.3",
"@emnapi/runtime": "^1.4.3",
"@tybys/wasm-util": "^0.10.0"
}
},
"node_modules/@unrs/resolver-binding-win32-arm64-msvc": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz",
@@ -6958,9 +6987,9 @@
}
},
"node_modules/ahooks": {
"version": "3.9.6",
"resolved": "https://registry.npmjs.org/ahooks/-/ahooks-3.9.6.tgz",
"integrity": "sha512-Mr7f05swd5SmKlR9SZo5U6M0LsL4ErweLzpdgXjA1JPmnZ78Vr6wzx0jUtvoxrcqGKYnX0Yjc02iEASVxHFPjQ==",
"version": "3.9.7",
"resolved": "https://registry.npmjs.org/ahooks/-/ahooks-3.9.7.tgz",
"integrity": "sha512-S0lvzhbdlhK36RFBkGv+RbOM/dbbweym+BIHM/bwwuWVSVN5TuVErHPMWo4w0t1NDYg5KPp2iEf7Y7E5LASYiw==",
"license": "MIT",
"peer": true,
"dependencies": {
@@ -7534,7 +7563,6 @@
"version": "2.9.19",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz",
"integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"baseline-browser-mapping": "dist/cli.js"
@@ -9162,9 +9190,9 @@
}
},
"node_modules/delaunator": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz",
"integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.1.0.tgz",
"integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==",
"license": "ISC",
"peer": true,
"dependencies": {
@@ -9718,13 +9746,13 @@
}
},
"node_modules/eslint-config-next": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.0.10.tgz",
"integrity": "sha512-BxouZUm0I45K4yjOOIzj24nTi0H2cGo0y7xUmk+Po/PYtJXFBYVDS1BguE7t28efXjKdcN0tmiLivxQy//SsZg==",
"version": "16.1.6",
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.1.6.tgz",
"integrity": "sha512-vKq40io2B0XtkkNDYyleATwblNt8xuh3FWp8SpSz3pt7P01OkBFlKsJZ2mWt5WsCySlDQLckb1zMY9yE9Qy0LA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@next/eslint-plugin-next": "16.0.10",
"@next/eslint-plugin-next": "16.1.6",
"eslint-import-resolver-node": "^0.3.6",
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-import": "^2.32.0",
@@ -12483,6 +12511,23 @@
"node": ">= 12"
}
},
"node_modules/keytar": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
"integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"node-addon-api": "^4.3.0",
"prebuild-install": "^7.0.1"
}
},
"node_modules/keytar/node_modules/node-addon-api": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
"integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==",
"license": "MIT"
},
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -12743,6 +12788,9 @@
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -12764,6 +12812,9 @@
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -14555,15 +14606,6 @@
"marked": "14.0.0"
}
},
"node_modules/monaco-editor/node_modules/dompurify": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz",
"integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==",
"license": "(MPL-2.0 OR Apache-2.0)",
"optionalDependencies": {
"@types/trusted-types": "^2.0.7"
}
},
"node_modules/motion": {
"version": "12.38.0",
"resolved": "https://registry.npmjs.org/motion/-/motion-12.38.0.tgz",
@@ -14671,13 +14713,14 @@
}
},
"node_modules/next": {
"version": "16.0.10",
"resolved": "https://registry.npmjs.org/next/-/next-16.0.10.tgz",
"integrity": "sha512-RtWh5PUgI+vxlV3HdR+IfWA1UUHu0+Ram/JBO4vWB54cVPentCD0e+lxyAYEsDTqGGMg7qpjhKh6dc6aW7W/sA==",
"version": "16.1.7",
"resolved": "https://registry.npmjs.org/next/-/next-16.1.7.tgz",
"integrity": "sha512-WM0L7WrSvKwoLegLYr6V+mz+RIofqQgVAfHhMp9a88ms0cFX8iX9ew+snpWlSBwpkURJOUdvCEt3uLl3NNzvWg==",
"license": "MIT",
"dependencies": {
"@next/env": "16.0.10",
"@next/env": "16.1.7",
"@swc/helpers": "0.5.15",
"baseline-browser-mapping": "^2.9.19",
"caniuse-lite": "^1.0.30001579",
"postcss": "8.4.31",
"styled-jsx": "5.1.6"
@@ -14689,14 +14732,14 @@
"node": ">=20.9.0"
},
"optionalDependencies": {
"@next/swc-darwin-arm64": "16.0.10",
"@next/swc-darwin-x64": "16.0.10",
"@next/swc-linux-arm64-gnu": "16.0.10",
"@next/swc-linux-arm64-musl": "16.0.10",
"@next/swc-linux-x64-gnu": "16.0.10",
"@next/swc-linux-x64-musl": "16.0.10",
"@next/swc-win32-arm64-msvc": "16.0.10",
"@next/swc-win32-x64-msvc": "16.0.10",
"@next/swc-darwin-arm64": "16.1.7",
"@next/swc-darwin-x64": "16.1.7",
"@next/swc-linux-arm64-gnu": "16.1.7",
"@next/swc-linux-arm64-musl": "16.1.7",
"@next/swc-linux-x64-gnu": "16.1.7",
"@next/swc-linux-x64-musl": "16.1.7",
"@next/swc-win32-arm64-msvc": "16.1.7",
"@next/swc-win32-x64-msvc": "16.1.7",
"sharp": "^0.34.4"
},
"peerDependencies": {
@@ -19312,6 +19355,9 @@
"arm64"
],
"dev": true,
"libc": [
"glibc"
],
"license": "MPL-2.0",
"optional": true,
"os": [
@@ -19333,6 +19379,9 @@
"arm64"
],
"dev": true,
"libc": [
"musl"
],
"license": "MPL-2.0",
"optional": true,
"os": [
+7 -2
View File
@@ -1,6 +1,6 @@
{
"name": "omniroute",
"version": "3.0.0-rc.10",
"version": "3.0.1",
"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": {
@@ -47,7 +47,7 @@
"homepage": "https://omniroute.online",
"scripts": {
"dev": "node scripts/run-next.mjs dev",
"build": "next build",
"build": "node scripts/build-next-isolated.mjs",
"build:cli": "node scripts/prepublish.mjs",
"start": "node scripts/run-next.mjs start",
"lint": "eslint .",
@@ -94,6 +94,7 @@
"http-proxy-middleware": "^3.0.5",
"https-proxy-agent": "^8.0.0",
"jose": "^6.1.3",
"keytar": "^7.9.0",
"lowdb": "^7.0.1",
"monaco-editor": "^0.55.1",
"next": "^16.0.10",
@@ -119,6 +120,7 @@
"@tailwindcss/postcss": "^4.1.18",
"@types/bcryptjs": "^3.0.0",
"@types/better-sqlite3": "^7.6.13",
"@types/keytar": "^4.4.0",
"@types/node": "^25.2.3",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
@@ -153,5 +155,8 @@
"omniroute",
"sharp"
]
},
"overrides": {
"dompurify": "^3.3.2"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none"><rect width="128" height="128" rx="24" fill="#1e293b"/><path d="M48 60a16 16 0 1 1 12 15.5V88h-8V75.5A16 16 0 0 1 48 60z" fill="none" stroke="#94a3b8" stroke-width="3"/><circle cx="56" cy="56" r="5" fill="#94a3b8"/><path d="M64 76h24M76 72v8M84 72v8" stroke="#94a3b8" stroke-width="3"/></svg>

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none"><rect width="128" height="128" rx="24" fill="#0f172a"/><path d="M40 40h48v48H40z" fill="none" stroke="#3b82f6" stroke-width="3"/><path d="M52 52h24v24H52z" fill="#3b82f6" opacity="0.4"/><path d="M58 58h12v12H58z" fill="#60a5fa"/></svg>

After

Width:  |  Height:  |  Size: 310 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none"><rect width="128" height="128" rx="24" fill="#1a1a2e"/><path d="M32 48h20v8H32zm44 0h20v8H76zm-22 24h20v8H54z" fill="#7c3aed"/><circle cx="52" cy="52" r="4" fill="#a78bfa"/><circle cx="76" cy="76" r="4" fill="#a78bfa"/><path d="M52 52l22 24" stroke="#7c3aed" stroke-width="2"/></svg>

After

Width:  |  Height:  |  Size: 358 B

+52
View File
@@ -0,0 +1,52 @@
<html>
<head>
<title>404</title>
<style>
@font-face {
font-family: 'colfax-web';
font-display: swap;
src: url('https://www.datocms.com/fonts/colfax-web-regular.woff2') format('woff2'), url('https://www.datocms.com/fonts/colfax-web-regular.woff') format('woff');
}
@font-face {
font-family: 'colfax-web';
font-display: swap;
font-weight: 700;
src: url('https://www.datocms.com/fonts/colfax-web-bold.woff2') format('woff2'), url('https://www.datocms.com/fonts/colfax-web-bold.woff') format('woff');
}
* {
margin: 0;
}
body {
box-sizing: border-box;
font-family: colfax;
display: grid;
align-items: center;
justify-content: center;
height: 100%;
text-align: center;
padding: 20px;
}
main {
display: flex;
flex-direction: column;
gap: 30px;
}
h1 {
font-size: 50px;
}
</style>
</head>
<body>
<main>
<h1>404</h1>
<p>Not Found</p>
</main>
</body>
</html>
+37
View File
@@ -0,0 +1,37 @@
<svg xmlns="http://www.w3.org/2000/svg" width="95" height="88" fill="none">
<path fill="#FFD21E" d="M47.21 76.5a34.75 34.75 0 1 0 0-69.5 34.75 34.75 0 0 0 0 69.5Z" />
<path
fill="#FF9D0B"
d="M81.96 41.75a34.75 34.75 0 1 0-69.5 0 34.75 34.75 0 0 0 69.5 0Zm-73.5 0a38.75 38.75 0 1 1 77.5 0 38.75 38.75 0 0 1-77.5 0Z"
/>
<path
fill="#3A3B45"
d="M58.5 32.3c1.28.44 1.78 3.06 3.07 2.38a5 5 0 1 0-6.76-2.07c.61 1.15 2.55-.72 3.7-.32ZM34.95 32.3c-1.28.44-1.79 3.06-3.07 2.38a5 5 0 1 1 6.76-2.07c-.61 1.15-2.56-.72-3.7-.32Z"
/>
<path
fill="#FF323D"
d="M46.96 56.29c9.83 0 13-8.76 13-13.26 0-2.34-1.57-1.6-4.09-.36-2.33 1.15-5.46 2.74-8.9 2.74-7.19 0-13-6.88-13-2.38s3.16 13.26 13 13.26Z"
/>
<path
fill="#3A3B45"
fill-rule="evenodd"
d="M39.43 54a8.7 8.7 0 0 1 5.3-4.49c.4-.12.81.57 1.24 1.28.4.68.82 1.37 1.24 1.37.45 0 .9-.68 1.33-1.35.45-.7.89-1.38 1.32-1.25a8.61 8.61 0 0 1 5 4.17c3.73-2.94 5.1-7.74 5.1-10.7 0-2.34-1.57-1.6-4.09-.36l-.14.07c-2.31 1.15-5.39 2.67-8.77 2.67s-6.45-1.52-8.77-2.67c-2.6-1.29-4.23-2.1-4.23.29 0 3.05 1.46 8.06 5.47 10.97Z"
clip-rule="evenodd"
/>
<path
fill="#FF9D0B"
d="M70.71 37a3.25 3.25 0 1 0 0-6.5 3.25 3.25 0 0 0 0 6.5ZM24.21 37a3.25 3.25 0 1 0 0-6.5 3.25 3.25 0 0 0 0 6.5ZM17.52 48c-1.62 0-3.06.66-4.07 1.87a5.97 5.97 0 0 0-1.33 3.76 7.1 7.1 0 0 0-1.94-.3c-1.55 0-2.95.59-3.94 1.66a5.8 5.8 0 0 0-.8 7 5.3 5.3 0 0 0-1.79 2.82c-.24.9-.48 2.8.8 4.74a5.22 5.22 0 0 0-.37 5.02c1.02 2.32 3.57 4.14 8.52 6.1 3.07 1.22 5.89 2 5.91 2.01a44.33 44.33 0 0 0 10.93 1.6c5.86 0 10.05-1.8 12.46-5.34 3.88-5.69 3.33-10.9-1.7-15.92-2.77-2.78-4.62-6.87-5-7.77-.78-2.66-2.84-5.62-6.25-5.62a5.7 5.7 0 0 0-4.6 2.46c-1-1.26-1.98-2.25-2.86-2.82A7.4 7.4 0 0 0 17.52 48Zm0 4c.51 0 1.14.22 1.82.65 2.14 1.36 6.25 8.43 7.76 11.18.5.92 1.37 1.31 2.14 1.31 1.55 0 2.75-1.53.15-3.48-3.92-2.93-2.55-7.72-.68-8.01.08-.02.17-.02.24-.02 1.7 0 2.45 2.93 2.45 2.93s2.2 5.52 5.98 9.3c3.77 3.77 3.97 6.8 1.22 10.83-1.88 2.75-5.47 3.58-9.16 3.58-3.81 0-7.73-.9-9.92-1.46-.11-.03-13.45-3.8-11.76-7 .28-.54.75-.76 1.34-.76 2.38 0 6.7 3.54 8.57 3.54.41 0 .7-.17.83-.6.79-2.85-12.06-4.05-10.98-8.17.2-.73.71-1.02 1.44-1.02 3.14 0 10.2 5.53 11.68 5.53.11 0 .2-.03.24-.1.74-1.2.33-2.04-4.9-5.2-5.21-3.16-8.88-5.06-6.8-7.33.24-.26.58-.38 1-.38 3.17 0 10.66 6.82 10.66 6.82s2.02 2.1 3.25 2.1c.28 0 .52-.1.68-.38.86-1.46-8.06-8.22-8.56-11.01-.34-1.9.24-2.85 1.31-2.85Z"
/>
<path
fill="#FFD21E"
d="M38.6 76.69c2.75-4.04 2.55-7.07-1.22-10.84-3.78-3.77-5.98-9.3-5.98-9.3s-.82-3.2-2.69-2.9c-1.87.3-3.24 5.08.68 8.01 3.91 2.93-.78 4.92-2.29 2.17-1.5-2.75-5.62-9.82-7.76-11.18-2.13-1.35-3.63-.6-3.13 2.2.5 2.79 9.43 9.55 8.56 11-.87 1.47-3.93-1.71-3.93-1.71s-9.57-8.71-11.66-6.44c-2.08 2.27 1.59 4.17 6.8 7.33 5.23 3.16 5.64 4 4.9 5.2-.75 1.2-12.28-8.53-13.36-4.4-1.08 4.11 11.77 5.3 10.98 8.15-.8 2.85-9.06-5.38-10.74-2.18-1.7 3.21 11.65 6.98 11.76 7.01 4.3 1.12 15.25 3.49 19.08-2.12Z"
/>
<path
fill="#FF9D0B"
d="M77.4 48c1.62 0 3.07.66 4.07 1.87a5.97 5.97 0 0 1 1.33 3.76 7.1 7.1 0 0 1 1.95-.3c1.55 0 2.95.59 3.94 1.66a5.8 5.8 0 0 1 .8 7 5.3 5.3 0 0 1 1.78 2.82c.24.9.48 2.8-.8 4.74a5.22 5.22 0 0 1 .37 5.02c-1.02 2.32-3.57 4.14-8.51 6.1-3.08 1.22-5.9 2-5.92 2.01a44.33 44.33 0 0 1-10.93 1.6c-5.86 0-10.05-1.8-12.46-5.34-3.88-5.69-3.33-10.9 1.7-15.92 2.78-2.78 4.63-6.87 5.01-7.77.78-2.66 2.83-5.62 6.24-5.62a5.7 5.7 0 0 1 4.6 2.46c1-1.26 1.98-2.25 2.87-2.82A7.4 7.4 0 0 1 77.4 48Zm0 4c-.51 0-1.13.22-1.82.65-2.13 1.36-6.25 8.43-7.76 11.18a2.43 2.43 0 0 1-2.14 1.31c-1.54 0-2.75-1.53-.14-3.48 3.91-2.93 2.54-7.72.67-8.01a1.54 1.54 0 0 0-.24-.02c-1.7 0-2.45 2.93-2.45 2.93s-2.2 5.52-5.97 9.3c-3.78 3.77-3.98 6.8-1.22 10.83 1.87 2.75 5.47 3.58 9.15 3.58 3.82 0 7.73-.9 9.93-1.46.1-.03 13.45-3.8 11.76-7-.29-.54-.75-.76-1.34-.76-2.38 0-6.71 3.54-8.57 3.54-.42 0-.71-.17-.83-.6-.8-2.85 12.05-4.05 10.97-8.17-.19-.73-.7-1.02-1.44-1.02-3.14 0-10.2 5.53-11.68 5.53-.1 0-.19-.03-.23-.1-.74-1.2-.34-2.04 4.88-5.2 5.23-3.16 8.9-5.06 6.8-7.33-.23-.26-.57-.38-.98-.38-3.18 0-10.67 6.82-10.67 6.82s-2.02 2.1-3.24 2.1a.74.74 0 0 1-.68-.38c-.87-1.46 8.05-8.22 8.55-11.01.34-1.9-.24-2.85-1.31-2.85Z"
/>
<path
fill="#FFD21E"
d="M56.33 76.69c-2.75-4.04-2.56-7.07 1.22-10.84 3.77-3.77 5.97-9.3 5.97-9.3s.82-3.2 2.7-2.9c1.86.3 3.23 5.08-.68 8.01-3.92 2.93.78 4.92 2.28 2.17 1.51-2.75 5.63-9.82 7.76-11.18 2.13-1.35 3.64-.6 3.13 2.2-.5 2.79-9.42 9.55-8.55 11 .86 1.47 3.92-1.71 3.92-1.71s9.58-8.71 11.66-6.44c2.08 2.27-1.58 4.17-6.8 7.33-5.23 3.16-5.63 4-4.9 5.2.75 1.2 12.28-8.53 13.36-4.4 1.08 4.11-11.76 5.3-10.97 8.15.8 2.85 9.05-5.38 10.74-2.18 1.69 3.21-11.65 6.98-11.76 7.01-4.31 1.12-15.26 3.49-19.08-2.12Z"
/>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none"><rect width="128" height="128" rx="24" fill="#1e293b"/><circle cx="64" cy="64" r="28" fill="none" stroke="#60a5fa" stroke-width="3"/><path d="M64 36v56M36 64h56" stroke="#60a5fa" stroke-width="2" opacity="0.3"/><circle cx="64" cy="64" r="8" fill="#3b82f6"/></svg>

After

Width:  |  Height:  |  Size: 338 B

+18
View File
@@ -0,0 +1,18 @@
<svg width="234" height="42" viewBox="0 0 234 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 30H6V18H18V30Z" fill="#4B4646"/>
<path d="M18 12H6V30H18V12ZM24 36H0V6H24V36Z" fill="#B7B1B1"/>
<path d="M48 30H36V18H48V30Z" fill="#4B4646"/>
<path d="M36 30H48V12H36V30ZM54 36H36V42H30V6H54V36Z" fill="#B7B1B1"/>
<path d="M84 24V30H66V24H84Z" fill="#4B4646"/>
<path d="M84 24H66V30H84V36H60V6H84V24ZM66 18H78V12H66V18Z" fill="#B7B1B1"/>
<path d="M108 36H96V18H108V36Z" fill="#4B4646"/>
<path d="M108 12H96V36H90V6H108V12ZM114 36H108V12H114V36Z" fill="#B7B1B1"/>
<path d="M144 30H126V18H144V30Z" fill="#4B4646"/>
<path d="M144 12H126V30H144V36H120V6H144V12Z" fill="#F1ECEC"/>
<path d="M168 30H156V18H168V30Z" fill="#4B4646"/>
<path d="M168 12H156V30H168V12ZM174 36H150V6H174V36Z" fill="#F1ECEC"/>
<path d="M198 30H186V18H198V30Z" fill="#4B4646"/>
<path d="M198 12H186V30H198V12ZM204 36H180V6H198V0H204V36Z" fill="#F1ECEC"/>
<path d="M234 24V30H216V24H234Z" fill="#4B4646"/>
<path d="M216 12V18H228V12H216ZM234 24H216V30H234V36H210V6H234V24Z" fill="#F1ECEC"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

+18
View File
@@ -0,0 +1,18 @@
<svg width="234" height="42" viewBox="0 0 234 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 30H6V18H18V30Z" fill="#4B4646"/>
<path d="M18 12H6V30H18V12ZM24 36H0V6H24V36Z" fill="#B7B1B1"/>
<path d="M48 30H36V18H48V30Z" fill="#4B4646"/>
<path d="M36 30H48V12H36V30ZM54 36H36V42H30V6H54V36Z" fill="#B7B1B1"/>
<path d="M84 24V30H66V24H84Z" fill="#4B4646"/>
<path d="M84 24H66V30H84V36H60V6H84V24ZM66 18H78V12H66V18Z" fill="#B7B1B1"/>
<path d="M108 36H96V18H108V36Z" fill="#4B4646"/>
<path d="M108 12H96V36H90V6H108V12ZM114 36H108V12H114V36Z" fill="#B7B1B1"/>
<path d="M144 30H126V18H144V30Z" fill="#4B4646"/>
<path d="M144 12H126V30H144V36H120V6H144V12Z" fill="#F1ECEC"/>
<path d="M168 30H156V18H168V30Z" fill="#4B4646"/>
<path d="M168 12H156V30H168V12ZM174 36H150V6H174V36Z" fill="#F1ECEC"/>
<path d="M198 30H186V18H198V30Z" fill="#4B4646"/>
<path d="M198 12H186V30H198V12ZM204 36H180V6H198V0H204V36Z" fill="#F1ECEC"/>
<path d="M234 24V30H216V24H234Z" fill="#4B4646"/>
<path d="M216 12V18H228V12H216ZM234 24H216V30H234V36H210V6H234V24Z" fill="#F1ECEC"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none"><rect width="128" height="128" rx="24" fill="#0c0a09"/><text x="64" y="74" font-family="sans-serif" font-size="36" font-weight="bold" fill="#fbbf24" text-anchor="middle">P</text><circle cx="64" cy="60" r="30" fill="none" stroke="#fbbf24" stroke-width="2" opacity="0.3"/></svg>

After

Width:  |  Height:  |  Size: 351 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none"><rect width="128" height="128" rx="24" fill="#1a1a2e"/><text x="64" y="70" font-family="sans-serif" font-size="40" font-weight="bold" fill="#f97316" text-anchor="middle">SD</text><text x="64" y="96" font-family="sans-serif" font-size="16" fill="#94a3b8" text-anchor="middle">WebUI</text></svg>

After

Width:  |  Height:  |  Size: 368 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none"><rect width="128" height="128" rx="24" fill="#1a1a2e"/><circle cx="64" cy="50" r="16" fill="none" stroke="#10b981" stroke-width="3"/><circle cx="44" cy="86" r="12" fill="none" stroke="#10b981" stroke-width="3"/><circle cx="84" cy="86" r="12" fill="none" stroke="#10b981" stroke-width="3"/><path d="M56 62l-8 16M72 62l8 16M52 86h24" stroke="#10b981" stroke-width="2"/></svg>

After

Width:  |  Height:  |  Size: 448 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none"><rect width="128" height="128" rx="24" fill="#1a1a2e"/><path d="M64 24L104 96H24L64 24z" fill="#4285F4" opacity="0.8"/><path d="M64 44L84 80H44L64 44z" fill="#34A853" opacity="0.9"/><circle cx="64" cy="68" r="8" fill="#FBBC04"/></svg>

After

Width:  |  Height:  |  Size: 309 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none"><rect width="128" height="128" rx="24" fill="#1e1b4b"/><text x="64" y="76" font-family="sans-serif" font-size="48" font-weight="bold" fill="#818cf8" text-anchor="middle">Z</text><text x="64" y="100" font-family="sans-serif" font-size="18" fill="#6366f1" text-anchor="middle">.AI</text></svg>

After

Width:  |  Height:  |  Size: 366 B

+84
View File
@@ -0,0 +1,84 @@
#!/usr/bin/env node
import fs from "node:fs/promises";
import path from "node:path";
import { spawn } from "node:child_process";
/**
* This repository contains a legacy `app/` snapshot (packaging/runtime artifacts)
* alongside the active Next.js source in `src/app/`. Next.js route discovery scans
* both and fails the build on legacy files. We temporarily move the legacy folder
* out of the project root during `next build`, then restore it in all outcomes.
*/
const projectRoot = process.cwd();
const legacyAppDir = path.join(projectRoot, "app");
const backupDir = path.join(projectRoot, `.app-build-backup-${process.pid}-${Date.now()}`);
async function exists(targetPath) {
try {
await fs.access(targetPath);
return true;
} catch {
return false;
}
}
function runNextBuild() {
return new Promise((resolve) => {
const nextBin = path.join(projectRoot, "node_modules", "next", "dist", "bin", "next");
const child = spawn(process.execPath, [nextBin, "build"], {
cwd: projectRoot,
stdio: "inherit",
env: process.env,
});
const forward = (signal) => {
if (!child.killed) child.kill(signal);
};
process.on("SIGINT", forward);
process.on("SIGTERM", forward);
child.on("exit", (code, signal) => {
process.off("SIGINT", forward);
process.off("SIGTERM", forward);
if (signal) {
resolve({ code: 1, signal });
return;
}
resolve({ code: code ?? 1, signal: null });
});
});
}
async function main() {
let moved = false;
try {
if (await exists(legacyAppDir)) {
await fs.rename(legacyAppDir, backupDir);
moved = true;
}
const result = await runNextBuild();
process.exitCode = result.code;
} catch (error) {
console.error("[build-next-isolated] Build failed:", error);
process.exitCode = 1;
} finally {
if (moved) {
try {
await fs.rename(backupDir, legacyAppDir);
} catch (restoreError) {
console.error(
`[build-next-isolated] Failed to restore legacy app dir from ${backupDir}:`,
restoreError
);
process.exitCode = 1;
}
}
}
}
await main();
+1 -1
View File
@@ -240,7 +240,7 @@ if (existsSync(mitmSrc)) {
writeFileSync(tmpTsconfigPath, JSON.stringify(mitmTsconfig, null, 2));
try {
execSync(`npx tsc -p ${tmpTsconfigPath}`, { cwd: ROOT, stdio: "inherit" });
execSync("npx tsc -p " + JSON.stringify(tmpTsconfigPath), { cwd: ROOT, stdio: "inherit" });
console.log(" ✅ MITM utilities compiled to app/src/mitm/");
} catch (err) {
console.warn(" ⚠️ MITM compile warning (non-fatal):", err.message);
+6 -6
View File
@@ -9,15 +9,15 @@ import { bootstrapEnv } from "./bootstrap-env.mjs";
const mode = process.argv[2] === "start" ? "start" : "dev";
const runtimePorts = resolveRuntimePorts();
// Load .env / server.env first so PORT / DASHBOARD_PORT from files affect --port below.
const env = bootstrapEnv();
const runtimePorts = resolveRuntimePorts(env);
const { dashboardPort } = runtimePorts;
// Auto-generate secrets on first run, merge .env + process.env
const env = bootstrapEnv();
const args = ["./node_modules/next/dist/bin/next", mode, "--port", String(dashboardPort)];
// Default: use webpack (stable). Set OMNIROUTE_USE_TURBOPACK=1 to use Turbopack (faster dev).
if (mode === "dev" && process.env.OMNIROUTE_USE_TURBOPACK !== "1") {
// Default: use webpack (stable). Set OMNIROUTE_USE_TURBOPACK=1 in .env for Turbopack (faster dev).
// Must read merged `env` from bootstrap — .env is not applied to process.env in the launcher.
if (mode === "dev" && env.OMNIROUTE_USE_TURBOPACK !== "1") {
args.splice(2, 0, "--webpack");
}

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