Compare commits
212 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f413615d9 | |||
| 2a79b833fb | |||
| 52e3d4b37b | |||
| d9b393a308 | |||
| 9a3d72c6a2 | |||
| 5b9b1cdd44 | |||
| d624ddde03 | |||
| d3ace8d611 | |||
| 177507bbc8 | |||
| d915e2a868 | |||
| a3d15cf971 | |||
| 5e72cd34f0 | |||
| b004d0472b | |||
| 6ed98fb21c | |||
| d8bf4b1db8 | |||
| fb2351ffe7 | |||
| 12f7d2b484 | |||
| 2c40ef0964 | |||
| ceb778a040 | |||
| 2c5a546759 | |||
| 3286f05b3b | |||
| 6a6a868845 | |||
| 56de009756 | |||
| deb855f9d4 | |||
| 7da0675907 | |||
| f8a22e71f7 | |||
| 5229290ac4 | |||
| 01c1bbfe29 | |||
| 234e14a30b | |||
| 0b0e503615 | |||
| e8be72ad28 | |||
| 3ca7b9eafa | |||
| 7feac7a158 | |||
| 3d7d02a10a | |||
| 7bab9e09d3 | |||
| c2a777580a | |||
| 952b0b22c7 | |||
| 4cfd1b94e1 | |||
| 1647005d6e | |||
| 369a0141de | |||
| cc97917ee2 | |||
| 0f49f82405 | |||
| 0d58a92479 | |||
| cde0a3bf4e | |||
| 344e602b26 | |||
| b941515c5a | |||
| fb597c677e | |||
| d0138a5037 | |||
| 2c2e0a95a1 | |||
| e0d5a78dd3 | |||
| 428a8490f8 | |||
| 96114bf92e | |||
| 77a3eece32 | |||
| 107b9e8cd2 | |||
| 187aba0514 | |||
| 2126b0ee8d | |||
| 113ac1c940 | |||
| fbaf30a6bf | |||
| 8abdf68718 | |||
| 67fa2592b5 | |||
| fed445c991 | |||
| 62069dac98 | |||
| 5a65585c16 | |||
| 4e3b363ba6 | |||
| f1d421bd8a | |||
| fb840d6392 | |||
| e659d2ee69 | |||
| ab1b0c890a | |||
| dbe6a4e30c | |||
| ce1e10c8c6 | |||
| 8caef4b688 | |||
| bc55911d0f | |||
| bc6b084c77 | |||
| 3d86ad7dc8 | |||
| 0844659e00 | |||
| e07edc663b | |||
| 5f38173387 | |||
| 481a630273 | |||
| 8592d02951 | |||
| 7f34835693 | |||
| 0ac264b39d | |||
| 87c7c83dd9 | |||
| 10d3120cdf | |||
| 27b9c331b7 | |||
| e1fe304dd3 | |||
| d226d68251 | |||
| a6014524ef | |||
| 1a98a6c966 | |||
| 0d13f4645c | |||
| 88d5986ac1 | |||
| f7fb68a798 | |||
| 5811e677f1 | |||
| 0d9a98c4e1 | |||
| 05d8d3d71d | |||
| f670a1e451 | |||
| 1591737528 | |||
| f74a007e27 | |||
| eb290a90cb | |||
| 9b80f723df | |||
| f2ace011ff | |||
| 0c0a56d4de | |||
| 981d163278 | |||
| 96cdd9bccb | |||
| 354d0b5f09 | |||
| 3d2de04dd1 | |||
| 93a220ba83 | |||
| d55b6e0b7a | |||
| 779957526b | |||
| f76482db87 | |||
| 1be20a4e2d | |||
| ff965234c9 | |||
| 62facba06f | |||
| 3c309f1fa4 | |||
| 090343aa01 | |||
| e674e5d87b | |||
| 2a90a05132 | |||
| a0af564b5a | |||
| ca2b1faa72 | |||
| bf49fdf0bf | |||
| c8989ddead | |||
| 4ea0426034 | |||
| 619c99ce4c | |||
| 86c566669c | |||
| 9aad413809 | |||
| 6afcebabab | |||
| ad1cc64e5a | |||
| 243cc4b60b | |||
| ddb02d6464 | |||
| f24abf074b | |||
| ff01e9edaa | |||
| 168b17adc7 | |||
| 7e0c6f0307 | |||
| dd573aed6f | |||
| b87af5d053 | |||
| 29b3e59d23 | |||
| ce6d7dc6bf | |||
| 19eeebae95 | |||
| 1dd05bffe8 | |||
| ac3d251a1a | |||
| 238e080928 | |||
| 7ed40c2139 | |||
| d2bee37e76 | |||
| 5a2fdacebe | |||
| 343e6c50e3 | |||
| 90d2dcac97 | |||
| 631ed4d97f | |||
| 9485985608 | |||
| b32db28a3d | |||
| 1516429b87 | |||
| 5668e16fbf | |||
| bd4a076942 | |||
| f0a0c97b5e | |||
| 7ffe21e23d | |||
| 4b137d8e72 | |||
| 6ba48241fe | |||
| a17583d3fc | |||
| 62c634ae78 | |||
| 02dc8ea0f3 | |||
| a40c463a87 | |||
| 5e0376c6c9 | |||
| 2bad777541 | |||
| 10793a7e65 | |||
| 5dab4058c8 | |||
| b26cc2a82e | |||
| 0610909116 | |||
| f8a401da4b | |||
| 3b70e9f786 | |||
| 39f992a2a8 | |||
| 0df1d46ae5 | |||
| 28c7e0d62f | |||
| 03965bf768 | |||
| 6b34a39f6e | |||
| f0513683e5 | |||
| b3e53ca250 | |||
| 7a3b21eff8 | |||
| f8c8501036 | |||
| 4e1b5a5253 | |||
| 1aa27ceefe | |||
| 340dcf9515 | |||
| 1bd5d552c1 | |||
| 862d94b859 | |||
| be36d9c452 | |||
| 5ce95dd829 | |||
| d0fa01cc0a | |||
| c69ad118d1 | |||
| 0deeaf5ffb | |||
| 87c7c92ddd | |||
| f12b90f373 | |||
| 4e37027e1f | |||
| 245345f37d | |||
| 99be29ce8e | |||
| 6aaaaccb12 | |||
| 282c46fd46 | |||
| bc719875f6 | |||
| 78b634b204 | |||
| 39aae51ca2 | |||
| 937a8f3714 | |||
| c34973f40d | |||
| 3045aa3055 | |||
| 1e332babd6 | |||
| 2ddf63fde1 | |||
| de2ef14bc3 | |||
| 37123160e8 | |||
| 5a645973eb | |||
| 0279341221 | |||
| 7efbfad9bd | |||
| 3aca5fa691 | |||
| 1a7b7e8799 | |||
| 4c93f0618c | |||
| 16b72970d7 | |||
| fbceb0d301 | |||
| ed05599cdd |
@@ -1,54 +0,0 @@
|
||||
---
|
||||
description: Git workflow — NEVER commit directly to main. Always use feature branches.
|
||||
---
|
||||
|
||||
# Git Workflow
|
||||
|
||||
## ⚠️ CRITICAL RULE: NEVER commit directly to `main`
|
||||
|
||||
## Steps
|
||||
|
||||
1. **Before starting any work**, create a feature branch from `main`:
|
||||
|
||||
```bash
|
||||
git checkout main && git pull origin main
|
||||
git checkout -b feature/<feature-name>
|
||||
```
|
||||
|
||||
2. **During development**, commit to the feature branch:
|
||||
|
||||
```bash
|
||||
git add -A && git commit -m "<type>(<scope>): <description>"
|
||||
```
|
||||
|
||||
3. **Before pushing**, verify the build passes:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
4. **When the feature is complete and verified**, push the branch and STOP:
|
||||
|
||||
```bash
|
||||
git push origin feature/<feature-name>
|
||||
```
|
||||
|
||||
5. **DO NOT** create a PR, merge, or push to `main`. Let the user handle that.
|
||||
|
||||
## Branch naming convention
|
||||
|
||||
- `feature/<name>` — new features
|
||||
- `fix/<name>` — bugfixes
|
||||
- `refactor/<name>` — refactoring
|
||||
- `docker/<name>` — Docker / infrastructure changes
|
||||
- `style/<name>` — UI / CSS changes
|
||||
|
||||
## Commit types
|
||||
|
||||
- `feat` — new feature
|
||||
- `fix` — bugfix
|
||||
- `refactor` — code refactoring
|
||||
- `style` — UI / CSS changes
|
||||
- `docker` — Docker / infrastructure
|
||||
- `docs` — documentation
|
||||
- `chore` — maintenance
|
||||
@@ -0,0 +1,131 @@
|
||||
---
|
||||
description: Analyze open feature request issues, implement viable ones on dedicated branches, and respond to authors
|
||||
---
|
||||
|
||||
# /implement-features — Feature Request Implementation Workflow
|
||||
|
||||
## Overview
|
||||
|
||||
Fetches open feature request issues, analyzes each against the current codebase, implements viable ones on dedicated branches, and responds to authors with results. Does NOT merge to main — leaves branches for author validation.
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Identify the Repository
|
||||
|
||||
// turbo
|
||||
|
||||
- Run: `git -C <project_root> remote get-url origin` to extract owner/repo
|
||||
|
||||
### 2. Fetch Open Feature Request Issues
|
||||
|
||||
// turbo
|
||||
|
||||
- Run: `gh issue list --repo <owner>/<repo> --state open --limit 50 --json number,title,labels,body,comments,createdAt,author`
|
||||
- Filter for issues that are feature requests (label `enhancement`/`feature`, or body describes new functionality, or previously classified as feature request)
|
||||
- Sort by oldest first
|
||||
|
||||
### 3. Analyze Each Feature Request
|
||||
|
||||
For each feature request issue, perform a **two-level analysis**:
|
||||
|
||||
#### Level 1 — Viability Assessment
|
||||
|
||||
Ask yourself:
|
||||
|
||||
- Does this feature align with the project's goals and architecture?
|
||||
- Is the request technically feasible with the current codebase?
|
||||
- Does it duplicate existing functionality?
|
||||
- Would it introduce breaking changes or security risks?
|
||||
- Is there enough detail to implement it?
|
||||
|
||||
**Verdict options:**
|
||||
|
||||
1. ✅ **VIABLE** — Makes sense, enough detail to implement → Go to Level 2
|
||||
2. ❓ **NEEDS MORE INFO** — Good idea but insufficient detail → Post comment asking for specifics
|
||||
3. ❌ **NOT VIABLE** — Doesn't fit the project or is fundamentally flawed → Post comment explaining why, close issue
|
||||
|
||||
#### Level 2 — Implementation (only for VIABLE features)
|
||||
|
||||
1. **Research** — Read all related source files to understand the current architecture
|
||||
2. **Design** — Plan the implementation, filling gaps in the original request
|
||||
3. **Create branch** — Name format: `feat/issue-<NUMBER>-<short-slug>`
|
||||
```bash
|
||||
git checkout main
|
||||
git pull origin main
|
||||
git checkout -b feat/issue-<NUMBER>-<short-slug>
|
||||
```
|
||||
4. **Implement** — Build the complete solution following project patterns
|
||||
5. **Build** — Run `npm run build` to verify compilation
|
||||
6. **Commit** — Commit with: `feat: <description> (#<NUMBER>)`
|
||||
7. **Push** — Push the branch: `git push -u origin feat/issue-<NUMBER>-<short-slug>`
|
||||
8. **Return to main** — `git checkout main`
|
||||
|
||||
### 4. Respond to Authors
|
||||
|
||||
#### For VIABLE (implemented) features:
|
||||
|
||||
// turbo
|
||||
Post a comment on the issue:
|
||||
|
||||
````markdown
|
||||
## ✅ Feature Implemented!
|
||||
|
||||
Hi @<author>! We've analyzed your request and implemented it on a dedicated branch.
|
||||
|
||||
**Branch:** `feat/issue-<NUMBER>-<short-slug>`
|
||||
|
||||
### What was implemented:
|
||||
|
||||
- <bullet list of what was done>
|
||||
|
||||
### How to try it:
|
||||
|
||||
```bash
|
||||
git fetch origin
|
||||
git checkout feat/issue-<NUMBER>-<short-slug>
|
||||
npm install && npm run dev
|
||||
```
|
||||
````
|
||||
|
||||
### Next steps:
|
||||
|
||||
1. **Test it** — Please verify it works as you expected
|
||||
2. **Want to improve it?** — You're welcome to contribute! Just:
|
||||
```bash
|
||||
git checkout feat/issue-<NUMBER>-<short-slug>
|
||||
# Make your improvements
|
||||
git add -A && git commit -m "improve: <your changes>"
|
||||
git push origin feat/issue-<NUMBER>-<short-slug>
|
||||
```
|
||||
Then open a Pull Request from your branch to `main` 🎉
|
||||
3. **Not quite right?** — Let us know in this issue what needs to change
|
||||
|
||||
Looking forward to your feedback! 🚀
|
||||
|
||||
```
|
||||
|
||||
#### For NEEDS MORE INFO:
|
||||
// turbo
|
||||
Post a comment asking for specific missing details needed to implement, e.g.:
|
||||
- "Could you describe the exact behavior when X happens?"
|
||||
- "Which API endpoints should be affected?"
|
||||
- "Should this apply to all providers or only specific ones?"
|
||||
|
||||
Add the context of WHY you need each piece of information.
|
||||
|
||||
#### For NOT VIABLE:
|
||||
// turbo
|
||||
Post a polite comment explaining why the feature doesn't fit at this time:
|
||||
- If the idea is decent but timing is wrong: "This is an interesting idea, but it doesn't align with our current priorities. Feel free to open a new issue with more details if you'd like us to reconsider."
|
||||
- If fundamentally flawed: Explain the technical or architectural reasons why it won't work, suggest alternatives if possible.
|
||||
- Close the issue after posting the comment.
|
||||
|
||||
### 5. Summary Report
|
||||
Present a summary report to the user via `notify_user`:
|
||||
|
||||
| Issue | Title | Verdict | Branch / Action |
|
||||
|---|---|---|---|
|
||||
| #N | Title | ✅ Implemented | `feat/issue-N-slug` |
|
||||
| #N | Title | ❓ Needs Info | Comment posted |
|
||||
| #N | Title | ❌ Not Viable | Closed with explanation |
|
||||
```
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
description: Fetch all open GitHub issues, analyze bugs, resolve what's possible, triage the rest, then commit and release
|
||||
---
|
||||
|
||||
# /resolve-issues — Automated Issue Resolution Workflow
|
||||
|
||||
## Overview
|
||||
|
||||
This workflow fetches all open issues from the project's GitHub repository, classifies them, analyzes bugs, resolves what can be fixed, triages issues with insufficient information, and generates a release with all fixes.
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Identify the GitHub Repository
|
||||
|
||||
// turbo
|
||||
|
||||
- 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 Issues
|
||||
|
||||
// turbo
|
||||
|
||||
- Run: `gh issue list --repo <owner>/<repo> --state open --limit 100 --json number,title,labels,body,comments,createdAt,author`
|
||||
- Parse the JSON output to get a list of all open issues
|
||||
- Sort by oldest first (FIFO)
|
||||
|
||||
### 3. Classify Each Issue
|
||||
|
||||
For each issue, determine its type:
|
||||
|
||||
- **Bug** — Has `bug` label, or body contains error messages, stack traces, "doesn't work", "broken", "crash", "error"
|
||||
- **Feature Request** — Has `enhancement`/`feature` label, or body describes new functionality
|
||||
- **Question** — Has `question` label, or is asking "how to" something
|
||||
- **Other** — Anything else
|
||||
|
||||
Focus ONLY on **Bugs** for resolution. Feature requests and questions should be skipped with a note in the final report.
|
||||
|
||||
### 4. Analyze Each Bug — For each bug issue:
|
||||
|
||||
#### 4a. Check Information Sufficiency
|
||||
|
||||
Verify the issue contains enough information to reproduce and fix:
|
||||
|
||||
- [ ] Clear description of the problem
|
||||
- [ ] Steps to reproduce
|
||||
- [ ] Error messages or logs
|
||||
- [ ] Expected vs actual behavior
|
||||
|
||||
#### 4b. If Information Is INSUFFICIENT
|
||||
|
||||
Call the `/issue-triage` workflow (located at `~/.gemini/antigravity/global_workflows/issue-triage.md`):
|
||||
// turbo
|
||||
|
||||
- Post a comment asking for more details using `gh issue comment`
|
||||
- Add `needs-info` label using `gh issue edit`
|
||||
- Mark this issue as **DEFERRED** and move to the next one
|
||||
|
||||
#### 4c. If Information Is SUFFICIENT
|
||||
|
||||
Proceed with resolution:
|
||||
|
||||
1. **Research** — Search the codebase for files related to the issue
|
||||
2. **Root Cause** — Identify the root cause by reading the relevant source files
|
||||
3. **Implement Fix** — Apply the fix following existing code patterns and conventions
|
||||
4. **Test** — Build the project and run tests to verify the fix
|
||||
5. **Commit** — Commit with message format: `fix: <description> (#<issue_number>)`
|
||||
|
||||
### 5. Commit All Fixes
|
||||
|
||||
After processing all issues:
|
||||
|
||||
- Ensure all fixes are committed with proper issue references
|
||||
- Each fix should be its own commit for clean git history
|
||||
|
||||
### 6. Close Resolved Issues
|
||||
|
||||
For each successfully fixed issue:
|
||||
// turbo
|
||||
|
||||
- Close with a comment: `gh issue close <NUMBER> --repo <owner>/<repo> --comment "Fixed in <commit_hash>. The fix will be included in the next release."`
|
||||
|
||||
### 7. Generate Report
|
||||
|
||||
Present a summary report to the user via `notify_user`:
|
||||
|
||||
| Issue | Title | Status | Action |
|
||||
| ----- | ----- | ------------- | --------------------------- |
|
||||
| #N | Title | ✅ Fixed | Commit hash |
|
||||
| #N | Title | ❓ Needs Info | Triage comment posted |
|
||||
| #N | Title | ⏭️ Skipped | Feature request / not a bug |
|
||||
|
||||
### 8. Update Docs & Release
|
||||
|
||||
If any fixes were committed:
|
||||
|
||||
1. Run the `/update-docs` workflow (at `~/.gemini/antigravity/global_workflows/update-docs.md`) to update CHANGELOG and README
|
||||
2. Run the `/generate-release` workflow (at `.agents/workflows/generate-release.md`) to bump version, tag, and publish
|
||||
|
||||
If NO fixes were committed, skip this step and just present the report.
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
description: Analyze open Pull Requests from the project's GitHub repository, generate a critical report, and optionally implement approved changes
|
||||
---
|
||||
|
||||
# /review-prs — PR Review & Analysis Workflow
|
||||
|
||||
## Overview
|
||||
|
||||
This workflow fetches all open PRs from the project's GitHub repository, performs a critical analysis of each one, generates a detailed report, and waits for user approval before proceeding with implementation.
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Identify the GitHub Repository
|
||||
|
||||
- Read `package.json` to get the repository URL, or use the git remote origin URL
|
||||
// turbo
|
||||
- Run: `git -C <project_root> remote get-url origin` to extract the owner/repo
|
||||
|
||||
### 2. Fetch Open Pull Requests
|
||||
|
||||
- Navigate to `https://github.com/<owner>/<repo>/pulls` and scrape all open PRs
|
||||
- For each open PR, collect:
|
||||
- PR number, title, author, branch, number of commits, date
|
||||
- PR description/body
|
||||
- Files changed (diff)
|
||||
- Existing review comments (from bots or humans)
|
||||
|
||||
### 3. Analyze Each PR — For each open PR, perform the following analysis:
|
||||
|
||||
#### 3a. Feature Assessment
|
||||
|
||||
- **Does it make sense?** Evaluate if the feature fills a real gap or solves a valid problem
|
||||
- **Alignment** — Check if it aligns with the project's architecture and roadmap
|
||||
- **Complexity** — Assess if the scope is reasonable or if it should be split
|
||||
|
||||
#### 3b. Code Quality Review
|
||||
|
||||
- Check for code duplication
|
||||
- Evaluate error handling patterns (consistent with existing codebase?)
|
||||
- Check naming conventions and code style
|
||||
- Verify TypeScript types (any `any` usage, missing types?)
|
||||
|
||||
#### 3c. Security Review
|
||||
|
||||
- Check for missing authentication/authorization on new endpoints
|
||||
- Check for injection vulnerabilities (URL params, SQL, XSS)
|
||||
- Verify input validation on all user-controlled data
|
||||
- Check for hardcoded secrets or credentials
|
||||
|
||||
#### 3d. Architecture Review
|
||||
|
||||
- Does the change follow existing patterns?
|
||||
- Are there any breaking changes to public APIs?
|
||||
- Is the database schema affected? Migration needed?
|
||||
- Impact on performance (N+1 queries, missing indexes?)
|
||||
|
||||
#### 3e. Test Coverage
|
||||
|
||||
- Does the PR include tests?
|
||||
- Are edge cases covered?
|
||||
- Would existing tests break?
|
||||
|
||||
### 4. Generate Report — Create a markdown report for each PR including:
|
||||
|
||||
- **PR Summary** — What it does, files affected, commit count
|
||||
- **Improvements/Benefits** — Numbered list with impact level (HIGH/MEDIUM/LOW)
|
||||
- **Risks & Issues** — Categorized as CRITICAL / IMPORTANT / MINOR
|
||||
- **Scoring Table** — Rate across: Feature Relevance, Code Quality, Security, Robustness, Tests
|
||||
- **Verdict** — Ready to merge? With mandatory vs optional fixes
|
||||
- **Next Steps** — What will happen if approved
|
||||
|
||||
### 5. Present to User
|
||||
|
||||
- Show the report via `notify_user` with `BlockedOnUser: true`
|
||||
- Wait for user decision:
|
||||
- **Approved** → Proceed to step 6
|
||||
- **Approved with changes** → Implement the fixes and corrections before merging
|
||||
- **Rejected** → Close the PR or leave a review comment
|
||||
|
||||
### 6. Implementation (if approved)
|
||||
|
||||
- Checkout the PR branch or apply changes locally
|
||||
- Implement any required fixes identified in the analysis
|
||||
- Run the project's test suite to verify nothing breaks
|
||||
// turbo
|
||||
- Run: `npm test` or equivalent test command
|
||||
- Build the project to verify compilation
|
||||
// turbo
|
||||
- Run: `npm run build` or equivalent build command
|
||||
- If all checks pass, prepare the merge
|
||||
|
||||
### 7. Post-Merge (if applicable)
|
||||
|
||||
- Update CHANGELOG.md with the new feature
|
||||
- Consider version bump if warranted
|
||||
- Follow the `/generate-release` workflow if a release is needed
|
||||
+70
-6
@@ -23,7 +23,15 @@ SQLITE_MAX_SIZE_MB=2048
|
||||
SQLITE_CLEAN_LEGACY_FILES=true
|
||||
|
||||
# Recommended runtime variables
|
||||
# Canonical/base port (keeps backward compatibility)
|
||||
PORT=20128
|
||||
# Optional split ports:
|
||||
# API_PORT=20129
|
||||
# API_HOST=0.0.0.0
|
||||
# DASHBOARD_PORT=20128
|
||||
# Optional Docker production host publish ports:
|
||||
# PROD_DASHBOARD_PORT=20130
|
||||
# PROD_API_PORT=20131
|
||||
NODE_ENV=production
|
||||
INSTANCE_NAME=omniroute
|
||||
|
||||
@@ -44,6 +52,9 @@ REQUIRE_API_KEY=false
|
||||
BASE_URL=http://localhost:20128
|
||||
CLOUD_URL=
|
||||
# Backward-compatible/public variables:
|
||||
# NEXT_PUBLIC_BASE_URL is also used as the OAuth redirect_uri origin when running behind a
|
||||
# reverse proxy (e.g., nginx). Set this to your public-facing URL so OAuth callbacks work.
|
||||
# Example: NEXT_PUBLIC_BASE_URL=https://omniroute.example.com
|
||||
NEXT_PUBLIC_BASE_URL=http://localhost:20128
|
||||
NEXT_PUBLIC_CLOUD_URL=
|
||||
|
||||
@@ -79,17 +90,45 @@ NEXT_PUBLIC_ENABLE_SOCKS5_PROXY=true
|
||||
# Provider OAuth Credentials (optional — override hardcoded defaults)
|
||||
# These can also be set via data/provider-credentials.json
|
||||
# CLAUDE_OAUTH_CLIENT_ID=
|
||||
# GEMINI_OAUTH_CLIENT_ID=
|
||||
# GEMINI_OAUTH_CLIENT_SECRET=
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# ⚠️ GOOGLE OAUTH (Antigravity, Gemini CLI) — IMPORTANT FOR REMOTE SERVERS
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# The built-in Google OAuth credentials ONLY work when OmniRoute runs on
|
||||
# localhost (127.0.0.1 / local network). They are registered with
|
||||
# redirect_uri = http://localhost:PORT/callback and Google will reject any
|
||||
# other redirect URI with: redirect_uri_mismatch.
|
||||
#
|
||||
# If you are hosting OmniRoute on a remote server (VPS, Docker, cloud), you
|
||||
# MUST register your own Google Cloud OAuth 2.0 credentials:
|
||||
#
|
||||
# 1. Go to https://console.cloud.google.com/apis/credentials
|
||||
# 2. Create an OAuth 2.0 Client ID (type: "Web application")
|
||||
# 3. Add your server URL as Authorized redirect URI:
|
||||
# https://your-server.com/callback
|
||||
# 4. Copy the Client ID and Client Secret below.
|
||||
#
|
||||
# See the full tutorial in README.md → "OAuth em Servidor Remoto" section.
|
||||
#
|
||||
# Antigravity (Google Gemini Code Assist):
|
||||
# ANTIGRAVITY_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
|
||||
# ANTIGRAVITY_OAUTH_CLIENT_SECRET=GOCSPX-your-secret
|
||||
ANTIGRAVITY_OAUTH_CLIENT_SECRET=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
|
||||
|
||||
# Gemini CLI (Google AI):
|
||||
# GEMINI_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
|
||||
# GEMINI_OAUTH_CLIENT_SECRET=GOCSPX-your-secret
|
||||
# GEMINI_CLI_OAUTH_CLIENT_ID=
|
||||
# GEMINI_CLI_OAUTH_CLIENT_SECRET=
|
||||
GEMINI_OAUTH_CLIENT_SECRET=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
|
||||
GEMINI_CLI_OAUTH_CLIENT_SECRET=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
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# CLAUDE_OAUTH_CLIENT_ID=
|
||||
# CODEX_OAUTH_CLIENT_ID=
|
||||
# CODEX_OAUTH_CLIENT_SECRET=
|
||||
# QWEN_OAUTH_CLIENT_ID=
|
||||
# IFLOW_OAUTH_CLIENT_ID=
|
||||
# IFLOW_OAUTH_CLIENT_SECRET=
|
||||
# ANTIGRAVITY_OAUTH_CLIENT_ID=
|
||||
# ANTIGRAVITY_OAUTH_CLIENT_SECRET=
|
||||
IFLOW_OAUTH_CLIENT_SECRET=4Z3YjXycVsQvyGF1etiNlIBB4RsqSDtW
|
||||
|
||||
# API Key Providers (Phase 1 + Phase 4)
|
||||
# Add via Dashboard → Providers → Add API Key, or set here
|
||||
@@ -118,3 +157,28 @@ NEXT_PUBLIC_ENABLE_SOCKS5_PROXY=true
|
||||
# Logging
|
||||
# LOG_LEVEL=info
|
||||
# LOG_FORMAT=text
|
||||
LOG_TO_FILE=true
|
||||
# LOG_FILE_PATH=logs/application/app.log
|
||||
# LOG_MAX_FILE_SIZE=50M
|
||||
# LOG_RETENTION_DAYS=7
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Memory Optimization (Low-RAM configurations)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Node.js heap limit in MB (default: 256 for Docker, system default for npm)
|
||||
# OMNIROUTE_MEMORY_MB=256
|
||||
|
||||
# Prompt cache settings
|
||||
# PROMPT_CACHE_MAX_SIZE=50
|
||||
# PROMPT_CACHE_MAX_BYTES=2097152
|
||||
# PROMPT_CACHE_TTL_MS=300000
|
||||
|
||||
# Semantic cache settings (temperature=0 responses)
|
||||
# SEMANTIC_CACHE_MAX_SIZE=100
|
||||
# SEMANTIC_CACHE_MAX_BYTES=4194304
|
||||
# SEMANTIC_CACHE_TTL_MS=1800000
|
||||
|
||||
# In-memory log buffers
|
||||
# PROXY_LOG_MAX_ENTRIES=200
|
||||
# CALL_LOGS_MAX=200
|
||||
# STREAM_HISTORY_MAX=50
|
||||
|
||||
@@ -36,7 +36,8 @@ jobs:
|
||||
- name: Dependency audit
|
||||
run: npm audit --audit-level=high --omit=dev
|
||||
- name: Check for known vulnerabilities
|
||||
run: npx is-my-node-vulnerable || true
|
||||
run: npx is-my-node-vulnerable
|
||||
continue-on-error: true
|
||||
|
||||
build:
|
||||
name: Build
|
||||
@@ -108,3 +109,39 @@ jobs:
|
||||
- run: npx playwright install --with-deps chromium
|
||||
- run: npm run build
|
||||
- run: npm run test:e2e
|
||||
|
||||
test-integration:
|
||||
name: Integration Tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
env:
|
||||
JWT_SECRET: ci-test-secret-with-sufficient-length-for-validation
|
||||
API_KEY_SECRET: ci-test-api-key-secret-long
|
||||
INITIAL_PASSWORD: ci-test-password-for-integration
|
||||
DATA_DIR: /tmp/omniroute-ci
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
- run: npm ci
|
||||
- run: npm run test:integration
|
||||
continue-on-error: true
|
||||
|
||||
test-security:
|
||||
name: Security Tests
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
env:
|
||||
JWT_SECRET: ci-test-secret-with-sufficient-length-for-validation
|
||||
API_KEY_SECRET: ci-test-api-key-secret-long
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
- run: npm ci
|
||||
- run: npm run test:security
|
||||
continue-on-error: true
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
name: Codex PR Review
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
jobs:
|
||||
request-codex-review:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Request Codex Review
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.payload.pull_request.number,
|
||||
body: '@codex review'
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
name: Deploy to VPS
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Publish to Docker Hub"]
|
||||
types: [completed]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
if: >-
|
||||
(github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success')
|
||||
&& vars.DEPLOY_ENABLED == 'true'
|
||||
name: Deploy OmniRoute to VPS
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Deploy via SSH
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{ secrets.VPS_HOST }}
|
||||
username: ${{ secrets.VPS_USER }}
|
||||
key: ${{ secrets.VPS_SSH_KEY }}
|
||||
port: 22
|
||||
timeout: 30s
|
||||
script: |
|
||||
echo "=== Updating OmniRoute ==="
|
||||
npm install -g omniroute@latest 2>&1
|
||||
INSTALLED_VERSION=$(omniroute --version 2>/dev/null || echo "unknown")
|
||||
echo "Installed version: $INSTALLED_VERSION"
|
||||
|
||||
echo "=== Restarting PM2 ==="
|
||||
pm2 restart omniroute || pm2 start omniroute --name omniroute -- --port 20128
|
||||
pm2 save
|
||||
|
||||
echo "=== Health Check ==="
|
||||
sleep 3
|
||||
curl -sf http://localhost:20128/api/settings > /dev/null && echo "✅ OmniRoute is healthy" || echo "❌ Health check failed"
|
||||
echo "=== Deploy complete ==="
|
||||
@@ -8,9 +8,65 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
name: Build & Push Docker Image
|
||||
build:
|
||||
name: Build (${{ matrix.platform }})
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- platform: linux/amd64
|
||||
platform_pair: linux-amd64
|
||||
runner: ubuntu-latest
|
||||
- platform: linux/arm64
|
||||
platform_pair: linux-arm64
|
||||
runner: ubuntu-24.04-arm
|
||||
env:
|
||||
IMAGE_NAME: diegosouzapw/omniroute
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
target: runner-base
|
||||
platforms: ${{ matrix.platform }}
|
||||
outputs: type=image,name=${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
|
||||
cache-from: type=gha,scope=omniroute-runner-base-${{ matrix.platform_pair }}
|
||||
cache-to: type=gha,mode=max,scope=omniroute-runner-base-${{ matrix.platform_pair }}
|
||||
|
||||
- name: Export digest
|
||||
run: |
|
||||
mkdir -p "${{ runner.temp }}/digests"
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: digests-${{ matrix.platform_pair }}
|
||||
path: ${{ runner.temp }}/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
merge:
|
||||
name: Merge manifest and publish tags
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
env:
|
||||
IMAGE_NAME: diegosouzapw/omniroute
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
@@ -23,8 +79,12 @@ jobs:
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "Publishing Docker image version: $VERSION"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
@@ -32,18 +92,20 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
target: runner-base
|
||||
push: true
|
||||
tags: |
|
||||
diegosouzapw/omniroute:${{ steps.version.outputs.version }}
|
||||
diegosouzapw/omniroute:latest
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
platforms: linux/amd64
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Create manifest list and push
|
||||
working-directory: ${{ runner.temp }}/digests
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
-t "${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}" \
|
||||
-t "${{ env.IMAGE_NAME }}:latest" \
|
||||
$(printf '${{ env.IMAGE_NAME }}@sha256:%s ' *)
|
||||
|
||||
- name: Inspect image
|
||||
run: |
|
||||
docker buildx imagetools inspect "${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}"
|
||||
|
||||
- name: Update Docker Hub description
|
||||
uses: peter-evans/dockerhub-description@v5
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
name: Build Electron Desktop App
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Electron (${{ matrix.os }})
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: windows
|
||||
runner: windows-latest
|
||||
target: win
|
||||
- os: macos
|
||||
runner: macos-latest
|
||||
target: mac
|
||||
- os: linux
|
||||
runner: ubuntu-latest
|
||||
target: linux
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build Next.js standalone
|
||||
run: npm run build
|
||||
|
||||
- name: Install Electron dependencies
|
||||
working-directory: electron
|
||||
run: npm install --no-audit --no-fund
|
||||
|
||||
- name: Build Electron for ${{ matrix.target }}
|
||||
working-directory: electron
|
||||
run: npm run build:${{ matrix.target }}
|
||||
|
||||
- name: Upload release assets
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: electron/dist-electron/**/*
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
+15
-3
@@ -1,7 +1,7 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
node_modules/
|
||||
/.pnp
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
@@ -11,10 +11,10 @@
|
||||
!.yarn/versions
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
coverage/
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
@@ -74,6 +74,8 @@ docs/*
|
||||
!docs/VM_DEPLOYMENT_GUIDE.md
|
||||
!docs/FEATURES.md
|
||||
!docs/screenshots/
|
||||
!docs/i18n/
|
||||
!docs/i18n/**
|
||||
|
||||
# open-sse tests
|
||||
open-sse/test/*
|
||||
@@ -94,3 +96,13 @@ security-analysis/
|
||||
|
||||
# Deploy workflow (contains sensitive VPS credentials)
|
||||
.agent/workflows/deploy.md
|
||||
clipr/
|
||||
app.log
|
||||
*.tgz
|
||||
|
||||
# Backup directories
|
||||
app.__qa_backup/
|
||||
|
||||
# Electron (subproject dependency lock)
|
||||
electron/package-lock.json
|
||||
icon.iconset/
|
||||
|
||||
+725
@@ -7,6 +7,702 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
---
|
||||
|
||||
## [1.6.5] — 2026-02-28
|
||||
|
||||
### 🖥️ Electron Desktop
|
||||
|
||||
- **Official app icons** — Added proper platform-specific icons derived from the OmniRoute SVG logo: `.icns` (macOS), `.ico` (Windows), `.png` (Linux), and `tray-icon.png` (32×32) — via PR [#154](https://github.com/diegosouzapw/OmniRoute/pull/154)
|
||||
- **Automated release workflow** — New GitHub Actions workflow (`electron-release.yml`) builds Electron for Windows/macOS/Linux on every GitHub release publish
|
||||
- **CI fix** — Changed `npm ci` → `npm install` in the Electron build step since `electron/package-lock.json` is `.gitignored`
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **Desktop App section** — Added to all 30 README files (9 fully translated: PT-BR, ES, FR, DE, ZH-CN, JA, RU, KO, AR)
|
||||
- **Electron Fix Plan** — Published detailed code review and fix documentation at `docs/ELECTRON_FIX_PLAN.md`
|
||||
|
||||
### 🐛 Issue Triage
|
||||
|
||||
- **#151** — Auth bypass after v1.6.3 upgrade — triaged, requesting more info from reporter
|
||||
- **#142** — Copilot Config Generator — previously triaged, 5 comments
|
||||
|
||||
---
|
||||
|
||||
## [1.6.4] — 2026-02-28
|
||||
|
||||
### 🖥️ Electron Desktop — Code Review Hardening (16 Fixes)
|
||||
|
||||
#### 🔴 Critical
|
||||
|
||||
- **Server readiness** — Window now waits for server health check before loading URL; no more blank screens on cold start (#1)
|
||||
- **Restart timeout** — `restart-server` IPC handler now has 5s timeout + `SIGKILL` to prevent indefinite hangs (#2)
|
||||
- **Port change lifecycle** — `changePort()` now stops and restarts the server on the new port instead of just reloading the URL (#3)
|
||||
|
||||
#### 🟡 Important
|
||||
|
||||
- **Tray cleanup** — Old `Tray` instance is now destroyed before recreating, preventing duplicate icons and memory leaks (#4)
|
||||
- **IPC event emission** — Main process now emits `server-status` and `port-changed` events to renderer, making React hooks functional (#5)
|
||||
- **Listener accumulation** — Preload now returns disposer functions for precise listener cleanup instead of `removeAllListeners` (#6)
|
||||
- **useIsElectron performance** — Replaced `useState`+`useEffect` with `useSyncExternalStore` to eliminate 5x unnecessary re-renders (#7)
|
||||
|
||||
#### 🔵 Minor
|
||||
|
||||
- Removed dead `isProduction` variable (#8)
|
||||
- Platform-conditional `titleBarStyle` — `hiddenInset` only on macOS, `default` on Windows/Linux (#9)
|
||||
- `stdio: pipe` — Server output captured for logging and readiness detection instead of `inherit` (#10)
|
||||
- Shared `AppInfo` type — `useElectronAppInfo` now uses the shared interface from `types.d.ts` (#11)
|
||||
- `useDataDir` error state — Now exposes errors instead of swallowing silently (#12)
|
||||
- Synced `electron/package.json` version to `1.6.4` (#13)
|
||||
- Removed dead `omniroute://` protocol config — no handler existed (#14)
|
||||
- **Content Security Policy** — Added CSP via `session.webRequest.onHeadersReceived` (#15)
|
||||
- Simplified preload validation — Generic `safeInvoke`/`safeSend`/`safeOn` wrappers reduce boilerplate (#16)
|
||||
|
||||
### 🧪 Test Suite Expansion
|
||||
|
||||
- **76 tests** across 15 suites (up from 64 tests / 9 suites)
|
||||
- New: server readiness timeout, restart race condition, CSP directives, platform options, disposer pattern, generic IPC wrappers
|
||||
|
||||
---
|
||||
|
||||
## [1.6.3] — 2026-02-28
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Database data preservation on upgrade** — Previously, upgrading from older versions (e.g. v1.2.0 → v1.6.x) could cause data loss by renaming the existing database when a legacy `schema_migrations` table was detected. Now checks for actual data before deciding to reset ([#146](https://github.com/diegosouzapw/OmniRoute/issues/146))
|
||||
- **Hardcoded build-machine paths in npm package** — Next.js standalone output baked absolute paths from the build machine into `server.js` and `required-server-files.json`. On other machines these paths don't exist, causing `ENOENT` errors. The prepublish script now sanitizes all build paths to relative ([#147](https://github.com/diegosouzapw/OmniRoute/issues/147))
|
||||
|
||||
---
|
||||
|
||||
## [1.6.2] — 2026-02-27
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Provider labels in Combos** — Combo cards now show user-defined provider names instead of long UUID identifiers, making complex multi-provider combos easier to read ([#121](https://github.com/diegosouzapw/OmniRoute/issues/121))
|
||||
- **Improved request log labels** — RequestLoggerV2 resolves OpenAI-compatible provider IDs to user-defined names via provider nodes lookup
|
||||
- **Smarter API key display** — `formatApiKey()` now shows the full key name for named keys instead of truncating them
|
||||
|
||||
---
|
||||
|
||||
## [1.6.1] — 2026-02-27
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Cross-platform npm install** — Added `postinstall` script to auto-rebuild `better-sqlite3` for the user's OS/architecture. Previously, the npm package shipped Linux x64 binaries that failed on Windows and macOS ([#129](https://github.com/diegosouzapw/OmniRoute/issues/129))
|
||||
|
||||
---
|
||||
|
||||
## [1.6.0] — 2026-02-27
|
||||
|
||||
> ### 🔀 Feature Release — Split-Port Mode
|
||||
>
|
||||
> API and Dashboard can now run on separate ports for advanced deployment scenarios (reverse proxies, container networking, network isolation). Community contribution by [@npmSteven](https://github.com/npmSteven) — PR [#140](https://github.com/diegosouzapw/OmniRoute/pull/140).
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Split-Port Runtime** — Serve dashboard and OpenAI-compatible API on different ports via `API_PORT` and `DASHBOARD_PORT` env vars. Opt-in; single-port mode unchanged ([#140](https://github.com/diegosouzapw/OmniRoute/pull/140))
|
||||
- **API Bridge Server** — Lightweight HTTP proxy routes only OpenAI-compatible paths (`/v1`, `/chat/completions`, `/responses`, `/models`, `/codex`) on the API port, returns 404 for everything else
|
||||
- **Centralized Port Resolution** — New `src/lib/runtime/ports.ts` module ensures consistent port config across server, CLI, OAuth, and cloud sync
|
||||
- **Runtime Wrapper Scripts** — `scripts/run-next.mjs` and `scripts/run-standalone.mjs` for proper env propagation in dev and Docker modes
|
||||
|
||||
### 🐛 Bug Fixes & Polish
|
||||
|
||||
- Added 30s timeout to API bridge proxy requests to prevent resource exhaustion
|
||||
- Extracted healthcheck into `scripts/healthcheck.mjs` (replaces duplicated inline code)
|
||||
- CLI tools page and onboarding derive endpoints from runtime API port
|
||||
- OAuth server fallback resolves to effective dashboard port
|
||||
- Cloud sync internal URL follows dashboard port
|
||||
|
||||
### 🔒 Security
|
||||
|
||||
- API bridge defaults to `127.0.0.1` (not `0.0.0.0`) — network-safe by default
|
||||
- `API_HOST` env var available for explicit override when needed
|
||||
|
||||
### 📦 Dependencies
|
||||
|
||||
- Bump `actions/upload-artifact` from 4 to 7 ([#143](https://github.com/diegosouzapw/OmniRoute/pull/143))
|
||||
- Bump `actions/download-artifact` from 4 to 8 ([#144](https://github.com/diegosouzapw/OmniRoute/pull/144))
|
||||
|
||||
### 🧪 Tests
|
||||
|
||||
- Added 14 unit tests for `parsePort` and `resolveRuntimePorts`
|
||||
|
||||
---
|
||||
|
||||
## [1.5.0] — 2026-02-26
|
||||
|
||||
> ### 🌍 Massive i18n Expansion — 30 Languages
|
||||
>
|
||||
> Dashboard UI, README, and technical documentation now available in 30 languages. CI pipeline hardened with deploy guards.
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Dashboard i18n — 30 Languages** — Expanded dashboard internationalization from 2 languages (EN, PT-BR) to 30 languages: Arabic, Bulgarian, Danish, German, Spanish, Finnish, French, Hebrew, Hindi, Hungarian, Indonesian, Italian, Japanese, Korean, Malay, Dutch, Norwegian, Polish, Portuguese (PT), Portuguese (BR), Romanian, Russian, Slovak, Swedish, Thai, Ukrainian, Vietnamese, Chinese (Simplified), Filipino, and English. All 500+ translation keys fully localized with RTL support for Arabic and Hebrew
|
||||
- **Multi-Language READMEs** — Added 22 new README translations (total: 30 languages), up from the original 8. Each translation includes full project overview, setup guide, feature list, and pricing table
|
||||
- **Multi-Language Documentation** — New `docs/i18n/` directory with translations of all core technical docs (API Reference, Architecture, Codebase Documentation, Features, Troubleshooting, User Guide) in 30 languages
|
||||
- **i18n QA Tooling** — Added `scripts/i18n/` with i18n-specific QA and validation scripts
|
||||
- **GitHub Discussions** — Enabled Discussions on the repository for community support and Q&A (#136)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Dashboard Responsiveness** — Fixed layout and responsiveness issues in dashboard components; improved i18n error message handling for missing translation keys
|
||||
|
||||
### 🔧 CI/CD
|
||||
|
||||
- **Deploy VPS Guard** — Added `DEPLOY_ENABLED` environment variable guard to `deploy-vps.yml` workflow, preventing accidental deployments. Removed broken Tailscale SSH step
|
||||
- **Deleted Broken Workflow** — Removed non-functional `codex-review.yml` workflow that was failing in CI
|
||||
|
||||
---
|
||||
|
||||
## [1.4.11] — 2026-02-25
|
||||
|
||||
> ### 🐛 Settings Persistence Fix
|
||||
>
|
||||
> Fixes routing strategy and wildcard aliases not saving after page refresh.
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Routing Strategy Not Saved After Refresh (#134)** — Added `fallbackStrategy`, `wildcardAliases`, and `stickyRoundRobinLimit` to the Zod validation schema. These fields were silently stripped during validation, preventing them from being persisted to the database
|
||||
|
||||
### 📝 Notes
|
||||
|
||||
- **#135 Closed** — Feature request for proxy configuration (global + per-provider) was already implemented in v1.4.10
|
||||
|
||||
---
|
||||
|
||||
## [1.4.10] — 2026-02-25
|
||||
|
||||
> ### 🔒 Proxy Visibility + Bug Fixes
|
||||
>
|
||||
> Color-coded proxy badges, provider-level proxy configuration, CLI tools page fix, and EACCES fix for restricted environments.
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Color-Coded Proxy Badges** — Each provider connection now shows its proxy status with color-coded badges: 🟢 green (global proxy), 🟡 amber (provider-level proxy), 🔵 blue (per-connection proxy). Badge always displays the proxy IP/host
|
||||
- **Provider-Level Proxy Button** — New "Provider Proxy" button in the Connections header of each provider detail page. Allows configuring a proxy that applies to all connections of that provider
|
||||
- **Proxy IP Display** — The proxy badge now always shows the proxy host/IP address for quick identification
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **CLI Tools Page Stuck in Loading** — Fixed the `/api/cli-tools/status` endpoint hanging indefinitely when binary checks stall on VPS. Added 5s server-side timeout per tool and 8s client-side AbortController timeout (#cli-tools-hang)
|
||||
- **EACCES on Restricted Home Directories** — Fixed crash when `~/.omniroute` directory cannot be created due to permission issues. Now gracefully warns and suggests using the `DATA_DIR` environment variable (#133)
|
||||
|
||||
---
|
||||
|
||||
> ### 🌐 Full Internationalization (i18n) + Multi-Account Fix
|
||||
>
|
||||
> Complete dashboard i18n migration with next-intl, supporting English and Portuguese (Brazil). Fixes production build issues and enables multiple Codex accounts from the same workspace.
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Full Dashboard Internationalization** — Complete i18n migration of 21+ pages and components using `next-intl`. Every dashboard string is now translatable with full EN and PT-BR support. Includes language selector (globe icon) in the header for real-time language switching
|
||||
- **Portuguese (Brazil) Translation** — Complete `pt-BR.json` translation file with 500+ keys covering all pages: Home, Providers, Settings, Combos, Analytics, Costs, Logs, Health, CLI Tools, Endpoint, API Manager, and Onboarding
|
||||
- **Language Selector Component** — New `LanguageSelector` component in the header with flag icons and dropdown for switching between 🇺🇸 English and 🇧🇷 Português
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Multiple Codex Accounts from Same Workspace** — Fixed deduplication logic in `createProviderConnection` that prevented adding multiple OpenAI Pro Business accounts from the same Team workspace. Now uses compound check (workspaceId + email) instead of workspaceId-only, allowing separate connections per user
|
||||
- **Production Build — Crypto Import** — Fixed `instrumentation.ts` using `eval('require')('crypto')` to bypass webpack's static analysis that blocked the Node.js crypto module in the bundled instrumentation file
|
||||
- **Production Build — Translation Scope** — Fixed sub-components `ProviderOverviewCard` and `ProviderModelsModal` in `HomePageClient.tsx` that referenced parent-scope translation hooks. Each sub-component now has its own `useTranslations()` call
|
||||
- **Production Build — app/ Directory Conflict** — Resolved Next.js 16 confusing the production `app/` directory (server build output) with the `src/app/` app router directory, which caused "missing root layout" build failures
|
||||
|
||||
### 📄 i18n Pages Migrated
|
||||
|
||||
Home, Endpoint, API Manager, Providers (list + detail + new), Combos, Logs, Costs, Analytics, Health, CLI Tools, Settings (General, Security, Routing, Session, IP Filter, Compliance, Fallback Chains, Thinking Budget, Policies, Pricing, Resilience, Advanced), Onboarding Wizard, Audit Log, Usage
|
||||
|
||||
---
|
||||
|
||||
## [1.4.7] — 2026-02-25
|
||||
|
||||
> ### 🐛 Bugfix — Antigravity Model Prefix & Version Sync
|
||||
>
|
||||
> Fixes model name sent to Antigravity upstream API containing `antigravity/` prefix, causing 400 errors for non-opus models. Also syncs package-lock.json version.
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Antigravity Model Prefix Stripping** — Model names sent to the Antigravity upstream API (Google Cloud Code) now have any `provider/` prefix defensively stripped. Previously, models like `antigravity/gemini-3-flash` were sent with the prefix intact, causing 400 errors from the upstream API. Only `claude-opus-4-6-thinking` worked because its routing path differed. Fix applied in 3 locations: `antigravity.ts` executor, and both `wrapInCloudCodeEnvelope` and `wrapInCloudCodeEnvelopeForClaude` in the translator
|
||||
- **Package-lock.json Version Sync** — Fixed `package-lock.json` being stuck at `1.4.3` while `package.json` was at `1.4.6`, which prevented npm from publishing the correct version and caused the VPS deploy to stay on the old version
|
||||
|
||||
---
|
||||
|
||||
## [1.4.6] — 2026-02-25
|
||||
|
||||
> ### ✨ Community Release — Security Fix, Multi-Platform Docker, Model Updates & Plus Tier
|
||||
>
|
||||
> Enforces API key model restrictions across all endpoints, adds ARM64 Docker support, updates model registry for latest AI models, and introduces Plus tier in ProviderLimits.
|
||||
|
||||
### 🔒 Security
|
||||
|
||||
- **API Key Model Restrictions Enforced** — `isModelAllowedForKey()` was never called, allowing API keys with `allowedModels` restrictions to access any model. Created centralized `enforceApiKeyPolicy()` middleware and wired it into all `/v1/*` endpoints (chat, embeddings, images, audio, moderations, rerank). Supports exact match, prefix match (`openai/*`), and wildcard patterns ([#130](https://github.com/diegosouzapw/OmniRoute/issues/130), [PR #131](https://github.com/diegosouzapw/OmniRoute/pull/131) by [@ersintarhan](https://github.com/ersintarhan))
|
||||
- **ApiKeyMetadata Type Safety** — Replaced `any` types with proper `ApiKeyMetadata` interface in the policy middleware. Added error logging in catch blocks for metadata fetch and budget check failures
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Docker Multi-Platform Builds** — Restructured Docker CI workflow to support both `linux/amd64` and `linux/arm64` using native runners and digest-based manifest merging. ARM64 users (Apple Silicon, AWS Graviton, Raspberry Pi) can now run OmniRoute natively ([PR #127](https://github.com/diegosouzapw/OmniRoute/pull/127) by [@npmSteven](https://github.com/npmSteven))
|
||||
- **Plus Tier in ProviderLimits** — Added "Plus" as a separate category in the ProviderLimits dashboard, distinguishing Plus/Paid plans from Pro plans with proper ranking and filtering ([PR #126](https://github.com/diegosouzapw/OmniRoute/pull/126) by [@nyatoru](https://github.com/nyatoru))
|
||||
|
||||
### 🔧 Improvements
|
||||
|
||||
- **Model Registry Updates** — Updated provider registry, usage tracking, CLI tools config, and pricing for latest AI models: added Claude Sonnet 4.6, Gemini 3.1 Pro (High/Low), GPT OSS 120B Medium; removed deprecated Claude 4.5 variants and Gemini 2.5 Flash ([PR #128](https://github.com/diegosouzapw/OmniRoute/pull/128) by [@nyatoru](https://github.com/nyatoru))
|
||||
- **Model ID Consistency** — Fixed `claude-sonnet-4-6-thinking` → `claude-sonnet-4-6` mismatch in `importantModels` to match the provider registry
|
||||
|
||||
---
|
||||
|
||||
## [1.4.5] — 2026-02-24
|
||||
|
||||
> ### 🐛 Bugfix Release — Claude Code OAuth & OAuth Proxy Routing
|
||||
>
|
||||
> Fixes Claude Code OAuth failures on remote deployments and routes all OAuth token exchanges through configured proxy.
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Claude Code OAuth** — Fixed `400 Bad Request` on remote deployments by using Anthropic's registered `redirect_uri` (`https://platform.claude.com/oauth/code/callback`) instead of the dynamic server URL. Added missing OAuth scopes (`user:sessions:claude_code`, `user:mcp_servers`) to match the official Claude CLI. Configurable via `CLAUDE_CODE_REDIRECT_URI` env var ([#124](https://github.com/diegosouzapw/OmniRoute/issues/124))
|
||||
- **OAuth Token Exchange Through Proxy** — OAuth token exchange during new connection setup now routes through the configured proxy (provider-level → global → direct), fixing `unsupported_country_region_territory` errors for region-restricted providers like OpenAI Codex ([#119](https://github.com/diegosouzapw/OmniRoute/issues/119))
|
||||
|
||||
---
|
||||
|
||||
## [1.4.4] — 2026-02-24
|
||||
|
||||
> ### ✨ Feature Release — Custom Provider Models in /v1/models
|
||||
>
|
||||
> Compatible provider models are now saved to the customModels database, making them visible via `/v1/models` for all OpenAI-compatible clients.
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Custom Provider Model Persistence** — Compatible provider models (manual or imported) are now saved to the `customModels` database so they appear in `/v1/models` listing for clients like Cursor, Cline, Antigravity, and Claude Code ([PR #122](https://github.com/diegosouzapw/OmniRoute/pull/122) by [@nyatoru](https://github.com/nyatoru))
|
||||
- **Provider Models API** — New `/api/provider-models` endpoint (GET/POST/DELETE) for managing custom model entries with full authentication via `isAuthenticated`
|
||||
- **Unified Model Deletion** — New `handleDeleteModel` removes models from both alias configuration and `customModels` database, preventing orphaned entries
|
||||
- **Provider Node Prefix Resolution** — `getModelInfo` refactored to use provider node prefixes for accurate custom provider model resolution
|
||||
|
||||
### 🔒 Security
|
||||
|
||||
- **Authentication on Provider Models API** — All `/api/provider-models` endpoints require API key or JWT session authentication via shared `isAuthenticated` utility
|
||||
- **URL Parameter Injection Fix** — Applied `encodeURIComponent` to all user-controlled URL parameters (`providerStorageAlias`, `providerId`) to prevent query string injection attacks
|
||||
- **Shared Auth Utility** — Authentication logic extracted to `@/shared/utils/apiAuth.ts`, eliminating code duplication across `/api/models/alias` and `/api/provider-models`
|
||||
|
||||
### 🔧 Improvements
|
||||
|
||||
- **Toast Notifications** — Replaced blocking `alert()` calls with non-blocking `notify.error`/`notify.success` toast notifications matching the project's notification system
|
||||
- **Transactional Save** — Model persistence is now transactional: database save must succeed before alias creation, preventing inconsistent state
|
||||
- **Consistent Error Handling** — All model operations (add, import, delete) now provide user-facing error/success feedback via toast notifications
|
||||
- **ComboFormModal Matching** — Improved provider node matching by ID or prefix for combo model selection
|
||||
|
||||
---
|
||||
|
||||
## [1.4.3] — 2026-02-23
|
||||
|
||||
### 🐛 Bug Fix
|
||||
|
||||
- **OAuth LAN Access** — Fixed OAuth flow for remote/LAN IP access (`192.168.x.x`). Previously, LAN IPs incorrectly used popup mode, leading to a broken redirect loop. Now defaults to manual callback URL input mode for non-localhost access
|
||||
|
||||
---
|
||||
|
||||
## [1.4.2] — 2026-02-23
|
||||
|
||||
### 🐛 Bug Fix
|
||||
|
||||
- **OAuth Token Refresh** — Fixed `client_secret is missing` error for Google-based OAuth providers (Antigravity, Gemini, Gemini CLI, iFlow). Desktop/CLI OAuth secrets are now hardcoded as defaults since Next.js inlined empty strings at build time.
|
||||
|
||||
---
|
||||
|
||||
## [1.4.1] — 2026-02-23
|
||||
|
||||
### 🔧 Improvements
|
||||
|
||||
- **Endpoint Page Cleanup** — Removed redundant API Key Management section from Endpoint page (now fully managed in the dedicated API Manager page)
|
||||
- **CI/CD** — Added `deploy-vps.yml` workflow for automatic VPS deployment on new releases
|
||||
|
||||
---
|
||||
|
||||
## [1.4.0] — 2026-02-23
|
||||
|
||||
> ### ✨ Feature Release — Dedicated API Key Manager with Model Permissions
|
||||
>
|
||||
> Community-contributed API Key Manager page with model-level access control, enhanced with usage statistics, key status indicators, and improved UX.
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Dedicated API Key Manager** — New `/dashboard/api-manager` page for managing API keys, extracted from the Endpoint page. Includes create, delete, and permissions management with a clean table UI ([PR #118](https://github.com/diegosouzapw/OmniRoute/pull/118) by [@nyatoru](https://github.com/nyatoru))
|
||||
- **Model-Level API Key Permissions** — Restrict API keys to specific models using `allowed_models` with wildcard pattern support (e.g., `openai/*`). Toggle between "Allow All" and "Restrict" modes with an intuitive provider-grouped model selector
|
||||
- **API Key Validation Cache** — 3-tier caching layer (validation, metadata, permission) reduces database hits on every request, with automatic cache invalidation on key changes
|
||||
- **Usage Statistics Per Key** — Each API key shows total request count and last used timestamp, with a stats summary dashboard (total keys, restricted keys, total requests, models available)
|
||||
- **Key Status Indicators** — Color-coded lock/unlock icons and copy buttons on each key row for quick identification of restricted vs unrestricted keys
|
||||
|
||||
### 🔧 Improvements
|
||||
|
||||
- **Endpoint Page Simplified** — API key management removed from Endpoint page and replaced with a prominent link to the API Manager
|
||||
- **Sidebar Navigation** — New "API Manager" entry with `vpn_key` icon in the sidebar
|
||||
- **Prepared Statements** — API key database operations now use cached prepared statements for better performance
|
||||
- **Input Validation** — XSS-safe sanitization and regex validation for key names; ID format validation for API calls
|
||||
|
||||
---
|
||||
|
||||
## [1.3.1] — 2026-02-23
|
||||
|
||||
> ### 🐛 Bugfix Release — Proxy Connection Tests & Compatible Provider Display
|
||||
>
|
||||
> Fixes provider connection tests bypassing configured proxy and improves compatible provider display in the request logger.
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Connection Tests Now Use Proxy** — Provider connection tests (`Test Connection` button) now route through the configured proxy (key → combo → provider → global → direct), matching the behavior of real API calls. Previously, `fetch()` was called directly, bypassing the proxy entirely ([#119](https://github.com/diegosouzapw/OmniRoute/issues/119))
|
||||
- **Compatible Provider Display in Logs** — OpenAI/Anthropic compatible providers now show friendly labels (`OAI-COMPAT`, `ANT-COMPAT`) instead of raw UUID-based IDs in the request logger's provider column, dropdown, and quick filters ([#113](https://github.com/diegosouzapw/OmniRoute/issues/113))
|
||||
|
||||
### 🧪 Tests
|
||||
|
||||
- **Connection Test Unit Tests** — 26 new test cases covering error classification logic, token expiry detection, and provider display label resolution
|
||||
|
||||
---
|
||||
|
||||
## [1.3.0] — 2026-02-23
|
||||
|
||||
> ### ✨ Feature Release — iFlow Fix, Health Check Logs Toggle, Kilocode Models & Model Deduplication
|
||||
>
|
||||
> Community-driven release with iFlow HMAC-SHA256 signature support, health check log management, expanded Kilocode model list, and model deduplication on the dashboard.
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Hide Health Check Logs** — New toggle in Settings → Appearance to suppress verbose `[HealthCheck]` messages from the server console. Uses a 30-second cache to minimize database reads with request coalescing for concurrent calls ([PR #111](https://github.com/diegosouzapw/OmniRoute/pull/111) by [@nyatoru](https://github.com/nyatoru))
|
||||
- **Kilocode Custom Models Endpoint** — Added `modelsUrl` support in `RegistryEntry` for providers with non-standard model endpoints. Expanded Kilocode model list from 8 to 26 models including Qwen3, GPT-5, Claude 3 Haiku, Gemini 2.5, DeepSeek V3, Llama 4, and more ([PR #115](https://github.com/diegosouzapw/OmniRoute/pull/115) by [@benzntech](https://github.com/benzntech))
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **iFlow 406 Error** — Created dedicated `IFlowExecutor` with HMAC-SHA256 signature support (`session-id`, `x-iflow-timestamp`, `x-iflow-signature` headers). The iFlow provider was previously using the default executor which lacked the required signature headers, causing 406 errors ([#114](https://github.com/diegosouzapw/OmniRoute/issues/114))
|
||||
- **Duplicate Models in Endpoint Lists** — Filtered out parent models (`!m.parent`) from all model categorization and count logic on the Endpoint page. Provider modal lists also exclude duplicates ([PR #112](https://github.com/diegosouzapw/OmniRoute/pull/112) by [@nyatoru](https://github.com/nyatoru))
|
||||
|
||||
### 🧪 Tests
|
||||
|
||||
- **IFlowExecutor Unit Tests** — 11 new test cases covering HMAC-SHA256 signature generation, header building, URL construction, body passthrough, and executor registry integration
|
||||
|
||||
---
|
||||
|
||||
## [1.2.0] — 2026-02-22
|
||||
|
||||
> ### ✨ Feature Release — Dashboard Session Auth for Models Endpoint
|
||||
>
|
||||
> Dashboard users can now access `/v1/models` via their existing session when API key auth is required.
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **JWT Session Auth Fallback** — When `requireAuthForModels` is enabled, the `/v1/models` endpoint now accepts both API key (Bearer token) for external clients **and** the dashboard JWT session cookie (`auth_token`), allowing logged-in dashboard users to view models without needing an explicit API key ([PR #110](https://github.com/diegosouzapw/OmniRoute/pull/110) by [@nyatoru](https://github.com/nyatoru))
|
||||
|
||||
### 🔧 Improvements
|
||||
|
||||
- **401 instead of 404** — Authentication failures on `/v1/models` now return `401 Unauthorized` with a structured JSON error body (OpenAI-compatible format) instead of a generic `404 Not Found`, improving debuggability for API clients
|
||||
- **Simplified auth logic** — Refactored the JWT cookie verification to reuse the same pattern as `apiAuth.ts`, removing redundant same-origin detection (~60 lines) since the `sameSite:lax` + `httpOnly` cookie flags already provide equivalent CSRF protection
|
||||
|
||||
---
|
||||
|
||||
## [1.1.1] — 2026-02-22
|
||||
|
||||
> ### 🐛 Bugfix Release — API Key Creation & Codex Team Plan Quotas
|
||||
>
|
||||
> Fixes API key creation crash when `API_KEY_SECRET` is not set and adds Code Review rate limit window to Codex quota display.
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **API Key Creation** — Added deterministic fallback for `API_KEY_SECRET` to prevent `crypto.createHmac` crash when the environment variable is not configured. Keys created without the secret are insecure (warned at startup) but the application no longer crashes ([#108](https://github.com/diegosouzapw/OmniRoute/issues/108))
|
||||
- **Codex Code Review Quota** — Added parsing of the third rate limit window (`code_review_rate_limit`) from the ChatGPT usage API, supporting Plus/Pro/Team plan differences. The dashboard now displays all three quota bars: Session (5h), Weekly, and Code Review ([#106](https://github.com/diegosouzapw/OmniRoute/issues/106))
|
||||
|
||||
---
|
||||
|
||||
## [1.1.0] — 2026-02-21
|
||||
|
||||
> ### 🐛 Bugfix Release — OAuth Client Secret and Codex Business Quotas
|
||||
>
|
||||
> Fixes missing remote-server OAuth configurations and adds ChatGPT Business account quota monitoring.
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **OAuth Client Secret** — Omitted explicitly empty `client_secret` parameters to resolve token exchange connection rejection on remote servers missing environment variables for Antigravity, Gemini and iFlow ([#103](https://github.com/diegosouzapw/OmniRoute/issues/103))
|
||||
- **Codex Business Quotas** — Automatically fetches the appropriate ChatGPT workspace to unlock the 5-hour Business usage limits directly inside the Quota tab and mapped `BIZ` string variant perfectly ([#101](https://github.com/diegosouzapw/OmniRoute/issues/101))
|
||||
|
||||
---
|
||||
|
||||
## [1.0.10] — 2026-02-21
|
||||
|
||||
> ### 🐛 Bugfix — Multi-Account Support for Qwen
|
||||
>
|
||||
> Solves the issue where adding a second Qwen account would overwrite the first one.
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **OAuth Accounts** — Extracted user email from the `id_token` using JWT decoding for Qwen and similar providers, allowing multiple accounts of the same provider to be authenticated simultaneously instead of triggering the fallback overwrite logic ([#99](https://github.com/diegosouzapw/OmniRoute/issues/99))
|
||||
|
||||
---
|
||||
|
||||
## [1.0.9] — 2026-02-21
|
||||
|
||||
> ### 🐛 Hotfix — Settings Persistence
|
||||
>
|
||||
> Fixes blocked providers and API auth toggle not being saved after page reload.
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Settings Persistence** — Added `requireAuthForModels` (boolean) and `blockedProviders` (string array) to the Zod validation schema, which was silently stripping these fields during PATCH requests, preventing them from being saved to the database
|
||||
|
||||
---
|
||||
|
||||
## [1.0.8] — 2026-02-21
|
||||
|
||||
> ### 🔒 API Security & Windows Support
|
||||
>
|
||||
> Adds API Endpoint Protection for `/models`, Windows server startup fixes, and UI improvements.
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **API Endpoint Protection (`/models`)** — New Security Tab settings to optionally require an API key for the `/v1/models` endpoint (returns 404 when unauthorized) and to selectively block specific providers from appearing in the models list ([#100](https://github.com/diegosouzapw/OmniRoute/issues/100), [#96](https://github.com/diegosouzapw/OmniRoute/issues/96))
|
||||
- **Interactive Provider UI** — Blocked Providers setting features an interactive chip selector with visual badges for all available AI providers
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Windows Server Startup** — Fixed `ERR_INVALID_FILE_URL_PATH` crash on Windows by safely wrapping `import.meta.url` resolution with a fallback to `process.cwd()` for globally installed npm packages ([#98](https://github.com/diegosouzapw/OmniRoute/issues/98))
|
||||
- **Combo buttons visibility** — Fixed layout overlap and tight spacing for the Quick Action buttons (Clone / Delete / Test) on the Combos page on narrower screens ([#95](https://github.com/diegosouzapw/OmniRoute/issues/95))
|
||||
|
||||
---
|
||||
|
||||
## [1.0.7] — 2026-02-20
|
||||
|
||||
> ### 🐛 Bugfix Release — OpenAI Compatibility, Custom Models & OAuth UX
|
||||
>
|
||||
> Fixes three community-reported issues: stream default now follows OpenAI spec, custom OpenAI-compatible providers appear in `/v1/models`, and Google OAuth shows a clear error + tutorial for remote deployments.
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **`stream` defaults to `false`** — Aligns with the OpenAI specification which explicitly states `stream` defaults to `false`. Previously OmniRoute defaulted to `true`, causing SSE data to be returned instead of a JSON object, breaking clients like Spacebot, OpenCode, and standard Python/Rust/Go OpenAI SDKs that don't explicitly set `stream: true` ([#89](https://github.com/diegosouzapw/OmniRoute/issues/89))
|
||||
- **Custom AI providers now appear in `/v1/models`** — OpenAI-compatible custom providers (e.g. FriendLI) whose provider ID wasn't in the built-in alias map were silently excluded from the models list even when active. Fixed by also checking the raw provider ID from the database against active connections ([#90](https://github.com/diegosouzapw/OmniRoute/issues/90))
|
||||
- **OAuth `redirect_uri_mismatch` — improved UX for remote deployments** — Google OAuth providers (Antigravity, Gemini CLI) now always use `localhost` as redirect URI matching the registered credentials. Remote-access users see a targeted amber warning with a link to the new setup guide. The token exchange error message explains the root cause and guides users to configure their own credentials ([#91](https://github.com/diegosouzapw/OmniRoute/issues/91))
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- **OAuth em Servidor Remoto tutorial** — New README section with step-by-step guide to configure custom Google Cloud OAuth 2.0 credentials for remote/VPS/Docker deployments
|
||||
- **`.env.example` Google OAuth block** — Added prominent warning block explaining remote credential requirements with direct links to Google Cloud Console
|
||||
|
||||
### 📁 Files Modified
|
||||
|
||||
| File | Change |
|
||||
| -------------------------------------- | ------------------------------------------------------------------------------------------- |
|
||||
| `open-sse/handlers/chatCore.ts` | `stream` defaults to `false` (was `true`) per OpenAI spec |
|
||||
| `src/app/api/v1/models/route.ts` | Added raw `providerId` check for custom models active-provider filter |
|
||||
| `src/shared/components/OAuthModal.tsx` | Force `localhost` redirect for Google OAuth; improved `redirect_uri_mismatch` error message |
|
||||
| `.env.example` | Added ⚠️ Google OAuth remote credentials block with step-by-step instructions |
|
||||
| `README.md` | New "🔐 OAuth em Servidor Remoto" tutorial section |
|
||||
|
||||
---
|
||||
|
||||
## [1.0.6] — 2026-02-20
|
||||
|
||||
> ### ✨ Provider & Combo Toggles — Strict Model Filtering
|
||||
>
|
||||
> `/v1/models` now shows only models from providers with active connections. Combos and providers can be toggled on/off directly from the dashboard.
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Provider toggle on Providers page** — Enable/disable all connections for a provider directly from the main Providers list. Toggle is always visible, no hover needed
|
||||
- **Combo enable/disable toggle** — Each combo on the Combos page now has a toggle. Disabled combos are excluded from `/v1/models`
|
||||
- **OAuth private IP support** — Expanded localhost detection to include private/LAN IPs (`192.168.x.x`, `10.x.x.x`, `172.16-31.x.x`) for correct OAuth redirect URIs
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **`/v1/models` strict filtering** — Models are now shown only from providers with active, enabled connections. Previously, if no connections existed or all were disabled, all 378+ models were shown as a fallback
|
||||
- **Disabled provider models hidden** — Toggling off a provider immediately removes its models from `/v1/models`
|
||||
|
||||
---
|
||||
|
||||
## [1.0.5] — 2026-02-20
|
||||
|
||||
> ### 🐛 Hotfix — Model Filtering & Docker DATA_DIR
|
||||
>
|
||||
> Filters all model types in `/v1/models` by active providers and fixes Docker data directory mismatch.
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **`/v1/models` full filtering** — Embedding, image, rerank, audio, and moderation models are now filtered by active provider connections, matching chat model behavior. Providers like Together AI no longer appear without a configured API key (#88)
|
||||
- **Docker `DATA_DIR`** — Added `ENV DATA_DIR=/app/data` to Dockerfile and `docker-compose.yml` ensuring the volume mount always matches the app data directory — prevents empty database on container recreation
|
||||
|
||||
---
|
||||
|
||||
## [1.0.4] — 2026-02-19
|
||||
|
||||
> ### 🔧 Provider Filtering, OAuth Proxy Fix & Documentation
|
||||
>
|
||||
> Dashboard model filtering by active providers, provider enable/disable visual indicators, OAuth login fix for nginx reverse proxy, and LLM onboarding documentation.
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **API Models filtering** — `GET /api/models` now returns only models from active providers; use `?all=true` for all models (#85)
|
||||
- **Provider disabled indicator** — Provider cards show ⏸ "Disabled" badge with reduced opacity when all connections are inactive (#85)
|
||||
- **`llm.txt`** — Comprehensive LLM onboarding file with project overview, architecture, flows, and conventions (#84)
|
||||
- **WhatsApp Community** — Added WhatsApp group link to README badges and Support section
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **OAuth behind nginx** — Fixed OAuth login failing when behind a reverse proxy by using `window.location.origin` for redirect URI instead of hardcoded `localhost` (#86)
|
||||
- **`NEXT_PUBLIC_BASE_URL` for OAuth** — Documented env var usage as redirect URI override for proxy deployments (#86)
|
||||
|
||||
### 📁 Files Added
|
||||
|
||||
| File | Purpose |
|
||||
| --------- | -------------------------------------------------- |
|
||||
| `llm.txt` | LLM and contributor onboarding (llms.txt standard) |
|
||||
|
||||
### 📁 Files Modified
|
||||
|
||||
| File | Change |
|
||||
| -------------------------------------------------- | ---------------------------------------------------------------- |
|
||||
| `src/app/api/models/route.ts` | Filter by active providers, `?all=true` param, `available` field |
|
||||
| `src/app/(dashboard)/dashboard/providers/page.tsx` | `allDisabled` detection + ⏸ badge + opacity-50 on provider cards |
|
||||
| `src/shared/components/OAuthModal.tsx` | Proxy-aware redirect URI using `window.location.origin` |
|
||||
| `.env.example` | Documented `NEXT_PUBLIC_BASE_URL` for OAuth behind proxy |
|
||||
|
||||
---
|
||||
|
||||
## [1.0.3] — 2026-02-19
|
||||
|
||||
> ### 📊 Logs Dashboard & Real-Time Console Viewer
|
||||
>
|
||||
> Unified logs interface with real-time console log viewer, file-based logging via console interception, and server initialization improvements.
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- **Logs Dashboard** — Consolidated 4-tab page at `/dashboard/logs` with Request Logs, Proxy Logs, Audit Logs, and Console tabs
|
||||
- **Console Log Viewer** — Terminal-style real-time log viewer with color-coded log levels, auto-scroll, search/filtering, level filter, and 5-second polling
|
||||
- **Console Interceptor** — Monkey-patches `console.log/info/warn/error/debug` at server start to capture all application output as JSON lines to `logs/application/app.log`
|
||||
- **Log Rotation** — Size-based rotation and retention-based cleanup for log files
|
||||
|
||||
### 🔧 Improvements
|
||||
|
||||
- **Instrumentation consolidation** — Moved `initAuditLog()`, `cleanupExpiredLogs()`, and console interceptor initialization to Next.js `instrumentation.ts` (runs on both dev and prod server start)
|
||||
- **Structured Logger file output** — `structuredLogger.ts` now also appends JSON log entries to the log file
|
||||
- **Pino Logger fix** — Fixed broken mix of pino `transport` targets + manual `createWriteStream`; now uses `pino/file` transport targets exclusively with absolute paths
|
||||
|
||||
### 🗂️ Files Added
|
||||
|
||||
| File | Purpose |
|
||||
| ---------------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `src/app/(dashboard)/dashboard/logs/page.tsx` | Tabbed Logs Dashboard page |
|
||||
| `src/app/(dashboard)/dashboard/logs/AuditLogTab.tsx` | Audit log tab component extracted from standalone page |
|
||||
| `src/shared/components/ConsoleLogViewer.tsx` | Terminal-style real-time log viewer |
|
||||
| `src/app/api/logs/console/route.ts` | API endpoint to read log file (filters last 1h, level, component) |
|
||||
| `src/lib/consoleInterceptor.ts` | Console method monkey-patching for file capture |
|
||||
| `src/lib/logRotation.ts` | Log rotation by size and cleanup by retention days |
|
||||
|
||||
### 🗂️ Files Modified
|
||||
|
||||
| File | Change |
|
||||
| --------------------------------------- | ------------------------------------------------------------------------------- |
|
||||
| `src/shared/components/Sidebar.tsx` | Nav: "Request Logs" → "Logs" with `description` icon |
|
||||
| `src/shared/components/Breadcrumbs.tsx` | Added breadcrumb labels for `logs`, `audit-log`, `console` |
|
||||
| `src/instrumentation.ts` | Added console interceptor + audit log init + expired log cleanup |
|
||||
| `src/server-init.ts` | Added console interceptor import (backup init) |
|
||||
| `src/shared/utils/logger.ts` | Fixed pino file transport using `pino/file` targets |
|
||||
| `src/shared/utils/structuredLogger.ts` | Added `appendFileSync` file writing + log file config |
|
||||
| `.env.example` | Added `LOG_TO_FILE`, `LOG_FILE_PATH`, `LOG_MAX_FILE_SIZE`, `LOG_RETENTION_DAYS` |
|
||||
|
||||
### ⚙️ Configuration
|
||||
|
||||
New environment variables:
|
||||
|
||||
| Variable | Default | Description |
|
||||
| -------------------- | -------------------------- | ----------------------------- |
|
||||
| `LOG_TO_FILE` | `true` | Enable/disable file logging |
|
||||
| `LOG_FILE_PATH` | `logs/application/app.log` | Log file path |
|
||||
| `LOG_MAX_FILE_SIZE` | `50M` | Max file size before rotation |
|
||||
| `LOG_RETENTION_DAYS` | `7` | Days to retain old log files |
|
||||
|
||||
---
|
||||
|
||||
## [1.0.2] — 2026-02-18
|
||||
|
||||
> ### 🔒 Security Hardening, Architecture Improvements & UX Polish
|
||||
>
|
||||
> Comprehensive audit-driven improvements across security, architecture, testing, and user experience.
|
||||
|
||||
### 🛡️ Security (Phase 0)
|
||||
|
||||
- **Auth guard** — API route protection via `withAuth` middleware for all dashboard routes
|
||||
- **CSRF protection** — Token-based CSRF guard for all state-changing API routes
|
||||
- **Request payload validation** — Zod schemas for provider, combo, key, and settings endpoints
|
||||
- **Prompt injection guard** — Input sanitization against malicious prompt patterns
|
||||
- **Body size guard** — Route-specific body size limits with dedicated audio upload threshold
|
||||
- **Rate limiter** — Per-IP rate limiting with configurable windows and thresholds
|
||||
|
||||
### 🏗️ Architecture (Phase 1–2)
|
||||
|
||||
- **DI container** — Simple dependency injection container for service registration
|
||||
- **Policy engine** — Consolidated `PolicyEngine` for routing, security, and rate limiting
|
||||
- **SQLite migration** — Database migration system with versioned migration runner
|
||||
- **Graceful shutdown** — Clean server shutdown with connection draining
|
||||
- **TypeScript fixes** — Resolved all `tsc` errors; removed redundant `@ts-check` directives
|
||||
- **Pipeline decomposition** — `handleSingleModelChat` decomposed into composable pipeline stages
|
||||
- **Prompt template versioning** — Version-tracked prompt templates with rollback support
|
||||
- **Eval scheduling** — Automated evaluation suite scheduling with cron-based runner
|
||||
- **Plugin architecture** — Extensible plugin system for custom middleware and handlers
|
||||
|
||||
### 🧪 Testing & CI (Phase 2)
|
||||
|
||||
- **Coverage thresholds** — Jest coverage thresholds enforced in CI (368 tests passing)
|
||||
- **Proxy pipeline integration tests** — End-to-end tests for the proxy request pipeline
|
||||
- **CI audit workflow** — npm audit and security scanning in GitHub Actions
|
||||
- **k6 load tests** — Performance testing with ramping VUs and custom metrics
|
||||
|
||||
### ✨ UX & Polish (Phase 3–4)
|
||||
|
||||
- **Session management** — Session info card with login time, age, user agent, and logout
|
||||
- **Focus indicators** — Global `:focus-visible` styles and `--focus-ring` CSS utility
|
||||
- **Audit log viewer** — Security event audit log with structured data display
|
||||
- **Dashboard cleanup** — Removed unused files, fixed Quick Start links to Endpoint page
|
||||
- **Documentation** — Troubleshooting guide, deployment improvements
|
||||
|
||||
---
|
||||
|
||||
## [1.0.1] — 2026-02-18
|
||||
|
||||
> ### 🔧 API Compatibility & SDK Hardening
|
||||
>
|
||||
> Response sanitization, role normalization, and structured output improvements for strict OpenAI SDK compatibility and cross-provider robustness.
|
||||
|
||||
### 🛡️ Response Sanitization (NEW)
|
||||
|
||||
- **Response sanitizer module** — New `responseSanitizer.ts` strips non-standard fields (`x_groq`, `usage_breakdown`, `service_tier`, etc.) from all OpenAI-format provider responses, fixing OpenAI Python SDK v1.83+ Pydantic validation failures that returned raw strings instead of parsed `ChatCompletion` objects
|
||||
- **Streaming chunk sanitization** — Passthrough streaming mode now sanitizes each SSE chunk in real-time via `sanitizeStreamingChunk()`, ensuring strict `chat.completion.chunk` schema compliance
|
||||
- **ID/Object/Usage normalization** — Ensures `id`, `object`, `created`, `model`, `choices`, and `usage` fields always exist with correct types
|
||||
- **Usage field cleanup** — Strips non-standard usage sub-fields, keeps only `prompt_tokens`, `completion_tokens`, `total_tokens`, and OpenAI detail fields
|
||||
|
||||
### 🧠 Think Tag Extraction (NEW)
|
||||
|
||||
- **`<think>` tag extraction** — Automatically extracts `<think>...</think>` blocks from thinking model responses (DeepSeek R1, Kimi K2 Thinking, etc.) into OpenAI's standard `reasoning_content` field
|
||||
- **Streaming think-tag stripping** — Real-time `<think>` extraction in passthrough SSE stream, preventing JSON parsing errors in downstream tools
|
||||
- **Preserves native reasoning** — Providers that already send `reasoning_content` natively (e.g., OpenAI o1) are not overwritten
|
||||
|
||||
### 🔄 Role Normalization (NEW)
|
||||
|
||||
- **`developer` → `system` conversion** — OpenAI's new `developer` role is automatically converted to `system` for all non-OpenAI providers (Claude, Gemini, Kiro, etc.)
|
||||
- **`system` → `user` merging** — For models that reject the `system` role (GLM, ERNIE), system messages are intelligently merged into the first user message with clear delimiters
|
||||
- **Model-aware normalization** — Uses model name prefix matching (`glm-*`, `ernie-*`) for compatibility decisions, avoiding hardcoded provider-level flags
|
||||
|
||||
### 📐 Structured Output for Gemini (NEW)
|
||||
|
||||
- **`response_format` → Gemini conversion** — OpenAI's `json_schema` structured output is now translated to Gemini's `responseMimeType` + `responseSchema` in the translator pipeline
|
||||
- **`json_object` support** — `response_format: { type: "json_object" }` maps to Gemini's `application/json` MIME type
|
||||
- **Schema cleanup** — Automatically removes unsupported JSON Schema keywords (`$schema`, `additionalProperties`) for Gemini compatibility
|
||||
|
||||
### 📁 Files Added
|
||||
|
||||
| File | Purpose |
|
||||
| ---------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| `open-sse/handlers/responseSanitizer.ts` | Response field stripping, think-tag extraction, ID/usage normalization |
|
||||
| `open-sse/services/roleNormalizer.ts` | Developer→system, system→user role conversion pipeline |
|
||||
|
||||
### 📁 Files Modified
|
||||
|
||||
| File | Change |
|
||||
| ------------------------------------------------- | ------------------------------------------------------------------------------- |
|
||||
| `open-sse/handlers/chatCore.ts` | Integrated response sanitizer for non-streaming OpenAI responses |
|
||||
| `open-sse/utils/stream.ts` | Integrated streaming chunk sanitizer + think-tag extraction in passthrough mode |
|
||||
| `open-sse/translator/index.ts` | Integrated role normalizer into the request translation pipeline |
|
||||
| `open-sse/translator/request/openai-to-gemini.ts` | Added `response_format` → `responseMimeType`/`responseSchema` conversion |
|
||||
|
||||
---
|
||||
|
||||
## [1.0.0] — 2026-02-18
|
||||
|
||||
> ### 🎉 First Major Release — OmniRoute 1.0
|
||||
@@ -138,4 +834,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
---
|
||||
|
||||
[1.6.3]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.6.3
|
||||
[1.6.2]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.6.2
|
||||
[1.6.1]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.6.1
|
||||
[1.6.0]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.6.0
|
||||
[1.5.0]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.5.0
|
||||
[1.4.11]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.4.11
|
||||
[1.4.10]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.4.10
|
||||
[1.4.9]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.4.9
|
||||
[1.4.8]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.4.8
|
||||
[1.4.7]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.4.7
|
||||
[1.4.6]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.4.6
|
||||
[1.4.5]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.4.5
|
||||
[1.4.4]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.4.4
|
||||
[1.4.3]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.4.3
|
||||
[1.4.2]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.4.2
|
||||
[1.4.1]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.4.1
|
||||
[1.4.0]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.4.0
|
||||
[1.3.1]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.3.1
|
||||
[1.3.0]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.3.0
|
||||
[1.2.0]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.2.0
|
||||
[1.1.1]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.1.1
|
||||
[1.0.7]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.0.7
|
||||
[1.0.6]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.0.6
|
||||
[1.0.5]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.0.5
|
||||
[1.0.4]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.0.4
|
||||
[1.1.0]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.1.0
|
||||
[1.0.1]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.0.1
|
||||
[1.0.3]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.0.3
|
||||
[1.0.2]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.0.2
|
||||
[1.0.0]: https://github.com/diegosouzapw/OmniRoute/releases/tag/v1.0.0
|
||||
|
||||
+1
-1
@@ -159,7 +159,7 @@ src/ # TypeScript (.ts / .tsx)
|
||||
│ ├── cacheLayer.ts # LRU cache
|
||||
│ ├── semanticCache.ts # Semantic response cache
|
||||
│ ├── idempotencyLayer.ts # Request deduplication
|
||||
│ └── localDb.ts # LowDB (JSON) storage
|
||||
│ └── localDb.ts # Settings facade (LowDB for config, SQLite for domain data)
|
||||
├── shared/
|
||||
│ ├── components/ # React components (.tsx)
|
||||
│ ├── middleware/ # Correlation IDs, etc.
|
||||
|
||||
+8
-4
@@ -19,20 +19,25 @@ LABEL org.opencontainers.image.title="omniroute" \
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=20128
|
||||
ENV HOSTNAME=0.0.0.0
|
||||
ENV NODE_OPTIONS="--max-old-space-size=256"
|
||||
|
||||
# Runtime writable location for localDb when DATA_DIR is configured to /app/data
|
||||
# Data directory inside Docker — must match the volume mount in docker-compose.yml
|
||||
ENV DATA_DIR=/app/data
|
||||
RUN mkdir -p /app/data
|
||||
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/.next/static ./.next/static
|
||||
COPY --from=builder /app/.next/standalone ./
|
||||
COPY --from=builder /app/scripts/run-standalone.mjs ./run-standalone.mjs
|
||||
COPY --from=builder /app/scripts/runtime-env.mjs ./runtime-env.mjs
|
||||
COPY --from=builder /app/scripts/healthcheck.mjs ./healthcheck.mjs
|
||||
|
||||
EXPOSE 20128
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
|
||||
CMD node -e "fetch('http://127.0.0.1:20128/api/settings').then(r=>{if(!r.ok)throw r.status}).catch(()=>process.exit(1))"
|
||||
CMD ["node", "healthcheck.mjs"]
|
||||
|
||||
CMD ["node", "server.js"]
|
||||
CMD ["node", "run-standalone.mjs"]
|
||||
|
||||
FROM runner-base AS runner-cli
|
||||
|
||||
@@ -44,4 +49,3 @@ RUN apt-get update \
|
||||
|
||||
# Install CLI tools globally. Separate layer from apt for better cache reuse.
|
||||
RUN npm install -g --no-audit --no-fund @openai/codex @anthropic-ai/claude-code droid openclaw@latest
|
||||
|
||||
|
||||
+1106
File diff suppressed because it is too large
Load Diff
+1111
File diff suppressed because it is too large
Load Diff
+1111
File diff suppressed because it is too large
Load Diff
+95
-134
@@ -100,10 +100,11 @@ _Verbinde jedes KI-gesteuerte IDE- oder CLI-Tool über OmniRoute — kostenloses
|
||||
[](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
|
||||
[](https://omniroute.online)
|
||||
[](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
|
||||
[🌐 Website](https://omniroute.online) • [🚀 Schnellstart](#-schnellstart) • [💡 Funktionen](#-hauptfunktionen) • [📖 Doku](#-dokumentation) • [💰 Preise](#-preisübersicht)
|
||||
|
||||
🌐 **Verfügbar in:** [English](README.md) | [Português](README.pt-BR.md) | [Español](README.es.md) | [Русский](README.ru.md) | [中文](README.zh-CN.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | [Italiano](README.it.md)
|
||||
🌐 **Verfügbar in:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](README.pt-BR.md) | 🇪🇸 [Español](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [Italiano](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [Magyar](README.hu.md) | 🇮🇩 [Bahasa Indonesia](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Nederlands](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Portugal)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Polski](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [Filipino](README.phi.md)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -242,7 +243,31 @@ docker compose --profile cli up -d
|
||||
| Image | Tag | Größe | Beschreibung |
|
||||
| ------------------------ | -------- | ------ | ------------------------ |
|
||||
| `diegosouzapw/omniroute` | `latest` | ~250MB | Letztes stabiles Release |
|
||||
| `diegosouzapw/omniroute` | `1.0.0` | ~250MB | Aktuelle Version |
|
||||
| `diegosouzapw/omniroute` | `1.0.6` | ~250MB | Aktuelle Version |
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Desktop-App — Offline & Immer Aktiv
|
||||
|
||||
> 🆕 **NEU!** OmniRoute ist jetzt als **native Desktop-Anwendung** für Windows, macOS und Linux verfügbar.
|
||||
|
||||
- 🖥️ **Natives Fenster** — Dediziertes App-Fenster mit System-Tray-Integration
|
||||
- 🔄 **Autostart** — OmniRoute beim Systemstart starten
|
||||
- 🔔 **Native Benachrichtigungen** — Warnungen bei Kontingent-Erschöpfung
|
||||
- ⚡ **Ein-Klick-Installation** — NSIS (Windows), DMG (macOS), AppImage (Linux)
|
||||
- 🌐 **Offline-Modus** — Funktioniert vollständig offline mit integriertem Server
|
||||
|
||||
```bash
|
||||
npm run electron:dev # Entwicklungsmodus
|
||||
npm run electron:build # Aktuelle Plattform
|
||||
npm run electron:build:win # Windows (.exe)
|
||||
npm run electron:build:mac # macOS (.dmg)
|
||||
npm run electron:build:linux # Linux (.AppImage)
|
||||
```
|
||||
|
||||
📖 Vollständige Dokumentation: [`electron/README.md`](electron/README.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -271,67 +296,6 @@ docker compose --profile cli up -d
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Anwendungsfälle
|
||||
|
||||
### Fall 1: „Ich habe ein Claude Pro Abo"
|
||||
|
||||
**Problem:** Kontingent verfällt ungenutzt, Rate-Limits während intensivem Programmieren
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (Abo voll ausnutzen)
|
||||
2. glm/glm-4.7 (günstiges Backup bei erschöpftem Kontingent)
|
||||
3. if/kimi-k2-thinking (kostenloser Notfall-Fallback)
|
||||
|
||||
Monatliche Kosten: $20 (Abo) + ~$5 (Backup) = $25 gesamt
|
||||
vs. $20 + an Limits stoßen = Frustration
|
||||
```
|
||||
|
||||
### Fall 2: „Ich will null Kosten"
|
||||
|
||||
**Problem:** Kann sich Abos nicht leisten, braucht zuverlässige KI zum Programmieren
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K gratis/Monat)
|
||||
2. if/kimi-k2-thinking (unbegrenzt gratis)
|
||||
3. qw/qwen3-coder-plus (unbegrenzt gratis)
|
||||
|
||||
Monatliche Kosten: $0
|
||||
Qualität: Produktionsreife Modelle
|
||||
```
|
||||
|
||||
### Fall 3: „Ich muss 24/7 programmieren, ohne Unterbrechungen"
|
||||
|
||||
**Problem:** Enge Deadlines, kann sich keine Ausfallzeit leisten
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (beste Qualität)
|
||||
2. cx/gpt-5.2-codex (zweites Abo)
|
||||
3. glm/glm-4.7 (günstig, täglicher Reset)
|
||||
4. minimax/MiniMax-M2.1 (günstigste, 5h Reset)
|
||||
5. if/kimi-k2-thinking (unbegrenzt kostenlos)
|
||||
|
||||
Ergebnis: 5 Fallback-Ebenen = null Ausfallzeit
|
||||
```
|
||||
|
||||
### Fall 4: „Ich will KOSTENLOSE KI in OpenClaw"
|
||||
|
||||
**Problem:** Braucht KI-Assistenz in Messaging-Apps, komplett kostenlos
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (unbegrenzt kostenlos)
|
||||
2. if/minimax-m2.1 (unbegrenzt kostenlos)
|
||||
3. if/kimi-k2-thinking (unbegrenzt kostenlos)
|
||||
|
||||
Monatliche Kosten: $0
|
||||
Zugang über: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 Hauptfunktionen
|
||||
|
||||
### 🧠 Routing & Intelligenz
|
||||
@@ -473,6 +437,67 @@ Nahtlose Übersetzung zwischen Formaten:
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Anwendungsfälle
|
||||
|
||||
### Fall 1: „Ich habe ein Claude Pro Abo"
|
||||
|
||||
**Problem:** Kontingent verfällt ungenutzt, Rate-Limits während intensivem Programmieren
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (Abo voll ausnutzen)
|
||||
2. glm/glm-4.7 (günstiges Backup bei erschöpftem Kontingent)
|
||||
3. if/kimi-k2-thinking (kostenloser Notfall-Fallback)
|
||||
|
||||
Monatliche Kosten: $20 (Abo) + ~$5 (Backup) = $25 gesamt
|
||||
vs. $20 + an Limits stoßen = Frustration
|
||||
```
|
||||
|
||||
### Fall 2: „Ich will null Kosten"
|
||||
|
||||
**Problem:** Kann sich Abos nicht leisten, braucht zuverlässige KI zum Programmieren
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K gratis/Monat)
|
||||
2. if/kimi-k2-thinking (unbegrenzt gratis)
|
||||
3. qw/qwen3-coder-plus (unbegrenzt gratis)
|
||||
|
||||
Monatliche Kosten: $0
|
||||
Qualität: Produktionsreife Modelle
|
||||
```
|
||||
|
||||
### Fall 3: „Ich muss 24/7 programmieren, ohne Unterbrechungen"
|
||||
|
||||
**Problem:** Enge Deadlines, kann sich keine Ausfallzeit leisten
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (beste Qualität)
|
||||
2. cx/gpt-5.2-codex (zweites Abo)
|
||||
3. glm/glm-4.7 (günstig, täglicher Reset)
|
||||
4. minimax/MiniMax-M2.1 (günstigste, 5h Reset)
|
||||
5. if/kimi-k2-thinking (unbegrenzt kostenlos)
|
||||
|
||||
Ergebnis: 5 Fallback-Ebenen = null Ausfallzeit
|
||||
```
|
||||
|
||||
### Fall 4: „Ich will KOSTENLOSE KI in OpenClaw"
|
||||
|
||||
**Problem:** Braucht KI-Assistenz in Messaging-Apps, komplett kostenlos
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (unbegrenzt kostenlos)
|
||||
2. if/minimax-m2.1 (unbegrenzt kostenlos)
|
||||
3. if/kimi-k2-thinking (unbegrenzt kostenlos)
|
||||
|
||||
Monatliche Kosten: $0
|
||||
Zugang über: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Einrichtungsanleitung
|
||||
|
||||
<details>
|
||||
@@ -753,74 +778,6 @@ Einstellungen → API-Konfiguration:
|
||||
|
||||
---
|
||||
|
||||
## 📊 Verfügbare Modelle
|
||||
|
||||
<details>
|
||||
<summary><b>Alle verfügbaren Modelle anzeigen</b></summary>
|
||||
|
||||
**Claude Code (`cc/`)** - Pro/Max:
|
||||
|
||||
- `cc/claude-opus-4-6`
|
||||
- `cc/claude-sonnet-4-5-20250929`
|
||||
- `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**Codex (`cx/`)** - Plus/Pro:
|
||||
|
||||
- `cx/gpt-5.2-codex`
|
||||
- `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** - KOSTENLOS:
|
||||
|
||||
- `gc/gemini-3-flash-preview`
|
||||
- `gc/gemini-2.5-pro`
|
||||
|
||||
**GitHub Copilot (`gh/`)**:
|
||||
|
||||
- `gh/gpt-5`
|
||||
- `gh/claude-4.5-sonnet`
|
||||
|
||||
**NVIDIA NIM (`nvidia/`)** - KOSTENLOSE Credits:
|
||||
|
||||
- `nvidia/llama-3.3-70b-instruct`
|
||||
- `nvidia/mistral-7b-instruct`
|
||||
- 50+ weitere Modelle auf [build.nvidia.com](https://build.nvidia.com)
|
||||
|
||||
**GLM (`glm/`)** - $0.6/1M:
|
||||
|
||||
- `glm/glm-4.7`
|
||||
|
||||
**MiniMax (`minimax/`)** - $0.2/1M:
|
||||
|
||||
- `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** - KOSTENLOS:
|
||||
|
||||
- `if/kimi-k2-thinking`
|
||||
- `if/qwen3-coder-plus`
|
||||
- `if/deepseek-r1`
|
||||
- `if/glm-4.7`
|
||||
- `if/minimax-m2`
|
||||
|
||||
**Qwen (`qw/`)** - KOSTENLOS:
|
||||
|
||||
- `qw/qwen3-coder-plus`
|
||||
- `qw/qwen3-coder-flash`
|
||||
|
||||
**Kiro (`kr/`)** - KOSTENLOS:
|
||||
|
||||
- `kr/claude-sonnet-4.5`
|
||||
- `kr/claude-haiku-4.5`
|
||||
|
||||
**OpenRouter (`or/`)** - 100+ Modelle:
|
||||
|
||||
- `or/anthropic/claude-4-sonnet`
|
||||
- `or/google/gemini-2.5-pro`
|
||||
- Jedes Modell von [openrouter.ai/models](https://openrouter.ai/models)
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Evaluierungen (Evals)
|
||||
|
||||
OmniRoute enthält ein integriertes Evaluierungs-Framework zum Testen der LLM-Antwortqualität gegen ein Golden Set. Zugang über **Analytics → Evals** im Dashboard.
|
||||
@@ -892,7 +849,7 @@ Das vorgeladene „OmniRoute Golden Set" enthält 10 Testfälle:
|
||||
**Verbindungstest zeigt „Invalid" für OpenAI-kompatible Anbieter**
|
||||
|
||||
- Viele Anbieter stellen den `/models` Endpoint nicht bereit
|
||||
- OmniRoute v1.0.0+ enthält Fallback-Validierung via Chat Completions
|
||||
- OmniRoute v1.0.6+ enthält Fallback-Validierung via Chat Completions
|
||||
- Stelle sicher, dass die Base URL den `/v1` Suffix enthält
|
||||
|
||||
</details>
|
||||
@@ -902,7 +859,7 @@ Das vorgeladene „OmniRoute Golden Set" enthält 10 Testfälle:
|
||||
## 🛠️ Technologie-Stack
|
||||
|
||||
- **Runtime**: Node.js 20+
|
||||
- **Sprache**: TypeScript 5.9 — **100% TypeScript** in `src/` und `open-sse/` (v1.0.0)
|
||||
- **Sprache**: TypeScript 5.9 — **100% TypeScript** in `src/` und `open-sse/` (v1.0.6)
|
||||
- **Framework**: Next.js 16 + React 19 + Tailwind CSS 4
|
||||
- **Datenbank**: LowDB (JSON) + SQLite (Domain-Status + Proxy-Logs)
|
||||
- **Streaming**: Server-Sent Events (SSE)
|
||||
@@ -932,9 +889,13 @@ Das vorgeladene „OmniRoute Golden Set" enthält 10 Testfälle:
|
||||
|
||||
## 📧 Support
|
||||
|
||||
> 💬 **Treten Sie unserer Community bei!** [WhatsApp-Gruppe](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Hilfe bekommen, Tipps teilen und auf dem Laufenden bleiben.
|
||||
|
||||
- **Website**: [omniroute.online](https://omniroute.online)
|
||||
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
|
||||
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **WhatsApp**: [Community-Gruppe](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
- **WhatsApp**: [Community-Gruppe](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
- **Originalprojekt**: [9router von decolua](https://github.com/decolua/9router)
|
||||
|
||||
---
|
||||
@@ -957,7 +918,7 @@ Siehe [CONTRIBUTING.md](CONTRIBUTING.md) für detaillierte Richtlinien.
|
||||
|
||||
```bash
|
||||
# Release erstellen — npm-Veröffentlichung erfolgt automatisch
|
||||
gh release create v1.0.0 --title "v1.0.0" --generate-notes
|
||||
gh release create v1.0.6 --title "v1.0.6" --generate-notes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+98
-134
@@ -100,10 +100,11 @@ _Conecta cualquier IDE o herramienta CLI con IA a través de OmniRoute — gatew
|
||||
[](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
|
||||
[](https://omniroute.online)
|
||||
[](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
|
||||
[🌐 Website](https://omniroute.online) • [🚀 Inicio Rápido](#-inicio-rápido) • [💡 Características](#-características-principales) • [📖 Docs](#-documentación) • [💰 Precios](#-precios-resumidos)
|
||||
|
||||
🌐 **Disponible en:** [English](README.md) | [Português](README.pt-BR.md) | [Español](README.es.md) | [Русский](README.ru.md) | [中文](README.zh-CN.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | [Italiano](README.it.md)
|
||||
🌐 **Disponible en:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](README.pt-BR.md) | 🇪🇸 [Español](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [Italiano](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [Magyar](README.hu.md) | 🇮🇩 [Bahasa Indonesia](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Nederlands](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Portugal)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Polski](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [Filipino](README.phi.md)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -242,7 +243,35 @@ docker compose --profile cli up -d
|
||||
| Imagen | Tag | Tamaño | Descripción |
|
||||
| ------------------------ | -------- | ------ | ---------------------- |
|
||||
| `diegosouzapw/omniroute` | `latest` | ~250MB | Última versión estable |
|
||||
| `diegosouzapw/omniroute` | `1.0.0` | ~250MB | Versión actual |
|
||||
| `diegosouzapw/omniroute` | `1.0.6` | ~250MB | Versión actual |
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Aplicación de Escritorio — Sin Conexión y Siempre Activo
|
||||
|
||||
> 🆕 **¡NUEVO!** OmniRoute ahora está disponible como **aplicación de escritorio nativa** para Windows, macOS y Linux.
|
||||
|
||||
Ejecuta OmniRoute como una aplicación de escritorio autónoma — sin terminal, sin navegador, sin internet necesario para modelos locales. La app basada en Electron incluye:
|
||||
|
||||
- 🖥️ **Ventana Nativa** — Ventana dedicada con integración en la bandeja del sistema
|
||||
- 🔄 **Inicio Automático** — Inicia OmniRoute al iniciar sesión
|
||||
- 🔔 **Notificaciones Nativas** — Recibe alertas sobre cuota o problemas de proveedores
|
||||
- ⚡ **Instalación con Un Clic** — NSIS (Windows), DMG (macOS), AppImage (Linux)
|
||||
- 🌐 **Modo Sin Conexión** — Funciona completamente offline con servidor incluido
|
||||
|
||||
### Inicio Rápido
|
||||
|
||||
```bash
|
||||
npm run electron:dev # Modo desarrollo
|
||||
npm run electron:build # Plataforma actual
|
||||
npm run electron:build:win # Windows (.exe)
|
||||
npm run electron:build:mac # macOS (.dmg)
|
||||
npm run electron:build:linux # Linux (.AppImage)
|
||||
```
|
||||
|
||||
📖 Documentación completa: [`electron/README.md`](electron/README.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -271,67 +300,6 @@ docker compose --profile cli up -d
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Casos de Uso
|
||||
|
||||
### Caso 1: "Tengo suscripción Claude Pro"
|
||||
|
||||
**Problema:** La cuota expira sin usar, límites de tasa durante programación intensa
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (usar suscripción al máximo)
|
||||
2. glm/glm-4.7 (respaldo barato cuando la cuota se agota)
|
||||
3. if/kimi-k2-thinking (fallback de emergencia gratuito)
|
||||
|
||||
Costo mensual: $20 (suscripción) + ~$5 (respaldo) = $25 total
|
||||
vs. $20 + chocar con límites = frustración
|
||||
```
|
||||
|
||||
### Caso 2: "Quiero costo cero"
|
||||
|
||||
**Problema:** No puede pagar suscripciones, necesita IA confiable para programar
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K gratis/mes)
|
||||
2. if/kimi-k2-thinking (ilimitado gratis)
|
||||
3. qw/qwen3-coder-plus (ilimitado gratis)
|
||||
|
||||
Costo mensual: $0
|
||||
Calidad: Modelos listos para producción
|
||||
```
|
||||
|
||||
### Caso 3: "Necesito programar 24/7, sin interrupciones"
|
||||
|
||||
**Problema:** Plazos ajustados, no puede permitirse tiempo de inactividad
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (mejor calidad)
|
||||
2. cx/gpt-5.2-codex (segunda suscripción)
|
||||
3. glm/glm-4.7 (barato, reset diario)
|
||||
4. minimax/MiniMax-M2.1 (más barato, reset 5h)
|
||||
5. if/kimi-k2-thinking (gratuito ilimitado)
|
||||
|
||||
Resultado: 5 capas de fallback = cero tiempo de inactividad
|
||||
```
|
||||
|
||||
### Caso 4: "Quiero IA GRATUITA en OpenClaw"
|
||||
|
||||
**Problema:** Necesita asistente de IA en apps de mensajería, completamente gratuito
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (ilimitado gratis)
|
||||
2. if/minimax-m2.1 (ilimitado gratis)
|
||||
3. if/kimi-k2-thinking (ilimitado gratis)
|
||||
|
||||
Costo mensual: $0
|
||||
Acceso vía: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 Características Principales
|
||||
|
||||
### 🧠 Enrutamiento e Inteligencia
|
||||
@@ -473,6 +441,67 @@ Traducción transparente entre formatos:
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Casos de Uso
|
||||
|
||||
### Caso 1: "Tengo suscripción Claude Pro"
|
||||
|
||||
**Problema:** La cuota expira sin usar, límites de tasa durante programación intensa
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (usar suscripción al máximo)
|
||||
2. glm/glm-4.7 (respaldo barato cuando la cuota se agota)
|
||||
3. if/kimi-k2-thinking (fallback de emergencia gratuito)
|
||||
|
||||
Costo mensual: $20 (suscripción) + ~$5 (respaldo) = $25 total
|
||||
vs. $20 + chocar con límites = frustración
|
||||
```
|
||||
|
||||
### Caso 2: "Quiero costo cero"
|
||||
|
||||
**Problema:** No puede pagar suscripciones, necesita IA confiable para programar
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K gratis/mes)
|
||||
2. if/kimi-k2-thinking (ilimitado gratis)
|
||||
3. qw/qwen3-coder-plus (ilimitado gratis)
|
||||
|
||||
Costo mensual: $0
|
||||
Calidad: Modelos listos para producción
|
||||
```
|
||||
|
||||
### Caso 3: "Necesito programar 24/7, sin interrupciones"
|
||||
|
||||
**Problema:** Plazos ajustados, no puede permitirse tiempo de inactividad
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (mejor calidad)
|
||||
2. cx/gpt-5.2-codex (segunda suscripción)
|
||||
3. glm/glm-4.7 (barato, reset diario)
|
||||
4. minimax/MiniMax-M2.1 (más barato, reset 5h)
|
||||
5. if/kimi-k2-thinking (gratuito ilimitado)
|
||||
|
||||
Resultado: 5 capas de fallback = cero tiempo de inactividad
|
||||
```
|
||||
|
||||
### Caso 4: "Quiero IA GRATUITA en OpenClaw"
|
||||
|
||||
**Problema:** Necesita asistente de IA en apps de mensajería, completamente gratuito
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (ilimitado gratis)
|
||||
2. if/minimax-m2.1 (ilimitado gratis)
|
||||
3. if/kimi-k2-thinking (ilimitado gratis)
|
||||
|
||||
Costo mensual: $0
|
||||
Acceso vía: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Guía de Configuración
|
||||
|
||||
<details>
|
||||
@@ -753,74 +782,6 @@ Configuración → Configuración de API:
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modelos Disponibles
|
||||
|
||||
<details>
|
||||
<summary><b>Ver todos los modelos disponibles</b></summary>
|
||||
|
||||
**Claude Code (`cc/`)** - Pro/Max:
|
||||
|
||||
- `cc/claude-opus-4-6`
|
||||
- `cc/claude-sonnet-4-5-20250929`
|
||||
- `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**Codex (`cx/`)** - Plus/Pro:
|
||||
|
||||
- `cx/gpt-5.2-codex`
|
||||
- `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** - GRATUITO:
|
||||
|
||||
- `gc/gemini-3-flash-preview`
|
||||
- `gc/gemini-2.5-pro`
|
||||
|
||||
**GitHub Copilot (`gh/`)**:
|
||||
|
||||
- `gh/gpt-5`
|
||||
- `gh/claude-4.5-sonnet`
|
||||
|
||||
**NVIDIA NIM (`nvidia/`)** - Créditos GRATUITOS:
|
||||
|
||||
- `nvidia/llama-3.3-70b-instruct`
|
||||
- `nvidia/mistral-7b-instruct`
|
||||
- 50+ más modelos en [build.nvidia.com](https://build.nvidia.com)
|
||||
|
||||
**GLM (`glm/`)** - $0.6/1M:
|
||||
|
||||
- `glm/glm-4.7`
|
||||
|
||||
**MiniMax (`minimax/`)** - $0.2/1M:
|
||||
|
||||
- `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** - GRATUITO:
|
||||
|
||||
- `if/kimi-k2-thinking`
|
||||
- `if/qwen3-coder-plus`
|
||||
- `if/deepseek-r1`
|
||||
- `if/glm-4.7`
|
||||
- `if/minimax-m2`
|
||||
|
||||
**Qwen (`qw/`)** - GRATUITO:
|
||||
|
||||
- `qw/qwen3-coder-plus`
|
||||
- `qw/qwen3-coder-flash`
|
||||
|
||||
**Kiro (`kr/`)** - GRATUITO:
|
||||
|
||||
- `kr/claude-sonnet-4.5`
|
||||
- `kr/claude-haiku-4.5`
|
||||
|
||||
**OpenRouter (`or/`)** - 100+ modelos:
|
||||
|
||||
- `or/anthropic/claude-4-sonnet`
|
||||
- `or/google/gemini-2.5-pro`
|
||||
- Cualquier modelo de [openrouter.ai/models](https://openrouter.ai/models)
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Evaluaciones (Evals)
|
||||
|
||||
OmniRoute incluye un framework de evaluación integrado para probar la calidad de respuestas de LLM contra un conjunto golden. Accede vía **Analytics → Evals** en el dashboard.
|
||||
@@ -892,7 +853,7 @@ El "OmniRoute Golden Set" precargado contiene 10 casos de prueba que cubren:
|
||||
**Prueba de conexión muestra "Invalid" para proveedores compatibles con OpenAI**
|
||||
|
||||
- Muchos proveedores no exponen el endpoint `/models`
|
||||
- OmniRoute v1.0.0+ incluye validación vía chat completions como fallback
|
||||
- OmniRoute v1.0.6+ incluye validación vía chat completions como fallback
|
||||
- Asegúrate de que la URL base incluya el sufijo `/v1`
|
||||
|
||||
</details>
|
||||
@@ -902,7 +863,7 @@ El "OmniRoute Golden Set" precargado contiene 10 casos de prueba que cubren:
|
||||
## 🛠️ Stack Tecnológico
|
||||
|
||||
- **Runtime**: Node.js 20+
|
||||
- **Lenguaje**: TypeScript 5.9 — **100% TypeScript** en `src/` y `open-sse/` (v1.0.0)
|
||||
- **Lenguaje**: TypeScript 5.9 — **100% TypeScript** en `src/` y `open-sse/` (v1.0.6)
|
||||
- **Framework**: Next.js 16 + React 19 + Tailwind CSS 4
|
||||
- **Base de Datos**: LowDB (JSON) + SQLite (estado del dominio + logs de proxy)
|
||||
- **Streaming**: Server-Sent Events (SSE)
|
||||
@@ -932,9 +893,12 @@ El "OmniRoute Golden Set" precargado contiene 10 casos de prueba que cubren:
|
||||
|
||||
## 📧 Soporte
|
||||
|
||||
> 💬 **¡Únete a la comunidad!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Obtén ayuda, comparte consejos y mantente al día.
|
||||
|
||||
- **Website**: [omniroute.online](https://omniroute.online)
|
||||
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
|
||||
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **WhatsApp**: [Grupo de la Comunidad](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
- **Proyecto Original**: [9router por decolua](https://github.com/decolua/9router)
|
||||
|
||||
---
|
||||
@@ -957,7 +921,7 @@ Consulta [CONTRIBUTING.md](CONTRIBUTING.md) para directrices detalladas.
|
||||
|
||||
```bash
|
||||
# Crea un release — la publicación en npm ocurre automáticamente
|
||||
gh release create v1.0.0 --title "v1.0.0" --generate-notes
|
||||
gh release create v1.0.6 --title "v1.0.6" --generate-notes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+1111
File diff suppressed because it is too large
Load Diff
+96
-134
@@ -100,10 +100,11 @@ _Connectez n'importe quel IDE ou outil CLI alimenté par l'IA via OmniRoute —
|
||||
[](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
|
||||
[](https://omniroute.online)
|
||||
[](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
|
||||
[🌐 Site web](https://omniroute.online) • [🚀 Démarrage rapide](#-démarrage-rapide) • [💡 Fonctionnalités](#-fonctionnalités-principales) • [📖 Docs](#-documentation) • [💰 Tarifs](#-aperçu-des-tarifs)
|
||||
|
||||
🌐 **Disponible en :** [English](README.md) | [Português](README.pt-BR.md) | [Español](README.es.md) | [Русский](README.ru.md) | [中文](README.zh-CN.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | [Italiano](README.it.md)
|
||||
🌐 **Disponible en :** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](README.pt-BR.md) | 🇪🇸 [Español](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [Italiano](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [Magyar](README.hu.md) | 🇮🇩 [Bahasa Indonesia](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Nederlands](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Portugal)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Polski](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [Filipino](README.phi.md)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -242,7 +243,33 @@ docker compose --profile cli up -d
|
||||
| Image | Tag | Taille | Description |
|
||||
| ------------------------ | -------- | ------ | ----------------------- |
|
||||
| `diegosouzapw/omniroute` | `latest` | ~250MB | Dernière version stable |
|
||||
| `diegosouzapw/omniroute` | `1.0.0` | ~250MB | Version actuelle |
|
||||
| `diegosouzapw/omniroute` | `1.0.6` | ~250MB | Version actuelle |
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Application Bureau — Hors Ligne et Toujours Actif
|
||||
|
||||
> 🆕 **NOUVEAU !** OmniRoute est maintenant disponible en tant qu'**application de bureau native** pour Windows, macOS et Linux.
|
||||
|
||||
Exécutez OmniRoute en tant qu'application de bureau autonome — sans terminal, sans navigateur, sans internet requis pour les modèles locaux.
|
||||
|
||||
- 🖥️ **Fenêtre Native** — Fenêtre dédiée avec intégration dans la barre d'état système
|
||||
- 🔄 **Démarrage Automatique** — Lancez OmniRoute à la connexion système
|
||||
- 🔔 **Notifications Natives** — Alertes pour l'épuisement de quota ou les problèmes
|
||||
- ⚡ **Installation en Un Clic** — NSIS (Windows), DMG (macOS), AppImage (Linux)
|
||||
- 🌐 **Mode Hors Ligne** — Fonctionne entièrement hors ligne avec serveur intégré
|
||||
|
||||
```bash
|
||||
npm run electron:dev # Mode développement
|
||||
npm run electron:build # Plateforme actuelle
|
||||
npm run electron:build:win # Windows (.exe)
|
||||
npm run electron:build:mac # macOS (.dmg)
|
||||
npm run electron:build:linux # Linux (.AppImage)
|
||||
```
|
||||
|
||||
📖 Documentation complète : [`electron/README.md`](electron/README.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -271,67 +298,6 @@ docker compose --profile cli up -d
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Cas d'utilisation
|
||||
|
||||
### Cas 1 : « J'ai un abonnement Claude Pro »
|
||||
|
||||
**Problème :** Le quota expire inutilisé, limites de débit pendant le codage intensif
|
||||
|
||||
```
|
||||
Combo : "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (utiliser l'abonnement au maximum)
|
||||
2. glm/glm-4.7 (backup économique quand le quota est épuisé)
|
||||
3. if/kimi-k2-thinking (fallback d'urgence gratuit)
|
||||
|
||||
Coût mensuel : 20 $ (abonnement) + ~5 $ (backup) = 25 $ au total
|
||||
vs. 20 $ + atteindre les limites = frustration
|
||||
```
|
||||
|
||||
### Cas 2 : « Je veux zéro coût »
|
||||
|
||||
**Problème :** Impossible de payer des abonnements, besoin d'IA fiable pour coder
|
||||
|
||||
```
|
||||
Combo : "free-forever"
|
||||
1. gc/gemini-3-flash (180K gratuits/mois)
|
||||
2. if/kimi-k2-thinking (illimité gratuit)
|
||||
3. qw/qwen3-coder-plus (illimité gratuit)
|
||||
|
||||
Coût mensuel : 0 $
|
||||
Qualité : Modèles prêts pour la production
|
||||
```
|
||||
|
||||
### Cas 3 : « Je dois coder 24/7, sans interruption »
|
||||
|
||||
**Problème :** Délais serrés, ne peut pas se permettre de temps d'arrêt
|
||||
|
||||
```
|
||||
Combo : "always-on"
|
||||
1. cc/claude-opus-4-6 (meilleure qualité)
|
||||
2. cx/gpt-5.2-codex (deuxième abonnement)
|
||||
3. glm/glm-4.7 (économique, reset quotidien)
|
||||
4. minimax/MiniMax-M2.1 (le moins cher, reset 5h)
|
||||
5. if/kimi-k2-thinking (gratuit illimité)
|
||||
|
||||
Résultat : 5 niveaux de fallback = zéro temps d'arrêt
|
||||
```
|
||||
|
||||
### Cas 4 : « Je veux l'IA GRATUITE dans OpenClaw »
|
||||
|
||||
**Problème :** Besoin d'assistant IA dans les apps de messagerie, entièrement gratuit
|
||||
|
||||
```
|
||||
Combo : "openclaw-free"
|
||||
1. if/glm-4.7 (illimité gratuit)
|
||||
2. if/minimax-m2.1 (illimité gratuit)
|
||||
3. if/kimi-k2-thinking (illimité gratuit)
|
||||
|
||||
Coût mensuel : 0 $
|
||||
Accès via : WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 Fonctionnalités principales
|
||||
|
||||
### 🧠 Routage & Intelligence
|
||||
@@ -473,6 +439,67 @@ Traduction transparente entre les formats :
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Cas d'utilisation
|
||||
|
||||
### Cas 1 : « J'ai un abonnement Claude Pro »
|
||||
|
||||
**Problème :** Le quota expire inutilisé, limites de débit pendant le codage intensif
|
||||
|
||||
```
|
||||
Combo : "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (utiliser l'abonnement au maximum)
|
||||
2. glm/glm-4.7 (backup économique quand le quota est épuisé)
|
||||
3. if/kimi-k2-thinking (fallback d'urgence gratuit)
|
||||
|
||||
Coût mensuel : 20 $ (abonnement) + ~5 $ (backup) = 25 $ au total
|
||||
vs. 20 $ + atteindre les limites = frustration
|
||||
```
|
||||
|
||||
### Cas 2 : « Je veux zéro coût »
|
||||
|
||||
**Problème :** Impossible de payer des abonnements, besoin d'IA fiable pour coder
|
||||
|
||||
```
|
||||
Combo : "free-forever"
|
||||
1. gc/gemini-3-flash (180K gratuits/mois)
|
||||
2. if/kimi-k2-thinking (illimité gratuit)
|
||||
3. qw/qwen3-coder-plus (illimité gratuit)
|
||||
|
||||
Coût mensuel : 0 $
|
||||
Qualité : Modèles prêts pour la production
|
||||
```
|
||||
|
||||
### Cas 3 : « Je dois coder 24/7, sans interruption »
|
||||
|
||||
**Problème :** Délais serrés, ne peut pas se permettre de temps d'arrêt
|
||||
|
||||
```
|
||||
Combo : "always-on"
|
||||
1. cc/claude-opus-4-6 (meilleure qualité)
|
||||
2. cx/gpt-5.2-codex (deuxième abonnement)
|
||||
3. glm/glm-4.7 (économique, reset quotidien)
|
||||
4. minimax/MiniMax-M2.1 (le moins cher, reset 5h)
|
||||
5. if/kimi-k2-thinking (gratuit illimité)
|
||||
|
||||
Résultat : 5 niveaux de fallback = zéro temps d'arrêt
|
||||
```
|
||||
|
||||
### Cas 4 : « Je veux l'IA GRATUITE dans OpenClaw »
|
||||
|
||||
**Problème :** Besoin d'assistant IA dans les apps de messagerie, entièrement gratuit
|
||||
|
||||
```
|
||||
Combo : "openclaw-free"
|
||||
1. if/glm-4.7 (illimité gratuit)
|
||||
2. if/minimax-m2.1 (illimité gratuit)
|
||||
3. if/kimi-k2-thinking (illimité gratuit)
|
||||
|
||||
Coût mensuel : 0 $
|
||||
Accès via : WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Guide de configuration
|
||||
|
||||
<details>
|
||||
@@ -753,74 +780,6 @@ Paramètres → Configuration API :
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modèles disponibles
|
||||
|
||||
<details>
|
||||
<summary><b>Voir tous les modèles disponibles</b></summary>
|
||||
|
||||
**Claude Code (`cc/`)** - Pro/Max :
|
||||
|
||||
- `cc/claude-opus-4-6`
|
||||
- `cc/claude-sonnet-4-5-20250929`
|
||||
- `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**Codex (`cx/`)** - Plus/Pro :
|
||||
|
||||
- `cx/gpt-5.2-codex`
|
||||
- `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** - GRATUIT :
|
||||
|
||||
- `gc/gemini-3-flash-preview`
|
||||
- `gc/gemini-2.5-pro`
|
||||
|
||||
**GitHub Copilot (`gh/`)** :
|
||||
|
||||
- `gh/gpt-5`
|
||||
- `gh/claude-4.5-sonnet`
|
||||
|
||||
**NVIDIA NIM (`nvidia/`)** - Crédits GRATUITS :
|
||||
|
||||
- `nvidia/llama-3.3-70b-instruct`
|
||||
- `nvidia/mistral-7b-instruct`
|
||||
- 50+ modèles sur [build.nvidia.com](https://build.nvidia.com)
|
||||
|
||||
**GLM (`glm/`)** - $0.6/1M :
|
||||
|
||||
- `glm/glm-4.7`
|
||||
|
||||
**MiniMax (`minimax/`)** - $0.2/1M :
|
||||
|
||||
- `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** - GRATUIT :
|
||||
|
||||
- `if/kimi-k2-thinking`
|
||||
- `if/qwen3-coder-plus`
|
||||
- `if/deepseek-r1`
|
||||
- `if/glm-4.7`
|
||||
- `if/minimax-m2`
|
||||
|
||||
**Qwen (`qw/`)** - GRATUIT :
|
||||
|
||||
- `qw/qwen3-coder-plus`
|
||||
- `qw/qwen3-coder-flash`
|
||||
|
||||
**Kiro (`kr/`)** - GRATUIT :
|
||||
|
||||
- `kr/claude-sonnet-4.5`
|
||||
- `kr/claude-haiku-4.5`
|
||||
|
||||
**OpenRouter (`or/`)** - 100+ modèles :
|
||||
|
||||
- `or/anthropic/claude-4-sonnet`
|
||||
- `or/google/gemini-2.5-pro`
|
||||
- Tout modèle de [openrouter.ai/models](https://openrouter.ai/models)
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Évaluations (Evals)
|
||||
|
||||
OmniRoute inclut un framework d'évaluation intégré pour tester la qualité des réponses LLM contre un golden set. Accès via **Analytics → Evals** dans le tableau de bord.
|
||||
@@ -892,7 +851,7 @@ Le « OmniRoute Golden Set » préchargé contient 10 cas de test :
|
||||
**Le test de connexion affiche « Invalid » pour les fournisseurs compatibles OpenAI**
|
||||
|
||||
- Beaucoup de fournisseurs n'exposent pas le point de terminaison `/models`
|
||||
- OmniRoute v1.0.0+ inclut une validation de secours via chat completions
|
||||
- OmniRoute v1.0.6+ inclut une validation de secours via chat completions
|
||||
- Assurez-vous que l'URL de base inclut le suffixe `/v1`
|
||||
|
||||
</details>
|
||||
@@ -902,7 +861,7 @@ Le « OmniRoute Golden Set » préchargé contient 10 cas de test :
|
||||
## 🛠️ Stack technologique
|
||||
|
||||
- **Runtime** : Node.js 20+
|
||||
- **Langage** : TypeScript 5.9 — **100% TypeScript** dans `src/` et `open-sse/` (v1.0.0)
|
||||
- **Langage** : TypeScript 5.9 — **100% TypeScript** dans `src/` et `open-sse/` (v1.0.6)
|
||||
- **Framework** : Next.js 16 + React 19 + Tailwind CSS 4
|
||||
- **Base de données** : LowDB (JSON) + SQLite (état du domaine + logs proxy)
|
||||
- **Streaming** : Server-Sent Events (SSE)
|
||||
@@ -932,9 +891,12 @@ Le « OmniRoute Golden Set » préchargé contient 10 cas de test :
|
||||
|
||||
## 📧 Support
|
||||
|
||||
> 💬 **Rejoignez notre communauté !** [Groupe WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Obtenez de l'aide, partagez des astuces et restez informé.
|
||||
|
||||
- **Site web** : [omniroute.online](https://omniroute.online)
|
||||
- **GitHub** : [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
|
||||
- **Issues** : [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **WhatsApp** : [Groupe communautaire](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
- **Projet original** : [9router par decolua](https://github.com/decolua/9router)
|
||||
|
||||
---
|
||||
@@ -957,7 +919,7 @@ Consultez [CONTRIBUTING.md](CONTRIBUTING.md) pour les directives détaillées.
|
||||
|
||||
```bash
|
||||
# Créer un release — la publication npm est automatique
|
||||
gh release create v1.0.0 --title "v1.0.0" --generate-notes
|
||||
gh release create v1.0.6 --title "v1.0.6" --generate-notes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+1111
File diff suppressed because it is too large
Load Diff
+1111
File diff suppressed because it is too large
Load Diff
+1111
File diff suppressed because it is too large
Load Diff
+887
@@ -0,0 +1,887 @@
|
||||
<div align="center">
|
||||
|
||||
|
||||
# 🚀 ओम्निरूट - निःशुल्क एआई गेटवे
|
||||
|
||||
🌐 **[English](#-omniroute--the-free-ai-gateway)** | \***\*ओएमएनआई_टोकन_159\*\***
|
||||
|
||||
### कोडिंग कभी बंद न करें। स्वचालित फ़ॉलबैक के साथ **मुफ़्त और कम लागत वाले AI मॉडल** के लिए स्मार्ट रूटिंग।
|
||||
|
||||
_आपका सार्वभौमिक एपीआई प्रॉक्सी - एक समापन बिंदु, 36+ प्रदाता, शून्य डाउनटाइम।_
|
||||
|
||||
**चैट समापन • एंबेडिंग • छवि निर्माण • ऑडियो • पुनर्रैंकिंग • 100% टाइपस्क्रिप्ट**
|
||||
|
||||
---
|
||||
|
||||
### 🤖 आपके पसंदीदा कोडिंग एजेंटों के लिए निःशुल्क एआई प्रदाता
|
||||
|
||||
_OmniRoute के माध्यम से किसी भी AI-संचालित IDE या CLI टूल को कनेक्ट करें - असीमित कोडिंग के लिए निःशुल्क API गेटवे।_
|
||||
|
||||
<sub>📡 सभी एजेंट <code>http://localhost:20128/v1</code> या <code>http://cloud.omniroute.online/v1</code> के माध्यम से जुड़ते हैं - एक कॉन्फ़िगरेशन, असीमित मॉडल और कोटा</sub>
|
||||
|
||||
---
|
||||
|
||||
[](https://www.npmjs.com/package/omniroute)
|
||||
[](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
|
||||
[](https://omniroute.online)
|
||||
[](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
|
||||
[🌐 Website](https://omniroute.online) • [🚀 Quick Start](#-quick-start) • [💡 Features](#-key-features) • [📖 Docs](#-documentation) • [💰 Pricing](#-pricing-at-a-glance) • [💬 WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
|
||||
🌐 **Available in:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](README.pt-BR.md) | 🇪🇸 [Español](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [Italiano](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [Magyar](README.hu.md) | 🇮🇩 [Bahasa Indonesia](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Nederlands](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Portugal)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Polski](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [Filipino](README.phi.md)
|
||||
|
||||
---
|
||||
|
||||
## 🤔ओम्नीरूट क्यों?
|
||||
|
||||
**पैसा बर्बाद करना और सीमा पार करना बंद करें:**
|
||||
|
||||
- <img src="https://img.shields.io/badge/✗-e74c3c?style=flat-square" height="16"/> सदस्यता कोटा हर महीने अप्रयुक्त रूप से समाप्त हो जाता है
|
||||
- <img src="https://img.shields.io/badge/✗-e74c3c?style=flat-square" height="16"/> दर सीमा आपको कोडिंग के बीच में रोक देती है
|
||||
- <img src="https://img.shields.io/badge/✗-e74c3c?style=flat-square" height="16"/> महँगे API ($20-50/माह प्रति प्रदाता)
|
||||
- <img src="https://img.shields.io/badge/✗-e74c3c?style=flat-square" height="16"/> प्रदाताओं के बीच मैन्युअल स्विचिंग
|
||||
|
||||
**OmniRoute इसका समाधान करता है:**
|
||||
|
||||
- ✅ **सब्सक्रिप्शन अधिकतम करें** - कोटा ट्रैक करें, रीसेट से पहले हर बिट का उपयोग करें
|
||||
- ✅ **ऑटो फ़ॉलबैक** - सदस्यता → एपीआई कुंजी → सस्ता → निःशुल्क, शून्य डाउनटाइम
|
||||
- ✅ **मल्टी-अकाउंट** - प्रति प्रदाता खातों के बीच राउंड-रॉबिन
|
||||
- ✅ **यूनिवर्सल** - क्लाउड कोड, कोडेक्स, जेमिनी सीएलआई, कर्सर, क्लाइन, ओपनक्लॉ, किसी भी सीएलआई टूल के साथ काम करता है
|
||||
|
||||
---
|
||||
|
||||
## 🔄 यह कैसे काम करता है
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
│ Your CLI │ (Claude Code, Codex, Gemini CLI, OpenClaw, Cursor, Cline...)
|
||||
│ Tool │
|
||||
└──────┬──────┘
|
||||
│ http://localhost:20128/v1
|
||||
↓
|
||||
┌─────────────────────────────────────────┐
|
||||
│ OmniRoute (Smart Router) │
|
||||
│ • Format translation (OpenAI ↔ Claude) │
|
||||
│ • Quota tracking + Embeddings + Images │
|
||||
│ • Auto token refresh │
|
||||
└──────┬──────────────────────────────────┘
|
||||
│
|
||||
├─→ [Tier 1: SUBSCRIPTION] Claude Code, Codex, Gemini CLI
|
||||
│ ↓ quota exhausted
|
||||
├─→ [Tier 2: API KEY] DeepSeek, Groq, xAI, Mistral, NVIDIA NIM, etc.
|
||||
│ ↓ budget limit
|
||||
├─→ [Tier 3: CHEAP] GLM ($0.6/1M), MiniMax ($0.2/1M)
|
||||
│ ↓ budget limit
|
||||
└─→ [Tier 4: FREE] iFlow, Qwen, Kiro (unlimited)
|
||||
|
||||
Result: Never stop coding, minimal cost
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚡ त्वरित शुरुआत
|
||||
|
||||
**1. विश्व स्तर पर स्थापित करें:**
|
||||
|
||||
🎉 डैशबोर्ड `http://localhost:20128` पर खुलता है
|
||||
|
||||
| आदेश | विवरण |
|
||||
| ----------------------- | ----------------------------------------- |
|
||||
| `omniroute` | सर्वर प्रारंभ करें (डिफ़ॉल्ट पोर्ट 20128) |
|
||||
| `omniroute --port 3000` | कस्टम पोर्ट का उपयोग करें |
|
||||
| `omniroute --no-open` | ब्राउज़र को स्वतः न खोलें |
|
||||
| `omniroute --help` | सहायता दिखाएँ |
|
||||
|
||||
**2. एक मुफ़्त प्रदाता से जुड़ें:**
|
||||
|
||||
डैशबोर्ड → प्रदाता → कनेक्ट **क्लाउड कोड** या **एंटीग्रेविटी** → OAuth लॉगिन → हो गया!
|
||||
|
||||
**3. अपने सीएलआई टूल में उपयोग करें:**
|
||||
|
||||
```
|
||||
Claude Code/Codex/Gemini CLI/OpenClaw/Cursor/Cline Settings:
|
||||
Endpoint: http://localhost:20128/v1
|
||||
API Key: [copy from dashboard]
|
||||
Model: if/kimi-k2-thinking
|
||||
```
|
||||
|
||||
**बस!** मुफ़्त AI मॉडल के साथ कोडिंग शुरू करें।
|
||||
|
||||
**वैकल्पिक - स्रोत से चलाएँ:**
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
npm install
|
||||
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐳 डॉकर
|
||||
|
||||
ओमनीरूट [Docker Hub](https://hub.docker.com/r/diegosouzapw/omniroute) पर सार्वजनिक डॉकर छवि के रूप में उपलब्ध है।
|
||||
|
||||
**त्वरित दौड़:**
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name omniroute \
|
||||
--restart unless-stopped \
|
||||
-p 20128:20128 \
|
||||
-v omniroute-data:/app/data \
|
||||
diegosouzapw/omniroute:latest
|
||||
```
|
||||
|
||||
**पर्यावरण फ़ाइल के साथ:**
|
||||
|
||||
**डॉकर कंपोज़ का उपयोग करना:**
|
||||
|
||||
| छवि | टैग | आकार | विवरण |
|
||||
| ------------------------ | -------- | -------- | ------------------- |
|
||||
| `diegosouzapw/omniroute` | `latest` | ~250एमबी | नवीनतम स्थिर रिलीज़ |
|
||||
| `diegosouzapw/omniroute` | `1.0.3` | ~250एमबी | वर्तमान संस्करण |
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Desktop App — Offline & Always-On
|
||||
|
||||
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
|
||||
|
||||
- 🖥️ **Native Window** — Dedicated app window with system tray integration
|
||||
- 🔄 **Auto-Start** — Launch OmniRoute on system login
|
||||
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
|
||||
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
|
||||
- 🌐 **Offline Mode** — Works fully offline with bundled server
|
||||
|
||||
```bash
|
||||
npm run electron:dev # Development mode
|
||||
npm run electron:build # Current platform
|
||||
npm run electron:build:win # Windows (.exe)
|
||||
npm run electron:build:mac # macOS (.dmg)
|
||||
npm run electron:build:linux # Linux (.AppImage)
|
||||
```
|
||||
|
||||
📖 Full documentation: [`electron/README.md`](electron/README.md)
|
||||
|
||||
---
|
||||
|
||||
## 💰 मूल्य निर्धारण एक नज़र में
|
||||
|
||||
| टियर | प्रदाता | लागत | कोटा रीसेट | के लिए सर्वश्रेष्ठ |
|
||||
| ----------------- | ------------------- | ------------------------- | -------------------- | ------------------------ |
|
||||
| **💳 सदस्यता** | क्लाउड कोड (प्रो) | $20/माह | 5 घंटे + साप्ताहिक | पहले ही सदस्यता ले ली है |
|
||||
| | कोडेक्स (प्लस/प्रो) | $20-200/महीना | 5 घंटे + साप्ताहिक | OpenAI उपयोगकर्ता |
|
||||
| | जेमिनी सीएलआई | **मुफ़्त** | 180K/माह + 1K/दिन | सब लोग! |
|
||||
| | गिटहब कोपायलट | $10-19/माह | मासिक | GitHub उपयोगकर्ता |
|
||||
| **🔑एपीआई कुंजी** | एनवीडिया एनआईएम | **मुफ़्त** (1000 क्रेडिट) | एक बार | निःशुल्क स्तरीय परीक्षण |
|
||||
| | डीपसीक | भुगतान-प्रति-उपयोग | कोई नहीं | सर्वोत्तम मूल्य/गुणवत्ता |
|
||||
| | ग्रोक | फ्री टियर + पेड | दर सीमित | अल्ट्रा-फास्ट अनुमान |
|
||||
| | एक्सएआई (ग्रोक) | भुगतान-प्रति-उपयोग | कोई नहीं | ग्रोक मॉडल |
|
||||
| | मिस्ट्रल | फ्री टियर + पेड | दर सीमित | यूरोपीय एआई |
|
||||
| | ओपनराउटर | भुगतान-प्रति-उपयोग | कोई नहीं | 100+ मॉडल |
|
||||
| **💰सस्ता** | जीएलएम-4.7 | $0.6/1 मिलियन | प्रतिदिन सुबह 10 बजे | बजट बैकअप |
|
||||
| | मिनीमैक्स एम2.1 | $0.2/1 मिलियन | 5 घंटे की रोलिंग | सबसे सस्ता विकल्प |
|
||||
| | किमी K2 | $9/महीना फ्लैट | 10एम टोकन/माह | अनुमानित लागत |
|
||||
| **🆓 मुफ़्त** | आईफ्लो | $0 | असीमित | 8 मॉडल निःशुल्क |
|
||||
| | क्वेन | $0 | असीमित | 3 मॉडल मुफ़्त |
|
||||
| | किरो | $0 | असीमित | क्लाउड मुक्त |
|
||||
|
||||
**💡 प्रो टिप:** जेमिनी सीएलआई (180 हजार निःशुल्क/माह) + आईफ्लो (असीमित निःशुल्क) कॉम्बो = $0 लागत से शुरू करें!
|
||||
|
||||
---
|
||||
|
||||
## 💡 मुख्य विशेषताएं
|
||||
|
||||
### 🧠 कोर रूटिंग और इंटेलिजेंस
|
||||
|
||||
| फ़ीचर | यह क्या करता है |
|
||||
| --------------------------------- | ------------------------------------------------------------------------------------ |
|
||||
| 🎯 **स्मार्ट 4-टियर फ़ॉलबैक** | ऑटो-रूट: सदस्यता → एपीआई कुंजी → सस्ता → मुफ़्त |
|
||||
| 📊 **वास्तविक समय कोटा ट्रैकिंग** | लाइव टोकन गिनती + प्रति प्रदाता रीसेट उलटी गिनती |
|
||||
| 🔄 **प्रारूप अनुवाद** | OpenAI ↔ क्लाउड ↔ जेमिनी ↔ कर्सर ↔ किरो सीमलेस + रिस्पॉन्स सैनिटाइजेशन |
|
||||
| 👥 **मल्टी-अकाउंट सपोर्ट** | बुद्धिमान चयन के साथ प्रति प्रदाता एकाधिक खाते |
|
||||
| 🔄 **ऑटो टोकन रिफ्रेश** | OAuth टोकन पुनः प्रयास के साथ स्वचालित रूप से ताज़ा हो जाते हैं |
|
||||
| 🎨 **कस्टम कॉम्बो** | 6 रणनीतियाँ: पहले भरें, राउंड-रॉबिन, पी2सी, यादृच्छिक, कम से कम उपयोग, लागत-अनुकूलित |
|
||||
| 🧩 **कस्टम मॉडल** | किसी भी प्रदाता से कोई भी मॉडल आईडी जोड़ें |
|
||||
| 🌐 **वाइल्डकार्ड राउटर** | `provider/*` पैटर्न को गतिशील रूप से किसी भी प्रदाता तक रूट करें |
|
||||
| 🧠 **सोच बजट** | तर्क मॉडल के लिए पासथ्रू, ऑटो, कस्टम और अनुकूली मोड |
|
||||
| 💬 **सिस्टम प्रॉम्प्ट इंजेक्शन** | ग्लोबल सिस्टम प्रॉम्प्ट सभी अनुरोधों पर लागू किया गया |
|
||||
| 📄 **प्रतिक्रियाएं एपीआई** | कोडेक्स के लिए पूर्ण ओपनएआई रिस्पॉन्स एपीआई (`/v1/responses`) समर्थन |
|
||||
|
||||
### 🎵 मल्टी-मॉडल एपीआई
|
||||
|
||||
| फ़ीचर | यह क्या करता है |
|
||||
| ---------------------------- | ------------------------------------------------- |
|
||||
| 🖼️ **छवि निर्माण** | `/v1/images/generations` - 4 प्रदाता, 9+ मॉडल |
|
||||
| 📐 **एंबेडिंग** | `/v1/embeddings` — 6 प्रदाता, 9+ मॉडल |
|
||||
| 🎤 **ऑडियो ट्रांस्क्रिप्शन** | `/v1/audio/transcriptions` - कानाफूसी-संगत |
|
||||
| 🔊 **टेक्स्ट-टू-स्पीच** | `/v1/audio/speech` - बहु-प्रदाता ऑडियो संश्लेषण |
|
||||
| 🛡️ **संयम** | `/v1/moderations` — सामग्री सुरक्षा जांच |
|
||||
| 🔀 **पुनर्रैंकिंग** | `/v1/rerank` — दस्तावेज़ प्रासंगिकता पुनर्रैंकिंग |
|
||||
|
||||
### 🛡️ लचीलापन और सुरक्षा
|
||||
|
||||
| फ़ीचर | यह क्या करता है |
|
||||
| ------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| 🔌 **सर्किट ब्रेकर** | कॉन्फ़िगर करने योग्य थ्रेशोल्ड के साथ प्रति-प्रदाता स्वतः खोलें/बंद करें |
|
||||
| 🛡️ **एंटी-थंडरिंग झुंड** | एपीआई कुंजी प्रदाताओं के लिए म्यूटेक्स + सेमाफोर दर-सीमा |
|
||||
| 🧠 **सिमेंटिक कैश** | दो-स्तरीय कैश (हस्ताक्षर + सिमेंटिक) लागत और विलंबता को कम करता है |
|
||||
| ⚡ **निष्क्रियता का अनुरोध** | डुप्लिकेट अनुरोधों के लिए 5s डिडअप विंडो |
|
||||
| 🔒 **टीएलएस फ़िंगरप्रिंट स्पूफ़िंग** | Wreq-js के माध्यम से टीएलएस-आधारित बॉट डिटेक्शन को बायपास करें |
|
||||
| 🌐 **आईपी फ़िल्टरिंग** | एपीआई अभिगम नियंत्रण के लिए अनुमति सूची/अवरुद्ध सूची |
|
||||
| 📊 **संपादन योग्य दर सीमाएँ** | सिस्टम स्तर पर कॉन्फ़िगर करने योग्य आरपीएम, न्यूनतम अंतर और अधिकतम समवर्ती |
|
||||
| 🛡 **एपीआई एंडपॉइंट सुरक्षा** | `/models` समापन बिंदु के लिए ऑथेंटिक गेटिंग + प्रदाता अवरोधन |
|
||||
| 🔒 **प्रॉक्सी दृश्यता** | रंग-कोडित बैज: 🟢 वैश्विक, 🟡 प्रदाता, 🔵 आईपी डिस्प्ले के साथ प्रति-कनेक्शन |
|
||||
| 🌐 **3-स्तरीय प्रॉक्सी कॉन्फ़िगरेशन** | वैश्विक, प्रति-प्रदाता, या प्रति-कनेक्शन स्तर पर प्रॉक्सी कॉन्फ़िगर करें |
|
||||
|
||||
### 📊 अवलोकनशीलता और विश्लेषण
|
||||
|
||||
| फ़ीचर | यह क्या करता है |
|
||||
| ------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| 📝 **लॉगिंग का अनुरोध** | पूर्ण अनुरोध/प्रतिक्रिया लॉग के साथ डिबग मोड |
|
||||
| 💾 **SQLite प्रॉक्सी लॉग्स** | लगातार प्रॉक्सी लॉग सर्वर पुनरारंभ होने से बचे रहते हैं |
|
||||
| 📊 **एनालिटिक्स डैशबोर्ड** | रिचार्ज-संचालित: स्टेट कार्ड, मॉडल उपयोग चार्ट, प्रदाता तालिका |
|
||||
| 📈 **प्रगति ट्रैकिंग** | स्ट्रीमिंग के लिए ऑप्ट-इन एसएसई प्रगति कार्यक्रम |
|
||||
| 🧪 **एलएलएम मूल्यांकन** | 4 मैच रणनीतियों के साथ गोल्डन सेट परीक्षण |
|
||||
| 🔍 **टेलीमेट्री के लिए अनुरोध** | p50/p95/p99 विलंबता एकत्रीकरण + एक्स-अनुरोध-आईडी ट्रेसिंग |
|
||||
| 📋 **लॉग्स डैशबोर्ड** | एकीकृत 4-टैब पृष्ठ: अनुरोध लॉग, प्रॉक्सी लॉग, ऑडिट लॉग, कंसोल |
|
||||
| 🖥️ **कंसोल लॉग व्यूअर** | लेवल फ़िल्टर, खोज, ऑटो-स्क्रॉल के साथ रीयल-टाइम टर्मिनल-शैली व्यूअर |
|
||||
| 📑 **फ़ाइल-आधारित लॉगिंग** | कंसोल इंटरसेप्टर रोटेशन के साथ सभी आउटपुट को JSON लॉग फ़ाइल में कैप्चर करता है |
|
||||
| 🏥 **स्वास्थ्य डैशबोर्ड** | सिस्टम अपटाइम, सर्किट ब्रेकर स्थिति, लॉकआउट, कैश आँकड़े |
|
||||
| 💰 **लागत ट्रैकिंग** | बजट प्रबंधन + प्रति-मॉडल मूल्य निर्धारण विन्यास |
|
||||
|
||||
### ☁️ परिनियोजन और सिंक
|
||||
|
||||
| फ़ीचर | यह क्या करता है |
|
||||
| ---------------------------- | ---------------------------------------------------------------------------- | ----------------------------- |
|
||||
| 💾 **क्लाउड सिंक** | क्लाउडफ्लेयर वर्कर्स के माध्यम से सभी डिवाइसों में कॉन्फिगरेशन सिंक करें |
|
||||
| 🌐 **कहीं भी तैनात करें** | लोकलहोस्ट, वीपीएस, डॉकर, क्लाउडफ्लेयर वर्कर्स |
|
||||
| 🔑 **एपीआई कुंजी प्रबंधन** | प्रति प्रदाता एपीआई कुंजियाँ उत्पन्न करें, घुमाएँ और स्कोप करें |
|
||||
| 🧙 **ऑनबोर्डिंग विज़ार्ड** | पहली बार उपयोगकर्ताओं के लिए 4-चरणीय निर्देशित सेटअप |
|
||||
| 🔧 **सीएलआई टूल्स डैशबोर्ड** | क्लाउड, कोडेक्स, क्लाइन, ओपनक्लॉ, किलो, एंटीग्रेविटी | को एक-क्लिक से कॉन्फ़िगर करें |
|
||||
| 🔄 **डीबी बैकअप** | सभी सेटिंग्स के लिए स्वचालित बैकअप, पुनर्स्थापना, निर्यात और आयात |
|
||||
| 🌐 **अंतर्राष्ट्रीयकरण** | नेक्स्ट-इंटल के साथ पूर्ण i18n - अंग्रेजी + पुर्तगाली (ब्राजील) समर्थन |
|
||||
| 🌍 **भाषा चयनकर्ता** | रीयल-टाइम भाषा स्विचिंग के लिए हेडर में ग्लोब आइकन (🇺🇸/🇧🇷) |
|
||||
| 📂 **कस्टम डेटा निर्देशिका** | `DATA_DIR` env var डिफ़ॉल्ट `~/.omniroute` संग्रहण पथ को ओवरराइड करने के लिए |
|
||||
|
||||
<summary><b>📖 सुविधा विवरण</b></summary>
|
||||
|
||||
### 🎯 स्मार्ट 4-टियर फ़ॉलबैक
|
||||
|
||||
स्वचालित फ़ॉलबैक के साथ कॉम्बो बनाएं:
|
||||
|
||||
### 📊 रीयल-टाइम कोटा ट्रैकिंग
|
||||
|
||||
- प्रति प्रदाता टोकन खपत
|
||||
- उलटी गिनती रीसेट करें (5 घंटे, दैनिक, साप्ताहिक)
|
||||
- भुगतान किए गए स्तरों के लिए लागत अनुमान
|
||||
- मासिक खर्च रिपोर्ट
|
||||
|
||||
### 🔄 प्रारूप अनुवाद
|
||||
|
||||
प्रारूपों के बीच निर्बाध अनुवाद:
|
||||
|
||||
- **ओपनएआई** ↔ **क्लाउड** ↔ **मिथुन** ↔ **ओपनएआई प्रतिक्रियाएं**
|
||||
- आपका सीएलआई उपकरण ओपनएआई प्रारूप भेजता है → ओमनीरूट अनुवाद करता है → प्रदाता मूल प्रारूप प्राप्त करता है
|
||||
- कस्टम ओपनएआई एंडपॉइंट्स का समर्थन करने वाले किसी भी टूल के साथ काम करता है
|
||||
- **प्रतिक्रिया स्वच्छता** - सख्त ओपनएआई एसडीके संगतता के लिए गैर-मानक फ़ील्ड को हटा देता है
|
||||
- **भूमिका सामान्यीकरण** - `developer` → गैर-OpenAI के लिए `system`; `system` → GLM/ERNIE मॉडल के लिए `user`
|
||||
- **टैग निष्कर्षण के बारे में सोचें** - `<think>` ब्लॉक → सोच मॉडल के लिए `reasoning_content`
|
||||
- **संरचित आउटपुट** — `json_schema` → मिथुन राशि का `responseMimeType`/`responseSchema`
|
||||
|
||||
### 👥 मल्टी-अकाउंट सपोर्ट
|
||||
|
||||
- प्रति प्रदाता एकाधिक खाते जोड़ें
|
||||
- ऑटो राउंड-रॉबिन या प्राथमिकता-आधारित रूटिंग
|
||||
- कोटा पूरा होने पर अगले खाते में फ़ॉलबैक
|
||||
|
||||
### 🔄 ऑटो टोकन रिफ्रेश
|
||||
|
||||
- OAuth टोकन समाप्ति से पहले स्वचालित रूप से ताज़ा हो जाते हैं
|
||||
- किसी मैन्युअल पुन: प्रमाणीकरण की आवश्यकता नहीं है
|
||||
- सभी प्रदाताओं के बीच निर्बाध अनुभव
|
||||
|
||||
### 🎨 कस्टम कॉम्बो
|
||||
|
||||
- असीमित मॉडल संयोजन बनाएं
|
||||
- 6 रणनीतियाँ: पहले भरें, राउंड-रॉबिन, दो-विकल्पों की शक्ति, यादृच्छिक, कम से कम उपयोग, लागत-अनुकूलित
|
||||
- क्लाउड सिंक के साथ सभी डिवाइसों पर कॉम्बो साझा करें
|
||||
|
||||
### 🏥 स्वास्थ्य डैशबोर्ड
|
||||
|
||||
- सिस्टम स्थिति (अपटाइम, संस्करण, मेमोरी उपयोग)
|
||||
- प्रति प्रदाता सर्किट ब्रेकर की स्थिति (बंद/खुला/आधा खुला)
|
||||
- दर सीमा स्थिति और सक्रिय तालाबंदी
|
||||
- हस्ताक्षर कैश आँकड़े
|
||||
- विलंबता टेलीमेट्री (p50/p95/p99) + शीघ्र कैश
|
||||
- एक क्लिक से स्वास्थ्य स्थिति रीसेट करें
|
||||
|
||||
### 🔧 अनुवादक खेल का मैदान
|
||||
|
||||
ओमनीरूट में डिबगिंग, परीक्षण और एपीआई अनुवादों की निगरानी के लिए **4 मोड** के साथ एक शक्तिशाली अंतर्निहित अनुवादक खेल का मैदान शामिल है:
|
||||
|
||||
| मोड | विवरण |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **💻खेल का मैदान** | प्रत्यक्ष प्रारूप अनुवाद - किसी भी एपीआई अनुरोध निकाय को पेस्ट करें और तुरंत देखें कि ओम्नीरूट प्रदाता प्रारूपों (ओपनएआई ↔ क्लाउड ↔ जेमिनी ↔ रिस्पॉन्स एपीआई) के बीच इसका अनुवाद कैसे करता है। उदाहरण टेम्प्लेट और प्रारूप ऑटो-डिटेक्शन शामिल है। |
|
||||
| **💬 चैट परीक्षक** | ओम्निरूट के माध्यम से वास्तविक चैट अनुरोध भेजें और पूरी राउंड-ट्रिप देखें: आपका इनपुट, अनुवादित अनुरोध, प्रदाता प्रतिक्रिया, और अनुवादित प्रतिक्रिया वापस। कॉम्बो रूटिंग को मान्य करने के लिए अमूल्य। |
|
||||
| **🧪 टेस्ट बेंच** | बैच परीक्षण मोड - विभिन्न इनपुट और अपेक्षित आउटपुट के साथ कई परीक्षण मामलों को परिभाषित करें, उन सभी को एक साथ चलाएं, और प्रदाताओं और मॉडलों के परिणामों की तुलना करें। |
|
||||
| **📱लाइव मॉनिटर** | वास्तविक समय अनुरोध की निगरानी - आने वाले अनुरोधों को ओम्नीरूट के माध्यम से प्रवाहित होते हुए देखें, प्रारूप अनुवाद को लाइव होते हुए देखें, और समस्याओं की तुरंत पहचान करें। |
|
||||
|
||||
**पहुँच:** डैशबोर्ड → अनुवादक (साइडबार)
|
||||
|
||||
### 💾 क्लाउड सिंक
|
||||
|
||||
- सभी डिवाइसों में सिंक प्रदाता, कॉम्बो और सेटिंग्स
|
||||
- स्वचालित पृष्ठभूमि सिंक
|
||||
- सुरक्षित एन्क्रिप्टेड भंडारण
|
||||
|
||||
---
|
||||
|
||||
## 🎯 उपयोग के मामले
|
||||
|
||||
### केस 1: "मेरे पास क्लाउड प्रो सदस्यता है"
|
||||
|
||||
**समस्या:** भारी कोडिंग के दौरान कोटा अप्रयुक्त, दर सीमा समाप्त हो जाता है
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (use subscription fully)
|
||||
2. glm/glm-4.7 (cheap backup when quota out)
|
||||
3. if/kimi-k2-thinking (free emergency fallback)
|
||||
|
||||
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
|
||||
vs. $20 + hitting limits = frustration
|
||||
```
|
||||
|
||||
### केस 2: "मुझे शून्य लागत चाहिए"
|
||||
|
||||
**समस्या:** सदस्यताएं वहन नहीं कर सकते, विश्वसनीय एआई कोडिंग की आवश्यकता है
|
||||
|
||||
### केस 3: "मुझे 24/7 कोडिंग चाहिए, कोई रुकावट नहीं"
|
||||
|
||||
**समस्या:** समय सीमा, डाउनटाइम बर्दाश्त नहीं कर सकते
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (best quality)
|
||||
2. cx/gpt-5.2-codex (second subscription)
|
||||
3. glm/glm-4.7 (cheap, resets daily)
|
||||
4. minimax/MiniMax-M2.1 (cheapest, 5h reset)
|
||||
5. if/kimi-k2-thinking (free unlimited)
|
||||
|
||||
Result: 5 layers of fallback = zero downtime
|
||||
```
|
||||
|
||||
### केस 4: "मुझे ओपनक्लॉ में मुफ़्त एआई चाहिए"
|
||||
|
||||
**समस्या:** मैसेजिंग ऐप्स में AI सहायक की आवश्यकता है, पूरी तरह से निःशुल्क
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (unlimited free)
|
||||
2. if/minimax-m2.1 (unlimited free)
|
||||
3. if/kimi-k2-thinking (unlimited free)
|
||||
|
||||
Monthly cost: $0
|
||||
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 सेटअप गाइड
|
||||
|
||||
<summary><b>💳 सदस्यता प्रदाता</b></summary>
|
||||
|
||||
### क्लाउड कोड (प्रो/मैक्स)
|
||||
|
||||
**प्रो टिप:** जटिल कार्यों के लिए ओपस और गति के लिए सॉनेट का उपयोग करें। ओमनीरूट प्रति मॉडल कोटा ट्रैक करता है!
|
||||
|
||||
### ओपनएआई कोडेक्स (प्लस/प्रो)
|
||||
|
||||
### जेमिनी सीएलआई (मुफ़्त 180K/माह!)
|
||||
|
||||
**सर्वोत्तम मूल्य:** विशाल निःशुल्क स्तर! सशुल्क स्तरों से पहले इसका उपयोग करें।
|
||||
|
||||
### गिटहब कोपायलट
|
||||
|
||||
<details>
|
||||
<summary><b>🔑 API कुंजी प्रदाता</b></summary>
|
||||
|
||||
### एनवीडिया एनआईएम (मुफ़्त 1000 क्रेडिट!)
|
||||
|
||||
1. साइन अप करें: [build.nvidia.com](https://build.nvidia.com)
|
||||
2. निःशुल्क एपीआई कुंजी प्राप्त करें (1000 अनुमान क्रेडिट शामिल)
|
||||
3. डैशबोर्ड → प्रदाता जोड़ें → एनवीडिया एनआईएम:
|
||||
- एपीआई कुंजी: `nvapi-your-key`
|
||||
|
||||
**मॉडल:** `nvidia/llama-3.3-70b-instruct`, `nvidia/mistral-7b-instruct`, और 50+ अधिक
|
||||
|
||||
**प्रो टिप:** ओपनएआई-संगत एपीआई - ओमनीरूट के प्रारूप अनुवाद के साथ सहजता से काम करता है!
|
||||
|
||||
### डीपसीक
|
||||
|
||||
1. साइन अप करें: [platform.deepseek.com](https://platform.deepseek.com)
|
||||
2. एपीआई कुंजी प्राप्त करें
|
||||
3. डैशबोर्ड → प्रदाता जोड़ें → डीपसीक
|
||||
|
||||
**मॉडल:** `deepseek/deepseek-chat`, `deepseek/deepseek-coder`
|
||||
|
||||
### ग्रोक (निःशुल्क टियर उपलब्ध!)
|
||||
|
||||
1. साइन अप करें: [console.groq.com](https://console.groq.com)
|
||||
2. एपीआई कुंजी प्राप्त करें (फ्री टियर शामिल)
|
||||
3. डैशबोर्ड → प्रदाता जोड़ें → ग्रोक
|
||||
|
||||
**मॉडल:** `groq/llama-3.3-70b`, `groq/mixtral-8x7b`
|
||||
|
||||
**प्रो टिप:** अल्ट्रा-फास्ट अनुमान - वास्तविक समय कोडिंग के लिए सर्वोत्तम!
|
||||
|
||||
### ओपनराउटर (100+ मॉडल)
|
||||
|
||||
1. साइन अप करें: [openrouter.ai](https://openrouter.ai)
|
||||
2. एपीआई कुंजी प्राप्त करें
|
||||
3. डैशबोर्ड → प्रदाता जोड़ें → ओपनराउटर
|
||||
|
||||
**मॉडल:** एक ही एपीआई कुंजी के माध्यम से सभी प्रमुख प्रदाताओं से 100+ मॉडल तक पहुंचें।
|
||||
|
||||
<summary><b>💰 सस्ते प्रदाता (बैकअप)</b></summary>
|
||||
|
||||
### GLM-4.7 (दैनिक रीसेट, $0.6/1 मिलियन)
|
||||
|
||||
1. साइन अप करें: [Zhipu AI](https://open.bigmodel.cn/)
|
||||
2. कोडिंग योजना से एपीआई कुंजी प्राप्त करें
|
||||
3. डैशबोर्ड → एपीआई कुंजी जोड़ें:
|
||||
- प्रदाता: `glm`
|
||||
- एपीआई कुंजी: `your-key`
|
||||
|
||||
**उपयोग करें:** `glm/glm-4.7`
|
||||
|
||||
**प्रो टिप:** कोडिंग प्लान 1/7 लागत पर 3× कोटा प्रदान करता है! प्रतिदिन सुबह 10:00 बजे रीसेट करें।
|
||||
|
||||
### मिनीमैक्स एम2.1 (5 घंटे रीसेट, $0.20/1 मिलियन)
|
||||
|
||||
1. साइन अप करें: [MiniMax](https://www.minimax.io/)
|
||||
2. एपीआई कुंजी प्राप्त करें
|
||||
3. डैशबोर्ड → एपीआई कुंजी जोड़ें
|
||||
|
||||
**उपयोग:** `minimax/MiniMax-M2.1`
|
||||
|
||||
**प्रो टिप:** लंबे संदर्भ के लिए सबसे सस्ता विकल्प (1M टोकन)!
|
||||
|
||||
### किमी K2 ($9/माह फ्लैट)
|
||||
|
||||
1. सदस्यता लें: [Moonshot AI](https://platform.moonshot.ai/)
|
||||
2. एपीआई कुंजी प्राप्त करें
|
||||
3. डैशबोर्ड → एपीआई कुंजी जोड़ें
|
||||
|
||||
**उपयोग करें:** `kimi/kimi-latest`
|
||||
|
||||
**प्रो टिप:** 10एम टोकन के लिए निश्चित $9/माह = $0.90/1एम प्रभावी लागत!
|
||||
|
||||
<summary><b>🆓 मुफ़्त प्रदाता (आपातकालीन बैकअप)</b></summary>
|
||||
|
||||
### आईफ्लो (8 मुफ़्त मॉडल)
|
||||
|
||||
### क्वेन (3 मुफ़्त मॉडल)
|
||||
|
||||
### किरो (क्लाउड फ्री)
|
||||
|
||||
<summary><b>🎨 कॉम्बो बनाएं</b></summary>
|
||||
|
||||
### उदाहरण 1: सदस्यता अधिकतम करें → सस्ता बैकअप
|
||||
|
||||
### उदाहरण 2: केवल निःशुल्क (शून्य लागत)
|
||||
|
||||
```
|
||||
Name: free-combo
|
||||
Models:
|
||||
1. gc/gemini-3-flash-preview (180K free/month)
|
||||
2. if/kimi-k2-thinking (unlimited)
|
||||
3. qw/qwen3-coder-plus (unlimited)
|
||||
|
||||
Cost: $0 forever!
|
||||
```
|
||||
|
||||
<summary><b>🔧 CLI एकीकरण</b></summary>
|
||||
|
||||
### कर्सर आईडीई
|
||||
|
||||
### क्लाउड कोड
|
||||
|
||||
एक-क्लिक कॉन्फ़िगरेशन के लिए डैशबोर्ड में **CLI टूल्स** पृष्ठ का उपयोग करें, या `~/.claude/settings.json` को मैन्युअल रूप से संपादित करें।
|
||||
|
||||
### कोडेक्स सीएलआई
|
||||
|
||||
### ओपनक्लॉ
|
||||
|
||||
**विकल्प 1 - डैशबोर्ड (अनुशंसित):**
|
||||
|
||||
**विकल्प 2 - मैनुअल:** संपादित करें `~/.openclaw/openclaw.json`:
|
||||
|
||||
> **ध्यान दें:** ओपनक्लाव केवल स्थानीय ओमनीरूट के साथ काम करता है। IPv6 रिज़ॉल्यूशन समस्याओं से बचने के लिए `localhost` के बजाय `127.0.0.1` का उपयोग करें।
|
||||
|
||||
### क्लाइन / जारी रखें / रूकोड
|
||||
|
||||
---
|
||||
|
||||
## 📊 उपलब्ध मॉडल
|
||||
|
||||
<details>
|
||||
<summary><b>सभी उपलब्ध मॉडल देखें</b></summary>
|
||||
|
||||
**क्लाउड कोड (`cc/`)** - प्रो/मैक्स:
|
||||
|
||||
- `cc/claude-opus-4-6`
|
||||
- `cc/claude-sonnet-4-5-20250929`
|
||||
- `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**कोडेक्स (`cx/`)** - प्लस/प्रो:
|
||||
|
||||
-
|
||||
- `cx/gpt-5.1-codex-max`
|
||||
|
||||
**मिथुन सीएलआई (`gc/`)** - मुफ़्त:
|
||||
|
||||
- `gc/gemini-3-flash-preview`
|
||||
- `gc/gemini-2.5-pro`
|
||||
|
||||
**गिटहब कोपायलट (`gh/`)**:
|
||||
|
||||
- `gh/gpt-5`
|
||||
- `gh/claude-4.5-sonnet`
|
||||
|
||||
**एनवीडिया एनआईएम (`nvidia/`)** - मुफ़्त क्रेडिट:
|
||||
|
||||
- `nvidia/llama-3.3-70b-instruct`
|
||||
- `nvidia/mistral-7b-instruct`
|
||||
- [build.nvidia.com](https://build.nvidia.com) पर 50+ अधिक मॉडल
|
||||
|
||||
**जीएलएम (`glm/`)** - $0.6/1M:
|
||||
|
||||
- `glm/glm-4.7`
|
||||
|
||||
**मिनीमैक्स (`minimax/`)** - $0.2/1M:
|
||||
|
||||
- `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** - मुफ़्त:
|
||||
|
||||
- `if/kimi-k2-thinking`
|
||||
- `if/qwen3-coder-plus`
|
||||
- `if/deepseek-r1`
|
||||
- `if/glm-4.7`
|
||||
- `if/minimax-m2`
|
||||
|
||||
**क्वेन (`qw/`)** - मुफ़्त:
|
||||
|
||||
- `qw/qwen3-coder-plus`
|
||||
- `qw/qwen3-coder-flash`
|
||||
|
||||
**किरो (`kr/`)** - मुफ़्त:
|
||||
|
||||
- `kr/claude-sonnet-4.5`
|
||||
- `kr/claude-haiku-4.5`
|
||||
|
||||
**ओपनराउटर (`or/`)** - 100+ मॉडल:
|
||||
|
||||
- `or/anthropic/claude-4-sonnet`
|
||||
- `or/google/gemini-2.5-pro`
|
||||
- [openrouter.ai/models](https://openrouter.ai/models) से कोई भी मॉडल
|
||||
|
||||
---
|
||||
|
||||
## 🧪 मूल्यांकन (Evaluations)
|
||||
|
||||
ओमनीरूट में गोल्डन सेट के मुकाबले एलएलएम प्रतिक्रिया गुणवत्ता का परीक्षण करने के लिए एक अंतर्निहित मूल्यांकन ढांचा शामिल है। डैशबोर्ड में **एनालिटिक्स → इवेल्स** के माध्यम से इसे एक्सेस करें।
|
||||
|
||||
### बिल्ट-इन गोल्डन सेट
|
||||
|
||||
प्री-लोडेड "ओम्नीरूट गोल्डन सेट" में 10 परीक्षण मामले शामिल हैं:
|
||||
|
||||
- नमस्ते, गणित, भूगोल, कोड जनरेशन
|
||||
- JSON प्रारूप अनुपालन, अनुवाद, मार्कडाउन
|
||||
- सुरक्षा इनकार (हानिकारक सामग्री), गिनती, बूलियन तर्क
|
||||
|
||||
### मूल्यांकन रणनीतियाँ
|
||||
|
||||
| रणनीति | विवरण | उदाहरण |
|
||||
| ---------- | ------------------------------------------------- | -------------------------------- |
|
||||
| `exact` | आउटपुट बिल्कुल मेल खाना चाहिए | `"4"` |
|
||||
| `contains` | आउटपुट में सबस्ट्रिंग (केस-असंवेदनशील) होना चाहिए | `"Paris"` |
|
||||
| `regex` | आउटपुट रेगेक्स पैटर्न से मेल खाना चाहिए | `"1.*2.*3"` |
|
||||
| `custom` | कस्टम जेएस फ़ंक्शन सही/गलत लौटाता है | `(output) => output.length > 10` |
|
||||
|
||||
---
|
||||
|
||||
## 🐛 समस्या निवारण
|
||||
|
||||
<summary><b>समस्या निवारण मार्गदर्शिका का विस्तार करने के लिए क्लिक करें</b></summary>
|
||||
|
||||
**"भाषा मॉडल ने संदेश प्रदान नहीं किया"**
|
||||
|
||||
- प्रदाता कोटा समाप्त → डैशबोर्ड कोटा ट्रैकर की जाँच करें
|
||||
- समाधान: कॉम्बो फ़ॉलबैक का उपयोग करें या सस्ते स्तर पर स्विच करें
|
||||
|
||||
**दर सीमित करना**
|
||||
|
||||
- सदस्यता कोटा ख़त्म → GLM/MiniMax पर फ़ॉलबैक
|
||||
- कॉम्बो जोड़ें: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
|
||||
|
||||
**OAuth टोकन समाप्त हो गया**
|
||||
|
||||
- ओम्निरूट द्वारा स्वतः ताज़ा
|
||||
- यदि समस्या बनी रहती है: डैशबोर्ड → प्रदाता → पुनः कनेक्ट करें
|
||||
|
||||
**उच्च लागत**
|
||||
|
||||
- डैशबोर्ड → लागत में उपयोग के आँकड़े जाँचें
|
||||
- प्राथमिक मॉडल को जीएलएम/मिनीमैक्स पर स्विच करें
|
||||
- गैर-महत्वपूर्ण कार्यों के लिए फ्री टियर (मिथुन सीएलआई, आईफ्लो) का उपयोग करें
|
||||
|
||||
**डैशबोर्ड गलत पोर्ट पर खुलता है**
|
||||
|
||||
- `PORT=20128` और `NEXT_PUBLIC_BASE_URL=http://localhost:20128` सेट करें
|
||||
|
||||
**क्लाउड सिंक त्रुटियाँ**
|
||||
|
||||
- अपने चल रहे उदाहरण के लिए `BASE_URL` अंक सत्यापित करें
|
||||
- अपने अपेक्षित क्लाउड एंडपॉइंट पर `CLOUD_URL` पॉइंट सत्यापित करें
|
||||
- `NEXT_PUBLIC_*` मानों को सर्वर-साइड मानों के साथ संरेखित रखें
|
||||
|
||||
**पहला लॉगिन काम नहीं कर रहा**
|
||||
|
||||
- `.env` में `INITIAL_PASSWORD` को जांचें
|
||||
- यदि सेट नहीं है, तो फ़ॉलबैक पासवर्ड `123456` है
|
||||
|
||||
**कोई अनुरोध लॉग नहीं**
|
||||
|
||||
- `.env` में `ENABLE_REQUEST_LOGS=true` सेट करें
|
||||
|
||||
**कनेक्शन परीक्षण OpenAI-संगत प्रदाताओं के लिए "अमान्य" दिखाता है**
|
||||
|
||||
- कई प्रदाता `/models` समापन बिंदु को उजागर नहीं करते हैं
|
||||
- ओमनीरूट v1.0.6+ में चैट पूर्णता के माध्यम से फ़ॉलबैक सत्यापन शामिल है
|
||||
- सुनिश्चित करें कि आधार URL में `/v1` प्रत्यय शामिल हो
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ टेक स्टैक
|
||||
|
||||
- **रनटाइम**: Node.js 18–22 LTS (⚠️ Node.js 24+ **समर्थित नहीं** है - `better-sqlite3` मूल बायनेरिज़ असंगत हैं)
|
||||
- **भाषा**: टाइपस्क्रिप्ट 5.9 - **100% टाइपस्क्रिप्ट** `src/` और `open-sse/` (v1.0.6) में
|
||||
- **फ्रेमवर्क**: नेक्स्ट.जेएस 16 + रिएक्ट 19 + टेलविंड सीएसएस 4
|
||||
- **डेटाबेस**: लोडीबी (JSON) + SQLite (डोमेन स्थिति + प्रॉक्सी लॉग)
|
||||
- **स्ट्रीमिंग**: सर्वर-भेजे गए इवेंट (एसएसई)
|
||||
- **प्रामाणिक**: OAuth 2.0 (PKCE) + JWT + API कुंजियाँ
|
||||
- **परीक्षण**: Node.js परीक्षण धावक (368+ इकाई परीक्षण)
|
||||
- **सीआई/सीडी**: गिटहब क्रियाएँ (ऑटो एनपीएम प्रकाशन + रिलीज पर डॉकर हब)
|
||||
- **वेबसाइट**: [omniroute.online](https://omniroute.online)
|
||||
- **पैकेज**: [npmjs.com/package/omniroute](https://www.npmjs.com/package/omniroute)
|
||||
- **डॉकर**: [hub.docker.com/r/diegosouzapw/omniroute](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
- **लचीलापन**: सर्किट ब्रेकर, एक्सपोनेंशियल बैकऑफ़, एंटी-थंडरिंग झुंड, टीएलएस स्पूफिंग
|
||||
|
||||
---
|
||||
|
||||
## 📖 दस्तावेज़ीकरण
|
||||
|
||||
| दस्तावेज़ | विवरण |
|
||||
| -------------------------------------------- | ------------------------------------------- |
|
||||
| [User Guide](docs/USER_GUIDE.md) | प्रदाता, कॉम्बो, सीएलआई एकीकरण, तैनाती |
|
||||
| [API Reference](docs/API_REFERENCE.md) | उदाहरण सहित सभी समापन बिंदु |
|
||||
| [Troubleshooting](docs/TROUBLESHOOTING.md) | सामान्य समस्याएँ एवं समाधान |
|
||||
| [Architecture](docs/ARCHITECTURE.md) | सिस्टम आर्किटेक्चर और आंतरिक |
|
||||
| [Contributing](CONTRIBUTING.md) | विकास सेटअप और दिशानिर्देश |
|
||||
| [OpenAPI Spec](docs/openapi.yaml) | ओपनएपीआई 3.0 विशिष्टता |
|
||||
| [Security Policy](SECURITY.md) | भेद्यता रिपोर्टिंग और सुरक्षा प्रथाएं |
|
||||
| [VM Deployment](docs/VM_DEPLOYMENT_GUIDE.md) | संपूर्ण गाइड: VM + nginx + Cloudflare सेटअप |
|
||||
| [Features Gallery](docs/FEATURES.md) | स्क्रीनशॉट के साथ विजुअल डैशबोर्ड टूर |
|
||||
|
||||
### 📸 डैशबोर्ड पूर्वावलोकन
|
||||
|
||||
<summary><b>डैशबोर्ड स्क्रीनशॉट देखने के लिए क्लिक करें</b></summary>
|
||||
|
||||
| पेज | स्क्रीनशॉट |
|
||||
| ----------------- | ------------------------------------------------- |
|
||||
| **प्रदाता** |  |
|
||||
| **कॉम्बोस** |  |
|
||||
| **एनालिटिक्स** |  |
|
||||
| **स्वास्थ्य** |  |
|
||||
| **अनुवादक** |  |
|
||||
| **सेटिंग्स** |  |
|
||||
| **सीएलआई उपकरण** |  |
|
||||
| **उपयोग लॉग** |  |
|
||||
| **समाप्ति बिंदु** |  |
|
||||
|
||||
---
|
||||
|
||||
## 🗺️ रोडमैप
|
||||
|
||||
ओम्निरूट ने कई विकास चरणों में **210+ सुविधाओं की योजना बनाई है**। यहां प्रमुख क्षेत्र हैं:
|
||||
|
||||
| श्रेणी | नियोजित विशेषताएं | हाइलाइट्स |
|
||||
| --------------------------- | ----------------- | ------------------------------------------------------------------------------------------- |
|
||||
| 🧠 **रूटिंग और इंटेलिजेंस** | 25+ | न्यूनतम-विलंबता रूटिंग, टैग-आधारित रूटिंग, कोटा प्रीफ़्लाइट, पी2सी खाता चयन |
|
||||
| 🔒 **सुरक्षा एवं अनुपालन** | 20+ | एसएसआरएफ हार्डनिंग, क्रेडेंशियल क्लोकिंग, प्रति समापन बिंदु दर-सीमा, प्रबंधन कुंजी स्कोपिंग |
|
||||
| 📊 **अवलोकनशीलता** | 15+ | ओपन टेलीमेट्री एकीकरण, वास्तविक समय कोटा निगरानी, प्रति मॉडल लागत ट्रैकिंग |
|
||||
| 🔄 **प्रदाता एकीकरण** | 20+ | डायनेमिक मॉडल रजिस्ट्री, प्रदाता कूलडाउन, मल्टी-अकाउंट कोडेक्स, कोपायलट कोटा पार्सिंग |
|
||||
| ⚡ **प्रदर्शन** | 15+ | दोहरी कैश परत, शीघ्र कैश, प्रतिक्रिया कैश, स्ट्रीमिंग कीपलाइव, बैच एपीआई |
|
||||
| 🌐 **पारिस्थितिकी तंत्र** | 10+ | वेबसॉकेट एपीआई, कॉन्फिग हॉट-रीलोड, वितरित कॉन्फिग स्टोर, वाणिज्यिक मोड |
|
||||
|
||||
### 🔜 जल्द आ रहा है
|
||||
|
||||
- 🔗 **ओपनकोड इंटीग्रेशन** - ओपनकोड एआई कोडिंग आईडीई के लिए मूल प्रदाता समर्थन
|
||||
- 🔗 **TRAE एकीकरण** - TRAE AI विकास ढांचे के लिए पूर्ण समर्थन
|
||||
- 📦 **बैच एपीआई** - थोक अनुरोधों के लिए अतुल्यकालिक बैच प्रोसेसिंग
|
||||
- 🎯 **टैग-आधारित रूटिंग** - कस्टम टैग और मेटाडेटा के आधार पर रूट अनुरोध
|
||||
- 💰 **न्यूनतम-लागत रणनीति** — स्वचालित रूप से सबसे सस्ते उपलब्ध प्रदाता का चयन करें
|
||||
|
||||
> 📝 पूर्ण फीचर विशिष्टताएं [link](docs/new-features/) में उपलब्ध हैं (217 विस्तृत विवरण)
|
||||
|
||||
---
|
||||
|
||||
## 📧समर्थन
|
||||
|
||||
> 💬 **हमारे समुदाय में शामिल हों!** [WhatsApp Group](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) - सहायता प्राप्त करें, सुझाव साझा करें और अपडेट रहें।
|
||||
|
||||
- **वेबसाइट**: [omniroute.online](https://omniroute.online)
|
||||
- **गिटहब**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
|
||||
- **मुद्दे**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **व्हाट्सएप**: [Community Group](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
- **मूल परियोजना**: [9router by decolua](https://github.com/decolua/9router)
|
||||
|
||||
---
|
||||
|
||||
## 👥 योगदानकर्ता
|
||||
|
||||
[](https://github.com/diegosouzapw/OmniRoute/graphs/contributors)
|
||||
|
||||
### योगदान कैसे करें
|
||||
|
||||
1. रिपॉजिटरी को फोर्क करें
|
||||
2. अपनी फीचर शाखा बनाएं (`git checkout -b feature/amazing-feature`)
|
||||
3. अपने परिवर्तन प्रतिबद्ध करें (`git commit -m 'Add amazing feature'`)
|
||||
4. शाखा में पुश करें (`git push origin feature/amazing-feature`)
|
||||
5. एक पुल अनुरोध खोलें
|
||||
|
||||
विस्तृत दिशानिर्देशों के लिए [CONTRIBUTING.md](CONTRIBUTING.md) देखें।
|
||||
|
||||
### एक नया संस्करण जारी करना
|
||||
|
||||
```bash
|
||||
# Create a release — npm publish happens automatically
|
||||
gh release create v1.0.6 --title "v1.0.6" --generate-notes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 सितारा इतिहास
|
||||
|
||||
<a href="https://star-history.com/#diegosouzapw/OmniRoute&Date">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</a>
|
||||
|
||||
---
|
||||
|
||||
## 🙏 आभार
|
||||
|
||||
**[decolua](https://github.com/decolua)** द्वारा **[decolua](https://github.com/decolua)** को विशेष धन्यवाद - मूल परियोजना जिसने इस फोर्क को प्रेरित किया। ओमनीरूट अतिरिक्त सुविधाओं, मल्टी-मोडल एपीआई और पूर्ण टाइपस्क्रिप्ट पुनर्लेखन के साथ उस अविश्वसनीय नींव पर आधारित है।
|
||||
|
||||
**[CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI)** को विशेष धन्यवाद - मूल गो कार्यान्वयन जिसने इस जावास्क्रिप्ट पोर्ट को प्रेरित किया।
|
||||
|
||||
---
|
||||
|
||||
## 📄 लाइसेंस
|
||||
|
||||
एमआईटी लाइसेंस - विवरण के लिए [LICENSE](LICENSE) देखें।
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 🇧🇷 ओमनीरूट - गेटवे डी आईए ग्रैटुइटो
|
||||
|
||||
<a name="-omniroute--gateway-de-ia-gratuito"></a>
|
||||
|
||||
### नूनका पारे डे कोडर। रोटेमेंटो इंटेलिजेंट पैरा **मॉडलोस डी आईए ग्रैटुइटोस और डे बैक्सो कस्टम** कॉम फ़ॉलबैक ऑटोमेटिको।
|
||||
|
||||
_एसईयू प्रॉक्सी यूनिवर्सल डी एपीआई - उम एंडपॉइंट, 36+ प्रोडोर्स, शून्य डाउनटाइम।_
|
||||
|
||||
### 🌐 इंटरनेशनलिज़ाकाओ (i18n)
|
||||
|
||||
ओम्नीरूट का डैशबोर्ड **मल्टीप्लोस इडियोमास** का समर्थन करता है। उन्हें वास्तविक वितरण:
|
||||
|
||||
| मुहावरा | कोडिगो | स्थिति |
|
||||
| ----------------------- | ------- | ----------- |
|
||||
| 🇺🇸 अंग्रेजी | `en` | ✅ कंप्लीटो |
|
||||
| 🇧🇷 पोर्टुगुएस (ब्राजील) | `pt-BR` | ✅ कंप्लीटो |
|
||||
|
||||
**मुहावरे के बारे में जानकारी:** मुहावरे के चयन पर क्लिक करें (🇺🇸 EN) डैशबोर्ड पर कोई हेडर नहीं → वाक्यांश के चयन के बारे में क्लिक करें।
|
||||
|
||||
**एक नया मुहावरा जोड़ने के लिए:**
|
||||
|
||||
1. `src/i18n/messages/{codigo}.json` को `en.json` पर आधारित करें
|
||||
2. `src/i18n/config.ts` → `LOCALES` और `LANGUAGES` कोड का उपयोग
|
||||
3. सेवा प्रदाता की सेवा
|
||||
|
||||
### ⚡ इनिसियो रैपिडो
|
||||
|
||||
```bash
|
||||
# Instalar via npm
|
||||
npx omniroute@latest
|
||||
|
||||
# Ou rodar do código-fonte
|
||||
cp .env.example .env
|
||||
npm install
|
||||
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
|
||||
```
|
||||
|
||||
### 🐳 डॉकर
|
||||
|
||||
```bash
|
||||
docker run -d --name omniroute -p 20128:20128 diegosouzapw/omniroute:latest
|
||||
```
|
||||
|
||||
### 🔑 फंक्सोनियलिडेड्स प्रिंसिपैस
|
||||
|
||||
- **36+ आईए** - क्लाउड, जीपीटी, जेमिनी, लामा, क्वेन, डीपसीक, और अन्य
|
||||
- **रोटीमेंटो इंटेलिजेंट** — फ़ॉलबैक ऑटोमेटिको एंटर प्रोवोर्स
|
||||
- **प्रारूप अनुवाद** — OpenAI ↔ क्लाउड ↔ जेमिनी ऑटोमैटिक
|
||||
- **मल्टी-कॉन्टा** - चयनित इंटेलिजेंट के लिए मल्टीप्लास कॉन्टास
|
||||
- **कैश सिमेंटिको** - कस्टम और लेटेंसी रेडुज़
|
||||
- **OAuth automático** — टोकन स्वचालित रूप से नवीनीकृत होते हैं
|
||||
- **व्यक्तिगत संयोजन** — 6 रोटेमेंटो एस्ट्रैटेजीस
|
||||
- **डैशबोर्ड संपूर्ण** - मॉनिटर, लॉग, विश्लेषण, कॉन्फ़िगरेशन
|
||||
- **सीएलआई उपकरण** - क्लाउड कोड, कोडेक्स, कर्सर, क्लाइन को एक क्लिक पर कॉन्फ़िगर करें
|
||||
- **100% टाइपस्क्रिप्ट** — कोडिगो लिम्पो और टिपडो
|
||||
|
||||
### 📖 दस्तावेज़ीकरण
|
||||
|
||||
| डॉक्यूमेंटो | विवरण |
|
||||
| ----------------------------------------------- | --------------------------------------------- |
|
||||
| [Guia do Usuário](docs/USER_GUIDE.md) | प्रोवेडोर्स, कॉम्बो, सीएलआई, तैनाती |
|
||||
| [Referência da API](docs/API_REFERENCE.md) | सभी ओएस एंडपॉइंट उदाहरण उदाहरण |
|
||||
| [Solução de Problemas](docs/TROUBLESHOOTING.md) | समस्याएं और समाधान |
|
||||
| [Arquitetura](docs/ARCHITECTURE.md) | आर्किटेक्चर और इंटर्नोस डो सिस्तेमा |
|
||||
| [Contribuição](CONTRIBUTING.md) | सेटअप डे डेसेनवोल्विमेंटो ई दिशानिर्देश |
|
||||
| [Deploy em VM](docs/VM_DEPLOYMENT_GUIDE.md) | संपूर्ण मार्गदर्शिका: VM + nginx + Cloudflare |
|
||||
|
||||
### 📧 सपोर्ट
|
||||
|
||||
> 💬 **एक अधिसूचना के लिए प्रवेश!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — दो सप्ताह, पूर्ण विवरण और पूर्ण विवरण।
|
||||
|
||||
- **वेबसाइट**: [omniroute.online](https://omniroute.online)
|
||||
- **गिटहब**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
|
||||
- **मुद्दे**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
|
||||
---
|
||||
|
||||
<sub>24/7 कोड करने वाले डेवलपर्स के लिए ❤️ के साथ निर्मित</sub>
|
||||
|
||||
<sub><a href="https://omniroute.online">omniroute.online</a></sub>
|
||||
+95
-134
@@ -100,10 +100,11 @@ _Connetti qualsiasi IDE o strumento CLI con IA tramite OmniRoute — gateway API
|
||||
[](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
|
||||
[](https://omniroute.online)
|
||||
[](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
|
||||
[🌐 Sito Web](https://omniroute.online) • [🚀 Avvio Rapido](#-avvio-rapido) • [💡 Funzionalità](#-funzionalità-principali) • [📖 Docs](#-documentazione) • [💰 Prezzi](#-panoramica-prezzi)
|
||||
|
||||
🌐 **Disponibile in:** [English](README.md) | [Português](README.pt-BR.md) | [Español](README.es.md) | [Русский](README.ru.md) | [中文](README.zh-CN.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | [Italiano](README.it.md)
|
||||
🌐 **Available in:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](README.pt-BR.md) | 🇪🇸 [Español](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [Italiano](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [Magyar](README.hu.md) | 🇮🇩 [Bahasa Indonesia](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Nederlands](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Portugal)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Polski](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [Filipino](README.phi.md)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -242,7 +243,31 @@ docker compose --profile cli up -d
|
||||
| Immagine | Tag | Dimensione | Descrizione |
|
||||
| ------------------------ | -------- | ---------- | ----------------------- |
|
||||
| `diegosouzapw/omniroute` | `latest` | ~250MB | Ultima versione stabile |
|
||||
| `diegosouzapw/omniroute` | `1.0.0` | ~250MB | Versione attuale |
|
||||
| `diegosouzapw/omniroute` | `1.0.6` | ~250MB | Versione attuale |
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Desktop App — Offline & Always-On
|
||||
|
||||
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
|
||||
|
||||
- 🖥️ **Native Window** — Dedicated app window with system tray integration
|
||||
- 🔄 **Auto-Start** — Launch OmniRoute on system login
|
||||
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
|
||||
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
|
||||
- 🌐 **Offline Mode** — Works fully offline with bundled server
|
||||
|
||||
```bash
|
||||
npm run electron:dev # Development mode
|
||||
npm run electron:build # Current platform
|
||||
npm run electron:build:win # Windows (.exe)
|
||||
npm run electron:build:mac # macOS (.dmg)
|
||||
npm run electron:build:linux # Linux (.AppImage)
|
||||
```
|
||||
|
||||
📖 Full documentation: [`electron/README.md`](electron/README.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -271,67 +296,6 @@ docker compose --profile cli up -d
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Casi d'Uso
|
||||
|
||||
### Caso 1: "Ho un abbonamento Claude Pro"
|
||||
|
||||
**Problema:** La quota scade inutilizzata, limiti di rate durante la programmazione intensa
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (usa l'abbonamento al massimo)
|
||||
2. glm/glm-4.7 (backup economico quando la quota è esaurita)
|
||||
3. if/kimi-k2-thinking (fallback d'emergenza gratuito)
|
||||
|
||||
Costo mensile: $20 (abbonamento) + ~$5 (backup) = $25 totale
|
||||
vs. $20 + sbattere contro i limiti = frustrazione
|
||||
```
|
||||
|
||||
### Caso 2: "Voglio costo zero"
|
||||
|
||||
**Problema:** Non può permettersi abbonamenti, ha bisogno di IA affidabile per programmare
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K gratis/mese)
|
||||
2. if/kimi-k2-thinking (illimitato gratis)
|
||||
3. qw/qwen3-coder-plus (illimitato gratis)
|
||||
|
||||
Costo mensile: $0
|
||||
Qualità: Modelli pronti per la produzione
|
||||
```
|
||||
|
||||
### Caso 3: "Devo programmare 24/7, senza interruzioni"
|
||||
|
||||
**Problema:** Scadenze strette, non può permettersi downtime
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (migliore qualità)
|
||||
2. cx/gpt-5.2-codex (secondo abbonamento)
|
||||
3. glm/glm-4.7 (economico, reset giornaliero)
|
||||
4. minimax/MiniMax-M2.1 (più economico, reset 5h)
|
||||
5. if/kimi-k2-thinking (gratuito illimitato)
|
||||
|
||||
Risultato: 5 livelli di fallback = zero downtime
|
||||
```
|
||||
|
||||
### Caso 4: "Voglio IA GRATUITA in OpenClaw"
|
||||
|
||||
**Problema:** Ha bisogno di assistente IA nelle app di messaggistica, completamente gratuito
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (illimitato gratis)
|
||||
2. if/minimax-m2.1 (illimitato gratis)
|
||||
3. if/kimi-k2-thinking (illimitato gratis)
|
||||
|
||||
Costo mensile: $0
|
||||
Accesso via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 Funzionalità Principali
|
||||
|
||||
### 🧠 Routing & Intelligenza
|
||||
@@ -473,6 +437,67 @@ Traduzione trasparente tra formati:
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Casi d'Uso
|
||||
|
||||
### Caso 1: "Ho un abbonamento Claude Pro"
|
||||
|
||||
**Problema:** La quota scade inutilizzata, limiti di rate durante la programmazione intensa
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (usa l'abbonamento al massimo)
|
||||
2. glm/glm-4.7 (backup economico quando la quota è esaurita)
|
||||
3. if/kimi-k2-thinking (fallback d'emergenza gratuito)
|
||||
|
||||
Costo mensile: $20 (abbonamento) + ~$5 (backup) = $25 totale
|
||||
vs. $20 + sbattere contro i limiti = frustrazione
|
||||
```
|
||||
|
||||
### Caso 2: "Voglio costo zero"
|
||||
|
||||
**Problema:** Non può permettersi abbonamenti, ha bisogno di IA affidabile per programmare
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K gratis/mese)
|
||||
2. if/kimi-k2-thinking (illimitato gratis)
|
||||
3. qw/qwen3-coder-plus (illimitato gratis)
|
||||
|
||||
Costo mensile: $0
|
||||
Qualità: Modelli pronti per la produzione
|
||||
```
|
||||
|
||||
### Caso 3: "Devo programmare 24/7, senza interruzioni"
|
||||
|
||||
**Problema:** Scadenze strette, non può permettersi downtime
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (migliore qualità)
|
||||
2. cx/gpt-5.2-codex (secondo abbonamento)
|
||||
3. glm/glm-4.7 (economico, reset giornaliero)
|
||||
4. minimax/MiniMax-M2.1 (più economico, reset 5h)
|
||||
5. if/kimi-k2-thinking (gratuito illimitato)
|
||||
|
||||
Risultato: 5 livelli di fallback = zero downtime
|
||||
```
|
||||
|
||||
### Caso 4: "Voglio IA GRATUITA in OpenClaw"
|
||||
|
||||
**Problema:** Ha bisogno di assistente IA nelle app di messaggistica, completamente gratuito
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (illimitato gratis)
|
||||
2. if/minimax-m2.1 (illimitato gratis)
|
||||
3. if/kimi-k2-thinking (illimitato gratis)
|
||||
|
||||
Costo mensile: $0
|
||||
Accesso via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Guida alla Configurazione
|
||||
|
||||
<details>
|
||||
@@ -753,74 +778,6 @@ Impostazioni → Configurazione API:
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modelli Disponibili
|
||||
|
||||
<details>
|
||||
<summary><b>Vedi tutti i modelli disponibili</b></summary>
|
||||
|
||||
**Claude Code (`cc/`)** - Pro/Max:
|
||||
|
||||
- `cc/claude-opus-4-6`
|
||||
- `cc/claude-sonnet-4-5-20250929`
|
||||
- `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**Codex (`cx/`)** - Plus/Pro:
|
||||
|
||||
- `cx/gpt-5.2-codex`
|
||||
- `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** - GRATUITO:
|
||||
|
||||
- `gc/gemini-3-flash-preview`
|
||||
- `gc/gemini-2.5-pro`
|
||||
|
||||
**GitHub Copilot (`gh/`)**:
|
||||
|
||||
- `gh/gpt-5`
|
||||
- `gh/claude-4.5-sonnet`
|
||||
|
||||
**NVIDIA NIM (`nvidia/`)** - Crediti GRATUITI:
|
||||
|
||||
- `nvidia/llama-3.3-70b-instruct`
|
||||
- `nvidia/mistral-7b-instruct`
|
||||
- 50+ modelli su [build.nvidia.com](https://build.nvidia.com)
|
||||
|
||||
**GLM (`glm/`)** - $0.6/1M:
|
||||
|
||||
- `glm/glm-4.7`
|
||||
|
||||
**MiniMax (`minimax/`)** - $0.2/1M:
|
||||
|
||||
- `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** - GRATUITO:
|
||||
|
||||
- `if/kimi-k2-thinking`
|
||||
- `if/qwen3-coder-plus`
|
||||
- `if/deepseek-r1`
|
||||
- `if/glm-4.7`
|
||||
- `if/minimax-m2`
|
||||
|
||||
**Qwen (`qw/`)** - GRATUITO:
|
||||
|
||||
- `qw/qwen3-coder-plus`
|
||||
- `qw/qwen3-coder-flash`
|
||||
|
||||
**Kiro (`kr/`)** - GRATUITO:
|
||||
|
||||
- `kr/claude-sonnet-4.5`
|
||||
- `kr/claude-haiku-4.5`
|
||||
|
||||
**OpenRouter (`or/`)** - 100+ modelli:
|
||||
|
||||
- `or/anthropic/claude-4-sonnet`
|
||||
- `or/google/gemini-2.5-pro`
|
||||
- Qualsiasi modello da [openrouter.ai/models](https://openrouter.ai/models)
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Valutazioni (Evals)
|
||||
|
||||
OmniRoute include un framework di valutazione integrato per testare la qualità delle risposte LLM contro un golden set. Accesso via **Analytics → Evals** nella dashboard.
|
||||
@@ -892,7 +849,7 @@ Il "OmniRoute Golden Set" precaricato contiene 10 casi di test:
|
||||
**Il test di connessione mostra "Invalid" per provider compatibili OpenAI**
|
||||
|
||||
- Molti provider non espongono l'endpoint `/models`
|
||||
- OmniRoute v1.0.0+ include validazione fallback tramite chat completions
|
||||
- OmniRoute v1.0.6+ include validazione fallback tramite chat completions
|
||||
- Assicurati che la URL base includa il suffisso `/v1`
|
||||
|
||||
</details>
|
||||
@@ -902,7 +859,7 @@ Il "OmniRoute Golden Set" precaricato contiene 10 casi di test:
|
||||
## 🛠️ Stack Tecnologico
|
||||
|
||||
- **Runtime**: Node.js 20+
|
||||
- **Linguaggio**: TypeScript 5.9 — **100% TypeScript** in `src/` e `open-sse/` (v1.0.0)
|
||||
- **Linguaggio**: TypeScript 5.9 — **100% TypeScript** in `src/` e `open-sse/` (v1.0.6)
|
||||
- **Framework**: Next.js 16 + React 19 + Tailwind CSS 4
|
||||
- **Database**: LowDB (JSON) + SQLite (stato dominio + log proxy)
|
||||
- **Streaming**: Server-Sent Events (SSE)
|
||||
@@ -932,9 +889,13 @@ Il "OmniRoute Golden Set" precaricato contiene 10 casi di test:
|
||||
|
||||
## 📧 Supporto
|
||||
|
||||
> 💬 **Unisciti alla nostra community!** [Gruppo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Ottieni aiuto, condividi consigli e rimani aggiornato.
|
||||
|
||||
- **Sito Web**: [omniroute.online](https://omniroute.online)
|
||||
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
|
||||
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **WhatsApp**: [Gruppo della comunità](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
- **WhatsApp**: [Gruppo della comunità](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
- **Progetto Originale**: [9router di decolua](https://github.com/decolua/9router)
|
||||
|
||||
---
|
||||
@@ -957,7 +918,7 @@ Consulta [CONTRIBUTING.md](CONTRIBUTING.md) per le linee guida dettagliate.
|
||||
|
||||
```bash
|
||||
# Crea un rilascio — la pubblicazione npm avviene automaticamente
|
||||
gh release create v1.0.0 --title "v1.0.0" --generate-notes
|
||||
gh release create v1.0.6 --title "v1.0.6" --generate-notes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+1106
File diff suppressed because it is too large
Load Diff
+1111
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,20 @@ _Your universal API proxy — one endpoint, 36+ providers, zero downtime._
|
||||
|
||||
---
|
||||
|
||||
[](https://www.npmjs.com/package/omniroute)
|
||||
[](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
|
||||
[](https://omniroute.online)
|
||||
[](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
|
||||
[🌐 Website](https://omniroute.online) • [🚀 Quick Start](#-quick-start) • [💡 Features](#-key-features) • [📖 Docs](#-documentation) • [💰 Pricing](#-pricing-at-a-glance) • [💬 WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
|
||||
🌐 **Available in:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](README.pt-BR.md) | 🇪🇸 [Español](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [Italiano](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [Magyar](README.hu.md) | 🇮🇩 [Bahasa Indonesia](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Nederlands](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Portugal)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Polski](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [Filipino](README.phi.md)
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
### 🤖 Free AI Provider for your favorite coding agents
|
||||
|
||||
_Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway for unlimited coding._
|
||||
@@ -96,16 +110,15 @@ _Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway f
|
||||
|
||||
---
|
||||
|
||||
[](https://www.npmjs.com/package/omniroute)
|
||||
[](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
|
||||
[](https://omniroute.online)
|
||||
## 📧 Support
|
||||
|
||||
[🌐 Website](https://omniroute.online) • [🚀 Quick Start](#-quick-start) • [💡 Features](#-key-features) • [📖 Docs](#-documentation) • [💰 Pricing](#-pricing-at-a-glance)
|
||||
> 💬 **Join our community!** [WhatsApp Group](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Get help, share tips, and stay updated.
|
||||
|
||||
🌐 **Available in:** [English](README.md) | [Português](README.pt-BR.md) | [Español](README.es.md) | [Русский](README.ru.md) | [中文](README.zh-CN.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | [Italiano](README.it.md)
|
||||
|
||||
</div>
|
||||
- **Website**: [omniroute.online](https://omniroute.online)
|
||||
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
|
||||
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **WhatsApp**: [Community Group](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
- **Original Project**: [9router by decolua](https://github.com/decolua/9router)
|
||||
|
||||
---
|
||||
|
||||
@@ -167,12 +180,22 @@ omniroute
|
||||
|
||||
🎉 Dashboard opens at `http://localhost:20128`
|
||||
|
||||
| Command | Description |
|
||||
| ----------------------- | --------------------------------- |
|
||||
| `omniroute` | Start server (default port 20128) |
|
||||
| `omniroute --port 3000` | Use custom port |
|
||||
| `omniroute --no-open` | Don't auto-open browser |
|
||||
| `omniroute --help` | Show help |
|
||||
| Command | Description |
|
||||
| ----------------------- | ----------------------------------------------------------- |
|
||||
| `omniroute` | Start server (`PORT=20128`, API and dashboard on same port) |
|
||||
| `omniroute --port 3000` | Set canonical/API port to 3000 |
|
||||
| `omniroute --no-open` | Don't auto-open browser |
|
||||
| `omniroute --help` | Show help |
|
||||
|
||||
Optional split-port mode:
|
||||
|
||||
```bash
|
||||
PORT=20128 DASHBOARD_PORT=20129 omniroute
|
||||
# API: http://localhost:20128/v1
|
||||
# Dashboard: http://localhost:20129
|
||||
```
|
||||
|
||||
When ports are split, the API port serves only OpenAI-compatible routes (`/v1`, `/chat/completions`, `/responses`, `/models`, `/codex/*`).
|
||||
|
||||
**2. Connect a FREE provider:**
|
||||
|
||||
@@ -194,7 +217,7 @@ Claude Code/Codex/Gemini CLI/OpenClaw/Cursor/Cline Settings:
|
||||
```bash
|
||||
cp .env.example .env
|
||||
npm install
|
||||
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
|
||||
PORT=20128 DASHBOARD_PORT=20129 NEXT_PUBLIC_BASE_URL=http://localhost:20129 npm run dev
|
||||
```
|
||||
|
||||
---
|
||||
@@ -242,7 +265,44 @@ docker compose --profile cli up -d
|
||||
| Image | Tag | Size | Description |
|
||||
| ------------------------ | -------- | ------ | --------------------- |
|
||||
| `diegosouzapw/omniroute` | `latest` | ~250MB | Latest stable release |
|
||||
| `diegosouzapw/omniroute` | `1.0.0` | ~250MB | Current version |
|
||||
| `diegosouzapw/omniroute` | `1.0.3` | ~250MB | Current version |
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Desktop App — Offline & Always-On
|
||||
|
||||
> 🆕 **NEW!** OmniRoute is now available as a **native desktop application** for Windows, macOS, and Linux.
|
||||
|
||||
Run OmniRoute as a standalone desktop app — no terminal, no browser, no internet required for local models. The Electron-based app includes:
|
||||
|
||||
- 🖥️ **Native Window** — Dedicated app window with system tray integration
|
||||
- 🔄 **Auto-Start** — Launch OmniRoute on system login
|
||||
- 🔔 **Native Notifications** — Get alerts for quota exhaustion or provider issues
|
||||
- ⚡ **One-Click Install** — NSIS (Windows), DMG (macOS), AppImage (Linux)
|
||||
- 🌐 **Offline Mode** — Works fully offline with bundled server
|
||||
|
||||
### Quick Start
|
||||
|
||||
```bash
|
||||
# Development mode
|
||||
npm run electron:dev
|
||||
|
||||
# Build for your platform
|
||||
npm run electron:build # Current platform
|
||||
npm run electron:build:win # Windows (.exe)
|
||||
npm run electron:build:mac # macOS (.dmg) — x64 & arm64
|
||||
npm run electron:build:linux # Linux (.AppImage)
|
||||
```
|
||||
|
||||
### System Tray
|
||||
|
||||
When minimized, OmniRoute lives in your system tray with quick actions:
|
||||
|
||||
- Open dashboard
|
||||
- Change server port
|
||||
- Quit application
|
||||
|
||||
📖 Full documentation: [`electron/README.md`](electron/README.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -271,6 +331,166 @@ docker compose --profile cli up -d
|
||||
|
||||
---
|
||||
|
||||
## 💡 Key Features
|
||||
|
||||
### 🧠 Core Routing & Intelligence
|
||||
|
||||
| Feature | What It Does |
|
||||
| ------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| 🎯 **Smart 4-Tier Fallback** | Auto-route: Subscription → API Key → Cheap → Free |
|
||||
| 📊 **Real-Time Quota Tracking** | Live token count + reset countdown per provider |
|
||||
| 🔄 **Format Translation** | OpenAI ↔ Claude ↔ Gemini ↔ Cursor ↔ Kiro seamless + response sanitization |
|
||||
| 👥 **Multi-Account Support** | Multiple accounts per provider with intelligent selection |
|
||||
| 🔄 **Auto Token Refresh** | OAuth tokens refresh automatically with retry |
|
||||
| 🎨 **Custom Combos** | 6 strategies: fill-first, round-robin, p2c, random, least-used, cost-optimized |
|
||||
| 🧩 **Custom Models** | Add any model ID to any provider |
|
||||
| 🌐 **Wildcard Router** | Route `provider/*` patterns to any provider dynamically |
|
||||
| 🧠 **Thinking Budget** | Passthrough, auto, custom, and adaptive modes for reasoning models |
|
||||
| 💬 **System Prompt Injection** | Global system prompt applied across all requests |
|
||||
| 📄 **Responses API** | Full OpenAI Responses API (`/v1/responses`) support for Codex |
|
||||
|
||||
### 🎵 Multi-Modal APIs
|
||||
|
||||
| Feature | What It Does |
|
||||
| -------------------------- | --------------------------------------------------- |
|
||||
| 🖼️ **Image Generation** | `/v1/images/generations` — 4 providers, 9+ models |
|
||||
| 📐 **Embeddings** | `/v1/embeddings` — 6 providers, 9+ models |
|
||||
| 🎤 **Audio Transcription** | `/v1/audio/transcriptions` — Whisper-compatible |
|
||||
| 🔊 **Text-to-Speech** | `/v1/audio/speech` — Multi-provider audio synthesis |
|
||||
| 🛡️ **Moderations** | `/v1/moderations` — Content safety checks |
|
||||
| 🔀 **Reranking** | `/v1/rerank` — Document relevance reranking |
|
||||
|
||||
### 🛡️ Resilience & Security
|
||||
|
||||
| Feature | What It Does |
|
||||
| ------------------------------- | ----------------------------------------------------------------------------- |
|
||||
| 🔌 **Circuit Breaker** | Auto-open/close per-provider with configurable thresholds |
|
||||
| 🛡️ **Anti-Thundering Herd** | Mutex + semaphore rate-limit for API key providers |
|
||||
| 🧠 **Semantic Cache** | Two-tier cache (signature + semantic) reduces cost & latency |
|
||||
| ⚡ **Request Idempotency** | 5s dedup window for duplicate requests |
|
||||
| 🔒 **TLS Fingerprint Spoofing** | Bypass TLS-based bot detection via wreq-js |
|
||||
| 🌐 **IP Filtering** | Allowlist/blocklist for API access control |
|
||||
| 📊 **Editable Rate Limits** | Configurable RPM, min gap, and max concurrent at system level |
|
||||
| 🛡 **API Endpoint Protection** | Auth gating + provider blocking for the `/models` endpoint |
|
||||
| 🔒 **Proxy Visibility** | Color-coded badges: 🟢 global, 🟡 provider, 🔵 per-connection with IP display |
|
||||
| 🌐 **3-Level Proxy Config** | Configure proxies at global, per-provider, or per-connection level |
|
||||
|
||||
### 📊 Observability & Analytics
|
||||
|
||||
| Feature | What It Does |
|
||||
| -------------------------- | ---------------------------------------------------------------------- |
|
||||
| 📝 **Request Logging** | Debug mode with full request/response logs |
|
||||
| 💾 **SQLite Proxy Logs** | Persistent proxy logs survive server restarts |
|
||||
| 📊 **Analytics Dashboard** | Recharts-powered: stat cards, model usage chart, provider table |
|
||||
| 📈 **Progress Tracking** | Opt-in SSE progress events for streaming |
|
||||
| 🧪 **LLM Evaluations** | Golden set testing with 4 match strategies |
|
||||
| 🔍 **Request Telemetry** | p50/p95/p99 latency aggregation + X-Request-Id tracing |
|
||||
| 📋 **Logs Dashboard** | Unified 4-tab page: Request Logs, Proxy Logs, Audit Logs, Console |
|
||||
| 🖥️ **Console Log Viewer** | Real-time terminal-style viewer with level filter, search, auto-scroll |
|
||||
| 📑 **File-Based Logging** | Console interceptor captures all output to JSON log file with rotation |
|
||||
| 🏥 **Health Dashboard** | System uptime, circuit breaker states, lockouts, cache stats |
|
||||
| 💰 **Cost Tracking** | Budget management + per-model pricing configuration |
|
||||
|
||||
### ☁️ Deployment & Sync
|
||||
|
||||
| Feature | What It Does |
|
||||
| ---------------------------- | --------------------------------------------------------------------- |
|
||||
| 💾 **Cloud Sync** | Sync config across devices via Cloudflare Workers |
|
||||
| 🌐 **Deploy Anywhere** | Localhost, VPS, Docker, Cloudflare Workers |
|
||||
| 🔑 **API Key Management** | Generate, rotate, and scope API keys per provider |
|
||||
| 🧙 **Onboarding Wizard** | 4-step guided setup for first-time users |
|
||||
| 🔧 **CLI Tools Dashboard** | One-click configure Claude, Codex, Cline, OpenClaw, Kilo, Antigravity |
|
||||
| 🔄 **DB Backups** | Automatic backup, restore, export & import for all settings |
|
||||
| 🌐 **Internationalization** | Full i18n with next-intl — 30 languages including RTL support |
|
||||
| 🌍 **Language Selector** | Globe icon in header for real-time switching between 30 languages |
|
||||
| 📂 **Custom Data Directory** | `DATA_DIR` env var to override default `~/.omniroute` storage path |
|
||||
|
||||
<details>
|
||||
<summary><b>📖 Feature Details</b></summary>
|
||||
|
||||
### 🎯 Smart 4-Tier Fallback
|
||||
|
||||
Create combos with automatic fallback:
|
||||
|
||||
```
|
||||
Combo: "my-coding-stack"
|
||||
1. cc/claude-opus-4-6 (your subscription)
|
||||
2. nvidia/llama-3.3-70b (free NVIDIA API)
|
||||
3. glm/glm-4.7 (cheap backup, $0.6/1M)
|
||||
4. if/kimi-k2-thinking (free fallback)
|
||||
|
||||
→ Auto switches when quota runs out or errors occur
|
||||
```
|
||||
|
||||
### 📊 Real-Time Quota Tracking
|
||||
|
||||
- Token consumption per provider
|
||||
- Reset countdown (5-hour, daily, weekly)
|
||||
- Cost estimation for paid tiers
|
||||
- Monthly spending reports
|
||||
|
||||
### 🔄 Format Translation
|
||||
|
||||
Seamless translation between formats:
|
||||
|
||||
- **OpenAI** ↔ **Claude** ↔ **Gemini** ↔ **OpenAI Responses**
|
||||
- Your CLI tool sends OpenAI format → OmniRoute translates → Provider receives native format
|
||||
- Works with any tool that supports custom OpenAI endpoints
|
||||
- **Response sanitization** — Strips non-standard fields for strict OpenAI SDK compatibility
|
||||
- **Role normalization** — `developer` → `system` for non-OpenAI; `system` → `user` for GLM/ERNIE models
|
||||
- **Think tag extraction** — `<think>` blocks → `reasoning_content` for thinking models
|
||||
- **Structured output** — `json_schema` → Gemini's `responseMimeType`/`responseSchema`
|
||||
|
||||
### 👥 Multi-Account Support
|
||||
|
||||
- Add multiple accounts per provider
|
||||
- Auto round-robin or priority-based routing
|
||||
- Fallback to next account when one hits quota
|
||||
|
||||
### 🔄 Auto Token Refresh
|
||||
|
||||
- OAuth tokens automatically refresh before expiration
|
||||
- No manual re-authentication needed
|
||||
- Seamless experience across all providers
|
||||
|
||||
### 🎨 Custom Combos
|
||||
|
||||
- Create unlimited model combinations
|
||||
- 6 strategies: fill-first, round-robin, power-of-two-choices, random, least-used, cost-optimized
|
||||
- Share combos across devices with Cloud Sync
|
||||
|
||||
### 🏥 Health Dashboard
|
||||
|
||||
- System status (uptime, version, memory usage)
|
||||
- Circuit breaker states per provider (Closed/Open/Half-Open)
|
||||
- Rate limit status and active lockouts
|
||||
- Signature cache statistics
|
||||
- Latency telemetry (p50/p95/p99) + prompt cache
|
||||
- Reset health status with one click
|
||||
|
||||
### 🔧 Translator Playground
|
||||
|
||||
OmniRoute includes a powerful built-in Translator Playground with **4 modes** for debugging, testing, and monitoring API translations:
|
||||
|
||||
| Mode | Description |
|
||||
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **💻 Playground** | Direct format translation — paste any API request body and instantly see how OmniRoute translates it between provider formats (OpenAI ↔ Claude ↔ Gemini ↔ Responses API). Includes example templates and format auto-detection. |
|
||||
| **💬 Chat Tester** | Send real chat requests through OmniRoute and see the full round-trip: your input, the translated request, the provider response, and the translated response back. Invaluable for validating combo routing. |
|
||||
| **🧪 Test Bench** | Batch testing mode — define multiple test cases with different inputs and expected outputs, run them all at once, and compare results across providers and models. |
|
||||
| **📱 Live Monitor** | Real-time request monitoring — watch incoming requests as they flow through OmniRoute, see format translations happening live, and identify issues instantly. |
|
||||
|
||||
**Access:** Dashboard → Translator (sidebar)
|
||||
|
||||
### 💾 Cloud Sync
|
||||
|
||||
- Sync providers, combos, and settings across devices
|
||||
- Automatic background sync
|
||||
- Secure encrypted storage
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Use Cases
|
||||
|
||||
### Case 1: "I have Claude Pro subscription"
|
||||
@@ -332,154 +552,6 @@ Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
|
||||
---
|
||||
|
||||
## 💡 Key Features
|
||||
|
||||
### 🧠 Core Routing & Intelligence
|
||||
|
||||
| Feature | What It Does |
|
||||
| ------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| 🎯 **Smart 4-Tier Fallback** | Auto-route: Subscription → API Key → Cheap → Free |
|
||||
| 📊 **Real-Time Quota Tracking** | Live token count + reset countdown per provider |
|
||||
| 🔄 **Format Translation** | OpenAI ↔ Claude ↔ Gemini ↔ Cursor ↔ Kiro seamless |
|
||||
| 👥 **Multi-Account Support** | Multiple accounts per provider with intelligent selection |
|
||||
| 🔄 **Auto Token Refresh** | OAuth tokens refresh automatically with retry |
|
||||
| 🎨 **Custom Combos** | 6 strategies: fill-first, round-robin, p2c, random, least-used, cost-optimized |
|
||||
| 🧩 **Custom Models** | Add any model ID to any provider |
|
||||
| 🌐 **Wildcard Router** | Route `provider/*` patterns to any provider dynamically |
|
||||
| 🧠 **Thinking Budget** | Passthrough, auto, custom, and adaptive modes for reasoning models |
|
||||
| 💬 **System Prompt Injection** | Global system prompt applied across all requests |
|
||||
| 📄 **Responses API** | Full OpenAI Responses API (`/v1/responses`) support for Codex |
|
||||
|
||||
### 🎵 Multi-Modal APIs
|
||||
|
||||
| Feature | What It Does |
|
||||
| -------------------------- | --------------------------------------------------- |
|
||||
| 🖼️ **Image Generation** | `/v1/images/generations` — 4 providers, 9+ models |
|
||||
| 📐 **Embeddings** | `/v1/embeddings` — 6 providers, 9+ models |
|
||||
| 🎤 **Audio Transcription** | `/v1/audio/transcriptions` — Whisper-compatible |
|
||||
| 🔊 **Text-to-Speech** | `/v1/audio/speech` — Multi-provider audio synthesis |
|
||||
| 🛡️ **Moderations** | `/v1/moderations` — Content safety checks |
|
||||
| 🔀 **Reranking** | `/v1/rerank` — Document relevance reranking |
|
||||
|
||||
### 🛡️ Resilience & Security
|
||||
|
||||
| Feature | What It Does |
|
||||
| ------------------------------- | ------------------------------------------------------------- |
|
||||
| 🔌 **Circuit Breaker** | Auto-open/close per-provider with configurable thresholds |
|
||||
| 🛡️ **Anti-Thundering Herd** | Mutex + semaphore rate-limit for API key providers |
|
||||
| 🧠 **Semantic Cache** | Two-tier cache (signature + semantic) reduces cost & latency |
|
||||
| ⚡ **Request Idempotency** | 5s dedup window for duplicate requests |
|
||||
| 🔒 **TLS Fingerprint Spoofing** | Bypass TLS-based bot detection via wreq-js |
|
||||
| 🌐 **IP Filtering** | Allowlist/blocklist for API access control |
|
||||
| 📊 **Editable Rate Limits** | Configurable RPM, min gap, and max concurrent at system level |
|
||||
|
||||
### 📊 Observability & Analytics
|
||||
|
||||
| Feature | What It Does |
|
||||
| ---------------------------- | --------------------------------------------------------------- |
|
||||
| 📝 **Request Logging** | Debug mode with full request/response logs |
|
||||
| 💾 **SQLite Proxy Logs** | Persistent proxy logs survive server restarts |
|
||||
| 📊 **Analytics Dashboard** | Recharts-powered: stat cards, model usage chart, provider table |
|
||||
| 📈 **Progress Tracking** | Opt-in SSE progress events for streaming |
|
||||
| 🧪 **LLM Evaluations** | Golden set testing with 4 match strategies |
|
||||
| 🔍 **Request Telemetry** | p50/p95/p99 latency aggregation + X-Request-Id tracing |
|
||||
| 📋 **Request Logs + Quotas** | Dedicated pages for log browsing and limits/quotas tracking |
|
||||
| 🏥 **Health Dashboard** | System uptime, circuit breaker states, lockouts, cache stats |
|
||||
| 💰 **Cost Tracking** | Budget management + per-model pricing configuration |
|
||||
|
||||
### ☁️ Deployment & Sync
|
||||
|
||||
| Feature | What It Does |
|
||||
| -------------------------- | --------------------------------------------------------------------- |
|
||||
| 💾 **Cloud Sync** | Sync config across devices via Cloudflare Workers |
|
||||
| 🌐 **Deploy Anywhere** | Localhost, VPS, Docker, Cloudflare Workers |
|
||||
| 🔑 **API Key Management** | Generate, rotate, and scope API keys per provider |
|
||||
| 🧙 **Onboarding Wizard** | 4-step guided setup for first-time users |
|
||||
| 🔧 **CLI Tools Dashboard** | One-click configure Claude, Codex, Cline, OpenClaw, Kilo, Antigravity |
|
||||
| 🔄 **DB Backups** | Automatic backup, restore, export & import for all settings |
|
||||
|
||||
<details>
|
||||
<summary><b>📖 Feature Details</b></summary>
|
||||
|
||||
### 🎯 Smart 4-Tier Fallback
|
||||
|
||||
Create combos with automatic fallback:
|
||||
|
||||
```
|
||||
Combo: "my-coding-stack"
|
||||
1. cc/claude-opus-4-6 (your subscription)
|
||||
2. nvidia/llama-3.3-70b (free NVIDIA API)
|
||||
3. glm/glm-4.7 (cheap backup, $0.6/1M)
|
||||
4. if/kimi-k2-thinking (free fallback)
|
||||
|
||||
→ Auto switches when quota runs out or errors occur
|
||||
```
|
||||
|
||||
### 📊 Real-Time Quota Tracking
|
||||
|
||||
- Token consumption per provider
|
||||
- Reset countdown (5-hour, daily, weekly)
|
||||
- Cost estimation for paid tiers
|
||||
- Monthly spending reports
|
||||
|
||||
### 🔄 Format Translation
|
||||
|
||||
Seamless translation between formats:
|
||||
|
||||
- **OpenAI** ↔ **Claude** ↔ **Gemini** ↔ **OpenAI Responses**
|
||||
- Your CLI tool sends OpenAI format → OmniRoute translates → Provider receives native format
|
||||
- Works with any tool that supports custom OpenAI endpoints
|
||||
|
||||
### 👥 Multi-Account Support
|
||||
|
||||
- Add multiple accounts per provider
|
||||
- Auto round-robin or priority-based routing
|
||||
- Fallback to next account when one hits quota
|
||||
|
||||
### 🔄 Auto Token Refresh
|
||||
|
||||
- OAuth tokens automatically refresh before expiration
|
||||
- No manual re-authentication needed
|
||||
- Seamless experience across all providers
|
||||
|
||||
### 🎨 Custom Combos
|
||||
|
||||
- Create unlimited model combinations
|
||||
- 6 strategies: fill-first, round-robin, power-of-two-choices, random, least-used, cost-optimized
|
||||
- Share combos across devices with Cloud Sync
|
||||
|
||||
### 🏥 Health Dashboard
|
||||
|
||||
- System status (uptime, version, memory usage)
|
||||
- Circuit breaker states per provider (Closed/Open/Half-Open)
|
||||
- Rate limit status and active lockouts
|
||||
- Signature cache statistics
|
||||
- Latency telemetry (p50/p95/p99) + prompt cache
|
||||
- Reset health status with one click
|
||||
|
||||
### 🔧 Translator Playground
|
||||
|
||||
OmniRoute includes a powerful built-in Translator Playground with **4 modes** for debugging, testing, and monitoring API translations:
|
||||
|
||||
| Mode | Description |
|
||||
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **💻 Playground** | Direct format translation — paste any API request body and instantly see how OmniRoute translates it between provider formats (OpenAI ↔ Claude ↔ Gemini ↔ Responses API). Includes example templates and format auto-detection. |
|
||||
| **💬 Chat Tester** | Send real chat requests through OmniRoute and see the full round-trip: your input, the translated request, the provider response, and the translated response back. Invaluable for validating combo routing. |
|
||||
| **🧪 Test Bench** | Batch testing mode — define multiple test cases with different inputs and expected outputs, run them all at once, and compare results across providers and models. |
|
||||
| **📱 Live Monitor** | Real-time request monitoring — watch incoming requests as they flow through OmniRoute, see format translations happening live, and identify issues instantly. |
|
||||
|
||||
**Access:** Dashboard → Translator (sidebar)
|
||||
|
||||
### 💾 Cloud Sync
|
||||
|
||||
- Sync providers, combos, and settings across devices
|
||||
- Automatic background sync
|
||||
- Secure encrypted storage
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 📖 Setup Guide
|
||||
|
||||
<details>
|
||||
@@ -760,74 +832,6 @@ Settings → API Configuration:
|
||||
|
||||
---
|
||||
|
||||
## 📊 Available Models
|
||||
|
||||
<details>
|
||||
<summary><b>View all available models</b></summary>
|
||||
|
||||
**Claude Code (`cc/`)** - Pro/Max:
|
||||
|
||||
- `cc/claude-opus-4-6`
|
||||
- `cc/claude-sonnet-4-5-20250929`
|
||||
- `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**Codex (`cx/`)** - Plus/Pro:
|
||||
|
||||
- `cx/gpt-5.2-codex`
|
||||
- `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** - FREE:
|
||||
|
||||
- `gc/gemini-3-flash-preview`
|
||||
- `gc/gemini-2.5-pro`
|
||||
|
||||
**GitHub Copilot (`gh/`)**:
|
||||
|
||||
- `gh/gpt-5`
|
||||
- `gh/claude-4.5-sonnet`
|
||||
|
||||
**NVIDIA NIM (`nvidia/`)** - FREE credits:
|
||||
|
||||
- `nvidia/llama-3.3-70b-instruct`
|
||||
- `nvidia/mistral-7b-instruct`
|
||||
- 50+ more models on [build.nvidia.com](https://build.nvidia.com)
|
||||
|
||||
**GLM (`glm/`)** - $0.6/1M:
|
||||
|
||||
- `glm/glm-4.7`
|
||||
|
||||
**MiniMax (`minimax/`)** - $0.2/1M:
|
||||
|
||||
- `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** - FREE:
|
||||
|
||||
- `if/kimi-k2-thinking`
|
||||
- `if/qwen3-coder-plus`
|
||||
- `if/deepseek-r1`
|
||||
- `if/glm-4.7`
|
||||
- `if/minimax-m2`
|
||||
|
||||
**Qwen (`qw/`)** - FREE:
|
||||
|
||||
- `qw/qwen3-coder-plus`
|
||||
- `qw/qwen3-coder-flash`
|
||||
|
||||
**Kiro (`kr/`)** - FREE:
|
||||
|
||||
- `kr/claude-sonnet-4.5`
|
||||
- `kr/claude-haiku-4.5`
|
||||
|
||||
**OpenRouter (`or/`)** - 100+ models:
|
||||
|
||||
- `or/anthropic/claude-4-sonnet`
|
||||
- `or/google/gemini-2.5-pro`
|
||||
- Any model from [openrouter.ai/models](https://openrouter.ai/models)
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Evaluations (Evals)
|
||||
|
||||
OmniRoute includes a built-in evaluation framework to test LLM response quality against a golden set. Access it via **Analytics → Evals** in the dashboard.
|
||||
@@ -877,9 +881,12 @@ The pre-loaded "OmniRoute Golden Set" contains 10 test cases covering:
|
||||
- Switch primary model to GLM/MiniMax
|
||||
- Use free tier (Gemini CLI, iFlow) for non-critical tasks
|
||||
|
||||
**Dashboard opens on wrong port**
|
||||
**Dashboard/API ports are wrong**
|
||||
|
||||
- Set `PORT=20128` and `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
|
||||
- `PORT` is the canonical base port (and API port by default)
|
||||
- `API_PORT` overrides only OpenAI-compatible API listener
|
||||
- `DASHBOARD_PORT` overrides only dashboard/Next.js listener
|
||||
- Set `NEXT_PUBLIC_BASE_URL` to your dashboard/public URL (for OAuth callbacks)
|
||||
|
||||
**Cloud sync errors**
|
||||
|
||||
@@ -899,17 +906,108 @@ The pre-loaded "OmniRoute Golden Set" contains 10 test cases covering:
|
||||
**Connection test shows "Invalid" for OpenAI-compatible providers**
|
||||
|
||||
- Many providers don't expose a `/models` endpoint
|
||||
- OmniRoute v1.0.0+ includes fallback validation via chat completions
|
||||
- OmniRoute v1.0.6+ includes fallback validation via chat completions
|
||||
- Ensure base URL includes `/v1` suffix
|
||||
|
||||
### 🔐 OAuth em Servidor Remoto (Remote OAuth Setup)
|
||||
|
||||
<a name="oauth-em-servidor-remoto"></a>
|
||||
|
||||
> **⚠️ IMPORTANTE para usuários com OmniRoute em VPS/Docker/servidor remoto**
|
||||
|
||||
#### Por que o OAuth do Antigravity / Gemini CLI falha em servidores remotos?
|
||||
|
||||
Os provedores **Antigravity** e **Gemini CLI** usam **Google OAuth 2.0** para autenticação. O Google exige que a `redirect_uri` usada no fluxo OAuth seja **exatamente** uma das URIs pré-cadastradas no Google Cloud Console do aplicativo.
|
||||
|
||||
As credenciais OAuth embutidas no OmniRoute estão cadastradas **apenas para `localhost`**. Quando você acessa o OmniRoute em um servidor remoto (ex: `https://omniroute.meuservidor.com`), o Google rejeita a autenticação com:
|
||||
|
||||
```
|
||||
Error 400: redirect_uri_mismatch
|
||||
```
|
||||
|
||||
#### Solução: Configure suas próprias credenciais OAuth
|
||||
|
||||
Você precisa criar um **OAuth 2.0 Client ID** no Google Cloud Console com a URI do seu servidor.
|
||||
|
||||
#### Passo a passo
|
||||
|
||||
**1. Acesse o 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**
|
||||
|
||||
- Clique em **"+ Create Credentials"** → **"OAuth client ID"**
|
||||
- Tipo de aplicativo: **"Web application"**
|
||||
- Nome: escolha qualquer nome (ex: `OmniRoute Remote`)
|
||||
|
||||
**3. Adicione as Authorized Redirect URIs**
|
||||
|
||||
No campo **"Authorized redirect URIs"**, adicione:
|
||||
|
||||
```
|
||||
https://seu-servidor.com/callback
|
||||
```
|
||||
|
||||
> Substitua `seu-servidor.com` pelo domínio ou IP do seu servidor (inclua a porta se necessário, ex: `http://45.33.32.156:20128/callback`).
|
||||
|
||||
**4. Salve e copie as credenciais**
|
||||
|
||||
Após criar, o Google mostrará o **Client ID** e o **Client Secret**.
|
||||
|
||||
**5. Configure as 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. Tente conectar novamente**
|
||||
|
||||
Dashboard → Providers → Antigravity (ou Gemini CLI) → OAuth
|
||||
|
||||
Agora o Google redirecionará corretamente para `https://seu-servidor.com/callback` e a autenticação funcionará.
|
||||
|
||||
---
|
||||
|
||||
#### Workaround temporário (sem configurar credenciais próprias)
|
||||
|
||||
Se não quiser criar credenciais próprias agora, ainda é possível usar o fluxo **manual de URL**:
|
||||
|
||||
1. O OmniRoute abrirá a URL de autorização do Google
|
||||
2. Após você autorizar, o Google tentará redirecionar para `localhost` (que falha no servidor remoto)
|
||||
3. **Copie a URL completa** da barra de endereço do seu browser (mesmo que a página não carregue)
|
||||
4. Cole essa URL no campo que aparece no modal de conexão do OmniRoute
|
||||
5. Clique em **"Connect"**
|
||||
|
||||
> Este workaround funciona porque o código de autorização na URL é válido independente do redirect ter carregado ou não.
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Tech Stack
|
||||
|
||||
- **Runtime**: Node.js 20+
|
||||
- **Language**: TypeScript 5.9 — **100% TypeScript** across `src/` and `open-sse/` (v1.0.0)
|
||||
- **Runtime**: Node.js 18–22 LTS (⚠️ Node.js 24+ is **not supported** — `better-sqlite3` native binaries are incompatible)
|
||||
- **Language**: TypeScript 5.9 — **100% TypeScript** across `src/` and `open-sse/` (v1.0.6)
|
||||
- **Framework**: Next.js 16 + React 19 + Tailwind CSS 4
|
||||
- **Database**: LowDB (JSON) + SQLite (domain state + proxy logs)
|
||||
- **Streaming**: Server-Sent Events (SSE)
|
||||
@@ -983,15 +1081,6 @@ OmniRoute has **210+ features planned** across multiple development phases. Here
|
||||
|
||||
---
|
||||
|
||||
## 📧 Support
|
||||
|
||||
- **Website**: [omniroute.online](https://omniroute.online)
|
||||
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
|
||||
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **Original Project**: [9router by decolua](https://github.com/decolua/9router)
|
||||
|
||||
---
|
||||
|
||||
## 👥 Contributors
|
||||
|
||||
[](https://github.com/diegosouzapw/OmniRoute/graphs/contributors)
|
||||
@@ -1010,7 +1099,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
|
||||
|
||||
```bash
|
||||
# Create a release — npm publish happens automatically
|
||||
gh release create v1.0.0 --title "v1.0.0" --generate-notes
|
||||
gh release create v1.0.6 --title "v1.0.6" --generate-notes
|
||||
```
|
||||
|
||||
---
|
||||
@@ -1046,3 +1135,4 @@ MIT License - see [LICENSE](LICENSE) for details.
|
||||
<br/>
|
||||
<sub><a href="https://omniroute.online">omniroute.online</a></sub>
|
||||
</div>
|
||||
<!-- GitHub Discussions enabled for community Q&A -->
|
||||
|
||||
+1111
File diff suppressed because it is too large
Load Diff
+1111
File diff suppressed because it is too large
Load Diff
+1111
File diff suppressed because it is too large
Load Diff
+1111
File diff suppressed because it is too large
Load Diff
+1111
File diff suppressed because it is too large
Load Diff
+124
-143
@@ -100,10 +100,11 @@ _Conecte qualquer IDE ou ferramenta CLI com IA através do OmniRoute — gateway
|
||||
[](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
|
||||
[](https://omniroute.online)
|
||||
[](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
|
||||
[🌐 Website](https://omniroute.online) • [🚀 Início Rápido](#-início-rápido) • [💡 Funcionalidades](#-funcionalidades-principais) • [📖 Docs](#-documentação) • [💰 Preços](#-preços-resumidos)
|
||||
|
||||
🌐 **Disponível em:** [English](README.md) | [Português](README.pt-BR.md) | [Español](README.es.md) | [Русский](README.ru.md) | [中文](README.zh-CN.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | [Italiano](README.it.md)
|
||||
🌐 **Available in:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](README.pt-BR.md) | 🇪🇸 [Español](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [Italiano](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [Magyar](README.hu.md) | 🇮🇩 [Bahasa Indonesia](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Nederlands](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Portugal)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Polski](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [Filipino](README.phi.md)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -242,7 +243,46 @@ docker compose --profile cli up -d
|
||||
| Imagem | Tag | Tamanho | Descrição |
|
||||
| ------------------------ | -------- | ------- | --------------------- |
|
||||
| `diegosouzapw/omniroute` | `latest` | ~250MB | Última versão estável |
|
||||
| `diegosouzapw/omniroute` | `1.0.0` | ~250MB | Versão atual |
|
||||
| `diegosouzapw/omniroute` | `1.0.6` | ~250MB | Versão atual |
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Aplicativo Desktop — Offline e Sempre Ativo
|
||||
|
||||
> 🆕 **NOVO!** O OmniRoute agora está disponível como **aplicativo desktop nativo** para Windows, macOS e Linux.
|
||||
|
||||
Execute o OmniRoute como um aplicativo desktop autônomo — sem terminal, sem navegador, sem internet necessária para modelos locais. O app baseado em Electron inclui:
|
||||
|
||||
- 🖥️ **Janela Nativa** — Janela dedicada com integração à bandeja do sistema
|
||||
- 🔄 **Iniciar Automaticamente** — Inicie o OmniRoute ao fazer login no sistema
|
||||
- 🔔 **Notificações Nativas** — Receba alertas sobre esgotamento de cota ou problemas
|
||||
- ⚡ **Instalação com Um Clique** — NSIS (Windows), DMG (macOS), AppImage (Linux)
|
||||
- 🌐 **Modo Offline** — Funciona totalmente offline com servidor embarcado
|
||||
|
||||
### Início Rápido
|
||||
|
||||
```bash
|
||||
# Modo desenvolvimento
|
||||
npm run electron:dev
|
||||
|
||||
# Compilar para sua plataforma
|
||||
npm run electron:build # Plataforma atual
|
||||
npm run electron:build:win # Windows (.exe)
|
||||
npm run electron:build:mac # macOS (.dmg) — x64 & arm64
|
||||
npm run electron:build:linux # Linux (.AppImage)
|
||||
```
|
||||
|
||||
### Bandeja do Sistema
|
||||
|
||||
Quando minimizado, o OmniRoute fica na bandeja do sistema com ações rápidas:
|
||||
|
||||
- Abrir dashboard
|
||||
- Alterar porta do servidor
|
||||
- Sair do aplicativo
|
||||
|
||||
📖 Documentação completa: [`electron/README.md`](electron/README.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -271,67 +311,6 @@ docker compose --profile cli up -d
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Casos de Uso
|
||||
|
||||
### Caso 1: "Tenho assinatura Claude Pro"
|
||||
|
||||
**Problema:** Cota expira sem uso, limites de taxa durante programação intensa
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (usar assinatura ao máximo)
|
||||
2. glm/glm-4.7 (backup barato quando a cota acabar)
|
||||
3. if/kimi-k2-thinking (fallback de emergência gratuito)
|
||||
|
||||
Custo mensal: $20 (assinatura) + ~$5 (backup) = $25 total
|
||||
vs. $20 + bater em limites = frustração
|
||||
```
|
||||
|
||||
### Caso 2: "Quero custo zero"
|
||||
|
||||
**Problema:** Não pode pagar assinaturas, precisa de IA confiável para programar
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K grátis/mês)
|
||||
2. if/kimi-k2-thinking (ilimitado grátis)
|
||||
3. qw/qwen3-coder-plus (ilimitado grátis)
|
||||
|
||||
Custo mensal: $0
|
||||
Qualidade: Modelos prontos para produção
|
||||
```
|
||||
|
||||
### Caso 3: "Preciso programar 24/7, sem interrupções"
|
||||
|
||||
**Problema:** Prazos apertados, não pode ter tempo de inatividade
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (melhor qualidade)
|
||||
2. cx/gpt-5.2-codex (segunda assinatura)
|
||||
3. glm/glm-4.7 (barato, reset diário)
|
||||
4. minimax/MiniMax-M2.1 (mais barato, reset 5h)
|
||||
5. if/kimi-k2-thinking (gratuito ilimitado)
|
||||
|
||||
Resultado: 5 camadas de fallback = zero tempo de inatividade
|
||||
```
|
||||
|
||||
### Caso 4: "Quero IA GRATUITA no OpenClaw"
|
||||
|
||||
**Problema:** Precisa de assistente de IA em aplicativos de mensagens, completamente gratuito
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (ilimitado grátis)
|
||||
2. if/minimax-m2.1 (ilimitado grátis)
|
||||
3. if/kimi-k2-thinking (ilimitado grátis)
|
||||
|
||||
Custo mensal: $0
|
||||
Acesso via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 Funcionalidades Principais
|
||||
|
||||
### 🧠 Roteamento e Inteligência
|
||||
@@ -363,15 +342,18 @@ Acesso via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
|
||||
### 🛡️ Resiliência e Segurança
|
||||
|
||||
| Funcionalidade | O que Faz |
|
||||
| ---------------------------------- | --------------------------------------------------------------------- |
|
||||
| 🔌 **Circuit Breaker** | Auto-abertura/fechamento por provedor com limites configuráveis |
|
||||
| 🛡️ **Anti-Thundering Herd** | Mutex + semáforo rate-limit para provedores com API key |
|
||||
| 🧠 **Cache Semântico** | Cache de duas camadas (assinatura + semântico) reduz custo e latência |
|
||||
| ⚡ **Idempotência de Requisição** | Janela de dedup de 5s para requisições duplicadas |
|
||||
| 🔒 **Spoofing de Fingerprint TLS** | Bypass de detecção de bot via TLS com wreq-js |
|
||||
| 🌐 **Filtragem de IP** | Allowlist/blocklist para controle de acesso à API |
|
||||
| 📊 **Rate Limits Editáveis** | RPM, gap mínimo e concorrência máxima configuráveis |
|
||||
| Funcionalidade | O que Faz |
|
||||
| ---------------------------------- | --------------------------------------------------------------------------- |
|
||||
| 🔌 **Circuit Breaker** | Auto-abertura/fechamento por provedor com limites configuráveis |
|
||||
| 🛡️ **Anti-Thundering Herd** | Mutex + semáforo rate-limit para provedores com API key |
|
||||
| 🧠 **Cache Semântico** | Cache de duas camadas (assinatura + semântico) reduz custo e latência |
|
||||
| ⚡ **Idempotência de Requisição** | Janela de dedup de 5s para requisições duplicadas |
|
||||
| 🔒 **Spoofing de Fingerprint TLS** | Bypass de detecção de bot via TLS com wreq-js |
|
||||
| 🌐 **Filtragem de IP** | Allowlist/blocklist para controle de acesso à API |
|
||||
| 📊 **Rate Limits Editáveis** | RPM, gap mínimo e concorrência máxima configuráveis |
|
||||
| 🛡 **Proteção de Endpoint API** | Gateway de Auth + bloqueio de provedores para o endpoint `/models` |
|
||||
| 🔒 **Visibilidade de Proxy** | Badges coloridos: 🟢 global, 🟡 provedor, 🔵 por-conexão com exibição de IP |
|
||||
| 🌐 **Proxy em 3 Níveis** | Configure proxies em nível global, por provedor ou por conexão |
|
||||
|
||||
### 📊 Observabilidade e Analytics
|
||||
|
||||
@@ -397,6 +379,9 @@ Acesso via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
| 🧙 **Assistente de Configuração** | Setup guiado em 4 etapas para novos usuários |
|
||||
| 🔧 **Dashboard CLI Tools** | Configuração em um clique para Claude, Codex, Cline, OpenClaw, Kilo, Antigravity |
|
||||
| 🔄 **Backups de DB** | Backup, restauração, exportação e importação automática de todas as configurações |
|
||||
| 🌐 **Internacionalização** | i18n completo com next-intl — suporte a 30 idiomas com RTL |
|
||||
| 🌍 **Seletor de Idioma** | Ícone de globo no cabeçalho para troca entre 30 idiomas em tempo real |
|
||||
| 📂 **Diretório de Dados Custom** | Variável `DATA_DIR` para sobrescrever o caminho padrão `~/.omniroute` |
|
||||
|
||||
<details>
|
||||
<summary><b>📖 Detalhes das Funcionalidades</b></summary>
|
||||
@@ -480,6 +465,67 @@ O OmniRoute inclui um poderoso Playground de Tradução integrado com **4 modos*
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Casos de Uso
|
||||
|
||||
### Caso 1: "Tenho assinatura Claude Pro"
|
||||
|
||||
**Problema:** Cota expira sem uso, limites de taxa durante programação intensa
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (usar assinatura ao máximo)
|
||||
2. glm/glm-4.7 (backup barato quando a cota acabar)
|
||||
3. if/kimi-k2-thinking (fallback de emergência gratuito)
|
||||
|
||||
Custo mensal: $20 (assinatura) + ~$5 (backup) = $25 total
|
||||
vs. $20 + bater em limites = frustração
|
||||
```
|
||||
|
||||
### Caso 2: "Quero custo zero"
|
||||
|
||||
**Problema:** Não pode pagar assinaturas, precisa de IA confiável para programar
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K grátis/mês)
|
||||
2. if/kimi-k2-thinking (ilimitado grátis)
|
||||
3. qw/qwen3-coder-plus (ilimitado grátis)
|
||||
|
||||
Custo mensal: $0
|
||||
Qualidade: Modelos prontos para produção
|
||||
```
|
||||
|
||||
### Caso 3: "Preciso programar 24/7, sem interrupções"
|
||||
|
||||
**Problema:** Prazos apertados, não pode ter tempo de inatividade
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (melhor qualidade)
|
||||
2. cx/gpt-5.2-codex (segunda assinatura)
|
||||
3. glm/glm-4.7 (barato, reset diário)
|
||||
4. minimax/MiniMax-M2.1 (mais barato, reset 5h)
|
||||
5. if/kimi-k2-thinking (gratuito ilimitado)
|
||||
|
||||
Resultado: 5 camadas de fallback = zero tempo de inatividade
|
||||
```
|
||||
|
||||
### Caso 4: "Quero IA GRATUITA no OpenClaw"
|
||||
|
||||
**Problema:** Precisa de assistente de IA em aplicativos de mensagens, completamente gratuito
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (ilimitado grátis)
|
||||
2. if/minimax-m2.1 (ilimitado grátis)
|
||||
3. if/kimi-k2-thinking (ilimitado grátis)
|
||||
|
||||
Custo mensal: $0
|
||||
Acesso via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Guia de Configuração
|
||||
|
||||
<details>
|
||||
@@ -760,74 +806,6 @@ Configurações → Configuração de API:
|
||||
|
||||
---
|
||||
|
||||
## 📊 Modelos Disponíveis
|
||||
|
||||
<details>
|
||||
<summary><b>Ver todos os modelos disponíveis</b></summary>
|
||||
|
||||
**Claude Code (`cc/`)** - Pro/Max:
|
||||
|
||||
- `cc/claude-opus-4-6`
|
||||
- `cc/claude-sonnet-4-5-20250929`
|
||||
- `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**Codex (`cx/`)** - Plus/Pro:
|
||||
|
||||
- `cx/gpt-5.2-codex`
|
||||
- `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** - GRATUITO:
|
||||
|
||||
- `gc/gemini-3-flash-preview`
|
||||
- `gc/gemini-2.5-pro`
|
||||
|
||||
**GitHub Copilot (`gh/`)**:
|
||||
|
||||
- `gh/gpt-5`
|
||||
- `gh/claude-4.5-sonnet`
|
||||
|
||||
**NVIDIA NIM (`nvidia/`)** - Créditos GRATUITOS:
|
||||
|
||||
- `nvidia/llama-3.3-70b-instruct`
|
||||
- `nvidia/mistral-7b-instruct`
|
||||
- 50+ mais modelos em [build.nvidia.com](https://build.nvidia.com)
|
||||
|
||||
**GLM (`glm/`)** - $0.6/1M:
|
||||
|
||||
- `glm/glm-4.7`
|
||||
|
||||
**MiniMax (`minimax/`)** - $0.2/1M:
|
||||
|
||||
- `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** - GRATUITO:
|
||||
|
||||
- `if/kimi-k2-thinking`
|
||||
- `if/qwen3-coder-plus`
|
||||
- `if/deepseek-r1`
|
||||
- `if/glm-4.7`
|
||||
- `if/minimax-m2`
|
||||
|
||||
**Qwen (`qw/`)** - GRATUITO:
|
||||
|
||||
- `qw/qwen3-coder-plus`
|
||||
- `qw/qwen3-coder-flash`
|
||||
|
||||
**Kiro (`kr/`)** - GRATUITO:
|
||||
|
||||
- `kr/claude-sonnet-4.5`
|
||||
- `kr/claude-haiku-4.5`
|
||||
|
||||
**OpenRouter (`or/`)** - 100+ modelos:
|
||||
|
||||
- `or/anthropic/claude-4-sonnet`
|
||||
- `or/google/gemini-2.5-pro`
|
||||
- Qualquer modelo de [openrouter.ai/models](https://openrouter.ai/models)
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Avaliações (Evals)
|
||||
|
||||
OmniRoute inclui um framework de avaliação integrado para testar a qualidade de respostas de LLM contra um conjunto golden. Acesse via **Analytics → Evals** no dashboard.
|
||||
@@ -899,7 +877,7 @@ O "OmniRoute Golden Set" pré-carregado contém 10 casos de teste cobrindo:
|
||||
**Teste de conexão mostra "Invalid" para provedores compatíveis com OpenAI**
|
||||
|
||||
- Muitos provedores não expõem endpoint `/models`
|
||||
- OmniRoute v1.0.0+ inclui validação via chat completions como fallback
|
||||
- OmniRoute v1.0.6+ inclui validação via chat completions como fallback
|
||||
- Certifique-se de que a base URL inclui sufixo `/v1`
|
||||
|
||||
</details>
|
||||
@@ -909,7 +887,7 @@ O "OmniRoute Golden Set" pré-carregado contém 10 casos de teste cobrindo:
|
||||
## 🛠️ Stack Tecnológico
|
||||
|
||||
- **Runtime**: Node.js 20+
|
||||
- **Linguagem**: TypeScript 5.9 — **100% TypeScript** em `src/` e `open-sse/` (v1.0.0)
|
||||
- **Linguagem**: TypeScript 5.9 — **100% TypeScript** em `src/` e `open-sse/` (v1.0.6)
|
||||
- **Framework**: Next.js 16 + React 19 + Tailwind CSS 4
|
||||
- **Banco de Dados**: LowDB (JSON) + SQLite (estado do domínio + logs de proxy)
|
||||
- **Streaming**: Server-Sent Events (SSE)
|
||||
@@ -985,9 +963,12 @@ O OmniRoute tem **210+ funcionalidades planejadas** em múltiplas fases de desen
|
||||
|
||||
## 📧 Suporte
|
||||
|
||||
> 💬 **Participe da comunidade!** [Grupo WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Tire dúvidas, compartilhe dicas e fique atualizado.
|
||||
|
||||
- **Website**: [omniroute.online](https://omniroute.online)
|
||||
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
|
||||
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **WhatsApp**: [Grupo da Comunidade](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
- **Projeto Original**: [9router por decolua](https://github.com/decolua/9router)
|
||||
|
||||
---
|
||||
@@ -1010,7 +991,7 @@ Veja [CONTRIBUTING.md](CONTRIBUTING.md) para diretrizes detalhadas.
|
||||
|
||||
```bash
|
||||
# Crie um release — publicação no npm acontece automaticamente
|
||||
gh release create v1.0.0 --title "v1.0.0" --generate-notes
|
||||
gh release create v1.0.6 --title "v1.0.6" --generate-notes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+1111
File diff suppressed because it is too large
Load Diff
+1111
File diff suppressed because it is too large
Load Diff
+94
-134
@@ -100,10 +100,11 @@ _Подключайте любую IDE или CLI-инструмент с AI ч
|
||||
[](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
|
||||
[](https://omniroute.online)
|
||||
[](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
|
||||
[🌐 Сайт](https://omniroute.online) • [🚀 Быстрый старт](#-быстрый-старт) • [💡 Функции](#-основные-функции) • [📖 Документация](#-документация) • [💰 Цены](#-обзор-цен)
|
||||
|
||||
🌐 **Доступно на:** [English](README.md) | [Português](README.pt-BR.md) | [Español](README.es.md) | [Русский](README.ru.md) | [中文](README.zh-CN.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | [Italiano](README.it.md)
|
||||
🌐 **Available in:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](README.pt-BR.md) | 🇪🇸 [Español](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [Italiano](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [Magyar](README.hu.md) | 🇮🇩 [Bahasa Indonesia](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Nederlands](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Portugal)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Polski](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [Filipino](README.phi.md)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -242,7 +243,31 @@ docker compose --profile cli up -d
|
||||
| Образ | Тег | Размер | Описание |
|
||||
| ------------------------ | -------- | ------ | -------------------------- |
|
||||
| `diegosouzapw/omniroute` | `latest` | ~250MB | Последний стабильный релиз |
|
||||
| `diegosouzapw/omniroute` | `1.0.0` | ~250MB | Текущая версия |
|
||||
| `diegosouzapw/omniroute` | `1.0.6` | ~250MB | Текущая версия |
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Настольное Приложение — Оффлайн и Всегда Активно
|
||||
|
||||
> 🆕 **НОВИНКА!** OmniRoute теперь доступен как **нативное настольное приложение** для Windows, macOS и Linux.
|
||||
|
||||
- 🖥️ **Нативное Окно** — Выделенное окно с интеграцией в системный трей
|
||||
- 🔄 **Автозапуск** — Запуск OmniRoute при входе в систему
|
||||
- 🔔 **Нативные Уведомления** — Оповещения об исчерпании квоты
|
||||
- ⚡ **Установка в Один Клик** — NSIS (Windows), DMG (macOS), AppImage (Linux)
|
||||
- 🌐 **Оффлайн Режим** — Полностью работает без интернета
|
||||
|
||||
```bash
|
||||
npm run electron:dev # Режим разработки
|
||||
npm run electron:build # Текущая платформа
|
||||
npm run electron:build:win # Windows (.exe)
|
||||
npm run electron:build:mac # macOS (.dmg)
|
||||
npm run electron:build:linux # Linux (.AppImage)
|
||||
```
|
||||
|
||||
📖 Полная документация: [`electron/README.md`](electron/README.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -271,67 +296,6 @@ docker compose --profile cli up -d
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Сценарии использования
|
||||
|
||||
### Сценарий 1: «У меня подписка Claude Pro»
|
||||
|
||||
**Проблема:** Квота истекает неиспользованной, лимиты скорости во время интенсивного программирования
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (используйте подписку полностью)
|
||||
2. glm/glm-4.7 (дешёвый бэкап при исчерпании квоты)
|
||||
3. if/kimi-k2-thinking (бесплатный аварийный fallback)
|
||||
|
||||
Месячная стоимость: $20 (подписка) + ~$5 (бэкап) = $25 итого
|
||||
vs. $20 + упирание в лимиты = разочарование
|
||||
```
|
||||
|
||||
### Сценарий 2: «Хочу нулевую стоимость»
|
||||
|
||||
**Проблема:** Не может позволить подписки, нужен надёжный AI для программирования
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K бесплатно/мес)
|
||||
2. if/kimi-k2-thinking (неограниченно бесплатно)
|
||||
3. qw/qwen3-coder-plus (неограниченно бесплатно)
|
||||
|
||||
Месячная стоимость: $0
|
||||
Качество: Модели готовые к продакшену
|
||||
```
|
||||
|
||||
### Сценарий 3: «Мне нужно программировать 24/7, без перерывов»
|
||||
|
||||
**Проблема:** Дедлайны, не может позволить простой
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (лучшее качество)
|
||||
2. cx/gpt-5.2-codex (вторая подписка)
|
||||
3. glm/glm-4.7 (дешёвый, ежедневный сброс)
|
||||
4. minimax/MiniMax-M2.1 (самый дешёвый, сброс 5ч)
|
||||
5. if/kimi-k2-thinking (бесплатно неограниченно)
|
||||
|
||||
Результат: 5 уровней fallback = нулевой простой
|
||||
```
|
||||
|
||||
### Сценарий 4: «Хочу БЕСПЛАТНЫЙ AI в OpenClaw»
|
||||
|
||||
**Проблема:** Нужен AI-ассистент в мессенджерах, полностью бесплатно
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (неограниченно бесплатно)
|
||||
2. if/minimax-m2.1 (неограниченно бесплатно)
|
||||
3. if/kimi-k2-thinking (неограниченно бесплатно)
|
||||
|
||||
Месячная стоимость: $0
|
||||
Доступ через: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 Основные функции
|
||||
|
||||
### 🧠 Маршрутизация и интеллект
|
||||
@@ -473,6 +437,67 @@ Combo: "my-coding-stack"
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Сценарии использования
|
||||
|
||||
### Сценарий 1: «У меня подписка Claude Pro»
|
||||
|
||||
**Проблема:** Квота истекает неиспользованной, лимиты скорости во время интенсивного программирования
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (используйте подписку полностью)
|
||||
2. glm/glm-4.7 (дешёвый бэкап при исчерпании квоты)
|
||||
3. if/kimi-k2-thinking (бесплатный аварийный fallback)
|
||||
|
||||
Месячная стоимость: $20 (подписка) + ~$5 (бэкап) = $25 итого
|
||||
vs. $20 + упирание в лимиты = разочарование
|
||||
```
|
||||
|
||||
### Сценарий 2: «Хочу нулевую стоимость»
|
||||
|
||||
**Проблема:** Не может позволить подписки, нужен надёжный AI для программирования
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K бесплатно/мес)
|
||||
2. if/kimi-k2-thinking (неограниченно бесплатно)
|
||||
3. qw/qwen3-coder-plus (неограниченно бесплатно)
|
||||
|
||||
Месячная стоимость: $0
|
||||
Качество: Модели готовые к продакшену
|
||||
```
|
||||
|
||||
### Сценарий 3: «Мне нужно программировать 24/7, без перерывов»
|
||||
|
||||
**Проблема:** Дедлайны, не может позволить простой
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (лучшее качество)
|
||||
2. cx/gpt-5.2-codex (вторая подписка)
|
||||
3. glm/glm-4.7 (дешёвый, ежедневный сброс)
|
||||
4. minimax/MiniMax-M2.1 (самый дешёвый, сброс 5ч)
|
||||
5. if/kimi-k2-thinking (бесплатно неограниченно)
|
||||
|
||||
Результат: 5 уровней fallback = нулевой простой
|
||||
```
|
||||
|
||||
### Сценарий 4: «Хочу БЕСПЛАТНЫЙ AI в OpenClaw»
|
||||
|
||||
**Проблема:** Нужен AI-ассистент в мессенджерах, полностью бесплатно
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (неограниченно бесплатно)
|
||||
2. if/minimax-m2.1 (неограниченно бесплатно)
|
||||
3. if/kimi-k2-thinking (неограниченно бесплатно)
|
||||
|
||||
Месячная стоимость: $0
|
||||
Доступ через: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Руководство по настройке
|
||||
|
||||
<details>
|
||||
@@ -753,74 +778,6 @@ Dashboard → CLI Tools → OpenClaw → Выбрать модель → При
|
||||
|
||||
---
|
||||
|
||||
## 📊 Доступные модели
|
||||
|
||||
<details>
|
||||
<summary><b>Посмотреть все доступные модели</b></summary>
|
||||
|
||||
**Claude Code (`cc/`)** - Pro/Max:
|
||||
|
||||
- `cc/claude-opus-4-6`
|
||||
- `cc/claude-sonnet-4-5-20250929`
|
||||
- `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**Codex (`cx/`)** - Plus/Pro:
|
||||
|
||||
- `cx/gpt-5.2-codex`
|
||||
- `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** - БЕСПЛАТНО:
|
||||
|
||||
- `gc/gemini-3-flash-preview`
|
||||
- `gc/gemini-2.5-pro`
|
||||
|
||||
**GitHub Copilot (`gh/`)**:
|
||||
|
||||
- `gh/gpt-5`
|
||||
- `gh/claude-4.5-sonnet`
|
||||
|
||||
**NVIDIA NIM (`nvidia/`)** - БЕСПЛАТНЫЕ кредиты:
|
||||
|
||||
- `nvidia/llama-3.3-70b-instruct`
|
||||
- `nvidia/mistral-7b-instruct`
|
||||
- 50+ моделей на [build.nvidia.com](https://build.nvidia.com)
|
||||
|
||||
**GLM (`glm/`)** - $0.6/1M:
|
||||
|
||||
- `glm/glm-4.7`
|
||||
|
||||
**MiniMax (`minimax/`)** - $0.2/1M:
|
||||
|
||||
- `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** - БЕСПЛАТНО:
|
||||
|
||||
- `if/kimi-k2-thinking`
|
||||
- `if/qwen3-coder-plus`
|
||||
- `if/deepseek-r1`
|
||||
- `if/glm-4.7`
|
||||
- `if/minimax-m2`
|
||||
|
||||
**Qwen (`qw/`)** - БЕСПЛАТНО:
|
||||
|
||||
- `qw/qwen3-coder-plus`
|
||||
- `qw/qwen3-coder-flash`
|
||||
|
||||
**Kiro (`kr/`)** - БЕСПЛАТНО:
|
||||
|
||||
- `kr/claude-sonnet-4.5`
|
||||
- `kr/claude-haiku-4.5`
|
||||
|
||||
**OpenRouter (`or/`)** - 100+ моделей:
|
||||
|
||||
- `or/anthropic/claude-4-sonnet`
|
||||
- `or/google/gemini-2.5-pro`
|
||||
- Любая модель с [openrouter.ai/models](https://openrouter.ai/models)
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Оценки (Evals)
|
||||
|
||||
OmniRoute включает встроенный фреймворк оценки для тестирования качества ответов LLM по golden set. Доступ через **Analytics → Evals** в dashboard.
|
||||
@@ -892,7 +849,7 @@ OmniRoute включает встроенный фреймворк оценки
|
||||
**Тест подключения показывает «Invalid» для OpenAI-совместимых провайдеров**
|
||||
|
||||
- Многие провайдеры не предоставляют endpoint `/models`
|
||||
- OmniRoute v1.0.0+ включает fallback-валидацию через chat completions
|
||||
- OmniRoute v1.0.6+ включает fallback-валидацию через chat completions
|
||||
- Убедитесь что base URL содержит суффикс `/v1`
|
||||
|
||||
</details>
|
||||
@@ -902,7 +859,7 @@ OmniRoute включает встроенный фреймворк оценки
|
||||
## 🛠️ Технологический стек
|
||||
|
||||
- **Runtime**: Node.js 20+
|
||||
- **Язык**: TypeScript 5.9 — **100% TypeScript** в `src/` и `open-sse/` (v1.0.0)
|
||||
- **Язык**: TypeScript 5.9 — **100% TypeScript** в `src/` и `open-sse/` (v1.0.6)
|
||||
- **Framework**: Next.js 16 + React 19 + Tailwind CSS 4
|
||||
- **База данных**: LowDB (JSON) + SQLite (состояние домена + proxy-логи)
|
||||
- **Стриминг**: Server-Sent Events (SSE)
|
||||
@@ -932,9 +889,12 @@ OmniRoute включает встроенный фреймворк оценки
|
||||
|
||||
## 📧 Поддержка
|
||||
|
||||
> 💬 **Присоединяйтесь к сообществу!** [Группа WhatsApp](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — Получайте помощь, делитесь советами и оставайтесь в курсе.
|
||||
|
||||
- **Сайт**: [omniroute.online](https://omniroute.online)
|
||||
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
|
||||
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **WhatsApp**: [Группа сообщества](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
- **Оригинальный проект**: [9router от decolua](https://github.com/decolua/9router)
|
||||
|
||||
---
|
||||
@@ -957,7 +917,7 @@ OmniRoute включает встроенный фреймворк оценки
|
||||
|
||||
```bash
|
||||
# Создайте релиз — публикация в npm происходит автоматически
|
||||
gh release create v1.0.0 --title "v1.0.0" --generate-notes
|
||||
gh release create v1.0.6 --title "v1.0.6" --generate-notes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+1112
File diff suppressed because it is too large
Load Diff
+1111
File diff suppressed because it is too large
Load Diff
+1102
File diff suppressed because it is too large
Load Diff
+1113
File diff suppressed because it is too large
Load Diff
+1111
File diff suppressed because it is too large
Load Diff
+94
-134
@@ -100,10 +100,11 @@ _通过 OmniRoute 连接任何 AI 驱动的 IDE 或 CLI 工具 — 免费 API
|
||||
[](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
|
||||
[](https://omniroute.online)
|
||||
[](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
|
||||
[🌐 网站](https://omniroute.online) • [🚀 快速开始](#-快速开始) • [💡 功能特性](#-核心功能) • [📖 文档](#-文档) • [💰 定价](#-定价概览)
|
||||
|
||||
🌐 **多语言版本:** [English](README.md) | [Português](README.pt-BR.md) | [Español](README.es.md) | [Русский](README.ru.md) | [中文](README.zh-CN.md) | [Deutsch](README.de.md) | [Français](README.fr.md) | [Italiano](README.it.md)
|
||||
🌐 **Available in:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](README.pt-BR.md) | 🇪🇸 [Español](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [Italiano](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [Magyar](README.hu.md) | 🇮🇩 [Bahasa Indonesia](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Nederlands](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Portugal)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Polski](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [Filipino](README.phi.md)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -242,7 +243,31 @@ docker compose --profile cli up -d
|
||||
| 镜像 | 标签 | 大小 | 描述 |
|
||||
| ------------------------ | -------- | ------ | ---------- |
|
||||
| `diegosouzapw/omniroute` | `latest` | ~250MB | 最新稳定版 |
|
||||
| `diegosouzapw/omniroute` | `1.0.0` | ~250MB | 当前版本 |
|
||||
| `diegosouzapw/omniroute` | `1.0.6` | ~250MB | 当前版本 |
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ 桌面应用 — 离线 & 始终在线
|
||||
|
||||
> 🆕 **全新!** OmniRoute 现已提供适用于 Windows、macOS 和 Linux 的**原生桌面应用程序**。
|
||||
|
||||
- 🖥️ **原生窗口** — 专属应用窗口,集成系统托盘
|
||||
- 🔄 **自动启动** — 系统登录时启动 OmniRoute
|
||||
- 🔔 **原生通知** — 配额耗尽或提供商问题时收到提醒
|
||||
- ⚡ **一键安装** — NSIS (Windows)、DMG (macOS)、AppImage (Linux)
|
||||
- 🌐 **离线模式** — 内置服务器,完全离线工作
|
||||
|
||||
```bash
|
||||
npm run electron:dev # 开发模式
|
||||
npm run electron:build # 当前平台
|
||||
npm run electron:build:win # Windows (.exe)
|
||||
npm run electron:build:mac # macOS (.dmg)
|
||||
npm run electron:build:linux # Linux (.AppImage)
|
||||
```
|
||||
|
||||
📖 完整文档:[`electron/README.md`](electron/README.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -271,67 +296,6 @@ docker compose --profile cli up -d
|
||||
|
||||
---
|
||||
|
||||
## 🎯 使用场景
|
||||
|
||||
### 场景 1:"我有 Claude Pro 订阅"
|
||||
|
||||
**问题:** 配额未使用就过期,编程高峰期遇到速率限制
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (充分使用订阅)
|
||||
2. glm/glm-4.7 (配额用完时的便宜备用)
|
||||
3. if/kimi-k2-thinking (免费应急后备)
|
||||
|
||||
每月成本:$20(订阅)+ ~$5(备用)= $25 总计
|
||||
对比:$20 + 遇到限制 = 受挫
|
||||
```
|
||||
|
||||
### 场景 2:"我想要零成本"
|
||||
|
||||
**问题:** 无法承担订阅费用,需要可靠的 AI 编程
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (每月 180K 免费)
|
||||
2. if/kimi-k2-thinking (无限免费)
|
||||
3. qw/qwen3-coder-plus (无限免费)
|
||||
|
||||
每月成本:$0
|
||||
质量:生产级模型
|
||||
```
|
||||
|
||||
### 场景 3:"我需要 24/7 编程,不中断"
|
||||
|
||||
**问题:** 截止日期紧迫,不能有停机时间
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (最佳质量)
|
||||
2. cx/gpt-5.2-codex (第二个订阅)
|
||||
3. glm/glm-4.7 (便宜,每日重置)
|
||||
4. minimax/MiniMax-M2.1 (最便宜,5小时重置)
|
||||
5. if/kimi-k2-thinking (免费无限制)
|
||||
|
||||
结果:5 层故障转移 = 零停机
|
||||
```
|
||||
|
||||
### 场景 4:"我想在 OpenClaw 中使用免费 AI"
|
||||
|
||||
**问题:** 需要在消息应用中使用 AI 助手,完全免费
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (无限免费)
|
||||
2. if/minimax-m2.1 (无限免费)
|
||||
3. if/kimi-k2-thinking (无限免费)
|
||||
|
||||
每月成本:$0
|
||||
访问方式:WhatsApp、Telegram、Slack、Discord、iMessage、Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 核心功能
|
||||
|
||||
### 🧠 路由与智能
|
||||
@@ -473,6 +437,67 @@ Combo: "my-coding-stack"
|
||||
|
||||
---
|
||||
|
||||
## 🎯 使用场景
|
||||
|
||||
### 场景 1:"我有 Claude Pro 订阅"
|
||||
|
||||
**问题:** 配额未使用就过期,编程高峰期遇到速率限制
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (充分使用订阅)
|
||||
2. glm/glm-4.7 (配额用完时的便宜备用)
|
||||
3. if/kimi-k2-thinking (免费应急后备)
|
||||
|
||||
每月成本:$20(订阅)+ ~$5(备用)= $25 总计
|
||||
对比:$20 + 遇到限制 = 受挫
|
||||
```
|
||||
|
||||
### 场景 2:"我想要零成本"
|
||||
|
||||
**问题:** 无法承担订阅费用,需要可靠的 AI 编程
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (每月 180K 免费)
|
||||
2. if/kimi-k2-thinking (无限免费)
|
||||
3. qw/qwen3-coder-plus (无限免费)
|
||||
|
||||
每月成本:$0
|
||||
质量:生产级模型
|
||||
```
|
||||
|
||||
### 场景 3:"我需要 24/7 编程,不中断"
|
||||
|
||||
**问题:** 截止日期紧迫,不能有停机时间
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (最佳质量)
|
||||
2. cx/gpt-5.2-codex (第二个订阅)
|
||||
3. glm/glm-4.7 (便宜,每日重置)
|
||||
4. minimax/MiniMax-M2.1 (最便宜,5小时重置)
|
||||
5. if/kimi-k2-thinking (免费无限制)
|
||||
|
||||
结果:5 层故障转移 = 零停机
|
||||
```
|
||||
|
||||
### 场景 4:"我想在 OpenClaw 中使用免费 AI"
|
||||
|
||||
**问题:** 需要在消息应用中使用 AI 助手,完全免费
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (无限免费)
|
||||
2. if/minimax-m2.1 (无限免费)
|
||||
3. if/kimi-k2-thinking (无限免费)
|
||||
|
||||
每月成本:$0
|
||||
访问方式:WhatsApp、Telegram、Slack、Discord、iMessage、Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 设置指南
|
||||
|
||||
<details>
|
||||
@@ -753,74 +778,6 @@ codex "your prompt"
|
||||
|
||||
---
|
||||
|
||||
## 📊 可用模型
|
||||
|
||||
<details>
|
||||
<summary><b>查看所有可用模型</b></summary>
|
||||
|
||||
**Claude Code (`cc/`)** - Pro/Max:
|
||||
|
||||
- `cc/claude-opus-4-6`
|
||||
- `cc/claude-sonnet-4-5-20250929`
|
||||
- `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**Codex (`cx/`)** - Plus/Pro:
|
||||
|
||||
- `cx/gpt-5.2-codex`
|
||||
- `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** - 免费:
|
||||
|
||||
- `gc/gemini-3-flash-preview`
|
||||
- `gc/gemini-2.5-pro`
|
||||
|
||||
**GitHub Copilot (`gh/`)**:
|
||||
|
||||
- `gh/gpt-5`
|
||||
- `gh/claude-4.5-sonnet`
|
||||
|
||||
**NVIDIA NIM (`nvidia/`)** - 免费积分:
|
||||
|
||||
- `nvidia/llama-3.3-70b-instruct`
|
||||
- `nvidia/mistral-7b-instruct`
|
||||
- 50+ 更多模型在 [build.nvidia.com](https://build.nvidia.com)
|
||||
|
||||
**GLM (`glm/`)** - $0.6/1M:
|
||||
|
||||
- `glm/glm-4.7`
|
||||
|
||||
**MiniMax (`minimax/`)** - $0.2/1M:
|
||||
|
||||
- `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** - 免费:
|
||||
|
||||
- `if/kimi-k2-thinking`
|
||||
- `if/qwen3-coder-plus`
|
||||
- `if/deepseek-r1`
|
||||
- `if/glm-4.7`
|
||||
- `if/minimax-m2`
|
||||
|
||||
**Qwen (`qw/`)** - 免费:
|
||||
|
||||
- `qw/qwen3-coder-plus`
|
||||
- `qw/qwen3-coder-flash`
|
||||
|
||||
**Kiro (`kr/`)** - 免费:
|
||||
|
||||
- `kr/claude-sonnet-4.5`
|
||||
- `kr/claude-haiku-4.5`
|
||||
|
||||
**OpenRouter (`or/`)** - 100+ 模型:
|
||||
|
||||
- `or/anthropic/claude-4-sonnet`
|
||||
- `or/google/gemini-2.5-pro`
|
||||
- [openrouter.ai/models](https://openrouter.ai/models) 上的任何模型
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🧪 评估 (Evals)
|
||||
|
||||
OmniRoute 包含内置评估框架,用于针对黄金集测试 LLM 响应质量。通过仪表板中的 **Analytics → Evals** 访问。
|
||||
@@ -892,7 +849,7 @@ OmniRoute 包含内置评估框架,用于针对黄金集测试 LLM 响应质
|
||||
**兼容 OpenAI 的提供商连接测试显示 "Invalid"**
|
||||
|
||||
- 许多提供商不暴露 `/models` 端点
|
||||
- OmniRoute v1.0.0+ 包含通过 chat completions 的回退验证
|
||||
- OmniRoute v1.0.6+ 包含通过 chat completions 的回退验证
|
||||
- 确保 base URL 包含 `/v1` 后缀
|
||||
|
||||
</details>
|
||||
@@ -902,7 +859,7 @@ OmniRoute 包含内置评估框架,用于针对黄金集测试 LLM 响应质
|
||||
## 🛠️ 技术栈
|
||||
|
||||
- **运行时**: Node.js 20+
|
||||
- **语言**: TypeScript 5.9 — `src/` 和 `open-sse/` 中 **100% TypeScript**(v1.0.0)
|
||||
- **语言**: TypeScript 5.9 — `src/` 和 `open-sse/` 中 **100% TypeScript**(v1.0.6)
|
||||
- **框架**: Next.js 16 + React 19 + Tailwind CSS 4
|
||||
- **数据库**: LowDB (JSON) + SQLite(领域状态 + 代理日志)
|
||||
- **流式传输**: Server-Sent Events (SSE)
|
||||
@@ -932,9 +889,12 @@ OmniRoute 包含内置评估框架,用于针对黄金集测试 LLM 响应质
|
||||
|
||||
## 📧 支持
|
||||
|
||||
> 💬 **加入我们的社区!** [WhatsApp 群组](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t) — 获取帮助、分享技巧、了解最新动态。
|
||||
|
||||
- **网站**: [omniroute.online](https://omniroute.online)
|
||||
- **GitHub**: [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
|
||||
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **WhatsApp**: [社区群组](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
- **原始项目**: [decolua 的 9router](https://github.com/decolua/9router)
|
||||
|
||||
---
|
||||
@@ -957,7 +917,7 @@ OmniRoute 包含内置评估框架,用于针对黄金集测试 LLM 响应质
|
||||
|
||||
```bash
|
||||
# 创建发布 — npm 发布自动完成
|
||||
gh release create v1.0.0 --title "v1.0.0" --generate-notes
|
||||
gh release create v1.0.6 --title "v1.0.6" --generate-notes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
+3
-3
@@ -20,9 +20,9 @@ If you discover a security vulnerability in OmniRoute, please report it responsi
|
||||
|
||||
| Version | Support Status |
|
||||
| ------- | -------------- |
|
||||
| 0.8.x | ✅ Active |
|
||||
| 0.7.x | ✅ Security |
|
||||
| < 0.7.0 | ❌ Unsupported |
|
||||
| 1.0.x | ✅ Active |
|
||||
| 0.8.x | ✅ Security |
|
||||
| < 0.8.0 | ❌ Unsupported |
|
||||
|
||||
---
|
||||
|
||||
|
||||
+118
-29
@@ -12,15 +12,69 @@
|
||||
*/
|
||||
|
||||
import { spawn } from "node:child_process";
|
||||
import { existsSync } from "node:fs";
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import { join, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { homedir, platform } from "node:os";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
const ROOT = join(__dirname, "..");
|
||||
const APP_DIR = join(ROOT, "app");
|
||||
|
||||
// ── Load .env file (for global npm install) ─────────────────
|
||||
function loadEnvFile() {
|
||||
const envPaths = [];
|
||||
|
||||
// 1. DATA_DIR/.env if set
|
||||
if (process.env.DATA_DIR) {
|
||||
envPaths.push(join(process.env.DATA_DIR, ".env"));
|
||||
}
|
||||
|
||||
// 2. ~/.omniroute/.env (default data dir)
|
||||
const home = homedir();
|
||||
if (home) {
|
||||
if (platform() === "win32") {
|
||||
const appData = process.env.APPDATA || join(home, "AppData", "Roaming");
|
||||
envPaths.push(join(appData, "omniroute", ".env"));
|
||||
} else {
|
||||
envPaths.push(join(home, ".omniroute", ".env"));
|
||||
}
|
||||
}
|
||||
|
||||
// 3. ./.env (current working directory)
|
||||
envPaths.push(join(process.cwd(), ".env"));
|
||||
|
||||
for (const envPath of envPaths) {
|
||||
try {
|
||||
if (existsSync(envPath)) {
|
||||
const content = readFileSync(envPath, "utf-8");
|
||||
for (const line of content.split("\n")) {
|
||||
const trimmed = line.trim();
|
||||
// Skip empty lines and comments
|
||||
if (!trimmed || trimmed.startsWith("#")) continue;
|
||||
const eqIdx = trimmed.indexOf("=");
|
||||
if (eqIdx > 0) {
|
||||
const key = trimmed.slice(0, eqIdx).trim();
|
||||
const value = trimmed.slice(eqIdx + 1).trim();
|
||||
// Don't override existing env vars
|
||||
if (process.env[key] === undefined) {
|
||||
// Remove surrounding quotes
|
||||
process.env[key] = value.replace(/^["']|["']$/g, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(` \x1b[2m📋 Loaded env from ${envPath}\x1b[0m`);
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
// Ignore errors reading env files
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadEnvFile();
|
||||
|
||||
// ── Parse args ─────────────────────────────────────────────
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
@@ -30,18 +84,22 @@ if (args.includes("--help") || args.includes("-h")) {
|
||||
|
||||
\x1b[1mUsage:\x1b[0m
|
||||
omniroute Start the server
|
||||
omniroute --port <port> Use custom port (default: 20128)
|
||||
omniroute --port <port> Use custom API port (default: 20128)
|
||||
omniroute --no-open Don't open browser automatically
|
||||
omniroute --help Show this help
|
||||
omniroute --version Show version
|
||||
|
||||
\x1b[1mConfig:\x1b[0m
|
||||
Loads .env from: ~/.omniroute/.env or ./.env
|
||||
Memory limit: OMNIROUTE_MEMORY_MB (default: 512)
|
||||
|
||||
\x1b[1mAfter starting:\x1b[0m
|
||||
Dashboard: http://localhost:<port>
|
||||
API: http://localhost:<port>/v1
|
||||
Dashboard: http://localhost:<dashboard-port>
|
||||
API: http://localhost:<api-port>/v1
|
||||
|
||||
\x1b[1mConnect your tools:\x1b[0m
|
||||
Set your CLI tool (Cursor, Cline, Codex, etc.) to use:
|
||||
\x1b[33mhttp://localhost:20128/v1\x1b[0m
|
||||
\x1b[33mhttp://localhost:<api-port>/v1\x1b[0m
|
||||
`);
|
||||
process.exit(0);
|
||||
}
|
||||
@@ -58,40 +116,58 @@ if (args.includes("--version") || args.includes("-v")) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Parse --port
|
||||
let port = 20128;
|
||||
function parsePort(value, fallback) {
|
||||
const parsed = parseInt(String(value), 10);
|
||||
return Number.isFinite(parsed) && parsed > 0 && parsed <= 65535 ? parsed : fallback;
|
||||
}
|
||||
|
||||
// Parse --port (canonical/base port)
|
||||
let port = parsePort(process.env.PORT || "20128", 20128);
|
||||
const portIdx = args.indexOf("--port");
|
||||
if (portIdx !== -1 && args[portIdx + 1]) {
|
||||
port = parseInt(args[portIdx + 1], 10);
|
||||
if (isNaN(port)) {
|
||||
const cliPort = parsePort(args[portIdx + 1], null);
|
||||
if (cliPort === null) {
|
||||
console.error("\x1b[31m✖ Invalid port number\x1b[0m");
|
||||
process.exit(1);
|
||||
}
|
||||
port = cliPort;
|
||||
}
|
||||
|
||||
const apiPort = parsePort(process.env.API_PORT || String(port), port);
|
||||
const dashboardPort = parsePort(process.env.DASHBOARD_PORT || String(port), port);
|
||||
|
||||
const noOpen = args.includes("--no-open");
|
||||
|
||||
// ── Banner ─────────────────────────────────────────────────
|
||||
console.log(`
|
||||
\x1b[36m ____ _ ____ _
|
||||
/ __ \\ (_) __ \\ | |
|
||||
| | | |_ __ ___ _ __ _| |__) |___ _ _| |_ ___
|
||||
| | | | '_ \` _ \\| '_ \\ | _ // _ \\| | | | __/ _ \\
|
||||
| |__| | | | | | | | | | | | \\ \\ (_) | |_| | || __/
|
||||
\\____/|_| |_| |_|_| |_|_|_| \\_\\___/ \\__,_|\\__\\___|
|
||||
/ __ \\ (_) __ \\ | |
|
||||
| | | |_ __ ___ _ __ _| |__) |___ _ _| |_ ___
|
||||
| | | | '_ \` _ \\| '_ \\ | _ // _ \\| | | | __/ _ \\
|
||||
| |__| | | | | | | | | | | | \\ \\ (_) | |_| | || __/
|
||||
\\____/|_| |_| |_|_| |_|_|_| \\_\\___/ \\__,_|\\__\\___|
|
||||
\x1b[0m`);
|
||||
|
||||
// ── Node.js version check ──────────────────────────────────
|
||||
const nodeMajor = parseInt(process.versions.node.split(".")[0], 10);
|
||||
if (nodeMajor >= 24) {
|
||||
console.warn(`\x1b[33m ⚠ Warning: You are running Node.js ${process.versions.node}.
|
||||
OmniRoute uses better-sqlite3, a native addon that does not yet
|
||||
have compatible prebuilt binaries for Node.js 24+.
|
||||
You may experience errors like "is not a valid Win32 application"
|
||||
or "NODE_MODULE_VERSION mismatch".
|
||||
|
||||
Recommended: use Node.js 22 LTS (or 20 LTS).
|
||||
Workaround: npm rebuild better-sqlite3\x1b[0m
|
||||
`);
|
||||
}
|
||||
|
||||
// ── Resolve server entry ───────────────────────────────────
|
||||
const serverJs = join(APP_DIR, "server.js");
|
||||
|
||||
if (!existsSync(serverJs)) {
|
||||
console.error(
|
||||
"\x1b[31m✖ Server not found at:\x1b[0m",
|
||||
serverJs,
|
||||
);
|
||||
console.error(
|
||||
" This usually means the package was not built correctly.",
|
||||
);
|
||||
console.error("\x1b[31m✖ Server not found at:\x1b[0m", serverJs);
|
||||
console.error(" This usually means the package was not built correctly.");
|
||||
console.error(" Try reinstalling: npm install -g omniroute");
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -99,14 +175,23 @@ if (!existsSync(serverJs)) {
|
||||
// ── Start server ───────────────────────────────────────────
|
||||
console.log(` \x1b[2m⏳ Starting server...\x1b[0m\n`);
|
||||
|
||||
// Sanitize memory limit — parseInt to prevent command injection (#150)
|
||||
const rawMemory = parseInt(process.env.OMNIROUTE_MEMORY_MB || "512", 10);
|
||||
const memoryLimit =
|
||||
Number.isFinite(rawMemory) && rawMemory >= 64 && rawMemory <= 16384 ? rawMemory : 512;
|
||||
|
||||
const env = {
|
||||
...process.env,
|
||||
PORT: String(port),
|
||||
OMNIROUTE_PORT: String(port),
|
||||
PORT: String(dashboardPort),
|
||||
DASHBOARD_PORT: String(dashboardPort),
|
||||
API_PORT: String(apiPort),
|
||||
HOSTNAME: "0.0.0.0",
|
||||
NODE_ENV: "production",
|
||||
NODE_OPTIONS: `--max-old-space-size=${memoryLimit}`,
|
||||
};
|
||||
|
||||
const server = spawn("node", [serverJs], {
|
||||
const server = spawn("node", [`--max-old-space-size=${memoryLimit}`, serverJs], {
|
||||
cwd: APP_DIR,
|
||||
env,
|
||||
stdio: "pipe",
|
||||
@@ -119,7 +204,10 @@ server.stdout.on("data", (data) => {
|
||||
process.stdout.write(text);
|
||||
|
||||
// Detect server ready
|
||||
if (!started && (text.includes("Ready") || text.includes("started") || text.includes("listening"))) {
|
||||
if (
|
||||
!started &&
|
||||
(text.includes("Ready") || text.includes("started") || text.includes("listening"))
|
||||
) {
|
||||
started = true;
|
||||
onReady();
|
||||
}
|
||||
@@ -156,16 +244,17 @@ process.on("SIGTERM", shutdown);
|
||||
|
||||
// ── On ready ───────────────────────────────────────────────
|
||||
async function onReady() {
|
||||
const url = `http://localhost:${port}`;
|
||||
const dashboardUrl = `http://localhost:${dashboardPort}`;
|
||||
const apiUrl = `http://localhost:${apiPort}`;
|
||||
|
||||
console.log(`
|
||||
\x1b[32m✔ OmniRoute is running!\x1b[0m
|
||||
|
||||
\x1b[1m Dashboard:\x1b[0m ${url}
|
||||
\x1b[1m API Base:\x1b[0m ${url}/v1
|
||||
\x1b[1m Dashboard:\x1b[0m ${dashboardUrl}
|
||||
\x1b[1m API Base:\x1b[0m ${apiUrl}/v1
|
||||
|
||||
\x1b[2m Point your CLI tool (Cursor, Cline, Codex) to:\x1b[0m
|
||||
\x1b[33m ${url}/v1\x1b[0m
|
||||
\x1b[33m ${apiUrl}/v1\x1b[0m
|
||||
|
||||
\x1b[2m Press Ctrl+C to stop\x1b[0m
|
||||
`);
|
||||
@@ -173,7 +262,7 @@ async function onReady() {
|
||||
if (!noOpen) {
|
||||
try {
|
||||
const open = await import("open");
|
||||
await open.default(url);
|
||||
await open.default(dashboardUrl);
|
||||
} catch {
|
||||
// open is optional — if not available, just skip
|
||||
}
|
||||
|
||||
@@ -22,21 +22,19 @@ services:
|
||||
env_file: .env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- PORT=20128
|
||||
- PORT=${PORT:-20128}
|
||||
- DASHBOARD_PORT=${DASHBOARD_PORT:-${PORT:-20128}}
|
||||
- API_PORT=${API_PORT:-20129}
|
||||
- API_HOST=${API_HOST:-0.0.0.0}
|
||||
- HOSTNAME=0.0.0.0
|
||||
- DATA_DIR=/app/data
|
||||
ports:
|
||||
- "20130:20128"
|
||||
- "${PROD_DASHBOARD_PORT:-20130}:${DASHBOARD_PORT:-${PORT:-20128}}"
|
||||
- "${PROD_API_PORT:-20131}:${API_PORT:-20129}"
|
||||
volumes:
|
||||
- omniroute-prod-data:/app/data
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"node",
|
||||
"-e",
|
||||
"fetch('http://127.0.0.1:20128/api/settings').then(r=>{if(!r.ok)throw r.status}).catch(()=>process.exit(1))",
|
||||
]
|
||||
test: ["CMD", "node", "healthcheck.mjs"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
+18
-10
@@ -18,16 +18,16 @@
|
||||
x-common: &common
|
||||
restart: unless-stopped
|
||||
env_file: .env
|
||||
environment:
|
||||
- DATA_DIR=/app/data # Must match the volume mount below
|
||||
- PORT=${PORT:-20128}
|
||||
- DASHBOARD_PORT=${DASHBOARD_PORT:-${PORT:-20128}}
|
||||
- API_PORT=${API_PORT:-20129}
|
||||
- API_HOST=${API_HOST:-0.0.0.0}
|
||||
volumes:
|
||||
- omniroute-data:/app/data
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD",
|
||||
"node",
|
||||
"-e",
|
||||
"fetch('http://127.0.0.1:20128/api/settings').then(r=>{if(!r.ok)throw r.status}).catch(()=>process.exit(1))",
|
||||
]
|
||||
test: ["CMD", "node", "healthcheck.mjs"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
@@ -43,7 +43,8 @@ services:
|
||||
target: runner-base
|
||||
image: omniroute:base
|
||||
ports:
|
||||
- "${PORT:-20128}:20128"
|
||||
- "${DASHBOARD_PORT:-${PORT:-20128}}:${DASHBOARD_PORT:-${PORT:-20128}}"
|
||||
- "${API_PORT:-20129}:${API_PORT:-20129}"
|
||||
profiles:
|
||||
- base
|
||||
|
||||
@@ -56,7 +57,8 @@ services:
|
||||
target: runner-cli
|
||||
image: omniroute:cli
|
||||
ports:
|
||||
- "${PORT:-20128}:20128"
|
||||
- "${DASHBOARD_PORT:-${PORT:-20128}}:${DASHBOARD_PORT:-${PORT:-20128}}"
|
||||
- "${API_PORT:-20129}:${API_PORT:-20129}"
|
||||
profiles:
|
||||
- cli
|
||||
|
||||
@@ -69,8 +71,14 @@ services:
|
||||
target: runner-base
|
||||
image: omniroute:base
|
||||
ports:
|
||||
- "${PORT:-20128}:20128"
|
||||
- "${DASHBOARD_PORT:-${PORT:-20128}}:${DASHBOARD_PORT:-${PORT:-20128}}"
|
||||
- "${API_PORT:-20129}:${API_PORT:-20129}"
|
||||
environment:
|
||||
- DATA_DIR=/app/data
|
||||
- PORT=${PORT:-20128}
|
||||
- DASHBOARD_PORT=${DASHBOARD_PORT:-${PORT:-20128}}
|
||||
- API_PORT=${API_PORT:-20129}
|
||||
- API_HOST=${API_HOST:-0.0.0.0}
|
||||
- CLI_MODE=host
|
||||
- CLI_EXTRA_PATHS=/host-local/bin:/host-node/bin
|
||||
- CLI_CONFIG_HOME=/host-home
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# API Reference
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](i18n/es/API_REFERENCE.md) | 🇫🇷 [Français](i18n/fr/API_REFERENCE.md) | 🇮🇹 [Italiano](i18n/it/API_REFERENCE.md) | 🇷🇺 [Русский](i18n/ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](i18n/de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](i18n/in/API_REFERENCE.md) | 🇹🇭 [ไทย](i18n/th/API_REFERENCE.md) | 🇺🇦 [Українська](i18n/uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](i18n/ar/API_REFERENCE.md) | 🇯🇵 [日本語](i18n/ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/API_REFERENCE.md) | 🇧🇬 [Български](i18n/bg/API_REFERENCE.md) | 🇩🇰 [Dansk](i18n/da/API_REFERENCE.md) | 🇫🇮 [Suomi](i18n/fi/API_REFERENCE.md) | 🇮🇱 [עברית](i18n/he/API_REFERENCE.md) | 🇭🇺 [Magyar](i18n/hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/API_REFERENCE.md) | 🇰🇷 [한국어](i18n/ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](i18n/nl/API_REFERENCE.md) | 🇳🇴 [Norsk](i18n/no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/API_REFERENCE.md) | 🇷🇴 [Română](i18n/ro/API_REFERENCE.md) | 🇵🇱 [Polski](i18n/pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](i18n/sk/API_REFERENCE.md) | 🇸🇪 [Svenska](i18n/sv/API_REFERENCE.md) | 🇵🇭 [Filipino](i18n/phi/API_REFERENCE.md)
|
||||
|
||||
Complete reference for all OmniRoute API endpoints.
|
||||
|
||||
---
|
||||
|
||||
+17
-3
@@ -1,6 +1,8 @@
|
||||
# OmniRoute Architecture
|
||||
|
||||
_Last updated: 2026-02-17_
|
||||
🌐 **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)
|
||||
|
||||
_Last updated: 2026-02-18_
|
||||
|
||||
## Executive Summary
|
||||
|
||||
@@ -17,6 +19,9 @@ Core capabilities:
|
||||
- Embedding generation via `/v1/embeddings` (6 providers, 9 models)
|
||||
- Image generation via `/v1/images/generations` (4 providers, 9 models)
|
||||
- Think tag parsing (`<think>...</think>`) for reasoning models
|
||||
- Response sanitization for strict OpenAI SDK compatibility
|
||||
- Role normalization (developer→system, system→user) for cross-provider compatibility
|
||||
- Structured output conversion (json_schema → Gemini responseSchema)
|
||||
- Local persistence for providers, keys, aliases, combos, settings, pricing
|
||||
- Usage/cost tracking and request logging
|
||||
- Optional cloud sync for multi-device/state sync
|
||||
@@ -180,6 +185,8 @@ Main flow modules:
|
||||
- Embedding provider registry: `open-sse/config/embeddingRegistry.ts`
|
||||
- Image generation handler: `open-sse/handlers/imageGeneration.ts`
|
||||
- Image provider registry: `open-sse/config/imageRegistry.ts`
|
||||
- Response sanitization: `open-sse/handlers/responseSanitizer.ts`
|
||||
- Role normalization: `open-sse/services/roleNormalizer.ts`
|
||||
|
||||
Services (business logic):
|
||||
|
||||
@@ -647,6 +654,13 @@ Source Format → OpenAI (hub) → Target Format
|
||||
|
||||
Translations are selected dynamically based on source payload shape and provider target format.
|
||||
|
||||
Additional processing layers in the translation pipeline:
|
||||
|
||||
- **Response sanitization** — Strips non-standard fields from OpenAI-format responses (both streaming and non-streaming) to ensure strict SDK compliance
|
||||
- **Role normalization** — Converts `developer` → `system` for non-OpenAI targets; merges `system` → `user` for models that reject the system role (GLM, ERNIE)
|
||||
- **Think tag extraction** — Parses `<think>...</think>` blocks from content into `reasoning_content` field
|
||||
- **Structured output** — Converts OpenAI `response_format.json_schema` to Gemini's `responseMimeType` + `responseSchema`
|
||||
|
||||
## Supported API Endpoints
|
||||
|
||||
| Endpoint | Format | Handler |
|
||||
@@ -759,8 +773,8 @@ Environment variables actively used by code:
|
||||
|
||||
## Operational Verification Checklist
|
||||
|
||||
- Build from source: `cd /root/dev/omniroute && npm run build`
|
||||
- Build Docker image: `cd /root/dev/omniroute && docker build -t omniroute .`
|
||||
- Build from source: `npm run build`
|
||||
- Build Docker image: `docker build -t omniroute .`
|
||||
- Start service and verify:
|
||||
- `GET /api/settings`
|
||||
- `GET /api/v1/models`
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# omniroute — Codebase Documentation
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](i18n/es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](i18n/fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](i18n/it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](i18n/ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](i18n/de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](i18n/in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](i18n/th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](i18n/uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](i18n/ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](i18n/ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](i18n/vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](i18n/bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](i18n/da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](i18n/fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](i18n/he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](i18n/hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](i18n/ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](i18n/nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](i18n/no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](i18n/pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](i18n/ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](i18n/pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](i18n/sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](i18n/sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](i18n/phi/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
> A comprehensive, beginner-friendly guide to the **omniroute** multi-provider AI proxy router.
|
||||
|
||||
---
|
||||
|
||||
+19
-1
@@ -1,5 +1,7 @@
|
||||
# OmniRoute — Dashboard Features Gallery
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](FEATURES.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/FEATURES.md) | 🇪🇸 [Español](i18n/es/FEATURES.md) | 🇫🇷 [Français](i18n/fr/FEATURES.md) | 🇮🇹 [Italiano](i18n/it/FEATURES.md) | 🇷🇺 [Русский](i18n/ru/FEATURES.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](i18n/de/FEATURES.md) | 🇮🇳 [हिन्दी](i18n/in/FEATURES.md) | 🇹🇭 [ไทย](i18n/th/FEATURES.md) | 🇺🇦 [Українська](i18n/uk-UA/FEATURES.md) | 🇸🇦 [العربية](i18n/ar/FEATURES.md) | 🇯🇵 [日本語](i18n/ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](i18n/vi/FEATURES.md) | 🇧🇬 [Български](i18n/bg/FEATURES.md) | 🇩🇰 [Dansk](i18n/da/FEATURES.md) | 🇫🇮 [Suomi](i18n/fi/FEATURES.md) | 🇮🇱 [עברית](i18n/he/FEATURES.md) | 🇭🇺 [Magyar](i18n/hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/FEATURES.md) | 🇰🇷 [한국어](i18n/ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/FEATURES.md) | 🇳🇱 [Nederlands](i18n/nl/FEATURES.md) | 🇳🇴 [Norsk](i18n/no/FEATURES.md) | 🇵🇹 [Português (Portugal)](i18n/pt/FEATURES.md) | 🇷🇴 [Română](i18n/ro/FEATURES.md) | 🇵🇱 [Polski](i18n/pl/FEATURES.md) | 🇸🇰 [Slovenčina](i18n/sk/FEATURES.md) | 🇸🇪 [Svenska](i18n/sv/FEATURES.md) | 🇵🇭 [Filipino](i18n/phi/FEATURES.md)
|
||||
|
||||
Visual guide to every section of the OmniRoute dashboard.
|
||||
|
||||
---
|
||||
@@ -46,7 +48,7 @@ Four modes for debugging API translations: **Playground** (format converter), **
|
||||
|
||||
## ⚙️ Settings
|
||||
|
||||
General settings, system storage, backup management (export/import database), appearance (dark/light mode), security, routing, resilience, and advanced configuration.
|
||||
General settings, system storage, backup management (export/import database), appearance (dark/light mode), security (includes API endpoint protection and custom provider blocking), routing, resilience, and advanced configuration.
|
||||
|
||||

|
||||
|
||||
@@ -73,3 +75,19 @@ Real-time request logging with filtering by provider, model, account, and API ke
|
||||
Your unified API endpoint with capability breakdown: Chat Completions, Embeddings, Image Generation, Reranking, Audio Transcription, and registered API keys.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Desktop Application
|
||||
|
||||
Native Electron desktop app for Windows, macOS, and Linux. Run OmniRoute as a standalone application with system tray integration, offline support, and one-click install.
|
||||
|
||||
Key features:
|
||||
|
||||
- Server readiness polling (no blank screen on cold start)
|
||||
- System tray with port management
|
||||
- Content Security Policy
|
||||
- Single-instance lock
|
||||
- Platform-conditional UI (macOS traffic lights, Windows/Linux default titlebar)
|
||||
|
||||
📖 See [`electron/README.md`](../electron/README.md) for full documentation.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Troubleshooting
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](i18n/es/TROUBLESHOOTING.md) | 🇫🇷 [Français](i18n/fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](i18n/it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](i18n/ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](i18n/de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](i18n/in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](i18n/th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](i18n/uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](i18n/ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](i18n/ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](i18n/vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](i18n/bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](i18n/da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](i18n/fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](i18n/he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](i18n/hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](i18n/ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](i18n/nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](i18n/no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](i18n/pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](i18n/ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](i18n/pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](i18n/sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](i18n/sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](i18n/phi/TROUBLESHOOTING.md)
|
||||
|
||||
Common problems and solutions for OmniRoute.
|
||||
|
||||
---
|
||||
@@ -11,6 +13,8 @@ Common problems and solutions for OmniRoute.
|
||||
| First login not working | Check `INITIAL_PASSWORD` in `.env` (default: `123456`) |
|
||||
| Dashboard opens on wrong port | Set `PORT=20128` and `NEXT_PUBLIC_BASE_URL=http://localhost:20128` |
|
||||
| No request logs under `logs/` | Set `ENABLE_REQUEST_LOGS=true` |
|
||||
| EACCES: permission denied | Set `DATA_DIR=/path/to/writable/dir` to override `~/.omniroute` |
|
||||
| Routing strategy not saving | Update to v1.4.11+ (Zod schema fix for settings persistence) |
|
||||
|
||||
---
|
||||
|
||||
@@ -177,6 +181,10 @@ Use **Dashboard → Translator** to debug format translation issues:
|
||||
- **Thinking tags not appearing** — Check if the target provider supports thinking and the thinking budget setting
|
||||
- **Tool calls dropping** — Some format translations may strip unsupported fields; verify in Playground mode
|
||||
- **System prompt missing** — Claude and Gemini handle system prompts differently; check translation output
|
||||
- **SDK returns raw string instead of object** — Fixed in v1.1.0: response sanitizer now strips non-standard fields (`x_groq`, `usage_breakdown`, etc.) that cause OpenAI SDK Pydantic validation failures
|
||||
- **GLM/ERNIE rejects `system` role** — Fixed in v1.1.0: role normalizer automatically merges system messages into user messages for incompatible models
|
||||
- **`developer` role not recognized** — Fixed in v1.1.0: automatically converted to `system` for non-OpenAI providers
|
||||
- **`json_schema` not working with Gemini** — Fixed in v1.1.0: `response_format` is now converted to Gemini's `responseMimeType` + `responseSchema`
|
||||
|
||||
---
|
||||
|
||||
|
||||
+128
-15
@@ -1,5 +1,7 @@
|
||||
# User Guide
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](i18n/es/USER_GUIDE.md) | 🇫🇷 [Français](i18n/fr/USER_GUIDE.md) | 🇮🇹 [Italiano](i18n/it/USER_GUIDE.md) | 🇷🇺 [Русский](i18n/ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](i18n/de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](i18n/in/USER_GUIDE.md) | 🇹🇭 [ไทย](i18n/th/USER_GUIDE.md) | 🇺🇦 [Українська](i18n/uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](i18n/ar/USER_GUIDE.md) | 🇯🇵 [日本語](i18n/ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/USER_GUIDE.md) | 🇧🇬 [Български](i18n/bg/USER_GUIDE.md) | 🇩🇰 [Dansk](i18n/da/USER_GUIDE.md) | 🇫🇮 [Suomi](i18n/fi/USER_GUIDE.md) | 🇮🇱 [עברית](i18n/he/USER_GUIDE.md) | 🇭🇺 [Magyar](i18n/hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/USER_GUIDE.md) | 🇰🇷 [한국어](i18n/ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](i18n/nl/USER_GUIDE.md) | 🇳🇴 [Norsk](i18n/no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/USER_GUIDE.md) | 🇷🇴 [Română](i18n/ro/USER_GUIDE.md) | 🇵🇱 [Polski](i18n/pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](i18n/sk/USER_GUIDE.md) | 🇸🇪 [Svenska](i18n/sv/USER_GUIDE.md) | 🇵🇭 [Filipino](i18n/phi/USER_GUIDE.md)
|
||||
|
||||
Complete guide for configuring providers, creating combos, integrating CLI tools, and deploying OmniRoute.
|
||||
|
||||
---
|
||||
@@ -316,6 +318,25 @@ Model: cc/claude-opus-4-6
|
||||
|
||||
## 🚀 Deployment
|
||||
|
||||
### Global npm install (Recommended)
|
||||
|
||||
```bash
|
||||
npm install -g omniroute
|
||||
|
||||
# Create config directory
|
||||
mkdir -p ~/.omniroute
|
||||
|
||||
# Create .env file (see .env.example)
|
||||
cp .env.example ~/.omniroute/.env
|
||||
|
||||
# Start server
|
||||
omniroute
|
||||
# Or with custom port:
|
||||
omniroute --port 3000
|
||||
```
|
||||
|
||||
The CLI automatically loads `.env` from `~/.omniroute/.env` or `./.env`.
|
||||
|
||||
### VPS Deployment
|
||||
|
||||
```bash
|
||||
@@ -335,6 +356,43 @@ npm run start
|
||||
# Or: pm2 start npm --name omniroute -- start
|
||||
```
|
||||
|
||||
### PM2 Deployment (Low Memory)
|
||||
|
||||
For servers with limited RAM, use the memory limit option:
|
||||
|
||||
```bash
|
||||
# With 512MB limit (default)
|
||||
pm2 start npm --name omniroute -- start
|
||||
|
||||
# Or with custom memory limit
|
||||
OMNIROUTE_MEMORY_MB=512 pm2 start npm --name omniroute -- start
|
||||
|
||||
# Or using ecosystem.config.js
|
||||
pm2 start ecosystem.config.js
|
||||
```
|
||||
|
||||
Create `ecosystem.config.js`:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: "omniroute",
|
||||
script: "npm",
|
||||
args: "start",
|
||||
env: {
|
||||
NODE_ENV: "production",
|
||||
OMNIROUTE_MEMORY_MB: "512",
|
||||
JWT_SECRET: "your-secret",
|
||||
INITIAL_PASSWORD: "your-password",
|
||||
},
|
||||
node_args: "--max-old-space-size=512",
|
||||
max_memory_restart: "300M",
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
@@ -349,20 +407,23 @@ For host-integrated mode with CLI binaries, see the Docker section in the main d
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
| --------------------- | ------------------------------------ | ------------------------------------------------------- |
|
||||
| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT signing secret (**change in production**) |
|
||||
| `INITIAL_PASSWORD` | `123456` | First login password |
|
||||
| `DATA_DIR` | `~/.omniroute` | Data directory (db, usage, logs) |
|
||||
| `PORT` | framework default | Service port (`20128` in examples) |
|
||||
| `HOSTNAME` | framework default | Bind host (Docker defaults to `0.0.0.0`) |
|
||||
| `NODE_ENV` | runtime default | Set `production` for deploy |
|
||||
| `BASE_URL` | `http://localhost:20128` | Server-side internal base URL |
|
||||
| `CLOUD_URL` | `https://omniroute.dev` | Cloud sync endpoint base URL |
|
||||
| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC secret for generated API keys |
|
||||
| `REQUIRE_API_KEY` | `false` | Enforce Bearer API key on `/v1/*` |
|
||||
| `ENABLE_REQUEST_LOGS` | `false` | Enables request/response logs |
|
||||
| `AUTH_COOKIE_SECURE` | `false` | Force `Secure` auth cookie (behind HTTPS reverse proxy) |
|
||||
| Variable | Default | Description |
|
||||
| ------------------------- | ------------------------------------ | ------------------------------------------------------- |
|
||||
| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT signing secret (**change in production**) |
|
||||
| `INITIAL_PASSWORD` | `123456` | First login password |
|
||||
| `DATA_DIR` | `~/.omniroute` | Data directory (db, usage, logs) |
|
||||
| `PORT` | framework default | Service port (`20128` in examples) |
|
||||
| `HOSTNAME` | framework default | Bind host (Docker defaults to `0.0.0.0`) |
|
||||
| `NODE_ENV` | runtime default | Set `production` for deploy |
|
||||
| `BASE_URL` | `http://localhost:20128` | Server-side internal base URL |
|
||||
| `CLOUD_URL` | `https://omniroute.dev` | Cloud sync endpoint base URL |
|
||||
| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC secret for generated API keys |
|
||||
| `REQUIRE_API_KEY` | `false` | Enforce Bearer API key on `/v1/*` |
|
||||
| `ENABLE_REQUEST_LOGS` | `false` | Enables request/response logs |
|
||||
| `AUTH_COOKIE_SECURE` | `false` | Force `Secure` auth cookie (behind HTTPS reverse proxy) |
|
||||
| `OMNIROUTE_MEMORY_MB` | `512` | Node.js heap limit in MB |
|
||||
| `PROMPT_CACHE_MAX_SIZE` | `50` | Max prompt cache entries |
|
||||
| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Max semantic cache entries |
|
||||
|
||||
For the full environment variable reference, see the [README](../README.md).
|
||||
|
||||
@@ -610,7 +671,7 @@ The settings page is organized into 5 tabs for easy navigation:
|
||||
|
||||
| Tab | Contents |
|
||||
| -------------- | ---------------------------------------------------------------------------------------------- |
|
||||
| **Security** | Login/Password settings and IP Access Control (allowlist/blocklist) |
|
||||
| **Security** | Login/Password settings, IP Access Control, API auth for `/models`, and Provider Blocking |
|
||||
| **Routing** | Global routing strategy (6 options), wildcard model aliases, fallback chains, combo defaults |
|
||||
| **Resilience** | Provider profiles, editable rate limits, circuit breaker status, policies & locked identifiers |
|
||||
| **AI** | Thinking budget configuration, global system prompt injection, prompt cache stats |
|
||||
@@ -694,3 +755,55 @@ Access via **Dashboard → Health**. Real-time system health overview with 6 car
|
||||
| **Latency Telemetry** | p50/p95/p99 latency aggregation per provider |
|
||||
|
||||
**Pro Tip:** The Health page auto-refreshes every 10 seconds. Use the circuit breaker card to identify which providers are experiencing issues.
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Desktop Application (Electron)
|
||||
|
||||
OmniRoute is available as a native desktop application for Windows, macOS, and Linux.
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# From the electron directory:
|
||||
cd electron
|
||||
npm install
|
||||
|
||||
# Development mode (connect to running Next.js dev server):
|
||||
npm run dev
|
||||
|
||||
# Production mode (uses standalone build):
|
||||
npm start
|
||||
```
|
||||
|
||||
### Building Installers
|
||||
|
||||
```bash
|
||||
cd electron
|
||||
npm run build # Current platform
|
||||
npm run build:win # Windows (.exe NSIS)
|
||||
npm run build:mac # macOS (.dmg universal)
|
||||
npm run build:linux # Linux (.AppImage)
|
||||
```
|
||||
|
||||
Output → `electron/dist-electron/`
|
||||
|
||||
### Key Features
|
||||
|
||||
| Feature | Description |
|
||||
| --------------------------- | ---------------------------------------------------- |
|
||||
| **Server Readiness** | Polls server before showing window (no blank screen) |
|
||||
| **System Tray** | Minimize to tray, change port, quit from tray menu |
|
||||
| **Port Management** | Change server port from tray (auto-restarts server) |
|
||||
| **Content Security Policy** | Restrictive CSP via session headers |
|
||||
| **Single Instance** | Only one app instance can run at a time |
|
||||
| **Offline Mode** | Bundled Next.js server works without internet |
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
| --------------------- | ------- | -------------------------------- |
|
||||
| `OMNIROUTE_PORT` | `20128` | Server port |
|
||||
| `OMNIROUTE_MEMORY_MB` | `512` | Node.js heap limit (64–16384 MB) |
|
||||
|
||||
📖 Full documentation: [`electron/README.md`](../electron/README.md)
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# ADR-001: Next.js as the Foundation for an AI Gateway
|
||||
|
||||
## Status: Accepted
|
||||
|
||||
## Context
|
||||
|
||||
OmniRoute is an AI routing gateway that translates, forwards, and manages requests across 20+ LLM providers. We needed a framework that could serve both the API proxy layer and a management dashboard from a single codebase.
|
||||
|
||||
**Alternatives considered:**
|
||||
|
||||
- **Express.js only** — Simpler proxy, but requires separate frontend tooling
|
||||
- **Fastify** — Fast, but no built-in SSR/dashboard support
|
||||
- **Next.js** — Unified full-stack framework with API routes, SSR, and static pages
|
||||
|
||||
## Decision
|
||||
|
||||
We chose Next.js because:
|
||||
|
||||
1. **Single deployment** — API routes (`/api/*`) and dashboard UI in one process
|
||||
2. **Middleware layer** — Native request interception for auth guards and request tracing
|
||||
3. **File-based routing** — Easy to map provider endpoints to handlers
|
||||
4. **Built-in TypeScript** — Type safety across the entire codebase
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
|
||||
- One `npm run build` produces both API and UI
|
||||
- Middleware provides centralized auth and request tracing
|
||||
- Dashboard gets automatic code splitting and optimization
|
||||
|
||||
**Negative:**
|
||||
|
||||
- Next.js middleware has limitations (no heavy imports, edge runtime constraints)
|
||||
- Serverless deployment model doesn't align with persistent WebSocket/SSE connections
|
||||
- Build times are longer than Express-only setups
|
||||
- The SSE proxy layer (`open-sse/`) operates outside Next.js conventions
|
||||
@@ -0,0 +1,37 @@
|
||||
# ADR-002: Hub-and-Spoke Translation with OpenAI as Intermediate Format
|
||||
|
||||
## Status: Accepted
|
||||
|
||||
## Context
|
||||
|
||||
OmniRoute routes requests across 20+ providers, each with its own API format (OpenAI, Anthropic Messages, Google Gemini, AWS Bedrock, etc.). Direct provider-to-provider translation would require O(n²) translators.
|
||||
|
||||
**Alternatives considered:**
|
||||
|
||||
- **Direct translation** — Each pair needs a dedicated translator (n² complexity)
|
||||
- **Common intermediate format** — Translate to/from a canonical format (2n complexity)
|
||||
- **Protocol buffers** — Strong typing but heavy overhead for a proxy
|
||||
|
||||
## Decision
|
||||
|
||||
We use the **OpenAI Chat Completions format** as the canonical intermediate representation. All incoming requests are normalized to OpenAI format, processed, then translated to the target provider's format.
|
||||
|
||||
```
|
||||
Client → [any format] → OpenAI canonical → [target format] → Provider
|
||||
Provider → [response] → OpenAI canonical → [original format] → Client
|
||||
```
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
|
||||
- Only 2 translators per provider (inbound + outbound) instead of n² pairs
|
||||
- OpenAI format is the de facto standard — most clients already use it
|
||||
- Adding a new provider requires only implementing one translator pair
|
||||
- Streaming (SSE) works consistently through the canonical format
|
||||
|
||||
**Negative:**
|
||||
|
||||
- Some provider-specific features may be lost in translation
|
||||
- The double translation adds latency (typically < 5ms)
|
||||
- OpenAI format changes require updating the canonical representation
|
||||
@@ -0,0 +1,39 @@
|
||||
# ADR-003: Dual Storage — SQLite Primary with JSON Migration Path
|
||||
|
||||
## Status: Accepted
|
||||
|
||||
## Context
|
||||
|
||||
OmniRoute originally used LowDB (JSON file) for all persistence. As the project grew, JSON-based storage became a bottleneck for concurrent access, querying, and data integrity.
|
||||
|
||||
**Alternatives considered:**
|
||||
|
||||
- **LowDB only** — Simple but no concurrent access, no ACID, no querying
|
||||
- **SQLite only** — Fast, ACID-compliant, but breaks existing deployments
|
||||
- **PostgreSQL** — Production-grade but requires external dependency
|
||||
- **Dual storage with migration** — SQLite primary + automatic JSON migration
|
||||
|
||||
## Decision
|
||||
|
||||
We migrated to **SQLite as the primary store** with an automatic one-time migration from `db.json`:
|
||||
|
||||
1. On startup, if `db.json` exists and SQLite is empty, auto-migrate all data
|
||||
2. All new reads/writes go through SQLite
|
||||
3. The `db.json` file is preserved but no longer written to
|
||||
|
||||
Settings remain in a hybrid model where LowDB handles simple key-value configuration for backward compatibility.
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
|
||||
- ACID transactions for provider connections, API keys, and usage data
|
||||
- Proper SQL queries for analytics and log filtering
|
||||
- Concurrent read/write safety via WAL mode
|
||||
- Zero-downtime migration from JSON — users upgrade transparently
|
||||
|
||||
**Negative:**
|
||||
|
||||
- Two storage engines to maintain (SQLite + LowDB for settings)
|
||||
- Migration code must handle edge cases and partial data
|
||||
- SQLite binary dependency needed in deployment environments
|
||||
@@ -0,0 +1,36 @@
|
||||
# Task 01 — Home Page (Dashboard)
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `home`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/page.tsx` | 17 | 0 (wrapper) |
|
||||
| `src/app/(dashboard)/dashboard/HomePageClient.tsx` | 500 | ~25 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
### HomePageClient.tsx
|
||||
| Linha | String EN | Chave i18n | String PT-BR |
|
||||
|-------|-----------|------------|--------------|
|
||||
| 138 | "Quick Start" | `home.quickStart` | "Início Rápido" |
|
||||
| 242 | "Providers Overview" | `home.providersOverview` | "Visão Geral dos Provedores" |
|
||||
| 436 | "No models available for this provider." | `home.noModelsAvailable` | "Nenhum modelo disponível para este provedor." |
|
||||
| — | "Total Requests" | `home.totalRequests` | "Total de Requisições" |
|
||||
| — | "Active Providers" | `home.activeProviders` | "Provedores Ativos" |
|
||||
| — | "Success Rate" | `home.successRate` | "Taxa de Sucesso" |
|
||||
| — | "Avg Latency" | `home.avgLatency` | "Latência Média" |
|
||||
| — | "Configure Endpoint" | `home.configureEndpoint` | "Configurar Endpoint" |
|
||||
| — | "Add Provider" | `home.addProvider` | "Adicionar Provedor" |
|
||||
| — | "View Docs" | `home.viewDocs` | "Ver Documentação" |
|
||||
| — | "Copied!" | `common.copied` | ✅ já existe |
|
||||
| — | "requests" | `home.requests` | "requisições" |
|
||||
| — | "models" | `home.models` | "modelos" |
|
||||
| — | "accounts" | `home.accounts` | "contas" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves no `en.json` (namespace `home`)
|
||||
- [ ] Adicionar traduções no `pt-BR.json`
|
||||
- [ ] Substituir strings por `t()` no `HomePageClient.tsx`
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -0,0 +1,25 @@
|
||||
# Task 02 — Analytics Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `analytics`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/analytics/page.tsx` | 46 | ~8 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| Linha | String EN | Chave i18n | String PT-BR |
|
||||
|-------|-----------|------------|--------------|
|
||||
| 11 | "Monitor your API usage patterns..." | `analytics.overviewDescription` | "Monitore padrões de uso da API..." |
|
||||
| 13 | "Run evaluation suites to test..." | `analytics.evalsDescription` | "Execute suítes de avaliação..." |
|
||||
| 24 | "Analytics" | `analytics.title` | "Análises" |
|
||||
| 32 | "Overview" | `analytics.overview` | "Visão Geral" |
|
||||
| 33 | "Evals" | `analytics.evals` | "Avaliações" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves no `en.json`
|
||||
- [ ] Adicionar traduções no `pt-BR.json`
|
||||
- [ ] Substituir strings por `t()` em `page.tsx`
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -0,0 +1,31 @@
|
||||
# Task 03 — API Manager Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `apiManager`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/api-manager/ApiManagerPageClient.tsx` | ~400 | ~20 |
|
||||
|
||||
## Strings a Traduzir (levantamento parcial — abrir código para completar)
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "API Keys" | `apiManager.title` | "Chaves de API" |
|
||||
| "Create API Key" | `apiManager.createKey` | "Criar Chave de API" |
|
||||
| "Name" | `apiManager.name` | "Nome" |
|
||||
| "Key" | `apiManager.key` | "Chave" |
|
||||
| "Created" | `apiManager.created` | "Criado em" |
|
||||
| "Last Used" | `apiManager.lastUsed` | "Último Uso" |
|
||||
| "Actions" | `apiManager.actions` | "Ações" |
|
||||
| "Delete" | `common.delete` | ✅ já existe |
|
||||
| "No API keys found" | `apiManager.noKeys` | "Nenhuma chave de API encontrada" |
|
||||
| ~11 strings adicionais | — | Levantar no código |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar todas as strings do `ApiManagerPageClient.tsx`
|
||||
- [ ] Adicionar chaves no `en.json`
|
||||
- [ ] Adicionar traduções no `pt-BR.json`
|
||||
- [ ] Substituir strings por `t()`
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -0,0 +1,31 @@
|
||||
# Task 04 — Audit Log Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `auditLog`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/audit-log/page.tsx` | 241 | ~12 |
|
||||
| `src/app/(dashboard)/dashboard/logs/AuditLogTab.tsx` | ~100 | ~3 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Audit Log" | `auditLog.title` | "Log de Auditoria" |
|
||||
| "Search actions..." | `auditLog.searchPlaceholder` | "Buscar ações..." |
|
||||
| "Action" | `auditLog.action` | "Ação" |
|
||||
| "Actor" | `auditLog.actor` | "Autor" |
|
||||
| "Target" | `auditLog.target` | "Alvo" |
|
||||
| "Details" | `auditLog.details` | "Detalhes" |
|
||||
| "IP Address" | `auditLog.ipAddress` | "Endereço IP" |
|
||||
| "Timestamp" | `auditLog.timestamp` | "Data/Hora" |
|
||||
| "No audit entries found" | `auditLog.noEntries` | "Nenhum registro de auditoria" |
|
||||
| "Load More" | `auditLog.loadMore` | "Carregar Mais" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves no `en.json`
|
||||
- [ ] Adicionar traduções no `pt-BR.json`
|
||||
- [ ] Substituir strings em `audit-log/page.tsx` e `AuditLogTab.tsx`
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -0,0 +1,37 @@
|
||||
# Task 05 — CLI Tools Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `cliTools`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `cli-tools/components/AntigravityToolCard.tsx` | ~3 |
|
||||
| `cli-tools/components/ClaudeToolCard.tsx` | ~3 |
|
||||
| `cli-tools/components/ClineToolCard.tsx` | ~4 |
|
||||
| `cli-tools/components/CodexToolCard.tsx` | ~3 |
|
||||
| `cli-tools/components/DefaultToolCard.tsx` | ~3 |
|
||||
| `cli-tools/components/DroidToolCard.tsx` | ~2 |
|
||||
| `cli-tools/components/KiloToolCard.tsx` | ~4 |
|
||||
| `cli-tools/components/OpenClawToolCard.tsx` | ~2 |
|
||||
|
||||
## Strings comuns entre Tool Cards
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Status" | `cliTools.status` | "Status" |
|
||||
| "Connected" | `cliTools.connected` | "Conectado" |
|
||||
| "Not Connected" | `cliTools.notConnected` | "Não Conectado" |
|
||||
| "Configure" | `cliTools.configure` | "Configurar" |
|
||||
| "Test Connection" | `cliTools.testConnection` | "Testar Conexão" |
|
||||
| "Models" | `cliTools.models` | "Modelos" |
|
||||
| "Map Models" | `cliTools.mapModels` | "Mapear Modelos" |
|
||||
| "Save" | `common.save` | ✅ já existe |
|
||||
| "Cancel" | `common.cancel` | ✅ já existe |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings de cada ToolCard
|
||||
- [ ] Adicionar chaves no `en.json`
|
||||
- [ ] Adicionar traduções no `pt-BR.json`
|
||||
- [ ] Substituir por `t()` em cada componente
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -0,0 +1,34 @@
|
||||
# Task 06 — Combos Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `combos`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/combos/page.tsx` | ~1000 | ~20 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| Linha | String EN | Chave i18n | String PT-BR |
|
||||
|-------|-----------|------------|--------------|
|
||||
| 207 | "Combos" | `combos.title` | "Combos" |
|
||||
| 372 | "No models" | `combos.noModels` | "Sem modelos" |
|
||||
| 747 | "Routing Strategy" | `combos.routingStrategy` | "Estratégia de Roteamento" |
|
||||
| 791 | "Models" | `combos.models` | "Modelos" |
|
||||
| 807 | "No models added yet" | `combos.noModelsYet` | "Nenhum modelo adicionado" |
|
||||
| 922 | "Max Retries" | `combos.maxRetries` | "Máximo de Tentativas" |
|
||||
| 959 | "Timeout (ms)" | `combos.timeout` | "Timeout (ms)" |
|
||||
| 977 | "Healthcheck" | `combos.healthcheck` | "Verificação de Saúde" |
|
||||
| — | "Create Combo" | `combos.create` | "Criar Combo" |
|
||||
| — | "Edit Combo" | `combos.edit` | "Editar Combo" |
|
||||
| — | "Delete Combo" | `combos.deleteCombo` | "Excluir Combo" |
|
||||
| — | "Add Model" | `combos.addModel` | "Adicionar Modelo" |
|
||||
| — | "Priority" | `combos.priority` | "Prioridade" |
|
||||
| — | "Fallback" | `combos.fallback` | "Fallback" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves no `en.json`
|
||||
- [ ] Adicionar traduções no `pt-BR.json`
|
||||
- [ ] Substituir strings por `t()` em `combos/page.tsx`
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -0,0 +1,23 @@
|
||||
# Task 07 — Costs Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `costs`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/costs/page.tsx` | ~200 | ~5 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Costs" | `costs.title` | "Custos" |
|
||||
| "Total Cost" | `costs.totalCost` | "Custo Total" |
|
||||
| "Cost Breakdown" | `costs.breakdown` | "Detalhamento de Custos" |
|
||||
| "No cost data" | `costs.noData` | "Sem dados de custo" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings completas do código
|
||||
- [ ] Adicionar chaves no `en.json` / `pt-BR.json`
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -0,0 +1,30 @@
|
||||
# Task 08 — Endpoint Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `endpoint`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.tsx` | ~750 | ~20 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| Linha | String EN | Chave i18n | String PT-BR |
|
||||
|-------|-----------|------------|--------------|
|
||||
| 320 | "API Endpoint" | `endpoint.title` | "Endpoint da API" |
|
||||
| 403 | "Available Endpoints" | `endpoint.available` | "Endpoints Disponíveis" |
|
||||
| 561 | "Cloud Proxy" | `endpoint.cloudProxy` | "Proxy na Nuvem" |
|
||||
| 632 | "Note" | `endpoint.note` | "Nota" |
|
||||
| 717 | "Warning" | `endpoint.warning` | "Aviso" |
|
||||
| 740 | "Are you sure you want to disable cloud proxy?" | `endpoint.disableConfirm` | "Tem certeza que deseja desativar o proxy na nuvem?" |
|
||||
| — | "Copy" | `common.copy` | ✅ já existe |
|
||||
| — | "Base URL" | `endpoint.baseUrl` | "URL Base" |
|
||||
| — | "Connected" | `endpoint.connected` | "Conectado" |
|
||||
| — | "Enable" | `endpoint.enable` | "Ativar" |
|
||||
| — | "Disable" | `endpoint.disable` | "Desativar" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings restantes
|
||||
- [ ] Adicionar chaves no `en.json` / `pt-BR.json`
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -0,0 +1,30 @@
|
||||
# Task 09 — Health Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `health`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/health/page.tsx` | ~350 | ~15 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "System Health" | `health.title` | "Saúde do Sistema" |
|
||||
| "Healthy" | `health.healthy` | "Saudável" |
|
||||
| "Degraded" | `health.degraded` | "Degradado" |
|
||||
| "Down" | `health.down` | "Offline" |
|
||||
| "Uptime" | `health.uptime` | "Tempo Ativo" |
|
||||
| "Memory" | `health.memory` | "Memória" |
|
||||
| "CPU" | `health.cpu` | "CPU" |
|
||||
| "Database" | `health.database` | "Banco de Dados" |
|
||||
| "Last Check" | `health.lastCheck` | "Última Verificação" |
|
||||
| "Refresh" | `common.refresh` | ✅ já existe |
|
||||
| ~5 strings adicionais | — | Levantar |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings restantes
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -0,0 +1,24 @@
|
||||
# Task 10 — Limits Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `limits`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/limits/page.tsx` | ~150 | ~5 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Limits & Quotas" | `limits.title` | "Limites e Cotas" |
|
||||
| "Rate Limit" | `limits.rateLimit` | "Limite de Taxa" |
|
||||
| "Provider" | `limits.provider` | "Provedor" |
|
||||
| "Remaining" | `limits.remaining` | "Restante" |
|
||||
| "Reset" | `limits.reset` | "Reiniciar" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings completas
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -0,0 +1,24 @@
|
||||
# Task 11 — Logs Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `logs`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/logs/` | ~200 | ~5 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Logs" | `logs.title` | "Logs" |
|
||||
| "Request Logs" | `logs.requestLogs` | "Logs de Requisições" |
|
||||
| "Proxy Logs" | `logs.proxyLogs` | "Logs do Proxy" |
|
||||
| "Audit Log" | `logs.auditLog` | "Log de Auditoria" |
|
||||
| "Console" | `logs.console` | "Console" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings completas
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -0,0 +1,26 @@
|
||||
# Task 12 — Onboarding Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `onboarding`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/onboarding/page.tsx` | ~300 | ~10 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Welcome to OmniRoute" | `onboarding.welcome` | "Bem-vindo ao OmniRoute" |
|
||||
| "Set Password" | `onboarding.setPassword` | "Definir Senha" |
|
||||
| "Add Provider" | `onboarding.addProvider` | "Adicionar Provedor" |
|
||||
| "Get Started" | `onboarding.getStarted` | "Começar" |
|
||||
| "Skip" | `onboarding.skip` | "Pular" |
|
||||
| "Next" | `common.next` | ✅ já existe |
|
||||
| ~4 strings adicionais | — | Levantar |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings completas
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -0,0 +1,35 @@
|
||||
# Task 13 — Providers Pages
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `providers`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `providers/page.tsx` | ~5 |
|
||||
| `providers/[id]/page.tsx` | ~12 |
|
||||
| `providers/new/page.tsx` | ~3 |
|
||||
| `providers/components/ModelAvailabilityPanel.tsx` | ~3 |
|
||||
| `providers/components/ModelAvailabilityBadge.tsx` | ~1 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Providers" | `providers.title` | "Provedores" |
|
||||
| "Add Provider" | `providers.add` | "Adicionar Provedor" |
|
||||
| "Edit Provider" | `providers.edit` | "Editar Provedor" |
|
||||
| "Test Connection" | `providers.testConnection` | "Testar Conexão" |
|
||||
| "Connected" | `providers.connected` | "Conectado" |
|
||||
| "Disconnected" | `providers.disconnected` | "Desconectado" |
|
||||
| "Models" | `providers.models` | "Modelos" |
|
||||
| "Accounts" | `providers.accounts` | "Contas" |
|
||||
| "Delete Provider" | `providers.deleteProvider` | "Excluir Provedor" |
|
||||
| "No providers configured" | `providers.noProviders` | "Nenhum provedor configurado" |
|
||||
| "Model Availability" | `providers.modelAvailability` | "Disponibilidade de Modelos" |
|
||||
| ~9 strings adicionais | — | Levantar |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings completas de todos os arquivos
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -0,0 +1,51 @@
|
||||
# Task 14 — Settings Page (MAIOR TAREFA)
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `settings`
|
||||
|
||||
## Arquivos (20 componentes!)
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `settings/components/AppearanceTab.tsx` | ~4 |
|
||||
| `settings/components/CacheStatsCard.tsx` | ~4 |
|
||||
| `settings/components/ComboDefaultsTab.tsx` | ~8 |
|
||||
| `settings/components/FallbackChainsEditor.tsx` | ~2 |
|
||||
| `settings/components/IPFilterSection.tsx` | ~2 |
|
||||
| `settings/components/PoliciesPanel.tsx` | ~5 |
|
||||
| `settings/components/PricingTab.tsx` | ~8 |
|
||||
| `settings/components/ProxyTab.tsx` | ~2 |
|
||||
| `settings/components/ResilienceTab.tsx` | ~7 |
|
||||
| `settings/components/RoutingTab.tsx` | ~4 |
|
||||
| `settings/components/SecurityTab.tsx` | ~5 |
|
||||
| `settings/components/SessionInfoCard.tsx` | ~5 |
|
||||
| `settings/components/SystemPromptTab.tsx` | ~2 |
|
||||
| `settings/components/SystemStorageTab.tsx` | ~8 |
|
||||
| `settings/components/ThinkingBudgetTab.tsx` | ~5 |
|
||||
| `settings/pricing/page.tsx` | ~17 |
|
||||
|
||||
## Strings a Traduzir (amostra)
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "General" | `settings.general` | "Geral" |
|
||||
| "Security" | `settings.security` | "Segurança" |
|
||||
| "Appearance" | `settings.appearance` | "Aparência" |
|
||||
| "Routing" | `settings.routing` | "Roteamento" |
|
||||
| "Cache" | `settings.cache` | "Cache" |
|
||||
| "Resilience" | `settings.resilience` | "Resiliência" |
|
||||
| "System Prompt" | `settings.systemPrompt` | "Prompt do Sistema" |
|
||||
| "Thinking Budget" | `settings.thinkingBudget` | "Orçamento de Raciocínio" |
|
||||
| "Proxy" | `settings.proxy` | "Proxy" |
|
||||
| "Pricing" | `settings.pricing` | "Preços" |
|
||||
| "Storage" | `settings.storage` | "Armazenamento" |
|
||||
| "Policies" | `settings.policies` | "Políticas" |
|
||||
| "IP Filter" | `settings.ipFilter` | "Filtro de IP" |
|
||||
| "Combo Defaults" | `settings.comboDefaults` | "Padrões de Combo" |
|
||||
| "Fallback Chains" | `settings.fallbackChains` | "Cadeias de Fallback" |
|
||||
| ~40 strings adicionais | — | Levantar em cada tab |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings de CADA componente (16 arquivos)
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em todos os 16 arquivos
|
||||
- [ ] Testar cada aba em EN e PT-BR
|
||||
@@ -0,0 +1,41 @@
|
||||
# Task 15 — Translator Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `translator`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `translator/components/LiveMonitorMode.tsx` | ~11 |
|
||||
| `translator/components/PlaygroundMode.tsx` | ~5 |
|
||||
| `translator/components/TestBenchMode.tsx` | ~3 |
|
||||
| `translator/components/ChatTesterMode.tsx` | ~4 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Real-Time Translation Activity" | `translator.realtime` | "Atividade de Tradução em Tempo Real" |
|
||||
| "Chat Tester" | `translator.chatTester` | "Testador de Chat" |
|
||||
| "Test Bench" | `translator.testBench` | "Bancada de Testes" |
|
||||
| "Recent Translations" | `translator.recentTranslations` | "Traduções Recentes" |
|
||||
| "No translations yet" | `translator.noTranslations` | "Nenhuma tradução ainda" |
|
||||
| "Time" | `translator.time` | "Tempo" |
|
||||
| "Source" | `translator.source` | "Origem" |
|
||||
| "Target" | `translator.target` | "Destino" |
|
||||
| "Model" | `translator.model` | "Modelo" |
|
||||
| "Status" | `translator.status` | "Status" |
|
||||
| "Latency" | `translator.latency` | "Latência" |
|
||||
| "Format Converter" | `translator.formatConverter` | "Conversor de Formato" |
|
||||
| "Input" | `translator.input` | "Entrada" |
|
||||
| "Output" | `translator.output` | "Saída" |
|
||||
| "Example Templates" | `translator.exampleTemplates` | "Modelos de Exemplo" |
|
||||
| "Compatibility Tester" | `translator.compatibilityTester` | "Testador de Compatibilidade" |
|
||||
| "Compatibility Report" | `translator.compatibilityReport` | "Relatório de Compatibilidade" |
|
||||
| "Pipeline Debugger" | `translator.pipelineDebugger` | "Depurador de Pipeline" |
|
||||
| "Translation Pipeline" | `translator.translationPipeline` | "Pipeline de Tradução" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em cada componente
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -0,0 +1,57 @@
|
||||
# Task 16 — Usage Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `usage`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `usage/components/BudgetTab.tsx` | ~4 |
|
||||
| `usage/components/BudgetTelemetryCards.tsx` | ~9 |
|
||||
| `usage/components/EvalsTab.tsx` | ~6 |
|
||||
| `usage/components/RateLimitStatus.tsx` | ~2 |
|
||||
| `usage/components/SessionsTab.tsx` | ~7 |
|
||||
| `usage/components/ProviderLimits/index.tsx` | ~7 |
|
||||
| `usage/components/ProviderLimits/ProviderLimitCard.tsx` | ~1 |
|
||||
| `usage/components/ProviderLimits/QuotaTable.tsx` | ~1 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Budget Management" | `usage.budgetManagement` | "Gerenciamento de Orçamento" |
|
||||
| "API Key" | `usage.apiKey` | "Chave de API" |
|
||||
| "This Month" | `usage.thisMonth` | "Este Mês" |
|
||||
| "Set Limits" | `usage.setLimits` | "Definir Limites" |
|
||||
| "Total requests" | `usage.totalRequests` | "Total de requisições" |
|
||||
| "No data yet" | `usage.noData` | "Sem dados ainda" |
|
||||
| "Entries" | `usage.entries` | "Entradas" |
|
||||
| "Hit Rate" | `usage.hitRate` | "Taxa de Acerto" |
|
||||
| "Circuit Breakers" | `usage.circuitBreakers` | "Disjuntores" |
|
||||
| "Locked IPs" | `usage.lockedIPs` | "IPs Bloqueados" |
|
||||
| "How It Works" | `usage.howItWorks` | "Como Funciona" |
|
||||
| "Define" | `usage.define` | "Definir" |
|
||||
| "Run" | `usage.run` | "Executar" |
|
||||
| "Evaluate" | `usage.evaluate` | "Avaliar" |
|
||||
| "Evaluation Suites" | `usage.evalSuites` | "Suítes de Avaliação" |
|
||||
| "Model Evaluations" | `usage.modelEvals` | "Avaliações de Modelos" |
|
||||
| "Model Lockouts" | `usage.modelLockouts` | "Bloqueios de Modelo" |
|
||||
| "No models currently locked" | `usage.noLockouts` | "Nenhum modelo bloqueado" |
|
||||
| "Active Sessions" | `usage.activeSessions` | "Sessões Ativas" |
|
||||
| "No active sessions" | `usage.noSessions` | "Sem sessões ativas" |
|
||||
| "Session" | `usage.session` | "Sessão" |
|
||||
| "Age" | `usage.age` | "Idade" |
|
||||
| "Requests" | `usage.requests` | "Requisições" |
|
||||
| "Connection" | `usage.connection` | "Conexão" |
|
||||
| "Provider Limits" | `usage.providerLimits` | "Limites do Provedor" |
|
||||
| "No Providers Connected" | `usage.noProviders` | "Nenhum Provedor Conectado" |
|
||||
| "Account" | `usage.account` | "Conta" |
|
||||
| "Model Quotas" | `usage.modelQuotas` | "Cotas de Modelo" |
|
||||
| "Last Used" | `usage.lastUsed` | "Último Uso" |
|
||||
| "Actions" | `usage.actions` | "Ações" |
|
||||
| "No quota data" | `usage.noQuota` | "Sem dados de cota" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em cada componente
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -0,0 +1,44 @@
|
||||
# Task 17 — Shared Modals
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `modals`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `shared/components/OAuthModal.tsx` | ~6 |
|
||||
| `shared/components/KiroAuthModal.tsx` | ~10 |
|
||||
| `shared/components/KiroSocialOAuthModal.tsx` | ~3 |
|
||||
| `shared/components/CursorAuthModal.tsx` | ~2 |
|
||||
| `shared/components/PricingModal.tsx` | ~10 |
|
||||
| `shared/components/ModelSelectModal.tsx` | ~2 |
|
||||
| `shared/components/ProxyConfigModal.tsx` | ~1 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "Waiting for Authorization" | "Aguardando Autorização" |
|
||||
| "Verification URL" | "URL de Verificação" |
|
||||
| "Your Code" | "Seu Código" |
|
||||
| "Remote access:" | "Acesso remoto:" |
|
||||
| "Connected Successfully!" | "Conectado com Sucesso!" |
|
||||
| "Connection Failed" | "Falha na Conexão" |
|
||||
| "Choose your authentication method:" | "Escolha seu método de autenticação:" |
|
||||
| "AWS Builder ID" | "AWS Builder ID" |
|
||||
| "AWS IAM Identity Center" | "AWS IAM Identity Center" |
|
||||
| "Google Account" | "Conta Google" |
|
||||
| "GitHub Account" | "Conta GitHub" |
|
||||
| "Import Token" | "Importar Token" |
|
||||
| "Auto-detecting tokens..." | "Detectando tokens automaticamente..." |
|
||||
| "Pricing Configuration" | "Configuração de Preços" |
|
||||
| "Loading pricing data..." | "Carregando dados de preços..." |
|
||||
| "Model" / "Input" / "Output" / "Cached" | "Modelo" / "Entrada" / "Saída" / "Em Cache" |
|
||||
| "Combos" | "Combos" |
|
||||
| "No models found" | "Nenhum modelo encontrado" |
|
||||
| "Connected" | "Conectado" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em cada modal
|
||||
- [ ] Testar cada modal em EN e PT-BR
|
||||
@@ -0,0 +1,37 @@
|
||||
# Task 18 — Shared Loggers
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `loggers`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `shared/components/RequestLoggerV2.tsx` | ~12 |
|
||||
| `shared/components/RequestLoggerDetail.tsx` | ~4 |
|
||||
| `shared/components/ProxyLogger.tsx` | ~7 |
|
||||
| `shared/components/ProxyLogDetail.tsx` | ~6 |
|
||||
| `shared/components/ConsoleLogViewer.tsx` | ~2 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "All Providers" | "Todos os Provedores" |
|
||||
| "All Models" | "Todos os Modelos" |
|
||||
| "All Accounts" | "Todas as Contas" |
|
||||
| "All API Keys" | "Todas as Chaves de API" |
|
||||
| "Newest" / "Oldest" | "Mais Recente" / "Mais Antigo" |
|
||||
| "Model A-Z" / "Model Z-A" | "Modelo A-Z" / "Modelo Z-A" |
|
||||
| "Columns" | "Colunas" |
|
||||
| "Loading logs..." | "Carregando logs..." |
|
||||
| "All Types" | "Todos os Tipos" |
|
||||
| "All Levels" | "Todos os Níveis" |
|
||||
| "Proxy Event" | "Evento do Proxy" |
|
||||
| "Time" / "Model" / "Combo" | "Tempo" / "Modelo" / "Combo" |
|
||||
| "No log entries found" | "Nenhuma entrada de log encontrada" |
|
||||
| "No payload data available" | "Nenhum dado de payload disponível" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em cada logger
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -0,0 +1,36 @@
|
||||
# Task 19 — Shared Charts & Stats
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `stats`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `shared/components/UsageStats.tsx` | ~6 |
|
||||
| `shared/components/analytics/charts.tsx` | ~15 |
|
||||
| `shared/components/TokenHealthBadge.tsx` | ~6 |
|
||||
| `shared/components/SystemMonitor.tsx` | ~1 |
|
||||
| `shared/components/Footer.tsx` | ~3 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "Usage Overview" | "Visão Geral de Uso" |
|
||||
| "Output Tokens" | "Tokens de Saída" |
|
||||
| "Total Cost" | "Custo Total" |
|
||||
| "Usage by Model" | "Uso por Modelo" |
|
||||
| "Usage by Account" | "Uso por Conta" |
|
||||
| "Failed to load usage statistics." | "Falha ao carregar estatísticas." |
|
||||
| "Token Health" | "Saúde dos Tokens" |
|
||||
| "Total OAuth" | "Total OAuth" |
|
||||
| "Healthy" / "Errored" / "Warning" | "Saudável" / "Com Erro" / "Aviso" |
|
||||
| "Last check" | "Última verificação" |
|
||||
| "No data" / "Share" | "Sem dados" / "Compartilhar" |
|
||||
| "Unable to load system metrics" | "Não foi possível carregar métricas" |
|
||||
| "Product" / "Resources" / "Company" (Footer) | "Produto" / "Recursos" / "Empresa" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em cada componente
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -0,0 +1,36 @@
|
||||
# Task 20 — Login & Auth Pages
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `auth`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `src/app/login/page.tsx` | ~8 |
|
||||
| `src/app/forgot-password/page.tsx` | ~3 |
|
||||
| `src/app/callback/page.tsx` | ~5 |
|
||||
| `src/app/forbidden/page.tsx` | ~1 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "Welcome" | "Bem-vindo" |
|
||||
| "OmniRoute" | "OmniRoute" (não traduzir) |
|
||||
| "Sign in" | "Entrar" |
|
||||
| "Enter your password to continue" | "Digite sua senha para continuar" |
|
||||
| "Password" | "Senha" |
|
||||
| "Unified AI API Proxy" | "Proxy Unificado de API de IA" |
|
||||
| "Loading..." | "Carregando..." |
|
||||
| "Password protection is not enabled" | "Proteção por senha não está ativada" |
|
||||
| "Reset Password" | "Redefinir Senha" |
|
||||
| "Choose a method to recover access" | "Escolha um método para recuperar acesso" |
|
||||
| "Processing..." | "Processando..." |
|
||||
| "Authorization Successful!" | "Autorização bem-sucedida!" |
|
||||
| "Copy This URL" | "Copiar esta URL" |
|
||||
| "Access Denied" | "Acesso Negado" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em cada página
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -0,0 +1,34 @@
|
||||
# Task 21 — Landing Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `landing`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `landing/components/HeroSection.tsx` | ~3 |
|
||||
| `landing/components/Features.tsx` | ~10 |
|
||||
| `landing/components/HowItWorks.tsx` | ~5 |
|
||||
| `landing/components/GetStarted.tsx` | ~5 |
|
||||
| `landing/components/Navigation.tsx` | ~2 |
|
||||
| `landing/components/FlowAnimation.tsx` | ~2 |
|
||||
| `landing/components/Footer.tsx` | ~5 |
|
||||
|
||||
## Strings a Traduzir (amostra)
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "All AI Providers" | "Todos os Provedores de IA" |
|
||||
| "One Endpoint" | "Um Endpoint" |
|
||||
| "Powerful Features" | "Recursos Poderosos" |
|
||||
| "How OmniRoute Works" | "Como o OmniRoute Funciona" |
|
||||
| "Install OmniRoute" | "Instalar o OmniRoute" |
|
||||
| "Open Dashboard" | "Abrir Painel" |
|
||||
| "Route Requests" | "Rotear Requisições" |
|
||||
| "Data Location:" | "Local dos Dados:" |
|
||||
| "Product" / "Resources" / "Legal" | "Produto" / "Recursos" / "Legal" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings completas de cada componente
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -0,0 +1,32 @@
|
||||
# Task 22 — Docs Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `docs`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `src/app/docs/page.tsx` | ~25 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "Quick Start" | "Início Rápido" |
|
||||
| "Features" | "Recursos" |
|
||||
| "Supported Providers" | "Provedores Suportados" |
|
||||
| "Common Use Cases" | "Casos de Uso Comuns" |
|
||||
| "Client Compatibility" | "Compatibilidade de Clientes" |
|
||||
| "Cherry Studio" | "Cherry Studio" (não traduzir) |
|
||||
| "Codex / GitHub Copilot Models" | "Modelos Codex / GitHub Copilot" |
|
||||
| "Cursor IDE" | "Cursor IDE" (não traduzir) |
|
||||
| "Claude Code / Antigravity" | "Claude Code / Antigravity" |
|
||||
| "API Reference" | "Referência da API" |
|
||||
| "Method" / "Path" / "Notes" | "Método" / "Caminho" / "Notas" |
|
||||
| "Model Prefixes" | "Prefixos de Modelo" |
|
||||
| "Prefix" / "Provider" / "Type" | "Prefixo" / "Provedor" / "Tipo" |
|
||||
| "Troubleshooting" | "Solução de Problemas" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -0,0 +1,31 @@
|
||||
# Task 23 — Legal Pages (Privacy & Terms)
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `legal`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `src/app/privacy/page.tsx` | ~10 |
|
||||
| `src/app/terms/page.tsx` | ~5 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "Privacy Policy" | "Política de Privacidade" |
|
||||
| "Terms of Service" | "Termos de Serviço" |
|
||||
| "Provider configurations" | "Configurações de provedores" |
|
||||
| "API keys" | "Chaves de API" |
|
||||
| "Usage logs" | "Logs de uso" |
|
||||
| "Application settings" | "Configurações do aplicativo" |
|
||||
| "View and export usage analytics" | "Visualizar e exportar análises de uso" |
|
||||
| "Clear usage history at any time" | "Limpar histórico de uso a qualquer momento" |
|
||||
| "Configure log retention policies" | "Configurar políticas de retenção de logs" |
|
||||
| "Back up and restore your database" | "Fazer backup e restaurar seu banco de dados" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
|
||||
> **Nota:** Textos legais podem requerer revisão jurídica para tradução formal.
|
||||
@@ -0,0 +1,51 @@
|
||||
# i18n Translation Tasks
|
||||
|
||||
Cada arquivo `.md` nesta pasta representa **uma tarefa de tradução** para uma página ou componente do OmniRoute.
|
||||
|
||||
## Status Legend
|
||||
|
||||
- `[ ]` — Não iniciado
|
||||
- `[/]` — Em progresso
|
||||
- `[x]` — Concluído
|
||||
|
||||
## Dashboard Pages (~260 strings)
|
||||
|
||||
| # | Tarefa | Arquivo | Strings | Status |
|
||||
| --- | ---------------------------------- | ----------------------------------------------------- | ------- | ------ |
|
||||
| 01 | [Home](./01-home.md) | `HomePageClient.tsx` | ~25 | `[ ]` |
|
||||
| 02 | [Analytics](./02-analytics.md) | `analytics/page.tsx` | ~8 | `[ ]` |
|
||||
| 03 | [API Manager](./03-api-manager.md) | `api-manager/` | ~20 | `[ ]` |
|
||||
| 04 | [Audit Log](./04-audit-log.md) | `audit-log/page.tsx`, `logs/AuditLogTab.tsx` | ~15 | `[ ]` |
|
||||
| 05 | [CLI Tools](./05-cli-tools.md) | `cli-tools/components/*.tsx` | ~20 | `[ ]` |
|
||||
| 06 | [Combos](./06-combos.md) | `combos/page.tsx` | ~20 | `[ ]` |
|
||||
| 07 | [Costs](./07-costs.md) | `costs/page.tsx` | ~5 | `[ ]` |
|
||||
| 08 | [Endpoint](./08-endpoint.md) | `endpoint/EndpointPageClient.tsx` | ~20 | `[ ]` |
|
||||
| 09 | [Health](./09-health.md) | `health/page.tsx` | ~15 | `[ ]` |
|
||||
| 10 | [Limits](./10-limits.md) | `limits/page.tsx` | ~5 | `[ ]` |
|
||||
| 11 | [Logs](./11-logs.md) | `logs/` | ~5 | `[ ]` |
|
||||
| 12 | [Onboarding](./12-onboarding.md) | `onboarding/page.tsx` | ~10 | `[ ]` |
|
||||
| 13 | [Providers](./13-providers.md) | `providers/page.tsx`, `[id]/page.tsx`, `new/page.tsx` | ~20 | `[ ]` |
|
||||
| 14 | [Settings](./14-settings.md) | `settings/components/*.tsx` | ~55 | `[ ]` |
|
||||
| 15 | [Translator](./15-translator.md) | `translator/components/*.tsx` | ~25 | `[ ]` |
|
||||
| 16 | [Usage](./16-usage.md) | `usage/components/*.tsx` | ~35 | `[ ]` |
|
||||
|
||||
## Shared Components (~95 strings)
|
||||
|
||||
| # | Tarefa | Arquivo(s) | Strings | Status |
|
||||
| --- | ---------------------------------------------- | ---------------------------------------------------- | ------- | ------ |
|
||||
| 17 | [Shared Modals](./17-shared-modals.md) | `OAuthModal`, `KiroAuthModal`, `PricingModal`, etc. | ~40 | `[ ]` |
|
||||
| 18 | [Shared Loggers](./18-shared-loggers.md) | `RequestLoggerV2`, `ProxyLogger`, `ProxyLogDetail` | ~30 | `[ ]` |
|
||||
| 19 | [Shared Charts & Stats](./19-shared-charts.md) | `UsageStats`, `analytics/charts`, `TokenHealthBadge` | ~25 | `[ ]` |
|
||||
|
||||
## Non-Dashboard Pages (~75 strings)
|
||||
|
||||
| # | Tarefa | Arquivo(s) | Strings | Status |
|
||||
| --- | ---------------------------------- | ------------------------------------------------------- | ------- | ------ |
|
||||
| 20 | [Login & Auth](./20-login-auth.md) | `login/`, `forgot-password/`, `callback/`, `forbidden/` | ~20 | `[ ]` |
|
||||
| 21 | [Landing Page](./21-landing.md) | `landing/components/*.tsx` | ~25 | `[ ]` |
|
||||
| 22 | [Docs Page](./22-docs.md) | `docs/page.tsx` | ~25 | `[ ]` |
|
||||
| 23 | [Legal Pages](./23-legal.md) | `privacy/`, `terms/` | ~15 | `[ ]` |
|
||||
|
||||
---
|
||||
|
||||
**Total estimado: ~460 strings em 23 tarefas**
|
||||
@@ -0,0 +1,12 @@
|
||||
# Multilingual Documentation
|
||||
|
||||
This directory contains machine-assisted translations based on the English docs.
|
||||
|
||||
- **API_REFERENCE.md**: 🇺🇸 [English](../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](./pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](./es/API_REFERENCE.md) | 🇫🇷 [Français](./fr/API_REFERENCE.md) | 🇮🇹 [Italiano](./it/API_REFERENCE.md) | 🇷🇺 [Русский](./ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](./zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](./de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](./in/API_REFERENCE.md) | 🇹🇭 [ไทย](./th/API_REFERENCE.md) | 🇺🇦 [Українська](./uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](./ar/API_REFERENCE.md) | 🇯🇵 [日本語](./ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](./vi/API_REFERENCE.md) | 🇧🇬 [Български](./bg/API_REFERENCE.md) | 🇩🇰 [Dansk](./da/API_REFERENCE.md) | 🇫🇮 [Suomi](./fi/API_REFERENCE.md) | 🇮🇱 [עברית](./he/API_REFERENCE.md) | 🇭🇺 [Magyar](./hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](./id/API_REFERENCE.md) | 🇰🇷 [한국어](./ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](./ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](./nl/API_REFERENCE.md) | 🇳🇴 [Norsk](./no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](./pt/API_REFERENCE.md) | 🇷🇴 [Română](./ro/API_REFERENCE.md) | 🇵🇱 [Polski](./pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](./sk/API_REFERENCE.md) | 🇸🇪 [Svenska](./sv/API_REFERENCE.md) | 🇵🇭 [Filipino](./phi/API_REFERENCE.md)
|
||||
- **ARCHITECTURE.md**: 🇺🇸 [English](../ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](./pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](./es/ARCHITECTURE.md) | 🇫🇷 [Français](./fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](./it/ARCHITECTURE.md) | 🇷🇺 [Русский](./ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](./zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](./de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](./in/ARCHITECTURE.md) | 🇹🇭 [ไทย](./th/ARCHITECTURE.md) | 🇺🇦 [Українська](./uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](./ar/ARCHITECTURE.md) | 🇯🇵 [日本語](./ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](./vi/ARCHITECTURE.md) | 🇧🇬 [Български](./bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](./da/ARCHITECTURE.md) | 🇫🇮 [Suomi](./fi/ARCHITECTURE.md) | 🇮🇱 [עברית](./he/ARCHITECTURE.md) | 🇭🇺 [Magyar](./hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](./id/ARCHITECTURE.md) | 🇰🇷 [한국어](./ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](./ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](./nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](./no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](./pt/ARCHITECTURE.md) | 🇷🇴 [Română](./ro/ARCHITECTURE.md) | 🇵🇱 [Polski](./pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](./sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](./sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](./phi/ARCHITECTURE.md)
|
||||
- **CODEBASE_DOCUMENTATION.md**: 🇺🇸 [English](../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](./pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](./es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](./fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](./it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](./ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](./zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](./de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](./in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](./th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](./uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](./ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](./ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](./vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](./bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](./da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](./fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](./he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](./hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](./id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](./ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](./ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](./nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](./no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](./pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](./ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](./pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](./sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](./sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](./phi/CODEBASE_DOCUMENTATION.md)
|
||||
- **FEATURES.md**: 🇺🇸 [English](../FEATURES.md) | 🇧🇷 [Português (Brasil)](./pt-BR/FEATURES.md) | 🇪🇸 [Español](./es/FEATURES.md) | 🇫🇷 [Français](./fr/FEATURES.md) | 🇮🇹 [Italiano](./it/FEATURES.md) | 🇷🇺 [Русский](./ru/FEATURES.md) | 🇨🇳 [中文 (简体)](./zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](./de/FEATURES.md) | 🇮🇳 [हिन्दी](./in/FEATURES.md) | 🇹🇭 [ไทย](./th/FEATURES.md) | 🇺🇦 [Українська](./uk-UA/FEATURES.md) | 🇸🇦 [العربية](./ar/FEATURES.md) | 🇯🇵 [日本語](./ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](./vi/FEATURES.md) | 🇧🇬 [Български](./bg/FEATURES.md) | 🇩🇰 [Dansk](./da/FEATURES.md) | 🇫🇮 [Suomi](./fi/FEATURES.md) | 🇮🇱 [עברית](./he/FEATURES.md) | 🇭🇺 [Magyar](./hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](./id/FEATURES.md) | 🇰🇷 [한국어](./ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](./ms/FEATURES.md) | 🇳🇱 [Nederlands](./nl/FEATURES.md) | 🇳🇴 [Norsk](./no/FEATURES.md) | 🇵🇹 [Português (Portugal)](./pt/FEATURES.md) | 🇷🇴 [Română](./ro/FEATURES.md) | 🇵🇱 [Polski](./pl/FEATURES.md) | 🇸🇰 [Slovenčina](./sk/FEATURES.md) | 🇸🇪 [Svenska](./sv/FEATURES.md) | 🇵🇭 [Filipino](./phi/FEATURES.md)
|
||||
- **TROUBLESHOOTING.md**: 🇺🇸 [English](../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](./pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](./es/TROUBLESHOOTING.md) | 🇫🇷 [Français](./fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](./it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](./ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](./zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](./de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](./in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](./th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](./uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](./ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](./ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](./vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](./bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](./da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](./fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](./he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](./hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](./id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](./ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](./ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](./nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](./no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](./pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](./ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](./pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](./sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](./sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](./phi/TROUBLESHOOTING.md)
|
||||
- **USER_GUIDE.md**: 🇺🇸 [English](../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](./pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](./es/USER_GUIDE.md) | 🇫🇷 [Français](./fr/USER_GUIDE.md) | 🇮🇹 [Italiano](./it/USER_GUIDE.md) | 🇷🇺 [Русский](./ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](./zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](./de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](./in/USER_GUIDE.md) | 🇹🇭 [ไทย](./th/USER_GUIDE.md) | 🇺🇦 [Українська](./uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](./ar/USER_GUIDE.md) | 🇯🇵 [日本語](./ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](./vi/USER_GUIDE.md) | 🇧🇬 [Български](./bg/USER_GUIDE.md) | 🇩🇰 [Dansk](./da/USER_GUIDE.md) | 🇫🇮 [Suomi](./fi/USER_GUIDE.md) | 🇮🇱 [עברית](./he/USER_GUIDE.md) | 🇭🇺 [Magyar](./hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](./id/USER_GUIDE.md) | 🇰🇷 [한국어](./ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](./ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](./nl/USER_GUIDE.md) | 🇳🇴 [Norsk](./no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](./pt/USER_GUIDE.md) | 🇷🇴 [Română](./ro/USER_GUIDE.md) | 🇵🇱 [Polski](./pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](./sk/USER_GUIDE.md) | 🇸🇪 [Svenska](./sv/USER_GUIDE.md) | 🇵🇭 [Filipino](./phi/USER_GUIDE.md)
|
||||
|
||||
Generated on 2026-02-26.
|
||||
@@ -0,0 +1,441 @@
|
||||
# مرجع واجهة برمجة التطبيقات
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](../es/API_REFERENCE.md) | 🇫🇷 [Français](../fr/API_REFERENCE.md) | 🇮🇹 [Italiano](../it/API_REFERENCE.md) | 🇷🇺 [Русский](../ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](../de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../in/API_REFERENCE.md) | 🇹🇭 [ไทย](../th/API_REFERENCE.md) | 🇺🇦 [Українська](../uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](../ar/API_REFERENCE.md) | 🇯🇵 [日本語](../ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../vi/API_REFERENCE.md) | 🇧🇬 [Български](../bg/API_REFERENCE.md) | 🇩🇰 [Dansk](../da/API_REFERENCE.md) | 🇫🇮 [Suomi](../fi/API_REFERENCE.md) | 🇮🇱 [עברית](../he/API_REFERENCE.md) | 🇭🇺 [Magyar](../hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../id/API_REFERENCE.md) | 🇰🇷 [한국어](../ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](../nl/API_REFERENCE.md) | 🇳🇴 [Norsk](../no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../pt/API_REFERENCE.md) | 🇷🇴 [Română](../ro/API_REFERENCE.md) | 🇵🇱 [Polski](../pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../sk/API_REFERENCE.md) | 🇸🇪 [Svenska](../sv/API_REFERENCE.md) | 🇵🇭 [Filipino](../phi/API_REFERENCE.md)
|
||||
|
||||
مرجع كامل لجميع نقاط نهاية OmniRoute API.
|
||||
|
||||
---
|
||||
|
||||
## جدول المحتويات
|
||||
|
||||
- [Chat Completions](#chat-completions)
|
||||
- [Embeddings](#embeddings)
|
||||
- [Image Generation](#image-generation)
|
||||
- [List Models](#list-models)
|
||||
- [Compatibility Endpoints](#compatibility-endpoints)
|
||||
- [Semantic Cache](#semantic-cache)
|
||||
- [Dashboard & Management](#dashboard--management)
|
||||
- [Request Processing](#request-processing)
|
||||
- [Authentication](#authentication)
|
||||
|
||||
---
|
||||
|
||||
## إكمالات الدردشة
|
||||
|
||||
```bash
|
||||
POST /v1/chat/completions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "cc/claude-opus-4-6",
|
||||
"messages": [
|
||||
{"role": "user", "content": "Write a function to..."}
|
||||
],
|
||||
"stream": true
|
||||
}
|
||||
```
|
||||
|
||||
### رؤوس مخصصة
|
||||
|
||||
| رأس | الاتجاه | الوصف |
|
||||
| ------------------------ | ------- | ------------------------------------------- |
|
||||
| `X-OmniRoute-No-Cache` | طلب | اضبط على `true` لتجاوز ذاكرة التخزين المؤقت |
|
||||
| `X-OmniRoute-Progress` | طلب | اضبط على `true` لأحداث التقدم |
|
||||
| `Idempotency-Key` | طلب | مفتاح Dedup (نافذة 5 ثواني) |
|
||||
| `X-Request-Id` | طلب | مفتاح إلغاء الحذف البديل |
|
||||
| `X-OmniRoute-Cache` | الرد | `HIT` أو `MISS` (غير متدفق) |
|
||||
| `X-OmniRoute-Idempotent` | الرد | `true` إذا تم إلغاء التكرار |
|
||||
| `X-OmniRoute-Progress` | الرد | `enabled` إذا تم تتبع التقدم على |
|
||||
|
||||
---
|
||||
|
||||
## التضمينات
|
||||
|
||||
```bash
|
||||
POST /v1/embeddings
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "nebius/Qwen/Qwen3-Embedding-8B",
|
||||
"input": "The food was delicious"
|
||||
}
|
||||
```
|
||||
|
||||
مقدمو الخدمة المتاحون: Nebius، وOpenAI، وMistral، وTogether AI، وFireworks، وNVIDIA.
|
||||
|
||||
```bash
|
||||
# List all embedding models
|
||||
GET /v1/embeddings
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## توليد الصور
|
||||
|
||||
```bash
|
||||
POST /v1/images/generations
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "openai/dall-e-3",
|
||||
"prompt": "A beautiful sunset over mountains",
|
||||
"size": "1024x1024"
|
||||
}
|
||||
```
|
||||
|
||||
الموفرون المتاحون: OpenAI (DALL-E)، xAI (Grok Image)، Together AI (FLUX)، Fireworks AI.
|
||||
|
||||
```bash
|
||||
# List all image models
|
||||
GET /v1/images/generations
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## قائمة النماذج
|
||||
|
||||
```bash
|
||||
GET /v1/models
|
||||
Authorization: Bearer your-api-key
|
||||
|
||||
→ Returns all chat, embedding, and image models + combos in OpenAI format
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## نقاط نهاية التوافق
|
||||
|
||||
| الطريقة | المسار | تنسيق |
|
||||
| -------- | --------------------------- | --------------------- |
|
||||
| مشاركة | `/v1/chat/completions` | أوبن آي |
|
||||
| مشاركة | `/v1/messages` | انثروبي |
|
||||
| مشاركة | `/v1/responses` | ردود OpenAI |
|
||||
| مشاركة | `/v1/embeddings` | أوبن آي |
|
||||
| مشاركة | `/v1/images/generations` | أوبن آي |
|
||||
| احصل على | `/v1/models` | أوبن آي |
|
||||
| مشاركة | `/v1/messages/count_tokens` | انثروبي |
|
||||
| احصل على | `/v1beta/models` | الجوزاء |
|
||||
| مشاركة | `/v1beta/models/{...path}` | الجوزاء توليد المحتوى |
|
||||
| مشاركة | `/v1/api/chat` | أولاما |
|
||||
|
||||
### مسارات موفر مخصصة
|
||||
|
||||
```bash
|
||||
POST /v1/providers/{provider}/chat/completions
|
||||
POST /v1/providers/{provider}/embeddings
|
||||
POST /v1/providers/{provider}/images/generations
|
||||
```
|
||||
|
||||
تتم إضافة بادئة الموفر تلقائيًا في حالة فقدانها. تُرجع النماذج غير المتطابقة `400`.
|
||||
|
||||
---
|
||||
|
||||
## ذاكرة التخزين المؤقت الدلالية
|
||||
|
||||
```bash
|
||||
# Get cache stats
|
||||
GET /api/cache
|
||||
|
||||
# Clear all caches
|
||||
DELETE /api/cache
|
||||
```
|
||||
|
||||
مثال الاستجابة:
|
||||
|
||||
```json
|
||||
{
|
||||
"semanticCache": {
|
||||
"memorySize": 42,
|
||||
"memoryMaxSize": 500,
|
||||
"dbSize": 128,
|
||||
"hitRate": 0.65
|
||||
},
|
||||
"idempotency": {
|
||||
"activeKeys": 3,
|
||||
"windowMs": 5000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## لوحة القيادة والإدارة
|
||||
|
||||
### المصادقة
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ----------------------------- | -------------- | ------------------------ |
|
||||
| `/api/auth/login` | مشاركة | تسجيل الدخول |
|
||||
| `/api/auth/logout` | مشاركة | تسجيل الخروج |
|
||||
| `/api/settings/require-login` | الحصول على/وضع | تبديل تسجيل الدخول مطلوب |
|
||||
|
||||
### إدارة مقدمي الخدمة
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ---------------------------- | ------------------ | --------------------------- |
|
||||
| `/api/providers` | الحصول على/النشر | قائمة / إنشاء مقدمي الخدمات |
|
||||
| `/api/providers/[id]` | الحصول على/وضع/حذف | إدارة مزود |
|
||||
| `/api/providers/[id]/test` | مشاركة | اختبار اتصال الموفر |
|
||||
| `/api/providers/[id]/models` | احصل على | قائمة نماذج المزود |
|
||||
| `/api/providers/validate` | مشاركة | التحقق من صحة تكوين الموفر |
|
||||
| `/api/provider-nodes*` | متنوع | إدارة عقدة الموفر |
|
||||
| `/api/provider-models` | الحصول على/نشر/حذف | نماذج مخصصة |
|
||||
|
||||
### تدفقات OAuth
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| -------------------------------- | ------- | ------------------------ |
|
||||
| `/api/oauth/[provider]/[action]` | متنوع | OAuth الخاص بموفر الخدمة |
|
||||
|
||||
### التوجيه والتكوين
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------------- | ---------------- | --------------------------------- |
|
||||
| `/api/models/alias` | الحصول على/النشر | الأسماء المستعارة للنموذج |
|
||||
| `/api/models/catalog` | احصل على | جميع الموديلات حسب المزود + النوع |
|
||||
| `/api/combos*` | متنوع | إدارة التحرير والسرد |
|
||||
| `/api/keys*` | متنوع | إدارة مفاتيح API |
|
||||
| `/api/pricing` | احصل على | التسعير النموذجي |
|
||||
|
||||
### الاستخدام والتحليلات
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------------------- | -------- | --------------------- |
|
||||
| `/api/usage/history` | احصل على | تاريخ الاستخدام |
|
||||
| `/api/usage/logs` | احصل على | سجلات الاستخدام |
|
||||
| `/api/usage/request-logs` | احصل على | سجلات على مستوى الطلب |
|
||||
| `/api/usage/[connectionId]` | احصل على | الاستخدام لكل اتصال |
|
||||
|
||||
### الإعدادات
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ------------------------------- | -------------- | ----------------------------------------------- |
|
||||
| `/api/settings` | الحصول على/وضع | الإعدادات العامة |
|
||||
| `/api/settings/proxy` | الحصول على/وضع | تكوين وكيل الشبكة |
|
||||
| `/api/settings/proxy/test` | مشاركة | اختبار اتصال الوكيل |
|
||||
| `/api/settings/ip-filter` | الحصول على/وضع | القائمة المسموح بها/القائمة المحظورة لعناوين IP |
|
||||
| `/api/settings/thinking-budget` | الحصول على/وضع | الميزانية الرمزية المنطقية |
|
||||
| `/api/settings/system-prompt` | الحصول على/وضع | موجه النظام العالمي |
|
||||
|
||||
### المراقبة
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ------------------------ | -------------- | ----------------------------------- |
|
||||
| `/api/sessions` | احصل على | تتبع الجلسة النشطة |
|
||||
| `/api/rate-limits` | احصل على | حدود المعدل لكل حساب |
|
||||
| `/api/monitoring/health` | احصل على | فحص الصحة |
|
||||
| `/api/cache` | الحصول على/حذف | إحصائيات ذاكرة التخزين المؤقت / مسح |
|
||||
|
||||
### النسخ الاحتياطي والتصدير/الاستيراد
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------------------- | -------- | -------------------------------------------------- |
|
||||
| `/api/db-backups` | احصل على | قائمة النسخ الاحتياطية المتاحة |
|
||||
| `/api/db-backups` | ضع | إنشاء نسخة احتياطية يدوية |
|
||||
| `/api/db-backups` | مشاركة | استعادة من نسخة احتياطية محددة |
|
||||
| `/api/db-backups/export` | احصل على | تنزيل قاعدة البيانات كملف .sqlite |
|
||||
| `/api/db-backups/import` | مشاركة | قم بتحميل ملف .sqlite لاستبدال قاعدة البيانات |
|
||||
| `/api/db-backups/exportAll` | احصل على | قم بتنزيل النسخة الاحتياطية الكاملة كأرشيف .tar.gz |
|
||||
|
||||
### المزامنة السحابية
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ---------------------- | ------- | ------------------------ |
|
||||
| `/api/sync/cloud` | متنوع | عمليات المزامنة السحابية |
|
||||
| `/api/sync/initialize` | مشاركة | تهيئة المزامنة |
|
||||
| `/api/cloud/*` | متنوع | إدارة السحابة |
|
||||
|
||||
### أدوات سطر الأوامر
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ---------------------------------- | -------- | ------------------- |
|
||||
| `/api/cli-tools/claude-settings` | احصل على | حالة كلود CLI |
|
||||
| `/api/cli-tools/codex-settings` | احصل على | حالة Codex CLI |
|
||||
| `/api/cli-tools/droid-settings` | احصل على | حالة Droid CLI |
|
||||
| `/api/cli-tools/openclaw-settings` | احصل على | حالة OpenClaw CLI |
|
||||
| `/api/cli-tools/runtime/[toolId]` | احصل على | وقت تشغيل CLI العام |
|
||||
|
||||
تتضمن استجابات واجهة سطر الأوامر: `installed`، `runnable`، `command`، `commandPath`، `runtimeMode`، `reason`.
|
||||
|
||||
### المرونة وحدود الأسعار
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ----------------------- | -------------- | ------------------------------------ |
|
||||
| `/api/resilience` | الحصول على/وضع | الحصول على/تحديث ملفات تعريف المرونة |
|
||||
| `/api/resilience/reset` | مشاركة | إعادة ضبط قواطع الدائرة |
|
||||
| `/api/rate-limits` | احصل على | حالة حد المعدل لكل حساب |
|
||||
| `/api/rate-limit` | احصل على | تكوين حد المعدل العالمي |
|
||||
|
||||
### التقييم
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ------------ | ---------------- | ------------------------------------- |
|
||||
| `/api/evals` | الحصول على/النشر | قائمة مجموعات التقييم / تشغيل التقييم |
|
||||
|
||||
### السياسات
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------- | ------------------ | -------------------- |
|
||||
| `/api/policies` | الحصول على/نشر/حذف | إدارة سياسات التوجيه |
|
||||
|
||||
###الامتثال
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------------------- | -------- | ---------------------------- |
|
||||
| `/api/compliance/audit-log` | احصل على | سجل تدقيق الامتثال (آخر رقم) |
|
||||
|
||||
### v1beta (متوافق مع الجوزاء)
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| -------------------------- | -------- | -------------------------------------- |
|
||||
| `/v1beta/models` | احصل على | قائمة النماذج بصيغة الجوزاء |
|
||||
| `/v1beta/models/{...path}` | مشاركة | الجوزاء `generateContent` نقطة النهاية |
|
||||
|
||||
تعكس نقاط النهاية هذه تنسيق Gemini API للعملاء الذين يتوقعون توافق Gemini SDK الأصلي.
|
||||
|
||||
### واجهات برمجة التطبيقات الداخلية / النظام
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------- | -------- | -------------------------------------------------- |
|
||||
| `/api/init` | احصل على | فحص تهيئة التطبيق (يستخدم عند التشغيل لأول مرة) |
|
||||
| `/api/tags` | احصل على | علامات النماذج المتوافقة مع Ollama (لعملاء Ollama) |
|
||||
| `/api/restart` | مشاركة | تشغيل إعادة تشغيل الخادم الرشيقة |
|
||||
| `/api/shutdown` | مشاركة | تشغيل إيقاف تشغيل الخادم بشكل رشيق |
|
||||
|
||||
> **ملاحظة:** يتم استخدام نقاط النهاية هذه داخليًا بواسطة النظام أو للتوافق مع عميل Ollama. لا يتم استدعاؤها عادة من قبل المستخدمين النهائيين.
|
||||
|
||||
---
|
||||
|
||||
## النسخ الصوتي
|
||||
|
||||
```bash
|
||||
POST /v1/audio/transcriptions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: multipart/form-data
|
||||
```
|
||||
|
||||
قم بنسخ الملفات الصوتية باستخدام Deepgram أو AssemblyAI.
|
||||
|
||||
**الطلب:**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
-H "Authorization: Bearer your-api-key" \
|
||||
-F "file=@recording.mp3" \
|
||||
-F "model=deepgram/nova-3"
|
||||
```
|
||||
|
||||
**الرد:**
|
||||
|
||||
```json
|
||||
{
|
||||
"text": "Hello, this is the transcribed audio content.",
|
||||
"task": "transcribe",
|
||||
"language": "en",
|
||||
"duration": 12.5
|
||||
}
|
||||
```
|
||||
|
||||
**الموفرون المدعمون:** `deepgram/nova-3`، `assemblyai/best`.
|
||||
|
||||
**التنسيقات المدعومة:** `mp3`، `wav`، `m4a`، `flac`، `ogg`، `webm`.
|
||||
|
||||
---
|
||||
|
||||
## التوافق مع أولاما
|
||||
|
||||
بالنسبة للعملاء الذين يستخدمون تنسيق واجهة برمجة تطبيقات Olma:
|
||||
|
||||
```bash
|
||||
# Chat endpoint (Ollama format)
|
||||
POST /v1/api/chat
|
||||
|
||||
# Model listing (Ollama format)
|
||||
GET /api/tags
|
||||
```
|
||||
|
||||
تتم ترجمة الطلبات تلقائيًا بين تنسيقات Ollama والتنسيقات الداخلية.
|
||||
|
||||
---
|
||||
|
||||
## القياس عن بعد
|
||||
|
||||
```bash
|
||||
# Get latency telemetry summary (p50/p95/p99 per provider)
|
||||
GET /api/telemetry/summary
|
||||
```
|
||||
|
||||
**الرد:**
|
||||
|
||||
```json
|
||||
{
|
||||
"providers": {
|
||||
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
|
||||
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## الميزانية
|
||||
|
||||
```bash
|
||||
# Get budget status for all API keys
|
||||
GET /api/usage/budget
|
||||
|
||||
# Set or update a budget
|
||||
POST /api/usage/budget
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"keyId": "key-123",
|
||||
"limit": 50.00,
|
||||
"period": "monthly"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## توفر النموذج
|
||||
|
||||
```bash
|
||||
# Get real-time model availability across all providers
|
||||
GET /api/models/availability
|
||||
|
||||
# Check availability for a specific model
|
||||
POST /api/models/availability
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "claude-sonnet-4-5-20250929"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## معالجة الطلب
|
||||
|
||||
1. يرسل العميل طلبًا إلى `/v1/*`
|
||||
2. يستدعي معالج المسار `handleChat`، `handleEmbedding`، `handleAudioTranscription`، أو `handleImageGeneration`
|
||||
3. تم حل النموذج (المزود/النموذج المباشر أو الاسم المستعار/السرد)
|
||||
4. تم تحديد بيانات الاعتماد من قاعدة البيانات المحلية مع تصفية توفر الحساب
|
||||
5. للدردشة: `handleChatCore` — اكتشاف التنسيق، والترجمة، والتحقق من ذاكرة التخزين المؤقت، والتحقق من عدم الكفاءة
|
||||
6. يقوم منفذ الموفر بإرسال طلب المنبع
|
||||
7. تتم ترجمة الاستجابة مرة أخرى إلى تنسيق العميل (الدردشة) أو إعادتها كما هي (التضمينات/الصور/الصوت)
|
||||
8. تم تسجيل الاستخدام/التسجيل
|
||||
9. يتم تطبيق الإجراء الاحتياطي على الأخطاء وفقًا لقواعد التحرير والسرد
|
||||
|
||||
مرجع البنية الكاملة: [link](ARCHITECTURE.md)
|
||||
|
||||
---
|
||||
|
||||
## المصادقة
|
||||
|
||||
- تستخدم مسارات لوحة المعلومات (`/dashboard/*`) ملف تعريف الارتباط `auth_token`
|
||||
- يستخدم تسجيل الدخول تجزئة كلمة المرور المحفوظة؛ الرجوع إلى `INITIAL_PASSWORD`
|
||||
- `requireLogin` قابل للتبديل عبر `/api/settings/require-login`
|
||||
- تتطلب مسارات `/v1/*` بشكل اختياري مفتاح Bearer API عندما `REQUIRE_API_KEY=true`
|
||||
@@ -0,0 +1,781 @@
|
||||
# العمارة OmniRoute
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](../es/ARCHITECTURE.md) | 🇫🇷 [Français](../fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](../it/ARCHITECTURE.md) | 🇷🇺 [Русский](../ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](../zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](../de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](../in/ARCHITECTURE.md) | 🇹🇭 [ไทย](../th/ARCHITECTURE.md) | 🇺🇦 [Українська](../uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](../ar/ARCHITECTURE.md) | 🇯🇵 [日本語](../ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](../vi/ARCHITECTURE.md) | 🇧🇬 [Български](../bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](../da/ARCHITECTURE.md) | 🇫🇮 [Suomi](../fi/ARCHITECTURE.md) | 🇮🇱 [עברית](../he/ARCHITECTURE.md) | 🇭🇺 [Magyar](../hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](../id/ARCHITECTURE.md) | 🇰🇷 [한국어](../ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](../ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](../nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](../no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](../pt/ARCHITECTURE.md) | 🇷🇴 [Română](../ro/ARCHITECTURE.md) | 🇵🇱 [Polski](../pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](../sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](../sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](../phi/ARCHITECTURE.md)
|
||||
|
||||
_آخر تحديث: 2026-02-18_
|
||||
|
||||
## ملخص تنفيذي
|
||||
|
||||
OmniRoute عبارة عن بوابة توجيه محلية تعمل بالذكاء الاصطناعي ولوحة معلومات مبنية على Next.js.
|
||||
فهو يوفر نقطة نهاية واحدة متوافقة مع OpenAI (`/v1/*`) ويوجه حركة المرور عبر العديد من موفري الخدمات الأولية مع الترجمة والاحتياط وتحديث الرمز المميز وتتبع الاستخدام.
|
||||
|
||||
القدرات الأساسية:
|
||||
|
||||
- سطح API متوافق مع OpenAI لـ CLI/الأدوات (28 مزودًا)
|
||||
- ترجمة الطلب/الاستجابة عبر تنسيقات الموفر
|
||||
- نموذج احتياطي التحرير والسرد (تسلسل متعدد النماذج)
|
||||
- احتياطي على مستوى الحساب (حسابات متعددة لكل مزود)
|
||||
- إدارة اتصال موفر OAuth + API-key
|
||||
- إنشاء التضمين عبر `/v1/embeddings` (6 موفري خدمات، 9 نماذج)
|
||||
- إنشاء الصور عبر `/v1/images/generations` (4 مقدمي خدمات، 9 نماذج)
|
||||
- فكر في تحليل العلامات (`<think>...</think>`) لنماذج الاستدلال
|
||||
- تعقيم الاستجابة للتوافق الصارم مع OpenAI SDK
|
||||
- تطبيع الدور (المطور → النظام، النظام → المستخدم) للتوافق بين الموفرين
|
||||
- تحويل الإخراج المنظم (json_schema → Gemini ResponseSchema)
|
||||
- الثبات المحلي لمقدمي الخدمات والمفاتيح والأسماء المستعارة والمجموعات والإعدادات والتسعير
|
||||
- تتبع الاستخدام/التكلفة وتسجيل الطلب
|
||||
- مزامنة سحابية اختيارية لمزامنة الأجهزة/الحالة المتعددة
|
||||
- القائمة المسموح بها/القائمة المحظورة لـ IP للتحكم في الوصول إلى واجهة برمجة التطبيقات
|
||||
- التفكير في إدارة الميزانية (العبور / التلقائي / المخصص / التكيفي)
|
||||
- الحقن الفوري للنظام العالمي
|
||||
- تتبع الجلسة وأخذ البصمات
|
||||
- تحديد المعدل المحسن لكل حساب مع الملفات الشخصية الخاصة بالمزود
|
||||
- نمط قاطع الدائرة لمرونة المزود
|
||||
- حماية القطيع ضد الرعد مع قفل Mutex
|
||||
- ذاكرة التخزين المؤقت لإلغاء البيانات المكررة للطلب المستندة إلى التوقيع
|
||||
- طبقة المجال: توفر النموذج، وقواعد التكلفة، والسياسة الاحتياطية، وسياسة الإغلاق
|
||||
- استمرارية حالة المجال (ذاكرة التخزين المؤقت للكتابة في SQLite للاحتياطيات والميزانيات وعمليات الإغلاق وقواطع الدائرة)
|
||||
- محرك السياسة لتقييم الطلب المركزي (التأمين → الميزانية → الاحتياطي)
|
||||
- طلب القياس عن بعد مع تجميع الكمون p50/p95/p99
|
||||
- معرف الارتباط (X-Request-Id) للتتبع الشامل
|
||||
- تسجيل تدقيق الامتثال مع إلغاء الاشتراك لكل مفتاح API
|
||||
- إطار تقييمي لضمان جودة LLM
|
||||
- لوحة تحكم واجهة المستخدم المرنة مع حالة قاطع الدائرة في الوقت الفعلي
|
||||
- موفرو OAuth المعياريون (12 وحدة فردية ضمن `src/lib/oauth/providers/`)
|
||||
|
||||
نموذج وقت التشغيل الأساسي:
|
||||
|
||||
- تقوم مسارات تطبيق Next.js ضمن `src/app/api/*` بتنفيذ كل من واجهات برمجة تطبيقات لوحة المعلومات وواجهات برمجة تطبيقات التوافق
|
||||
- نواة توجيه/SSE مشتركة في `src/sse/*` + `open-sse/*` تتعامل مع تنفيذ الموفر والترجمة والتدفق والرجوع والاستخدام
|
||||
|
||||
## النطاق والحدود
|
||||
|
||||
### في النطاق
|
||||
|
||||
- وقت تشغيل البوابة المحلية
|
||||
- واجهات برمجة التطبيقات لإدارة لوحة المعلومات
|
||||
- مصادقة الموفر وتحديث الرمز المميز
|
||||
- طلب الترجمة وتدفق SSE
|
||||
- الحالة المحلية + استمرارية الاستخدام
|
||||
- تنسيق مزامنة سحابية اختيارية
|
||||
|
||||
### خارج النطاق
|
||||
|
||||
- تنفيذ الخدمة السحابية خلف `NEXT_PUBLIC_CLOUD_URL`
|
||||
- مزود مستوى جيش تحرير السودان/مستوى التحكم خارج العملية المحلية
|
||||
- ثنائيات CLI الخارجية نفسها (Claude CLI، Codex CLI، وما إلى ذلك)
|
||||
|
||||
## سياق النظام عالي المستوى
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Clients[Developer Clients]
|
||||
C1[Claude Code]
|
||||
C2[Codex CLI]
|
||||
C3[OpenClaw / Droid / Cline / Continue / Roo]
|
||||
C4[Custom OpenAI-compatible clients]
|
||||
BROWSER[Browser Dashboard]
|
||||
end
|
||||
|
||||
subgraph Router[OmniRoute Local Process]
|
||||
API[V1 Compatibility API\n/v1/*]
|
||||
DASH[Dashboard + Management API\n/api/*]
|
||||
CORE[SSE + Translation Core\nopen-sse + src/sse]
|
||||
DB[(db.json)]
|
||||
UDB[(usage.json + log.txt)]
|
||||
end
|
||||
|
||||
subgraph Upstreams[Upstream Providers]
|
||||
P1[OAuth Providers\nClaude/Codex/Gemini/Qwen/iFlow/GitHub/Kiro/Cursor/Antigravity]
|
||||
P2[API Key Providers\nOpenAI/Anthropic/OpenRouter/GLM/Kimi/MiniMax\nDeepSeek/Groq/xAI/Mistral/Perplexity\nTogether/Fireworks/Cerebras/Cohere/NVIDIA]
|
||||
P3[Compatible Nodes\nOpenAI-compatible / Anthropic-compatible]
|
||||
end
|
||||
|
||||
subgraph Cloud[Optional Cloud Sync]
|
||||
CLOUD[Cloud Sync Endpoint\nNEXT_PUBLIC_CLOUD_URL]
|
||||
end
|
||||
|
||||
C1 --> API
|
||||
C2 --> API
|
||||
C3 --> API
|
||||
C4 --> API
|
||||
BROWSER --> DASH
|
||||
|
||||
API --> CORE
|
||||
DASH --> DB
|
||||
CORE --> DB
|
||||
CORE --> UDB
|
||||
|
||||
CORE --> P1
|
||||
CORE --> P2
|
||||
CORE --> P3
|
||||
|
||||
DASH --> CLOUD
|
||||
```
|
||||
|
||||
## مكونات وقت التشغيل الأساسية
|
||||
|
||||
## 1) واجهة برمجة التطبيقات وطبقة التوجيه (مسارات تطبيق Next.js)
|
||||
|
||||
الدلائل الرئيسية:
|
||||
|
||||
- `src/app/api/v1/*` و`src/app/api/v1beta/*` لواجهات برمجة تطبيقات التوافق
|
||||
- `src/app/api/*` لواجهات برمجة التطبيقات للإدارة/التكوين
|
||||
- تتم إعادة الكتابة التالية في الخريطة `next.config.mjs` من `/v1/*` إلى `/api/v1/*`
|
||||
|
||||
طرق التوافق الهامة:
|
||||
|
||||
- `src/app/api/v1/chat/completions/route.ts`
|
||||
- `src/app/api/v1/messages/route.ts`
|
||||
- `src/app/api/v1/responses/route.ts`
|
||||
- `src/app/api/v1/models/route.ts` — يتضمن نماذج مخصصة مع `custom: true`
|
||||
- `src/app/api/v1/embeddings/route.ts` — إنشاء التضمين (6 موفري)
|
||||
- `src/app/api/v1/images/generations/route.ts` — إنشاء الصور (أكثر من 4 موفري خدمة، بما في ذلك Antigravity/Nebius)
|
||||
- `src/app/api/v1/messages/count_tokens/route.ts`
|
||||
- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — دردشة مخصصة لكل مزود
|
||||
- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — عمليات التضمين المخصصة لكل مزود
|
||||
- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — صور مخصصة لكل مزود
|
||||
- `src/app/api/v1beta/models/route.ts`
|
||||
- `src/app/api/v1beta/models/[...path]/route.ts`
|
||||
|
||||
مجالات الإدارة:
|
||||
|
||||
- المصادقة/الإعدادات: `src/app/api/auth/*`، `src/app/api/settings/*`
|
||||
- مقدمو الخدمة/الاتصالات: `src/app/api/providers*`
|
||||
- عقد الموفر: `src/app/api/provider-nodes*`
|
||||
- النماذج المخصصة: `src/app/api/provider-models` (GET/POST/DELETE)
|
||||
- كتالوج النماذج: `src/app/api/models/catalog` (GET)
|
||||
- تكوين الوكيل: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST)
|
||||
- OAuth: `src/app/api/oauth/*`
|
||||
- المفاتيح/الأسماء المستعارة/المجموعات/التسعير: `src/app/api/keys*`، `src/app/api/models/alias`، `src/app/api/combos*`، `src/app/api/pricing`
|
||||
- الاستخدام: `src/app/api/usage/*`
|
||||
- المزامنة/السحابة: `src/app/api/sync/*`، `src/app/api/cloud/*`
|
||||
- مساعدي أدوات CLI: `src/app/api/cli-tools/*`
|
||||
- مرشح IP: `src/app/api/settings/ip-filter` (GET/PUT)
|
||||
- ميزانية التفكير: `src/app/api/settings/thinking-budget` (GET/PUT)
|
||||
- موجه النظام: `src/app/api/settings/system-prompt` (GET/PUT)
|
||||
- الجلسات: `src/app/api/sessions` (GET)
|
||||
- حدود الأسعار: `src/app/api/rate-limits` (GET)
|
||||
- المرونة: `src/app/api/resilience` (GET/PATCH) - ملفات تعريف الموفر، قاطع الدائرة، حالة حد المعدل
|
||||
- إعادة ضبط المرونة: `src/app/api/resilience/reset` (POST) — إعادة ضبط الفواصل + فترات التهدئة
|
||||
- إحصائيات ذاكرة التخزين المؤقت: `src/app/api/cache/stats` (الحصول على/الحذف)
|
||||
- توفر النموذج: `src/app/api/models/availability` (GET/POST)
|
||||
- القياس عن بعد: `src/app/api/telemetry/summary` (GET)
|
||||
- الميزانية: `src/app/api/usage/budget` (GET/POST)
|
||||
- السلاسل الاحتياطية: `src/app/api/fallback/chains` (GET/POST/DELETE)
|
||||
- تدقيق الامتثال: `src/app/api/compliance/audit-log` (GET)
|
||||
- التقييمات: `src/app/api/evals` (GET/POST)، `src/app/api/evals/[suiteId]` (GET)
|
||||
- السياسات: `src/app/api/policies` (GET/POST)
|
||||
|
||||
## 2) SSE + جوهر الترجمة
|
||||
|
||||
وحدات التدفق الرئيسية:
|
||||
|
||||
- الإدخال: `src/sse/handlers/chat.ts`
|
||||
- التنسيق الأساسي: `open-sse/handlers/chatCore.ts`
|
||||
- محولات تنفيذ الموفر: `open-sse/executors/*`
|
||||
- اكتشاف التنسيق/تكوين الموفر: `open-sse/services/provider.ts`
|
||||
- تحليل/حل النموذج: `src/sse/services/model.ts`، `open-sse/services/model.ts`
|
||||
- المنطق الاحتياطي للحساب: `open-sse/services/accountFallback.ts`
|
||||
- سجل الترجمة: `open-sse/translator/index.ts`
|
||||
- تحويلات الدفق: `open-sse/utils/stream.ts`، `open-sse/utils/streamHandler.ts`
|
||||
- استخراج/تسوية الاستخدام: `open-sse/utils/usageTracking.ts`
|
||||
- محلل العلامات: `open-sse/utils/thinkTagParser.ts`
|
||||
- معالج التضمين: `open-sse/handlers/embeddings.ts`
|
||||
- تسجيل موفر التضمين: `open-sse/config/embeddingRegistry.ts`
|
||||
- معالج إنشاء الصور: `open-sse/handlers/imageGeneration.ts`
|
||||
- سجل موفر الصور: `open-sse/config/imageRegistry.ts`
|
||||
- تعقيم الاستجابة: `open-sse/handlers/responseSanitizer.ts`
|
||||
- تطبيع الدور: `open-sse/services/roleNormalizer.ts`
|
||||
|
||||
الخدمات (منطق الأعمال):
|
||||
|
||||
- اختيار الحساب/تسجيل النقاط: `open-sse/services/accountSelector.ts`
|
||||
- إدارة دورة حياة السياق: `open-sse/services/contextManager.ts`
|
||||
- فرض عامل تصفية IP: `open-sse/services/ipFilter.ts`
|
||||
- تتبع الجلسة: `open-sse/services/sessionManager.ts`
|
||||
- طلب إلغاء البيانات المكررة: `open-sse/services/signatureCache.ts`
|
||||
- الحقن الفوري للنظام: `open-sse/services/systemPrompt.ts`
|
||||
- إدارة ميزانية التفكير: `open-sse/services/thinkingBudget.ts`
|
||||
- توجيه نموذج حرف البدل: `open-sse/services/wildcardRouter.ts`
|
||||
- إدارة حدود السعر: `open-sse/services/rateLimitManager.ts`
|
||||
- قاطع الدائرة: `open-sse/services/circuitBreaker.ts`
|
||||
|
||||
وحدات طبقة المجال:
|
||||
|
||||
- توفر النموذج: `src/lib/domain/modelAvailability.ts`
|
||||
- قواعد/ميزانيات التكلفة: `src/lib/domain/costRules.ts`
|
||||
- السياسة الاحتياطية: `src/lib/domain/fallbackPolicy.ts`
|
||||
- محلل التحرير والسرد: `src/lib/domain/comboResolver.ts`
|
||||
- سياسة التأمين: `src/lib/domain/lockoutPolicy.ts`
|
||||
- محرك السياسة: `src/domain/policyEngine.ts` — الإغلاق المركزي ← الميزانية ← التقييم الاحتياطي
|
||||
- كتالوج رموز الأخطاء: `src/lib/domain/errorCodes.ts`
|
||||
- معرف الطلب: `src/lib/domain/requestId.ts`
|
||||
- مهلة الجلب: `src/lib/domain/fetchTimeout.ts`
|
||||
- طلب القياس عن بعد: `src/lib/domain/requestTelemetry.ts`
|
||||
- الامتثال/التدقيق: `src/lib/domain/compliance/index.ts`
|
||||
- عداء التقييم: `src/lib/domain/evalRunner.ts`
|
||||
- استمرارية حالة المجال: `src/lib/db/domainState.ts` — SQLite CRUD للسلاسل الاحتياطية، والميزانيات، وتاريخ التكلفة، وحالة الإغلاق، وقواطع الدائرة
|
||||
|
||||
وحدات موفر OAuth (12 ملفًا فرديًا ضمن `src/lib/oauth/providers/`):
|
||||
|
||||
- فهرس التسجيل: `src/lib/oauth/providers/index.ts`
|
||||
- مقدمو الخدمات الأفراد: `claude.ts`، `codex.ts`، `gemini.ts`، `antigravity.ts`، `iflow.ts`، `qwen.ts`، `kimi-coding.ts`، `github.ts`، `kiro.ts`، `cursor.ts`، `kilocode.ts`، `cline.ts`
|
||||
- الغلاف الرقيق: `src/lib/oauth/providers.ts` — إعادة التصدير من الوحدات الفردية
|
||||
|
||||
## 3) طبقة الثبات
|
||||
|
||||
قاعدة بيانات الحالة الأساسية:
|
||||
|
||||
- `src/lib/localDb.ts`
|
||||
- الملف: `${DATA_DIR}/db.json` (أو `$XDG_CONFIG_HOME/omniroute/db.json` عند التعيين، وإلا `~/.omniroute/db.json`)
|
||||
- الكيانات:providerConnections، وproviderNodes، وmodelAliases، والمجموعات، وapiKeys، والإعدادات، والتسعير، **customModels**، **proxyConfig**، **ipFilter**، **thinkingBudget**، **systemPrompt**
|
||||
|
||||
قاعدة بيانات الاستخدام:
|
||||
|
||||
- `src/lib/usageDb.ts`
|
||||
- الملفات: `${DATA_DIR}/usage.json`، `${DATA_DIR}/log.txt`، `${DATA_DIR}/call_logs/`
|
||||
- يتبع نفس سياسة الدليل الأساسي مثل `localDb` (`DATA_DIR`، ثم `XDG_CONFIG_HOME/omniroute` عند التعيين)
|
||||
- مقسمة إلى وحدات فرعية مركزة: `migrations.ts`، `usageHistory.ts`، `costCalculator.ts`، `usageStats.ts`، `callLogs.ts`
|
||||
|
||||
قاعدة بيانات حالة المجال (SQLite):
|
||||
|
||||
- `src/lib/db/domainState.ts` — عمليات CRUD لحالة المجال
|
||||
- الجداول (التي تم إنشاؤها في `src/lib/db/core.ts`): `domain_fallback_chains`، `domain_budgets`، `domain_cost_history`، `domain_lockout_state`، `domain_circuit_breakers`
|
||||
- نمط ذاكرة التخزين المؤقت للكتابة: تعد الخرائط الموجودة في الذاكرة موثوقة في وقت التشغيل؛ تتم كتابة الطفرات بشكل متزامن إلى SQLite؛ تتم استعادة الحالة من قاعدة البيانات عند البداية الباردة
|
||||
|
||||
## 4) المصادقة + الأسطح الأمنية
|
||||
|
||||
- مصادقة ملف تعريف الارتباط للوحة المعلومات: `src/proxy.ts`، `src/app/api/auth/login/route.ts`
|
||||
- إنشاء/التحقق من مفتاح واجهة برمجة التطبيقات: `src/shared/utils/apiKey.ts`
|
||||
- استمرت أسرار الموفر في إدخالات `providerConnections`
|
||||
- دعم الوكيل الصادر عبر `open-sse/utils/proxyFetch.ts` (env vars) و`open-sse/utils/networkProxy.ts` (قابل للتكوين لكل موفر أو عالمي)
|
||||
|
||||
## 5) المزامنة السحابية
|
||||
|
||||
- الحرف الأول للمجدول: `src/lib/initCloudSync.ts`، `src/shared/services/initializeCloudSync.ts`
|
||||
- المهمة الدورية: `src/shared/services/cloudSyncScheduler.ts`
|
||||
- مسار التحكم: `src/app/api/sync/cloud/route.ts`
|
||||
|
||||
## دورة حياة الطلب (`/v1/chat/completions`)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant Client as CLI/SDK Client
|
||||
participant Route as /api/v1/chat/completions
|
||||
participant Chat as src/sse/handlers/chat
|
||||
participant Core as open-sse/handlers/chatCore
|
||||
participant Model as Model Resolver
|
||||
participant Auth as Credential Selector
|
||||
participant Exec as Provider Executor
|
||||
participant Prov as Upstream Provider
|
||||
participant Stream as Stream Translator
|
||||
participant Usage as usageDb
|
||||
|
||||
Client->>Route: POST /v1/chat/completions
|
||||
Route->>Chat: handleChat(request)
|
||||
Chat->>Model: parse/resolve model or combo
|
||||
|
||||
alt Combo model
|
||||
Chat->>Chat: iterate combo models (handleComboChat)
|
||||
end
|
||||
|
||||
Chat->>Auth: getProviderCredentials(provider)
|
||||
Auth-->>Chat: active account + tokens/api key
|
||||
|
||||
Chat->>Core: handleChatCore(body, modelInfo, credentials)
|
||||
Core->>Core: detect source format
|
||||
Core->>Core: translate request to target format
|
||||
Core->>Exec: execute(provider, transformedBody)
|
||||
Exec->>Prov: upstream API call
|
||||
Prov-->>Exec: SSE/JSON response
|
||||
Exec-->>Core: response + metadata
|
||||
|
||||
alt 401/403
|
||||
Core->>Exec: refreshCredentials()
|
||||
Exec-->>Core: updated tokens
|
||||
Core->>Exec: retry request
|
||||
end
|
||||
|
||||
Core->>Stream: translate/normalize stream to client format
|
||||
Stream-->>Client: SSE chunks / JSON response
|
||||
|
||||
Stream->>Usage: extract usage + persist history/log
|
||||
```
|
||||
|
||||
## التحرير والسرد + التدفق الاحتياطي للحساب
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Incoming model string] --> B{Is combo name?}
|
||||
B -- Yes --> C[Load combo models sequence]
|
||||
B -- No --> D[Single model path]
|
||||
|
||||
C --> E[Try model N]
|
||||
E --> F[Resolve provider/model]
|
||||
D --> F
|
||||
|
||||
F --> G[Select account credentials]
|
||||
G --> H{Credentials available?}
|
||||
H -- No --> I[Return provider unavailable]
|
||||
H -- Yes --> J[Execute request]
|
||||
|
||||
J --> K{Success?}
|
||||
K -- Yes --> L[Return response]
|
||||
K -- No --> M{Fallback-eligible error?}
|
||||
|
||||
M -- No --> N[Return error]
|
||||
M -- Yes --> O[Mark account unavailable cooldown]
|
||||
O --> P{Another account for provider?}
|
||||
P -- Yes --> G
|
||||
P -- No --> Q{In combo with next model?}
|
||||
Q -- Yes --> E
|
||||
Q -- No --> R[Return all unavailable]
|
||||
```
|
||||
|
||||
يتم اتخاذ القرارات الاحتياطية بواسطة `open-sse/services/accountFallback.ts` باستخدام رموز الحالة والاستدلال على رسائل الخطأ.
|
||||
|
||||
## دورة حياة OAuth Onboarding وتحديث الرمز المميز
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI as Dashboard UI
|
||||
participant OAuth as /api/oauth/[provider]/[action]
|
||||
participant ProvAuth as Provider Auth Server
|
||||
participant DB as localDb
|
||||
participant Test as /api/providers/[id]/test
|
||||
participant Exec as Provider Executor
|
||||
|
||||
UI->>OAuth: GET authorize or device-code
|
||||
OAuth->>ProvAuth: create auth/device flow
|
||||
ProvAuth-->>OAuth: auth URL or device code payload
|
||||
OAuth-->>UI: flow data
|
||||
|
||||
UI->>OAuth: POST exchange or poll
|
||||
OAuth->>ProvAuth: token exchange/poll
|
||||
ProvAuth-->>OAuth: access/refresh tokens
|
||||
OAuth->>DB: createProviderConnection(oauth data)
|
||||
OAuth-->>UI: success + connection id
|
||||
|
||||
UI->>Test: POST /api/providers/[id]/test
|
||||
Test->>Exec: validate credentials / optional refresh
|
||||
Exec-->>Test: valid or refreshed token info
|
||||
Test->>DB: update status/tokens/errors
|
||||
Test-->>UI: validation result
|
||||
```
|
||||
|
||||
يتم تنفيذ التحديث أثناء حركة المرور المباشرة داخل `open-sse/handlers/chatCore.ts` عبر المنفذ `refreshCredentials()`.
|
||||
|
||||
## دورة حياة المزامنة السحابية (تمكين / مزامنة / تعطيل)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI as Endpoint Page UI
|
||||
participant Sync as /api/sync/cloud
|
||||
participant DB as localDb
|
||||
participant Cloud as External Cloud Sync
|
||||
participant Claude as ~/.claude/settings.json
|
||||
|
||||
UI->>Sync: POST action=enable
|
||||
Sync->>DB: set cloudEnabled=true
|
||||
Sync->>DB: ensure API key exists
|
||||
Sync->>Cloud: POST /sync/{machineId} (providers/aliases/combos/keys)
|
||||
Cloud-->>Sync: sync result
|
||||
Sync->>Cloud: GET /{machineId}/v1/verify
|
||||
Sync-->>UI: enabled + verification status
|
||||
|
||||
UI->>Sync: POST action=sync
|
||||
Sync->>Cloud: POST /sync/{machineId}
|
||||
Cloud-->>Sync: remote data
|
||||
Sync->>DB: update newer local tokens/status
|
||||
Sync-->>UI: synced
|
||||
|
||||
UI->>Sync: POST action=disable
|
||||
Sync->>DB: set cloudEnabled=false
|
||||
Sync->>Cloud: DELETE /sync/{machineId}
|
||||
Sync->>Claude: switch ANTHROPIC_BASE_URL back to local (if needed)
|
||||
Sync-->>UI: disabled
|
||||
```
|
||||
|
||||
يتم تشغيل المزامنة الدورية بواسطة `CloudSyncScheduler` عند تمكين السحابة.
|
||||
|
||||
## نموذج البيانات وخريطة التخزين
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
SETTINGS ||--o{ PROVIDER_CONNECTION : controls
|
||||
PROVIDER_NODE ||--o{ PROVIDER_CONNECTION : backs_compatible_provider
|
||||
PROVIDER_CONNECTION ||--o{ USAGE_ENTRY : emits_usage
|
||||
|
||||
SETTINGS {
|
||||
boolean cloudEnabled
|
||||
number stickyRoundRobinLimit
|
||||
boolean requireLogin
|
||||
string password_hash
|
||||
string fallbackStrategy
|
||||
json rateLimitDefaults
|
||||
json providerProfiles
|
||||
}
|
||||
|
||||
PROVIDER_CONNECTION {
|
||||
string id
|
||||
string provider
|
||||
string authType
|
||||
string name
|
||||
number priority
|
||||
boolean isActive
|
||||
string apiKey
|
||||
string accessToken
|
||||
string refreshToken
|
||||
string expiresAt
|
||||
string testStatus
|
||||
string lastError
|
||||
string rateLimitedUntil
|
||||
json providerSpecificData
|
||||
}
|
||||
|
||||
PROVIDER_NODE {
|
||||
string id
|
||||
string type
|
||||
string name
|
||||
string prefix
|
||||
string apiType
|
||||
string baseUrl
|
||||
}
|
||||
|
||||
MODEL_ALIAS {
|
||||
string alias
|
||||
string targetModel
|
||||
}
|
||||
|
||||
COMBO {
|
||||
string id
|
||||
string name
|
||||
string[] models
|
||||
}
|
||||
|
||||
API_KEY {
|
||||
string id
|
||||
string name
|
||||
string key
|
||||
string machineId
|
||||
}
|
||||
|
||||
USAGE_ENTRY {
|
||||
string provider
|
||||
string model
|
||||
number prompt_tokens
|
||||
number completion_tokens
|
||||
string connectionId
|
||||
string timestamp
|
||||
}
|
||||
|
||||
CUSTOM_MODEL {
|
||||
string id
|
||||
string name
|
||||
string providerId
|
||||
}
|
||||
|
||||
PROXY_CONFIG {
|
||||
string global
|
||||
json providers
|
||||
}
|
||||
|
||||
IP_FILTER {
|
||||
string mode
|
||||
string[] allowlist
|
||||
string[] blocklist
|
||||
}
|
||||
|
||||
THINKING_BUDGET {
|
||||
string mode
|
||||
number customBudget
|
||||
string effortLevel
|
||||
}
|
||||
|
||||
SYSTEM_PROMPT {
|
||||
boolean enabled
|
||||
string prompt
|
||||
string position
|
||||
}
|
||||
```
|
||||
|
||||
ملفات التخزين المادية:
|
||||
|
||||
- الحالة الرئيسية: `${DATA_DIR}/db.json` (أو `$XDG_CONFIG_HOME/omniroute/db.json` عند التعيين، وإلا `~/.omniroute/db.json`)
|
||||
- إحصائيات الاستخدام: `${DATA_DIR}/usage.json`
|
||||
- خطوط سجل الطلب: `${DATA_DIR}/log.txt`
|
||||
- جلسات تصحيح أخطاء المترجم/الطلب الاختيارية: `<repo>/logs/...`
|
||||
|
||||
## طبولوجيا النشر
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph LocalHost[Developer Host]
|
||||
CLI[CLI Tools]
|
||||
Browser[Dashboard Browser]
|
||||
end
|
||||
|
||||
subgraph ContainerOrProcess[OmniRoute Runtime]
|
||||
Next[Next.js Server\nPORT=20128]
|
||||
Core[SSE Core + Executors]
|
||||
MainDB[(db.json)]
|
||||
UsageDB[(usage.json/log.txt)]
|
||||
end
|
||||
|
||||
subgraph External[External Services]
|
||||
Providers[AI Providers]
|
||||
SyncCloud[Cloud Sync Service]
|
||||
end
|
||||
|
||||
CLI --> Next
|
||||
Browser --> Next
|
||||
Next --> Core
|
||||
Next --> MainDB
|
||||
Core --> MainDB
|
||||
Core --> UsageDB
|
||||
Core --> Providers
|
||||
Next --> SyncCloud
|
||||
```
|
||||
|
||||
## تعيين الوحدة (القرار الحاسم)
|
||||
|
||||
### وحدات المسار وواجهة برمجة التطبيقات
|
||||
|
||||
- `src/app/api/v1/*`، `src/app/api/v1beta/*`: واجهات برمجة تطبيقات التوافق
|
||||
- `src/app/api/v1/providers/[provider]/*`: مسارات مخصصة لكل مزود (الدردشة والتضمين والصور)
|
||||
- `src/app/api/providers*`: موفر CRUD والتحقق من الصحة والاختبار
|
||||
- `src/app/api/provider-nodes*`: إدارة العقدة المتوافقة المخصصة
|
||||
- `src/app/api/provider-models`: إدارة النماذج المخصصة (CRUD)
|
||||
- `src/app/api/models/catalog`: واجهة برمجة تطبيقات كتالوج النموذج الكامل (جميع الأنواع مجمعة حسب الموفر)
|
||||
- `src/app/api/oauth/*`: تدفقات OAuth/رمز الجهاز
|
||||
- `src/app/api/keys*`: دورة حياة مفتاح واجهة برمجة التطبيقات المحلية
|
||||
- `src/app/api/models/alias`: إدارة الاسم المستعار
|
||||
- `src/app/api/combos*`: إدارة التحرير والسرد الاحتياطية
|
||||
- `src/app/api/pricing`: تجاوزات التسعير لحساب التكلفة
|
||||
- `src/app/api/settings/proxy`: تكوين الوكيل (GET/PUT/DELETE)
|
||||
- `src/app/api/settings/proxy/test`: اختبار اتصال الوكيل الصادر (POST)
|
||||
- `src/app/api/usage/*`: واجهات برمجة تطبيقات الاستخدام والسجلات
|
||||
- `src/app/api/sync/*` + `src/app/api/cloud/*`: المزامنة السحابية والمساعدون الذين يواجهون السحابة
|
||||
- `src/app/api/cli-tools/*`: كاتب/أداة فحص تكوين CLI المحلية
|
||||
- `src/app/api/settings/ip-filter`: قائمة IP المسموح بها/القائمة المحظورة (GET/PUT)
|
||||
- `src/app/api/settings/thinking-budget`: تكوين ميزانية الرمز المميز (GET/PUT)
|
||||
- `src/app/api/settings/system-prompt`: موجه النظام العالمي (GET/PUT)
|
||||
- `src/app/api/sessions`: قائمة الجلسة النشطة (GET)
|
||||
- `src/app/api/rate-limits`: حالة حد السعر لكل حساب (GET)
|
||||
|
||||
### التوجيه والتنفيذ الأساسي
|
||||
|
||||
- `src/sse/handlers/chat.ts`: تحليل الطلب، ومعالجة التحرير والسرد، وحلقة اختيار الحساب
|
||||
- `open-sse/handlers/chatCore.ts`: الترجمة، إرسال المنفذ، معالجة إعادة المحاولة/التحديث، إعداد الدفق
|
||||
- `open-sse/executors/*`: سلوك الشبكة والتنسيق الخاص بالموفر
|
||||
|
||||
### سجل الترجمة ومحولات التنسيق
|
||||
|
||||
- `open-sse/translator/index.ts`: تسجيل المترجم وتنسيقه
|
||||
- طلب المترجمين: `open-sse/translator/request/*`
|
||||
- مترجمو الرد: `open-sse/translator/response/*`
|
||||
- ثوابت التنسيق: `open-sse/translator/formats.ts`
|
||||
|
||||
### المثابرة
|
||||
|
||||
- `src/lib/localDb.ts`: التكوين/الحالة المستمرة
|
||||
- `src/lib/usageDb.ts`: سجل الاستخدام وسجلات الطلبات المتجددة
|
||||
|
||||
## تغطية منفذي الخدمة (نمط الإستراتيجية)
|
||||
|
||||
كل مزود لديه منفذ متخصص يمتد `BaseExecutor` (في `open-sse/executors/base.ts`)، والذي يوفر بناء عنوان URL، وإنشاء الرأس، وإعادة المحاولة مع التراجع الأسي، وخطافات تحديث بيانات الاعتماد، وطريقة التنسيق `execute()`.
|
||||
|
||||
| المنفذ | المزود (المقدمون) | التعامل الخاص |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
|
||||
| `DefaultExecutor` | OpenAI، Claude، Gemini، Qwen، iFlow، OpenRouter، GLM، Kimi، MiniMax، DeepSeek، Groq، xAI، Mistral، Perplexity، Together، Fireworks، Cerebras، Cohere، NVIDIA | تكوين عنوان URL/الرأس الديناميكي لكل مزود |
|
||||
| `AntigravityExecutor` | جوجل مكافحة الجاذبية | معرفات المشروع/الجلسة المخصصة، إعادة المحاولة بعد التحليل |
|
||||
| `CodexExecutor` | OpenAI Codex | يحقن تعليمات النظام، ويفرض جهدًا منطقيًا |
|
||||
| `CursorExecutor` | بيئة تطوير متكاملة للمؤشر | بروتوكول ConnectRPC، تشفير Protobuf، طلب التوقيع عبر المجموع الاختباري |
|
||||
| `GithubExecutor` | جيثب مساعد الطيار | تحديث الرمز المميز لـ Copilot، ورؤوس محاكاة VSCode |
|
||||
| `KiroExecutor` | AWS CodeWhisperer/كيرو | تنسيق AWS EventStream الثنائي → تحويل SSE |
|
||||
| `GeminiCLIExecutor` | الجوزاء CLI | دورة تحديث رمز OAuth المميز لـ Google |
|
||||
|
||||
يستخدم جميع الموفرين الآخرين (بما في ذلك العقد المتوافقة المخصصة) `DefaultExecutor`.
|
||||
|
||||
## مصفوفة توافق الموفر
|
||||
|
||||
| مقدم | تنسيق | مصادقة | تيار | غير دفق | تحديث الرمز المميز | واجهة برمجة تطبيقات الاستخدام |
|
||||
| ----------------------------------- | ---------------- | --------------------------- | --------------- | ------- | ------------------ | ----------------------------- |
|
||||
| كلود | كلود | مفتاح API / OAuth | ✅ | ✅ | ✅ | ⚠️ المشرف فقط |
|
||||
| الجوزاء | الجوزاء | مفتاح API / OAuth | ✅ | ✅ | ✅ | ⚠️ وحدة التحكم السحابية |
|
||||
| الجوزاء CLI | الجوزاء-cli | أووث | ✅ | ✅ | ✅ | ⚠️ وحدة التحكم السحابية |
|
||||
| مكافحة الجاذبية | ضد الجاذبية | أووث | ✅ | ✅ | ✅ | ✅ الحصة الكاملة API |
|
||||
| أوبن آي | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| الدستور الغذائي | openai-responses | أووث | ✅ مجبور | ❌ | ✅ | ✅ حدود المعدل |
|
||||
| جيثب مساعد الطيار | أوبيناي | OAuth + رمز مساعد الطيار | ✅ | ✅ | ✅ | ✅ لقطات الحصص |
|
||||
| المؤشر | المؤشر | المجموع الاختباري المخصص | ✅ | ✅ | ❌ | ❌ |
|
||||
| كيرو | كيرو | AWS SSO OIDC | ✅(ايفنت ستريم) | ❌ | ✅ | ✅ حدود الاستخدام |
|
||||
| كوين | أوبيناي | أووث | ✅ | ✅ | ✅ | ⚠️ حسب الطلب |
|
||||
| اي فلو | أوبيناي | OAuth (أساسي) | ✅ | ✅ | ✅ | ⚠️ حسب الطلب |
|
||||
| اوبن راوتر | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| جي إل إم/كيمي/ميني ماكس | كلود | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| ديب سيك | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| جروك | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| xAI (جروك) | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| ميسترال | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| الحيرة | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| معا منظمة العفو الدولية | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| الألعاب النارية منظمة العفو الدولية | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| المخيخ | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| كوهير | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| نفيديا نيم | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
|
||||
## تنسيق تغطية الترجمة
|
||||
|
||||
تتضمن تنسيقات المصدر المكتشفة ما يلي:
|
||||
|
||||
- `openai`
|
||||
- `openai-responses`
|
||||
- `claude`
|
||||
- `gemini`
|
||||
|
||||
تتضمن التنسيقات المستهدفة ما يلي:
|
||||
|
||||
- دردشة/ردود OpenAI
|
||||
- كلود
|
||||
- الجوزاء/الجوزاء-CLI/الظرف المضاد للجاذبية
|
||||
- كيرو
|
||||
- المؤشر
|
||||
|
||||
تستخدم الترجمات **OpenAI كتنسيق مركزي** — تمر جميع التحويلات عبر OpenAI كتنسيق وسيط:
|
||||
|
||||
```
|
||||
Source Format → OpenAI (hub) → Target Format
|
||||
```
|
||||
|
||||
يتم تحديد الترجمات ديناميكيًا استنادًا إلى شكل حمولة المصدر والتنسيق المستهدف للموفر.
|
||||
|
||||
طبقات معالجة إضافية في مسار الترجمة:
|
||||
|
||||
- **تطهير الاستجابة** — يزيل الحقول غير القياسية من استجابات تنسيق OpenAI (سواء المتدفقة أو غير المتدفقة) لضمان الامتثال الصارم لـ SDK
|
||||
- **تطبيع الدور** — تحويل `developer` → `system` للأهداف غير التابعة لـ OpenAI؛ يدمج `system` → `user` للنماذج التي ترفض دور النظام (GLM، ERNIE)
|
||||
- **فكر في استخراج العلامات** — يوزع كتل `<think>...</think>` من المحتوى إلى حقل `reasoning_content`
|
||||
- **الإخراج المنظم** — يحول OpenAI `response_format.json_schema` إلى `responseMimeType` + `responseSchema` الخاص بـ Gemini
|
||||
|
||||
## نقاط نهاية واجهة برمجة التطبيقات المدعومة
|
||||
|
||||
| نقطة النهاية | تنسيق | معالج |
|
||||
| -------------------------------------------------- | ------------------ | ------------------------------------------------------------------------- |
|
||||
| `POST /v1/chat/completions` | دردشة OpenAI | `src/sse/handlers/chat.ts` |
|
||||
| `POST /v1/messages` | رسائل كلود | نفس المعالج (تم اكتشافه تلقائيًا) |
|
||||
| `POST /v1/responses` | ردود OpenAI | `open-sse/handlers/responsesHandler.ts` |
|
||||
| `POST /v1/embeddings` | تضمينات OpenAI | `open-sse/handlers/embeddings.ts` |
|
||||
| `GET /v1/embeddings` | قائمة النماذج | طريق API |
|
||||
| `POST /v1/images/generations` | صور OpenAI | `open-sse/handlers/imageGeneration.ts` |
|
||||
| `GET /v1/images/generations` | قائمة النماذج | طريق API |
|
||||
| `POST /v1/providers/{provider}/chat/completions` | دردشة OpenAI | مخصص لكل مزود مع التحقق من صحة النموذج |
|
||||
| `POST /v1/providers/{provider}/embeddings` | تضمينات OpenAI | مخصص لكل مزود مع التحقق من صحة النموذج |
|
||||
| `POST /v1/providers/{provider}/images/generations` | صور OpenAI | مخصص لكل مزود مع التحقق من صحة النموذج |
|
||||
| `POST /v1/messages/count_tokens` | عدد كلود توكن | طريق API |
|
||||
| `GET /v1/models` | قائمة نماذج OpenAI | مسار واجهة برمجة التطبيقات (الدردشة + التضمين + الصورة + النماذج المخصصة) |
|
||||
| `GET /api/models/catalog` | كتالوج | جميع النماذج مجمعة حسب الموفر + النوع |
|
||||
| `POST /v1beta/models/*:streamGenerateContent` | مولود برج الجوزاء | طريق API |
|
||||
| `GET/PUT/DELETE /api/settings/proxy` | تكوين الوكيل | تكوين وكيل الشبكة |
|
||||
| `POST /api/settings/proxy/test` | اتصال الوكيل | نقطة نهاية اختبار صحة الوكيل/الاتصال |
|
||||
| `GET/POST/DELETE /api/provider-models` | نماذج مخصصة | إدارة النماذج المخصصة لكل مزود |
|
||||
|
||||
## تجاوز المعالج
|
||||
|
||||
يعترض معالج التجاوز (`open-sse/utils/bypassHandler.ts`) طلبات "الرمي" المعروفة من Claude CLI - أصوات التمهيد، واستخراج العناوين، وعدد الرموز المميزة - ويعيد **استجابة زائفة** دون استهلاك الرموز المميزة للموفر الرئيسي. يتم تشغيل هذا فقط عندما يحتوي `User-Agent` على `claude-cli`.
|
||||
|
||||
## طلب خط أنابيب المسجل
|
||||
|
||||
يوفر مسجل الطلب (`open-sse/utils/requestLogger.ts`) مسارًا لتسجيل تصحيح الأخطاء مكون من 7 مراحل، معطل افتراضيًا، وممكن عبر `ENABLE_REQUEST_LOGS=true`:
|
||||
|
||||
```
|
||||
1_req_client.json → 2_req_source.json → 3_req_openai.json → 4_req_target.json
|
||||
→ 5_res_provider.txt → 6_res_openai.txt → 7_res_client.txt
|
||||
```
|
||||
|
||||
تتم كتابة الملفات إلى `<repo>/logs/<session>/` لكل جلسة طلب.
|
||||
|
||||
## أوضاع الفشل والمرونة
|
||||
|
||||
## 1) توفر الحساب/المزود
|
||||
|
||||
- فترة تباطؤ حساب الموفر عند حدوث أخطاء عابرة/معدل/مصادقة
|
||||
- احتياطي الحساب قبل فشل الطلب
|
||||
- نموذج التحرير والسرد الاحتياطي عند استنفاد مسار النموذج/المزود الحالي
|
||||
|
||||
## 2) انتهاء صلاحية الرمز المميز
|
||||
|
||||
- الفحص المسبق والتحديث مع إعادة المحاولة لموفري الخدمة القابلين للتحديث
|
||||
- 401/403 إعادة المحاولة بعد محاولة التحديث في المسار الأساسي
|
||||
|
||||
## 3) سلامة الدفق
|
||||
|
||||
- وحدة تحكم تيار قطع الاتصال
|
||||
- دفق الترجمة مع تدفق نهاية الدفق ومعالجة `[DONE]`
|
||||
- احتياطي تقدير الاستخدام عندما تكون البيانات الوصفية لاستخدام الموفر مفقودة
|
||||
|
||||
## 4) تدهور المزامنة السحابية
|
||||
|
||||
- ظهرت أخطاء المزامنة ولكن يستمر وقت التشغيل المحلي
|
||||
- يحتوي المجدول على منطق قادر على إعادة المحاولة، ولكن التنفيذ الدوري يستدعي حاليًا مزامنة المحاولة الواحدة بشكل افتراضي
|
||||
|
||||
## 5) سلامة البيانات
|
||||
|
||||
- ترحيل/إصلاح شكل قاعدة البيانات للمفاتيح المفقودة
|
||||
- ضمانات إعادة تعيين JSON الفاسدة لـ localDb وuseDb
|
||||
|
||||
## إمكانية الملاحظة والإشارات التشغيلية
|
||||
|
||||
مصادر رؤية وقت التشغيل:
|
||||
|
||||
- سجلات وحدة التحكم من `src/sse/utils/logger.ts`
|
||||
- مجاميع الاستخدام لكل طلب في `usage.json`
|
||||
- سجل حالة الطلب النصي في `log.txt`
|
||||
- سجلات الطلب/الترجمة العميقة الاختيارية ضمن `logs/` عندما `ENABLE_REQUEST_LOGS=true`
|
||||
- نقاط نهاية استخدام لوحة المعلومات (`/api/usage/*`) لاستهلاك واجهة المستخدم
|
||||
|
||||
## الحدود الحساسة للأمن
|
||||
|
||||
- سر JWT (`JWT_SECRET`) يؤمن التحقق/التوقيع على ملف تعريف الارتباط لجلسة لوحة المعلومات
|
||||
- يجب تجاوز الاحتياطي الأولي لكلمة المرور (`INITIAL_PASSWORD`، الافتراضي `123456`) في عمليات النشر الحقيقية
|
||||
- سر HMAC لمفتاح API (`API_KEY_SECRET`) يؤمن تنسيق مفتاح API المحلي الذي تم إنشاؤه
|
||||
- تظل أسرار الموفر (مفاتيح/رموز واجهة برمجة التطبيقات) موجودة في قاعدة البيانات المحلية ويجب حمايتها على مستوى نظام الملفات
|
||||
- تعتمد نقاط نهاية المزامنة السحابية على مصادقة مفتاح API + دلالات معرف الجهاز
|
||||
|
||||
## مصفوفة البيئة ووقت التشغيل
|
||||
|
||||
متغيرات البيئة المستخدمة بشكل نشط بواسطة التعليمات البرمجية:
|
||||
|
||||
- التطبيق/المصادقة: `JWT_SECRET`، `INITIAL_PASSWORD`
|
||||
- التخزين: `DATA_DIR`
|
||||
- سلوك العقدة المتوافقة: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE`
|
||||
- تجاوز قاعدة التخزين الاختيارية (Linux/macOS عند إلغاء تعيين `DATA_DIR`): `XDG_CONFIG_HOME`
|
||||
- التجزئة الأمنية: `API_KEY_SECRET`، `MACHINE_ID_SALT`
|
||||
- التسجيل: `ENABLE_REQUEST_LOGS`
|
||||
- عنوان URL للمزامنة/السحابة: `NEXT_PUBLIC_BASE_URL`، `NEXT_PUBLIC_CLOUD_URL`
|
||||
- الوكيل الصادر: `HTTP_PROXY`، `HTTPS_PROXY`، `ALL_PROXY`، `NO_PROXY` ومتغيرات الأحرف الصغيرة
|
||||
- علامات ميزات SOCKS5: `ENABLE_SOCKS5_PROXY`، `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY`
|
||||
- مساعدو النظام الأساسي/وقت التشغيل (ليس التكوين الخاص بالتطبيق): `APPDATA`، `NODE_ENV`، `PORT`، `HOSTNAME`
|
||||
|
||||
## الملاحظات المعمارية المعروفة
|
||||
|
||||
1. يتشارك `usageDb` و`localDb` الآن نفس سياسة الدليل الأساسي (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) مع ترحيل الملفات القديمة.
|
||||
2. يقوم `/api/v1/route.ts` بإرجاع قائمة نماذج ثابتة وهو ليس مصدر النماذج الرئيسي الذي يستخدمه `/v1/models`.
|
||||
3. يقوم مسجل الطلب بكتابة الرؤوس/النص الكامل عند تمكينه؛ التعامل مع دليل السجل على أنه حساس.
|
||||
4. يعتمد سلوك السحابة على `NEXT_PUBLIC_BASE_URL` الصحيح وإمكانية الوصول إلى نقطة نهاية السحابة.
|
||||
5. تم نشر الدليل `open-sse/` باسم `@omniroute/open-sse` **حزمة مساحة عمل npm**. يقوم كود المصدر باستيراده عبر `@omniroute/open-sse/...` (تم حله بواسطة Next.js `transpilePackages`). لا تزال مسارات الملفات في هذا المستند تستخدم اسم الدليل `open-sse/` لتحقيق الاتساق.
|
||||
6. تستخدم المخططات الموجودة في لوحة المعلومات **Recharts** (المستندة إلى SVG) لتصورات التحليلات التفاعلية التي يمكن الوصول إليها (المخططات الشريطية لاستخدام النموذج، والجداول التفصيلية للموفرين مع معدلات النجاح).
|
||||
7. تستخدم اختبارات E2E **Playwright** (`tests/e2e/`)، ويتم تشغيلها عبر `npm run test:e2e`. تستخدم اختبارات الوحدة **مشغل اختبار Node.js** (`tests/unit/`)، ويتم تشغيله عبر `npm run test:plan3`. كود المصدر ضمن `src/` هو **TypeScript** (`.ts`/`.tsx`)؛ تظل مساحة العمل `open-sse/` JavaScript (`.js`).
|
||||
8. تم تنظيم صفحة الإعدادات في 5 علامات تبويب: الأمان، التوجيه (6 إستراتيجيات عالمية: التعبئة أولاً، جولة روبن، p2c، عشوائي، الأقل استخدامًا، تحسين التكلفة)، المرونة (حدود المعدل القابلة للتحرير، قاطع الدائرة، السياسات)، الذكاء الاصطناعي (ميزانية التفكير، موجه النظام، ذاكرة التخزين المؤقت السريعة)، المتقدم (الوكيل).
|
||||
|
||||
## قائمة التحقق التشغيلية
|
||||
|
||||
- البناء من المصدر: `npm run build`
|
||||
- إنشاء صورة Docker: `docker build -t omniroute .`
|
||||
- ابدأ الخدمة وتحقق:
|
||||
- `GET /api/settings`
|
||||
- `GET /api/v1/models`
|
||||
- يجب أن يكون عنوان URL الأساسي لهدف واجهة سطر الأوامر هو `http://<host>:20128/v1` عندما يكون `PORT=20128`
|
||||
@@ -0,0 +1,589 @@
|
||||
# الطريق الشامل - وثائق قاعدة التعليمات البرمجية
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](../pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](../es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](../fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](../it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](../ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](../zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](../de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](../in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](../th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](../uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](../ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](../ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](../vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](../bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](../da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](../fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](../he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](../hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](../id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](../ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](../ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](../nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](../no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](../pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](../ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](../pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](../sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](../sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](../phi/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
> دليل شامل ومناسب للمبتدئين إلى جهاز التوجيه الوكيل AI **omniroute** متعدد الموفرين.
|
||||
|
||||
---
|
||||
|
||||
## 1. ما هو الطريق الشامل؟
|
||||
|
||||
omniroute هو **جهاز توجيه وكيل** يقع بين عملاء الذكاء الاصطناعي (Claude CLI، وCodex، وCursor IDE، وما إلى ذلك) وموفري الذكاء الاصطناعي (Anthropic، وGoogle، وOpenAI، وAWS، وGitHub، وما إلى ذلك). إنه يحل مشكلة واحدة كبيرة:
|
||||
|
||||
> **يتحدث عملاء الذكاء الاصطناعي المختلفون "لغات" مختلفة (تنسيقات واجهة برمجة التطبيقات)، ويتوقع مقدمو خدمات الذكاء الاصطناعي المختلفون "لغات" مختلفة أيضًا. ** يترجم المسار الشامل بينهم تلقائيًا.
|
||||
|
||||
فكر في الأمر وكأنه مترجم عالمي في الأمم المتحدة - يمكن لأي مندوب التحدث بأي لغة، ويقوم المترجم بتحويلها لأي مندوب آخر.
|
||||
|
||||
---
|
||||
|
||||
## 2. نظرة عامة على الهندسة المعمارية
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph Clients
|
||||
A[Claude CLI]
|
||||
B[Codex]
|
||||
C[Cursor IDE]
|
||||
D[OpenAI-compatible]
|
||||
end
|
||||
|
||||
subgraph omniroute
|
||||
E[Handler Layer]
|
||||
F[Translator Layer]
|
||||
G[Executor Layer]
|
||||
H[Services Layer]
|
||||
end
|
||||
|
||||
subgraph Providers
|
||||
I[Anthropic Claude]
|
||||
J[Google Gemini]
|
||||
K[OpenAI / Codex]
|
||||
L[GitHub Copilot]
|
||||
M[AWS Kiro]
|
||||
N[Antigravity]
|
||||
O[Cursor API]
|
||||
end
|
||||
|
||||
A --> E
|
||||
B --> E
|
||||
C --> E
|
||||
D --> E
|
||||
E --> F
|
||||
F --> G
|
||||
G --> I
|
||||
G --> J
|
||||
G --> K
|
||||
G --> L
|
||||
G --> M
|
||||
G --> N
|
||||
G --> O
|
||||
H -.-> E
|
||||
H -.-> G
|
||||
```
|
||||
|
||||
### المبدأ الأساسي: الترجمة المحورية
|
||||
|
||||
تمر جميع ترجمة التنسيقات عبر **تنسيق OpenAI كمركز**:
|
||||
|
||||
```
|
||||
Client Format → [OpenAI Hub] → Provider Format (request)
|
||||
Provider Format → [OpenAI Hub] → Client Format (response)
|
||||
```
|
||||
|
||||
هذا يعني أنك تحتاج فقط إلى مترجمين **N** (واحد لكل تنسيق) بدلاً من **N²** (كل زوج).
|
||||
|
||||
---
|
||||
|
||||
## 3. هيكل المشروع
|
||||
|
||||
```
|
||||
omniroute/
|
||||
├── open-sse/ ← Core proxy library (portable, framework-agnostic)
|
||||
│ ├── index.js ← Main entry point, exports everything
|
||||
│ ├── config/ ← Configuration & constants
|
||||
│ ├── executors/ ← Provider-specific request execution
|
||||
│ ├── handlers/ ← Request handling orchestration
|
||||
│ ├── services/ ← Business logic (auth, models, fallback, usage)
|
||||
│ ├── translator/ ← Format translation engine
|
||||
│ │ ├── request/ ← Request translators (8 files)
|
||||
│ │ ├── response/ ← Response translators (7 files)
|
||||
│ │ └── helpers/ ← Shared translation utilities (6 files)
|
||||
│ └── utils/ ← Utility functions
|
||||
├── src/ ← Application layer (Express/Worker runtime)
|
||||
│ ├── app/ ← Web UI, API routes, middleware
|
||||
│ ├── lib/ ← Database, auth, and shared library code
|
||||
│ ├── mitm/ ← Man-in-the-middle proxy utilities
|
||||
│ ├── models/ ← Database models
|
||||
│ ├── shared/ ← Shared utilities (wrappers around open-sse)
|
||||
│ ├── sse/ ← SSE endpoint handlers
|
||||
│ └── store/ ← State management
|
||||
├── data/ ← Runtime data (credentials, logs)
|
||||
│ └── provider-credentials.json (external credentials override, gitignored)
|
||||
└── tester/ ← Test utilities
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. تفصيل الوحدة تلو الأخرى
|
||||
|
||||
### 4.1 التكوين (`open-sse/config/`)
|
||||
|
||||
**المصدر الوحيد للحقيقة** لجميع إعدادات الموفر.
|
||||
|
||||
| ملف | الغرض |
|
||||
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `constants.ts` | كائن `PROVIDERS` يحتوي على عناوين URL الأساسية وبيانات اعتماد OAuth (الافتراضية) والرؤوس ومطالبات النظام الافتراضية لكل موفر. يحدد أيضًا `HTTP_STATUS`، و`ERROR_TYPES`، و`COOLDOWN_MS`، و`BACKOFF_CONFIG`، و`SKIP_PATTERNS`. |
|
||||
| `credentialLoader.ts` | يقوم بتحميل بيانات الاعتماد الخارجية من `data/provider-credentials.json` ويدمجها في الإعدادات الافتراضية المشفرة في `PROVIDERS`. يحافظ على الأسرار خارج نطاق التحكم بالمصدر مع الحفاظ على التوافق مع الإصدارات السابقة. |
|
||||
| `providerModels.ts` | سجل النموذج المركزي: الأسماء المستعارة لموفر الخرائط → معرفات النموذج. وظائف مثل `getModels()`، `getProviderByAlias()`. |
|
||||
| `codexInstructions.ts` | تعليمات النظام التي تم إدخالها في طلبات الدستور الغذائي (قيود التحرير، قواعد الاختبار، سياسات الموافقة). |
|
||||
| `defaultThinkingSignature.ts` | توقيعات "التفكير" الافتراضية لنماذج كلود وجيميني. |
|
||||
| `ollamaModels.ts` | تعريف المخطط لنماذج أولاما المحلية (الاسم، الحجم، العائلة، التكميم). |
|
||||
|
||||
#### تدفق تحميل بيانات الاعتماد
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["App starts"] --> B["constants.ts defines PROVIDERS\nwith hardcoded defaults"]
|
||||
B --> C{"data/provider-credentials.json\nexists?"}
|
||||
C -->|Yes| D["credentialLoader reads JSON"]
|
||||
C -->|No| E["Use hardcoded defaults"]
|
||||
D --> F{"For each provider in JSON"}
|
||||
F --> G{"Provider exists\nin PROVIDERS?"}
|
||||
G -->|No| H["Log warning, skip"]
|
||||
G -->|Yes| I{"Value is object?"}
|
||||
I -->|No| J["Log warning, skip"]
|
||||
I -->|Yes| K["Merge clientId, clientSecret,\ntokenUrl, authUrl, refreshUrl"]
|
||||
K --> F
|
||||
H --> F
|
||||
J --> F
|
||||
F -->|Done| L["PROVIDERS ready with\nmerged credentials"]
|
||||
E --> L
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.2 المنفذون (`open-sse/executors/`)
|
||||
|
||||
يقوم المنفذون بتغليف **المنطق الخاص بالمزود** باستخدام **نمط الإستراتيجية**. يتجاوز كل منفذ الأساليب الأساسية حسب الحاجة.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class BaseExecutor {
|
||||
+buildUrl(model, stream, options)
|
||||
+buildHeaders(credentials, stream, body)
|
||||
+transformRequest(body, model, stream, credentials)
|
||||
+execute(url, options)
|
||||
+shouldRetry(status, error)
|
||||
+refreshCredentials(credentials, log)
|
||||
}
|
||||
|
||||
class DefaultExecutor {
|
||||
+refreshCredentials()
|
||||
}
|
||||
|
||||
class AntigravityExecutor {
|
||||
+buildUrl()
|
||||
+buildHeaders()
|
||||
+transformRequest()
|
||||
+shouldRetry()
|
||||
+refreshCredentials()
|
||||
}
|
||||
|
||||
class CursorExecutor {
|
||||
+buildUrl()
|
||||
+buildHeaders()
|
||||
+transformRequest()
|
||||
+parseResponse()
|
||||
+generateChecksum()
|
||||
}
|
||||
|
||||
class KiroExecutor {
|
||||
+buildUrl()
|
||||
+buildHeaders()
|
||||
+transformRequest()
|
||||
+parseEventStream()
|
||||
+refreshCredentials()
|
||||
}
|
||||
|
||||
BaseExecutor <|-- DefaultExecutor
|
||||
BaseExecutor <|-- AntigravityExecutor
|
||||
BaseExecutor <|-- CursorExecutor
|
||||
BaseExecutor <|-- KiroExecutor
|
||||
BaseExecutor <|-- CodexExecutor
|
||||
BaseExecutor <|-- GeminiCLIExecutor
|
||||
BaseExecutor <|-- GithubExecutor
|
||||
```
|
||||
|
||||
| المنفذ | مقدم | التخصصات الرئيسية |
|
||||
| ---------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `base.ts` | — | قاعدة الملخصات: إنشاء عنوان URL، والرؤوس، ومنطق إعادة المحاولة، وتحديث بيانات الاعتماد |
|
||||
| `default.ts` | كلود، جيميني، أوبن آي آي، جي إل إم، كيمي، ميني ماكس | تحديث رمز OAuth العام للموفرين القياسيين |
|
||||
| `antigravity.ts` | جوجل كلاود كود | إنشاء معرف المشروع/الجلسة، وإرجاع عناوين URL المتعددة، وإعادة محاولة التحليل المخصصة من رسائل الخطأ ("إعادة التعيين بعد 2 ساعة و7 دقائق و23 ثانية") |
|
||||
| `cursor.ts` | بيئة تطوير متكاملة للمؤشر | **الأكثر تعقيدًا**: مصادقة المجموع الاختباري SHA-256، وترميز طلب Protobuf، وEventStream الثنائي → تحليل استجابة SSE |
|
||||
| `codex.ts` | OpenAI Codex | إدخال تعليمات النظام، وإدارة مستويات التفكير، وإزالة المعلمات غير المدعومة |
|
||||
| `gemini-cli.ts` | جوجل الجوزاء CLI | بناء عنوان URL المخصص (`streamGenerateContent`)، تحديث رمز OAuth المميز لـ Google |
|
||||
| `github.ts` | جيثب مساعد الطيار | نظام الرمز المزدوج (GitHub OAuth + Copilot token)، محاكاة رأس VSCode |
|
||||
| `kiro.ts` | AWS CodeWhisperer | التحليل الثنائي لـ AWS EventStream، وإطارات أحداث AMZN، وتقدير الرمز المميز |
|
||||
| `index.ts` | — | المصنع: اسم موفر الخرائط ← فئة المنفذ، مع خيار احتياطي افتراضي |
|
||||
|
||||
---
|
||||
|
||||
### 4.3 المعالجات (`open-sse/handlers/`)
|
||||
|
||||
**طبقة التنسيق** — تتولى تنسيق الترجمة والتنفيذ والتدفق ومعالجة الأخطاء.
|
||||
|
||||
| ملف | الغرض |
|
||||
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `chatCore.ts` | ** المنسق المركزي ** (~ 600 سطر). يتعامل مع دورة حياة الطلب الكاملة: اكتشاف التنسيق ← الترجمة ← إرسال المنفذ ← استجابة التدفق/غير المتدفق ← تحديث الرمز المميز ← معالجة الأخطاء ← تسجيل الاستخدام. |
|
||||
| `responsesHandler.ts` | محول واجهة برمجة تطبيقات استجابات OpenAI: يحول تنسيق الردود ← إكمالات الدردشة ← يرسل إلى `chatCore` ← يحول SSE مرة أخرى إلى تنسيق الردود. |
|
||||
| `embeddings.ts` | معالج إنشاء التضمين: يحل نموذج التضمين → الموفر، ويرسل إلى واجهة برمجة تطبيقات الموفر، ويعيد استجابة التضمين المتوافقة مع OpenAI. يدعم 6+ مقدمي الخدمات. |
|
||||
| `imageGeneration.ts` | معالج إنشاء الصور: يحل نموذج الصورة → الموفر، ويدعم الأوضاع المتوافقة مع OpenAI، وGemini-image (Antigravity)، والوضع الاحتياطي (Nebius). إرجاع صور base64 أو URL. |
|
||||
|
||||
#### دورة حياة الطلب (chatCore.ts)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client
|
||||
participant chatCore
|
||||
participant Translator
|
||||
participant Executor
|
||||
participant Provider
|
||||
|
||||
Client->>chatCore: Request (any format)
|
||||
chatCore->>chatCore: Detect source format
|
||||
chatCore->>chatCore: Check bypass patterns
|
||||
chatCore->>chatCore: Resolve model & provider
|
||||
chatCore->>Translator: Translate request (source → OpenAI → target)
|
||||
chatCore->>Executor: Get executor for provider
|
||||
Executor->>Executor: Build URL, headers, transform request
|
||||
Executor->>Executor: Refresh credentials if needed
|
||||
Executor->>Provider: HTTP fetch (streaming or non-streaming)
|
||||
|
||||
alt Streaming
|
||||
Provider-->>chatCore: SSE stream
|
||||
chatCore->>chatCore: Pipe through SSE transform stream
|
||||
Note over chatCore: Transform stream translates<br/>each chunk: target → OpenAI → source
|
||||
chatCore-->>Client: Translated SSE stream
|
||||
else Non-streaming
|
||||
Provider-->>chatCore: JSON response
|
||||
chatCore->>Translator: Translate response
|
||||
chatCore-->>Client: Translated JSON
|
||||
end
|
||||
|
||||
alt Error (401, 429, 500...)
|
||||
chatCore->>Executor: Retry with credential refresh
|
||||
chatCore->>chatCore: Account fallback logic
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.4 الخدمات (`open-sse/services/`)
|
||||
|
||||
منطق الأعمال الذي يدعم المعالجات والمنفذين.
|
||||
|
||||
| ملف | الغرض |
|
||||
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `provider.ts` | **كشف التنسيق** (`detectFormat`): تحليلات بنية الجسم لتحديد تنسيقات Claude/OpenAI/Gemini/Antigravity/Responses (تتضمن `max_tokens` الاستدلال لكلود). أيضًا: بناء عنوان URL، وبناء الرأس، وتطبيع تكوين التفكير. يدعم موفري الخدمات الديناميكيين `openai-compatible-*` و`anthropic-compatible-*`. |
|
||||
| `model.ts` | تحليل سلسلة النموذج (`claude/model-name` → `{provider: "claude", model: "model-name"}`)، ودقة الاسم المستعار مع اكتشاف التصادم، وتعقيم الإدخال (يرفض أحرف اجتياز المسار/التحكم)، ودقة معلومات النموذج مع دعم getter للاسم المستعار غير المتزامن. |
|
||||
| `accountFallback.ts` | التعامل مع الحد الأقصى للمعدل: التراجع الأسي (1s → 2s → 4s → 2min كحد أقصى)، وإدارة فترة تهدئة الحساب، وتصنيف الأخطاء (أي الأخطاء تؤدي إلى التراجع مقابل عدم حدوثه). |
|
||||
| `tokenRefresh.ts` | تحديث رمز OAuth المميز **لكل مزود**: Google (Gemini، Antigravity)، Claude، Codex، Qwen، iFlow، GitHub (OAuth + Copilot Dual-Token)، Kiro (AWS SSO OIDC + Social Auth). يتضمن ذاكرة تخزين مؤقت لإلغاء البيانات المكررة أثناء الرحلة وإعادة المحاولة مع التراجع المتسارع. |
|
||||
| `combo.ts` | **نماذج مجمعة**: سلاسل من النماذج الاحتياطية. إذا فشل النموذج A مع وجود خطأ مؤهل للرجوع إليه، فجرّب النموذج B، ثم C، وما إلى ذلك. يقوم بإرجاع رموز الحالة الأولية الفعلية. |
|
||||
| `usage.ts` | جلب بيانات الحصص/الاستخدام من واجهات برمجة تطبيقات الموفر (حصص GitHub Copilot، وحصص نماذج Antigravity، وحدود معدل Codex، وأعطال استخدام Kiro، وإعدادات Claude). |
|
||||
| `accountSelector.ts` | اختيار الحساب الذكي باستخدام خوارزمية التسجيل: يأخذ في الاعتبار الأولوية والحالة الصحية والموضع الدائري وحالة التهدئة لاختيار الحساب الأمثل لكل طلب. |
|
||||
| `contextManager.ts` | إدارة دورة حياة سياق الطلب: إنشاء وتتبع كائنات السياق لكل طلب باستخدام بيانات التعريف (معرف الطلب، والطوابع الزمنية، ومعلومات الموفر) لتصحيح الأخطاء والتسجيل. |
|
||||
| `ipFilter.ts` | التحكم في الوصول المستند إلى IP: يدعم وضعي القائمة المسموح بها والقائمة المحظورة. التحقق من صحة عنوان IP للعميل مقابل القواعد التي تم تكوينها قبل معالجة طلبات واجهة برمجة التطبيقات. |
|
||||
| `sessionManager.ts` | تتبع الجلسة باستخدام بصمة العميل: يتتبع الجلسات النشطة باستخدام معرفات العميل المجزأة، ويراقب عدد الطلبات، ويوفر مقاييس الجلسة. |
|
||||
| `signatureCache.ts` | طلب ذاكرة التخزين المؤقت لإلغاء البيانات المكررة المستندة إلى التوقيع: يمنع الطلبات المكررة عن طريق تخزين توقيعات الطلب الأخيرة مؤقتًا وإرجاع الاستجابات المخزنة مؤقتًا للطلبات المتطابقة خلال نافذة زمنية. |
|
||||
| `systemPrompt.ts` | الحقن الفوري للنظام العالمي: يُلحق أو يُلحق موجه نظام قابل للتكوين لجميع الطلبات، مع معالجة التوافق لكل مزود. |
|
||||
| `thinkingBudget.ts` | إدارة ميزانية الرموز المميزة: تدعم أوضاع المرور، والتلقائي (تكوين التفكير الشريطي)، والمخصص (الميزانية الثابتة)، والتكيفية (مدرجة التعقيد) للتحكم في رموز التفكير/الاستدلال. |
|
||||
| `wildcardRouter.ts` | توجيه نمط نموذج حرف البدل: يحل أنماط حرف البدل (على سبيل المثال، `*/claude-*`) لأزواج الموفر/النموذج الملموسة بناءً على التوفر والأولوية. |
|
||||
|
||||
#### إلغاء البيانات المكررة لتحديث الرمز المميز
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant R1 as Request 1
|
||||
participant R2 as Request 2
|
||||
participant Cache as refreshPromiseCache
|
||||
participant OAuth as OAuth Provider
|
||||
|
||||
R1->>Cache: getAccessToken("gemini", token)
|
||||
Cache->>Cache: No in-flight promise
|
||||
Cache->>OAuth: Start refresh
|
||||
R2->>Cache: getAccessToken("gemini", token)
|
||||
Cache->>Cache: Found in-flight promise
|
||||
Cache-->>R2: Return existing promise
|
||||
OAuth-->>Cache: New access token
|
||||
Cache-->>R1: New access token
|
||||
Cache-->>R2: Same access token (shared)
|
||||
Cache->>Cache: Delete cache entry
|
||||
```
|
||||
|
||||
#### آلة الحالة الاحتياطية للحساب
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Active
|
||||
Active --> Error: Request fails (401/429/500)
|
||||
Error --> Cooldown: Apply backoff
|
||||
Cooldown --> Active: Cooldown expires
|
||||
Active --> Active: Request succeeds (reset backoff)
|
||||
|
||||
state Error {
|
||||
[*] --> ClassifyError
|
||||
ClassifyError --> ShouldFallback: Rate limit / Auth / Transient
|
||||
ClassifyError --> NoFallback: 400 Bad Request
|
||||
}
|
||||
|
||||
state Cooldown {
|
||||
[*] --> ExponentialBackoff
|
||||
ExponentialBackoff: Level 0 = 1s
|
||||
ExponentialBackoff: Level 1 = 2s
|
||||
ExponentialBackoff: Level 2 = 4s
|
||||
ExponentialBackoff: Max = 2min
|
||||
}
|
||||
```
|
||||
|
||||
#### سلسلة نماذج كومبو
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Request with\ncombo model"] --> B["Model A"]
|
||||
B -->|"2xx Success"| C["Return response"]
|
||||
B -->|"429/401/500"| D{"Fallback\neligible?"}
|
||||
D -->|Yes| E["Model B"]
|
||||
D -->|No| F["Return error"]
|
||||
E -->|"2xx Success"| C
|
||||
E -->|"429/401/500"| G{"Fallback\neligible?"}
|
||||
G -->|Yes| H["Model C"]
|
||||
G -->|No| F
|
||||
H -->|"2xx Success"| C
|
||||
H -->|"Fail"| I["All failed →\nReturn last status"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### مترجم 4.5 (`open-sse/translator/`)
|
||||
|
||||
**محرك ترجمة التنسيق** باستخدام نظام إضافي للتسجيل الذاتي.
|
||||
|
||||
####الهندسة المعمارية
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "Request Translation"
|
||||
A["Claude → OpenAI"]
|
||||
B["Gemini → OpenAI"]
|
||||
C["Antigravity → OpenAI"]
|
||||
D["OpenAI Responses → OpenAI"]
|
||||
E["OpenAI → Claude"]
|
||||
F["OpenAI → Gemini"]
|
||||
G["OpenAI → Kiro"]
|
||||
H["OpenAI → Cursor"]
|
||||
end
|
||||
|
||||
subgraph "Response Translation"
|
||||
I["Claude → OpenAI"]
|
||||
J["Gemini → OpenAI"]
|
||||
K["Kiro → OpenAI"]
|
||||
L["Cursor → OpenAI"]
|
||||
M["OpenAI → Claude"]
|
||||
N["OpenAI → Antigravity"]
|
||||
O["OpenAI → Responses"]
|
||||
end
|
||||
```
|
||||
|
||||
| الدليل | ملفات | الوصف |
|
||||
| ------------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `request/` | 8 مترجمين | تحويل أجسام الطلب بين الصيغ. يتم تسجيل كل ملف ذاتيًا عبر `register(from, to, fn)` عند الاستيراد. |
|
||||
| `response/` | 7 مترجمين | تحويل قطع الاستجابة المتدفقة بين الصيغ. يتعامل مع أنواع أحداث SSE وكتل التفكير واستدعاءات الأدوات. |
|
||||
| `helpers/` | 6 مساعدين | الأدوات المساعدة المشتركة: `claudeHelper` (استخراج موجه النظام، تكوين التفكير)، `geminiHelper` (تعيين الأجزاء/المحتويات)، `openaiHelper` (تصفية التنسيق)، `toolCallHelper` (إنشاء المعرف، حقن الاستجابة المفقودة)، `maxTokensHelper`، `responsesApiHelper`. |
|
||||
| `index.ts` | — | محرك الترجمة: `translateRequest()`، `translateResponse()`، إدارة الحالة، التسجيل. |
|
||||
| `formats.ts` | — | ثوابت التنسيق: `OPENAI`، `CLAUDE`، `GEMINI`، `ANTIGRAVITY`، `KIRO`، `CURSOR`، `OPENAI_RESPONSES`. |
|
||||
|
||||
#### التصميم الرئيسي: المكونات الإضافية للتسجيل الذاتي
|
||||
|
||||
```javascript
|
||||
// Each translator file calls register() on import:
|
||||
import { register } from "../index.js";
|
||||
register("claude", "openai", translateClaudeToOpenAI);
|
||||
|
||||
// The index.js imports all translator files, triggering registration:
|
||||
import "./request/claude-to-openai.js"; // ← self-registers
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.6 الأدوات المساعدة (`open-sse/utils/`)
|
||||
|
||||
| ملف | الغرض |
|
||||
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `error.ts` | إنشاء استجابة للأخطاء (تنسيق متوافق مع OpenAI)، وتحليل الأخطاء الأولية، واستخراج وقت إعادة محاولة Antigravity من رسائل الخطأ، وتدفق أخطاء SSE. |
|
||||
| `stream.ts` | **SSE Transform Stream** — خط أنابيب البث الأساسي. وضعان: `TRANSLATE` (ترجمة التنسيق الكامل) و`PASSTHROUGH` (تطبيع + استخراج الاستخدام). يتعامل مع التخزين المؤقت للقطعة وتقدير الاستخدام وتتبع طول المحتوى. تتجنب مثيلات وحدة التشفير/وحدة فك التشفير لكل تيار الحالة المشتركة. |
|
||||
| `streamHelpers.ts` | أدوات SSE ذات المستوى المنخفض: `parseSSELine` (تتحمل المسافات البيضاء)، `hasValuableContent` (تصفية الأجزاء الفارغة لـ OpenAI/Claude/Gemini)، `fixInvalidId`، `formatSSE` (تسلسل SSE مدرك للتنسيق مع تنظيف `perf_metrics`). |
|
||||
| `usageTracking.ts` | استخراج استخدام الرمز المميز من أي تنسيق (Claude/OpenAI/Gemini/Responses)، والتقدير باستخدام نسب الأحرف لكل رمز مميز للأداة/الرسالة، وإضافة المخزن المؤقت (هامش أمان 2000 رمز مميز)، وتصفية الحقول الخاصة بالتنسيق، وتسجيل وحدة التحكم بألوان ANSI. |
|
||||
| `requestLogger.ts` | تسجيل الطلب المستند إلى الملف (الاشتراك عبر `ENABLE_REQUEST_LOGS=true`). ينشئ مجلدات الجلسة بملفات مرقمة: `1_req_client.json` → `7_res_client.txt`. كل عمليات الإدخال/الإخراج غير متزامنة (أطلق النار وانسى). أقنعة الرؤوس الحساسة. |
|
||||
| `bypassHandler.ts` | يعترض أنماطًا محددة من Claude CLI (استخراج العنوان، والتحمية، والعد) ويعيد استجابات مزيفة دون الاتصال بأي مزود. يدعم كلا من الدفق وغير الدفق. يقتصر عمدا على نطاق كلود CLI. |
|
||||
| `networkProxy.ts` | يحل عنوان URL للوكيل الصادر لموفر معين مع الأسبقية: التكوين الخاص بالموفر → التكوين العام → متغيرات البيئة (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). يدعم استثناءات `NO_PROXY`. تكوين ذاكرة التخزين المؤقت لمدة 30 ثانية. |
|
||||
|
||||
#### خط أنابيب تدفق SSE
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"]
|
||||
B --> C["Buffer lines\n(split on newline)"]
|
||||
C --> D["parseSSELine()\n(trim whitespace, parse JSON)"]
|
||||
D --> E{"Mode?"}
|
||||
E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"]
|
||||
E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"]
|
||||
F --> H["hasValuableContent()\nfilter empty chunks"]
|
||||
G --> H
|
||||
H -->|"Has content"| I["extractUsage()\ntrack token counts"]
|
||||
H -->|"Empty"| J["Skip chunk"]
|
||||
I --> K["formatSSE()\nserialize + clean perf_metrics"]
|
||||
K --> L["TextEncoder\n(per-stream instance)"]
|
||||
L --> M["Enqueue to\nclient stream"]
|
||||
|
||||
style A fill:#f9f,stroke:#333
|
||||
style M fill:#9f9,stroke:#333
|
||||
```
|
||||
|
||||
#### بنية جلسة مسجل الطلب
|
||||
|
||||
```
|
||||
logs/
|
||||
└── claude_gemini_claude-sonnet_20260208_143045/
|
||||
├── 1_req_client.json ← Raw client request
|
||||
├── 2_req_source.json ← After initial conversion
|
||||
├── 3_req_openai.json ← OpenAI intermediate format
|
||||
├── 4_req_target.json ← Final target format
|
||||
├── 5_res_provider.txt ← Provider SSE chunks (streaming)
|
||||
├── 5_res_provider.json ← Provider response (non-streaming)
|
||||
├── 6_res_openai.txt ← OpenAI intermediate chunks
|
||||
├── 7_res_client.txt ← Client-facing SSE chunks
|
||||
└── 6_error.json ← Error details (if any)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.7 طبقة التطبيق (`src/`)
|
||||
|
||||
| الدليل | الغرض |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------------- |
|
||||
| `src/app/` | واجهة مستخدم الويب، مسارات واجهة برمجة التطبيقات (API)، البرامج الوسيطة السريعة، معالجات رد اتصال OAuth |
|
||||
| `src/lib/` | الوصول إلى قاعدة البيانات (`localDb.ts`، `usageDb.ts`)، المصادقة، مشتركة |
|
||||
| `src/mitm/` | أدوات مساعدة للوكيل الوسيط لاعتراض حركة مرور الموفر |
|
||||
| `src/models/` | تعريفات نماذج قواعد البيانات |
|
||||
| `src/shared/` | أغلفة حول وظائف open-sse (المزود، الدفق، الخطأ، إلخ) |
|
||||
| `src/sse/` | معالجات نقطة نهاية SSE التي تربط مكتبة open-sse بمسارات Express |
|
||||
| `src/store/` | إدارة حالة التطبيق |
|
||||
|
||||
#### مسارات API البارزة
|
||||
|
||||
| الطريق | طرق | الغرض |
|
||||
| --------------------------------------------- | ------------------ | ------------------------------------------------------------------------------ |
|
||||
| `/api/provider-models` | الحصول على/نشر/حذف | CRUD للنماذج المخصصة لكل مزود |
|
||||
| `/api/models/catalog` | احصل على | كتالوج مجمع لجميع النماذج (الدردشة، التضمين، الصورة، المخصصة) مجمعة حسب الموفر |
|
||||
| `/api/settings/proxy` | الحصول على/وضع/حذف | تكوين الوكيل الصادر الهرمي (`global/providers/combos/keys`) |
|
||||
| `/api/settings/proxy/test` | مشاركة | التحقق من صحة اتصال الوكيل وإرجاع IP/زمن الوصول العام |
|
||||
| `/v1/providers/[provider]/chat/completions` | مشاركة | عمليات إكمال الدردشة المخصصة لكل مزود مع التحقق من صحة النموذج |
|
||||
| `/v1/providers/[provider]/embeddings` | مشاركة | عمليات التضمين المخصصة لكل مزود مع التحقق من صحة النموذج |
|
||||
| `/v1/providers/[provider]/images/generations` | مشاركة | إنشاء صور مخصصة لكل مزود مع التحقق من صحة النموذج |
|
||||
| `/api/settings/ip-filter` | الحصول على/وضع | قائمة IP المسموح بها/إدارة القائمة المحظورة |
|
||||
| `/api/settings/thinking-budget` | الحصول على/وضع | تكوين ميزانية الرمز المميز (العبور/التلقائي/المخصص/التكيفي) |
|
||||
| `/api/settings/system-prompt` | الحصول على/وضع | الحقن الفوري للنظام العالمي لجميع الطلبات |
|
||||
| `/api/sessions` | احصل على | تتبع الجلسة النشطة ومقاييسها |
|
||||
| `/api/rate-limits` | احصل على | حالة حد المعدل لكل حساب |
|
||||
|
||||
---
|
||||
|
||||
## 5. أنماط التصميم الرئيسية
|
||||
|
||||
### 5.1 الترجمة المحورية والمتحدثة
|
||||
|
||||
تتم ترجمة جميع التنسيقات من خلال **تنسيق OpenAI كمحور**. لا تتطلب إضافة موفر جديد سوى كتابة **زوج واحد** من المترجمين (من/إلى OpenAI)، وليس عدد N من المترجمين.
|
||||
|
||||
### 5.2 نمط استراتيجية المنفذ
|
||||
|
||||
كل مزود لديه فئة منفذة مخصصة ترث من `BaseExecutor`. يقوم المصنع في `executors/index.ts` باختيار المصنع المناسب في وقت التشغيل.
|
||||
|
||||
### 5.3 نظام البرنامج المساعد للتسجيل الذاتي
|
||||
|
||||
تسجل وحدات المترجم نفسها عند الاستيراد عبر `register()`. إن إضافة مترجم جديد يعني مجرد إنشاء ملف واستيراده.
|
||||
|
||||
### 5.4 التراجع في الحساب مع التراجع الأسي
|
||||
|
||||
عندما يقوم مقدم الخدمة بإرجاع 429/401/500، يمكن للنظام التبديل إلى الحساب التالي، مع تطبيق فترات التباطؤ الأسية (1ث → 2ث → 4ث → 2 دقيقة كحد أقصى).
|
||||
|
||||
### 5.5 سلاسل نماذج كومبو
|
||||
|
||||
يقوم "التحرير والسرد" بتجميع سلاسل `provider/model` متعددة. إذا فشل الأول، يتم الرجوع إلى التالي تلقائيًا.
|
||||
|
||||
### 5.6 ترجمة متدفقة رائعة
|
||||
|
||||
تحافظ ترجمة الاستجابة على الحالة عبر أجزاء SSE (تتبع كتلة التفكير، وتراكم استدعاءات الأداة، وفهرسة كتلة المحتوى) عبر آلية `initState()`.
|
||||
|
||||
### 5.7 المخزن المؤقت لسلامة الاستخدام
|
||||
|
||||
تتم إضافة مخزن مؤقت مكون من 2000 رمز مميز إلى الاستخدام المبلغ عنه لمنع العملاء من الوصول إلى حدود نافذة السياق بسبب الحمل الزائد من مطالبات النظام وترجمة التنسيق.
|
||||
|
||||
---
|
||||
|
||||
## 6. التنسيقات المدعومة
|
||||
|
||||
| تنسيق | الاتجاه | المعرف |
|
||||
| ----------------------------------- | -------------- | ------------------ |
|
||||
| استكمالات الدردشة OpenAI | المصدر + الهدف | `openai` |
|
||||
| واجهة برمجة تطبيقات استجابات OpenAI | المصدر + الهدف | `openai-responses` |
|
||||
| أنثروبي كلود | المصدر + الهدف | `claude` |
|
||||
| جوجل الجوزاء | المصدر + الهدف | `gemini` |
|
||||
| جوجل الجوزاء CLI | الهدف فقط | `gemini-cli` |
|
||||
| مكافحة الجاذبية | المصدر + الهدف | `antigravity` |
|
||||
| أوس كيرو | الهدف فقط | `kiro` |
|
||||
| المؤشر | الهدف فقط | `cursor` |
|
||||
|
||||
---
|
||||
|
||||
## 7. مقدمو الخدمة المدعومين
|
||||
|
||||
| مقدم | طريقة المصادقة | المنفذ | الملاحظات الرئيسية |
|
||||
| ------------------------- | ------------------------ | --------------- | --------------------------------------------------------- |
|
||||
| أنثروبي كلود | مفتاح API أو OAuth | الافتراضي | يستخدم رأس `x-api-key` |
|
||||
| جوجل الجوزاء | مفتاح API أو OAuth | الافتراضي | يستخدم رأس `x-goog-api-key` |
|
||||
| جوجل الجوزاء CLI | أووث | الجوزاء كلي | يستخدم `streamGenerateContent` نقطة النهاية |
|
||||
| مكافحة الجاذبية | أووث | مكافحة الجاذبية | احتياطي عناوين URL المتعددة، إعادة محاولة التحليل المخصصة |
|
||||
| أوبن آي | مفتاح API | الافتراضي | مصادقة حامل المعيار |
|
||||
| الدستور الغذائي | أووث | الدستور الغذائي | يدخل تعليمات النظام ويدير التفكير |
|
||||
| جيثب مساعد الطيار | OAuth + رمز مساعد الطيار | جيثب | رمز مزدوج، محاكاة رأس VSCode |
|
||||
| كيرو (AWS) | AWS SSO OIDC أو Social | كيرو | تحليل دفق الأحداث الثنائية |
|
||||
| بيئة تطوير متكاملة للمؤشر | مصادقة المجموع الاختباري | المؤشر | ترميز Protobuf، المجموع الاختباري SHA-256 |
|
||||
| كوين | أووث | الافتراضي | المصادقة القياسية |
|
||||
| اي فلو | OAuth (أساسي + حامل) | الافتراضي | رأس المصادقة المزدوجة |
|
||||
| اوبن راوتر | مفتاح API | الافتراضي | مصادقة حامل المعيار |
|
||||
| جي إل إم، كيمي، ميني ماكس | مفتاح API | الافتراضي | متوافق مع كلود، استخدم `x-api-key` |
|
||||
| `openai-compatible-*` | مفتاح API | الافتراضي | ديناميكي: أي نقطة نهاية متوافقة مع OpenAI |
|
||||
| `anthropic-compatible-*` | مفتاح API | الافتراضي | ديناميكي: أي نقطة نهاية متوافقة مع كلود |
|
||||
|
||||
---
|
||||
|
||||
## 8. ملخص تدفق البيانات
|
||||
|
||||
### طلب البث
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Client"] --> B["detectFormat()"]
|
||||
B --> C["translateRequest()\nsource → OpenAI → target"]
|
||||
C --> D["Executor\nbuildUrl + buildHeaders"]
|
||||
D --> E["fetch(providerURL)"]
|
||||
E --> F["createSSEStream()\nTRANSLATE mode"]
|
||||
F --> G["parseSSELine()"]
|
||||
G --> H["translateResponse()\ntarget → OpenAI → source"]
|
||||
H --> I["extractUsage()\n+ addBuffer"]
|
||||
I --> J["formatSSE()"]
|
||||
J --> K["Client receives\ntranslated SSE"]
|
||||
K --> L["logUsage()\nsaveRequestUsage()"]
|
||||
```
|
||||
|
||||
### طلب عدم البث
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Client"] --> B["detectFormat()"]
|
||||
B --> C["translateRequest()\nsource → OpenAI → target"]
|
||||
C --> D["Executor.execute()"]
|
||||
D --> E["translateResponse()\ntarget → OpenAI → source"]
|
||||
E --> F["Return JSON\nresponse"]
|
||||
```
|
||||
|
||||
### تجاوز التدفق (كلود CLI)
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Claude CLI request"] --> B{"Match bypass\npattern?"}
|
||||
B -->|"Title/Warmup/Count"| C["Generate fake\nOpenAI response"]
|
||||
B -->|"No match"| D["Normal flow"]
|
||||
C --> E["Translate to\nsource format"]
|
||||
E --> F["Return without\ncalling provider"]
|
||||
```
|
||||
@@ -0,0 +1,77 @@
|
||||
# OmniRoute — معرض ميزات لوحة المعلومات
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../FEATURES.md) | 🇧🇷 [Português (Brasil)](../pt-BR/FEATURES.md) | 🇪🇸 [Español](../es/FEATURES.md) | 🇫🇷 [Français](../fr/FEATURES.md) | 🇮🇹 [Italiano](../it/FEATURES.md) | 🇷🇺 [Русский](../ru/FEATURES.md) | 🇨🇳 [中文 (简体)](../zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](../de/FEATURES.md) | 🇮🇳 [हिन्दी](../in/FEATURES.md) | 🇹🇭 [ไทย](../th/FEATURES.md) | 🇺🇦 [Українська](../uk-UA/FEATURES.md) | 🇸🇦 [العربية](../ar/FEATURES.md) | 🇯🇵 [日本語](../ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](../vi/FEATURES.md) | 🇧🇬 [Български](../bg/FEATURES.md) | 🇩🇰 [Dansk](../da/FEATURES.md) | 🇫🇮 [Suomi](../fi/FEATURES.md) | 🇮🇱 [עברית](../he/FEATURES.md) | 🇭🇺 [Magyar](../hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](../id/FEATURES.md) | 🇰🇷 [한국어](../ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](../ms/FEATURES.md) | 🇳🇱 [Nederlands](../nl/FEATURES.md) | 🇳🇴 [Norsk](../no/FEATURES.md) | 🇵🇹 [Português (Portugal)](../pt/FEATURES.md) | 🇷🇴 [Română](../ro/FEATURES.md) | 🇵🇱 [Polski](../pl/FEATURES.md) | 🇸🇰 [Slovenčina](../sk/FEATURES.md) | 🇸🇪 [Svenska](../sv/FEATURES.md) | 🇵🇭 [Filipino](../phi/FEATURES.md)
|
||||
|
||||
دليل مرئي لكل قسم من لوحة معلومات OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## 🔌 مقدمو الخدمة
|
||||
|
||||
إدارة اتصالات مزودي الذكاء الاصطناعي: موفري OAuth (Claude Code وCodex وGemini CLI) وموفري مفاتيح API (Groq وDeepSeek وOpenRouter) ومقدمي الخدمات المجانية (iFlow وQwen وKiro).
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🎨 المجموعات
|
||||
|
||||
أنشئ مجموعات توجيه النماذج باستخدام 6 إستراتيجيات: التعبئة أولاً، والتدوير الدائري، وقوة الاختيارين، والعشوائية، والأقل استخدامًا، والمُحسَّنة من حيث التكلفة. تقوم كل مجموعة بتسلسل نماذج متعددة مع الرجوع التلقائي.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 📊تحليلات
|
||||
|
||||
تحليلات استخدام شاملة مع استهلاك الرمز المميز، وتقديرات التكلفة، وخرائط النشاط، ومخططات التوزيع الأسبوعية، والتفاصيل لكل مزود.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🏥 صحة النظام
|
||||
|
||||
المراقبة في الوقت الفعلي: وقت التشغيل، والذاكرة، والإصدار، والنسب المئوية لزمن الوصول (p50/p95/p99)، وإحصائيات ذاكرة التخزين المؤقت، وحالات قاطع دائرة الموفر.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🔧 ملعب المترجم
|
||||
|
||||
أربعة أوضاع لتصحيح أخطاء ترجمات واجهة برمجة التطبيقات: **ساحة اللعب** (محول التنسيق)، **اختبار الدردشة** (الطلبات المباشرة)، **منصة الاختبار** (اختبارات الدفعة)، و **المراقب المباشر** (البث في الوقت الفعلي).
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## ⚙️ الإعدادات
|
||||
|
||||
الإعدادات العامة، وتخزين النظام، وإدارة النسخ الاحتياطي (قاعدة بيانات التصدير/الاستيراد)، والمظهر (الوضع الداكن/الفاتح)، والأمان (يتضمن حماية نقطة نهاية واجهة برمجة التطبيقات وحظر الموفر المخصص)، والتوجيه، والمرونة، والتكوين المتقدم.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🔧 أدوات CLI
|
||||
|
||||
تكوين بنقرة واحدة لأدوات ترميز الذكاء الاصطناعي: Claude Code، وCodex CLI، وGemini CLI، وOpenClaw، وKilo Code، وAntigravity.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 📝 سجلات الطلب
|
||||
|
||||
تسجيل الطلبات في الوقت الفعلي مع التصفية حسب الموفر والطراز والحساب ومفتاح واجهة برمجة التطبيقات. يعرض رموز الحالة واستخدام الرمز المميز ووقت الاستجابة وتفاصيل الاستجابة.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🌐 نقطة نهاية API
|
||||
|
||||
نقطة نهاية واجهة برمجة التطبيقات الموحدة الخاصة بك مع تفاصيل الإمكانات: عمليات إكمال الدردشة والتضمين وإنشاء الصور وإعادة الترتيب والنسخ الصوتي ومفاتيح واجهة برمجة التطبيقات المسجلة.
|
||||
|
||||

|
||||
@@ -0,0 +1,219 @@
|
||||
# استكشاف الأخطاء وإصلاحها
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](../es/TROUBLESHOOTING.md) | 🇫🇷 [Français](../fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](../bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](../ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../phi/TROUBLESHOOTING.md)
|
||||
|
||||
المشاكل والحلول الشائعة لـ OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## إصلاحات سريعة
|
||||
|
||||
| مشكلة | الحل |
|
||||
| --------------------------------- | ----------------------------------------------------------------- |
|
||||
| تسجيل الدخول الأول لا يعمل | تحقق من `INITIAL_PASSWORD` في `.env` (الافتراضي: `123456`) |
|
||||
| تفتح لوحة المعلومات على منفذ خاطئ | اضبط `PORT=20128` و`NEXT_PUBLIC_BASE_URL=http://localhost:20128` |
|
||||
| لا توجد سجلات للطلب ضمن `logs/` | تعيين `ENABLE_REQUEST_LOGS=true` |
|
||||
| EACCES: تم رفض الإذن | اضبط `DATA_DIR=/path/to/writable/dir` لتجاوز `~/.omniroute` |
|
||||
| استراتيجية التوجيه لا تنقذ | التحديث إلى الإصدار 1.4.11+ (إصلاح مخطط Zod لاستمرارية الإعدادات) |
|
||||
|
||||
---
|
||||
|
||||
## مشكلات المزود
|
||||
|
||||
### "نموذج اللغة لم يقدم رسائل"
|
||||
|
||||
**السبب:** استنفدت حصة الموفر.
|
||||
|
||||
**الإصلاح:**
|
||||
|
||||
1. تحقق من تعقب الحصص في لوحة القيادة
|
||||
2. استخدم مجموعة من المستويات الاحتياطية
|
||||
3. قم بالتبديل إلى الطبقة الأرخص/المجانية
|
||||
|
||||
### تحديد المعدل
|
||||
|
||||
**السبب:** استنفدت حصة الاشتراك.
|
||||
|
||||
**الإصلاح:**
|
||||
|
||||
- إضافة احتياطي: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
|
||||
- استخدم GLM/MiniMax كنسخة احتياطية رخيصة الثمن
|
||||
|
||||
### انتهت صلاحية رمز OAuth
|
||||
|
||||
يقوم OmniRoute بتحديث الرموز المميزة تلقائيًا. إذا استمرت المشكلات:
|
||||
|
||||
1. لوحة المعلومات → الموفر → إعادة الاتصال
|
||||
2. قم بحذف وإعادة إضافة اتصال الموفر
|
||||
|
||||
---
|
||||
|
||||
## مشكلات السحابة
|
||||
|
||||
### أخطاء المزامنة السحابية
|
||||
|
||||
1. تحقق من نقاط `BASE_URL` لمثيلك قيد التشغيل (على سبيل المثال، `http://localhost:20128`)
|
||||
2. تحقق من نقاط `CLOUD_URL` إلى نقطة نهاية السحابة الخاصة بك (على سبيل المثال، `https://omniroute.dev`)
|
||||
3. حافظ على محاذاة قيم `NEXT_PUBLIC_*` مع القيم من جانب الخادم
|
||||
|
||||
### السحابة `stream=false` تُرجع 500
|
||||
|
||||
**العَرَض:** `Unexpected token 'd'...` على نقطة نهاية السحابة للمكالمات غير المتدفقة.
|
||||
|
||||
**السبب:** يقوم المنبع بإرجاع حمولة SSE بينما يتوقع العميل JSON.
|
||||
|
||||
**الحل البديل:** استخدم `stream=true` للمكالمات السحابية المباشرة. يتضمن وقت التشغيل المحلي SSE → JSON الاحتياطي.
|
||||
|
||||
### تقول السحابة إنها متصلة ولكن "مفتاح واجهة برمجة التطبيقات غير صالح"
|
||||
|
||||
1. قم بإنشاء مفتاح جديد من لوحة المعلومات المحلية (`/api/keys`)
|
||||
2. قم بتشغيل المزامنة السحابية: قم بتمكين السحابة → المزامنة الآن
|
||||
3. لا يزال بإمكان المفاتيح القديمة/غير المتزامنة إرجاع `401` على السحابة
|
||||
|
||||
---
|
||||
|
||||
## مشكلات عامل الميناء
|
||||
|
||||
### تظهر أداة CLI غير مثبتة
|
||||
|
||||
1. تحقق من حقول وقت التشغيل: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq`
|
||||
2. بالنسبة للوضع المحمول: استخدم هدف الصورة `runner-cli` (CLIs المجمعة)
|
||||
3. بالنسبة لوضع تثبيت المضيف: قم بتعيين `CLI_EXTRA_PATHS` وتثبيت دليل حاوية المضيف للقراءة فقط
|
||||
4. إذا تم العثور على `installed=true` و`runnable=false`: ثنائي ولكن فشل التحقق من الصحة
|
||||
|
||||
### التحقق السريع من وقت التشغيل
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## قضايا التكلفة
|
||||
|
||||
### ارتفاع التكاليف
|
||||
|
||||
1. تحقق من إحصائيات الاستخدام في لوحة المعلومات → الاستخدام
|
||||
2. قم بتبديل النموذج الأساسي إلى GLM/MiniMax
|
||||
3. استخدم الطبقة المجانية (Gemini CLI، iFlow) للمهام غير الحرجة
|
||||
4. قم بتعيين ميزانيات التكلفة لكل مفتاح واجهة برمجة التطبيقات: لوحة المعلومات ← مفاتيح واجهة برمجة التطبيقات ← الميزانية
|
||||
|
||||
---
|
||||
|
||||
## التصحيح
|
||||
|
||||
### تمكين سجلات الطلبات
|
||||
|
||||
قم بتعيين `ENABLE_REQUEST_LOGS=true` في ملف `.env` الخاص بك. تظهر السجلات ضمن الدليل `logs/`.
|
||||
|
||||
### التحقق من صحة مقدم الخدمة
|
||||
|
||||
```bash
|
||||
# Health dashboard
|
||||
http://localhost:20128/dashboard/health
|
||||
|
||||
# API health check
|
||||
curl http://localhost:20128/api/monitoring/health
|
||||
```
|
||||
|
||||
### تخزين وقت التشغيل
|
||||
|
||||
- الحالة الرئيسية: `${DATA_DIR}/db.json` (المزودون، المجموعات، الأسماء المستعارة، المفاتيح، الإعدادات)
|
||||
- الاستخدام: `${DATA_DIR}/usage.json`، `${DATA_DIR}/log.txt`، `${DATA_DIR}/call_logs/`
|
||||
- سجلات الطلب: `<repo>/logs/...` (عندما `ENABLE_REQUEST_LOGS=true`)
|
||||
|
||||
---
|
||||
|
||||
## مشكلات قواطع الدائرة
|
||||
|
||||
### الموفر عالق في الحالة المفتوحة
|
||||
|
||||
عندما يكون قاطع دائرة الموفر مفتوحًا، يتم حظر الطلبات حتى تنتهي فترة التهدئة.
|
||||
|
||||
**الإصلاح:**
|
||||
|
||||
1. انتقل إلى **لوحة التحكم ← الإعدادات ← المرونة**
|
||||
2. تحقق من بطاقة قاطع الدائرة الكهربائية الخاصة بالمزود المتأثر
|
||||
3. انقر فوق **إعادة تعيين الكل** لمسح جميع القواطع، أو انتظر حتى تنتهي فترة التهدئة
|
||||
4. تحقق من أن الموفر متاح فعليًا قبل إعادة التعيين
|
||||
|
||||
### يستمر المزود في تعطيل قاطع الدائرة
|
||||
|
||||
إذا دخل مقدم الخدمة بشكل متكرر في الحالة المفتوحة:
|
||||
|
||||
1. تحقق من **Dashboard → Health → Provider Health** لمعرفة نمط الفشل
|
||||
2. انتقل إلى **الإعدادات → المرونة → ملفات تعريف الموفر** وقم بزيادة حد الفشل
|
||||
3. تحقق مما إذا كان الموفر قد قام بتغيير حدود واجهة برمجة التطبيقات (API) أو طلب إعادة المصادقة
|
||||
4. قم بمراجعة القياس عن بعد لزمن الاستجابة - قد يتسبب زمن الاستجابة العالي في حدوث أعطال بسبب انتهاء المهلة
|
||||
|
||||
---
|
||||
|
||||
## مشكلات النسخ الصوتي
|
||||
|
||||
### خطأ "نموذج غير مدعوم".
|
||||
|
||||
- تأكد من أنك تستخدم البادئة الصحيحة: `deepgram/nova-3` أو `assemblyai/best`
|
||||
- تحقق من أن الموفر متصل في **لوحة التحكم ← الموفرون**
|
||||
|
||||
### يعود النسخ فارغًا أو يفشل
|
||||
|
||||
- تحقق من تنسيقات الصوت المدعومة: `mp3`، `wav`، `m4a`، `flac`، `ogg`، `webm`
|
||||
- التحقق من أن حجم الملف يقع ضمن حدود الموفر (عادةً أقل من 25 ميجابايت)
|
||||
- التحقق من صلاحية مفتاح API الخاص بالموفر في بطاقة المزود
|
||||
|
||||
---
|
||||
|
||||
## تصحيح أخطاء المترجم
|
||||
|
||||
استخدم **لوحة المعلومات → المترجم** لتصحيح مشكلات ترجمة التنسيق:
|
||||
|
||||
| الوضع | متى تستخدم |
|
||||
| -------------------- | ---------------------------------------------------------------------------------- |
|
||||
| **ساحة اللعب** | قارن تنسيقات الإدخال/الإخراج جنبًا إلى جنب — الصق طلبًا فاشلاً لترى كيف تتم ترجمته |
|
||||
| ** اختبار الدردشة ** | أرسل رسائل مباشرة وافحص حمولة الطلب/الاستجابة الكاملة بما في ذلك الرؤوس |
|
||||
| ** مقعد الاختبار ** | قم بإجراء اختبارات مجمعة عبر مجموعات التنسيق للعثور على الترجمات المعطلة |
|
||||
| **مراقبة حية** | شاهد تدفق الطلبات في الوقت الفعلي للتعرف على مشكلات الترجمة المتقطعة |
|
||||
|
||||
### مشكلات التنسيق الشائعة
|
||||
|
||||
- **لا تظهر علامات التفكير** — تحقق مما إذا كان الموفر المستهدف يدعم التفكير وإعداد ميزانية التفكير
|
||||
- **استدعاءات الأداة** — قد تؤدي بعض ترجمات التنسيق إلى إزالة الحقول غير المدعومة؛ تحقق في وضع الملعب
|
||||
- **مطالبة النظام مفقودة** — يتعامل نظام Claude وGemini مع المطالبات بشكل مختلف؛ التحقق من إخراج الترجمة
|
||||
- ** تقوم SDK بإرجاع سلسلة أولية بدلاً من الكائن ** - تم الإصلاح في الإصدار 1.1.0: تقوم أداة معالجة الاستجابة الآن بإزالة الحقول غير القياسية (`x_groq`، `usage_breakdown`، وما إلى ذلك) التي تتسبب في فشل التحقق من صحة OpenAI SDK Pydantic
|
||||
- **GLM/ERNIE يرفض دور `system`** — تم إصلاحه في الإصدار 1.1.0: يقوم مُطبيع الدور تلقائيًا بدمج رسائل النظام في رسائل المستخدم للنماذج غير المتوافقة
|
||||
- **`developer` لم يتم التعرف على الدور** — تم إصلاحه في الإصدار 1.1.0: تم تحويله تلقائيًا إلى `system` لمقدمي الخدمات غير التابعين لـ OpenAI
|
||||
- **`json_schema` لا يعمل مع Gemini** — تم إصلاحه في الإصدار 1.1.0: `response_format` تم تحويله الآن إلى `responseMimeType` + `responseSchema` الخاص بـ Gemini\_\_
|
||||
|
||||
---
|
||||
|
||||
## إعدادات المرونة
|
||||
|
||||
### لا يتم تشغيل حد المعدل التلقائي
|
||||
|
||||
- ينطبق حد المعدل التلقائي فقط على موفري مفاتيح واجهة برمجة التطبيقات (وليس OAuth/الاشتراك)
|
||||
- تحقق من أن **الإعدادات → المرونة → ملفات تعريف الموفر** تم تمكين حد المعدل التلقائي
|
||||
- تحقق مما إذا كان الموفر يعرض `429` رموز الحالة أو رؤوس `Retry-After`
|
||||
|
||||
### ضبط التراجع الأسي
|
||||
|
||||
تدعم ملفات تعريف الموفر هذه الإعدادات:
|
||||
|
||||
- **التأخير الأساسي** — وقت الانتظار الأولي بعد الفشل الأول (الافتراضي: 1 ثانية)
|
||||
- **الحد الأقصى للتأخير** — الحد الأقصى لوقت الانتظار (الافتراضي: 30 ثانية)
|
||||
- **المضاعف** — مقدار زيادة التأخير لكل فشل متتالي (الافتراضي: 2x)
|
||||
|
||||
### قطيع مضاد للرعد
|
||||
|
||||
عندما تصل العديد من الطلبات المتزامنة إلى موفر محدود السعر، يستخدم OmniRoute تحديد المعدل التلقائي + mutex لإجراء تسلسل للطلبات ومنع حالات الفشل المتتالية. وهذا تلقائي لموفري مفاتيح API.
|
||||
|
||||
---
|
||||
|
||||
## هل مازلت عالقًا؟
|
||||
|
||||
- **مشكلات GitHub**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **الهندسة المعمارية**: راجع [link](ARCHITECTURE.md) للحصول على التفاصيل الداخلية
|
||||
- **مرجع واجهة برمجة التطبيقات**: راجع [link](API_REFERENCE.md) لجميع نقاط النهاية
|
||||
- **لوحة معلومات الصحة**: تحقق من **لوحة المعلومات ← الصحة** لمعرفة حالة النظام في الوقت الفعلي
|
||||
- **المترجم**: استخدم **لوحة المعلومات ← المترجم** لتصحيح مشكلات التنسيق
|
||||
@@ -0,0 +1,698 @@
|
||||
# دليل المستخدم
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](../es/USER_GUIDE.md) | 🇫🇷 [Français](../fr/USER_GUIDE.md) | 🇮🇹 [Italiano](../it/USER_GUIDE.md) | 🇷🇺 [Русский](../ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](../de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](../in/USER_GUIDE.md) | 🇹🇭 [ไทย](../th/USER_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](../ar/USER_GUIDE.md) | 🇯🇵 [日本語](../ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/USER_GUIDE.md) | 🇧🇬 [Български](../bg/USER_GUIDE.md) | 🇩🇰 [Dansk](../da/USER_GUIDE.md) | 🇫🇮 [Suomi](../fi/USER_GUIDE.md) | 🇮🇱 [עברית](../he/USER_GUIDE.md) | 🇭🇺 [Magyar](../hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/USER_GUIDE.md) | 🇰🇷 [한국어](../ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](../nl/USER_GUIDE.md) | 🇳🇴 [Norsk](../no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/USER_GUIDE.md) | 🇷🇴 [Română](../ro/USER_GUIDE.md) | 🇵🇱 [Polski](../pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/USER_GUIDE.md) | 🇸🇪 [Svenska](../sv/USER_GUIDE.md) | 🇵🇭 [Filipino](../phi/USER_GUIDE.md)
|
||||
|
||||
الدليل الكامل لتكوين مقدمي الخدمات، وإنشاء المجموعات، ودمج أدوات CLI، ونشر OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## جدول المحتويات
|
||||
|
||||
- [Pricing at a Glance](#-pricing-at-a-glance)
|
||||
- [Use Cases](#-use-cases)
|
||||
- [Provider Setup](#-provider-setup)
|
||||
- [CLI Integration](#-cli-integration)
|
||||
- [Deployment](#-deployment)
|
||||
- [Available Models](#-available-models)
|
||||
- [Advanced Features](#-advanced-features)
|
||||
|
||||
---
|
||||
|
||||
## 💰 لمحة سريعة عن الأسعار
|
||||
|
||||
| الطبقة | مقدم | التكلفة | إعادة ضبط الحصص | الأفضل لـ |
|
||||
| ---------------------------------- | ----------------------------------- | ---------------------- | ----------------------- | -------------------------------------- |
|
||||
| **💳الإشتراك** | كلود كود (برو) | 20 دولارًا شهريًا | 5 ساعات + أسبوعي | اشتركت بالفعل |
|
||||
| | الدستور الغذائي (زائد / برو) | 20-200 دولار شهريًا | 5 ساعات + أسبوعي | مستخدمي OpenAI |
|
||||
| | الجوزاء CLI | **مجاني** | 180 ألف/شهر + 1 ألف/يوم | الجميع! |
|
||||
| | جيثب مساعد الطيار | 10-19 دولارًا شهريًا | شهري | مستخدمي جيثب |
|
||||
| **🔑 مفتاح واجهة برمجة التطبيقات** | ديب سيك | الدفع لكل استخدام | لا شيء | الاستدلال الرخيص |
|
||||
| | جروك | الدفع لكل استخدام | لا شيء | الاستدلال فائق السرعة |
|
||||
| | xAI (جروك) | الدفع لكل استخدام | لا شيء | جروك 4 المنطق |
|
||||
| | ميسترال | الدفع لكل استخدام | لا شيء | النماذج التي يستضيفها الاتحاد الأوروبي |
|
||||
| | الحيرة | الدفع لكل استخدام | لا شيء | البحث المعزز |
|
||||
| | معا منظمة العفو الدولية | الدفع لكل استخدام | لا شيء | نماذج مفتوحة المصدر |
|
||||
| | الألعاب النارية منظمة العفو الدولية | الدفع لكل استخدام | لا شيء | صور التدفق السريع |
|
||||
| | المخيخ | الدفع لكل استخدام | لا شيء | سرعة على نطاق الرقاقة |
|
||||
| | كوهير | الدفع لكل استخدام | لا شيء | الأمر R+ RAG |
|
||||
| | نفيديا نيم | الدفع لكل استخدام | لا شيء | نماذج المؤسسات |
|
||||
| **💰 رخيص** | جي إل إم-4.7 | 0.6 دولار/1 مليون | يوميا 10 صباحا | نسخة احتياطية للميزانية |
|
||||
| | ميني ماكس M2.1 | 0.2 دولار/1 مليون | المتداول لمدة 5 ساعات | الخيار الأرخص |
|
||||
| | كيمي ك2 | 9 دولارات شهريًا مسطحة | 10 مليون رمز/شهر | التكلفة المتوقعة |
|
||||
| **🆓مجانًا** | اي فلو | $0 | غير محدود | 8 نماذج مجانية |
|
||||
| | كوين | $0 | غير محدود | 3 نماذج مجانية |
|
||||
| | كيرو | $0 | غير محدود | كلود مجاني |
|
||||
|
||||
**💡 نصيحة احترافية:** ابدأ مع مجموعة Gemini CLI (180 ألفًا مجانًا شهريًا) + مجموعة iFlow (مجانية غير محدودة) = تكلفة 0 دولار!
|
||||
|
||||
---
|
||||
|
||||
## 🎯 حالات الاستخدام
|
||||
|
||||
### الحالة 1: "لدي اشتراك Claude Pro"
|
||||
|
||||
**المشكلة:** تنتهي صلاحية الحصة غير المستخدمة، وحدود المعدل أثناء عملية الترميز المكثف
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (use subscription fully)
|
||||
2. glm/glm-4.7 (cheap backup when quota out)
|
||||
3. if/kimi-k2-thinking (free emergency fallback)
|
||||
|
||||
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
|
||||
vs. $20 + hitting limits = frustration
|
||||
```
|
||||
|
||||
### الحالة 2: "أريد تكلفة صفرية"
|
||||
|
||||
**المشكلة:** لا أستطيع تحمل تكلفة الاشتراكات، وتحتاج إلى ترميز يعتمد على الذكاء الاصطناعي
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K free/month)
|
||||
2. if/kimi-k2-thinking (unlimited free)
|
||||
3. qw/qwen3-coder-plus (unlimited free)
|
||||
|
||||
Monthly cost: $0
|
||||
Quality: Production-ready models
|
||||
```
|
||||
|
||||
### الحالة 3: "أحتاج إلى تشفير على مدار 24 ساعة طوال أيام الأسبوع، دون انقطاع"
|
||||
|
||||
**المشكلة:** المواعيد النهائية، لا أستطيع تحمل فترات التوقف عن العمل
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (best quality)
|
||||
2. cx/gpt-5.2-codex (second subscription)
|
||||
3. glm/glm-4.7 (cheap, resets daily)
|
||||
4. minimax/MiniMax-M2.1 (cheapest, 5h reset)
|
||||
5. if/kimi-k2-thinking (free unlimited)
|
||||
|
||||
Result: 5 layers of fallback = zero downtime
|
||||
Monthly cost: $20-200 (subscriptions) + $10-20 (backup)
|
||||
```
|
||||
|
||||
### الحالة 4: "أريد ذكاءً اصطناعيًا مجانيًا في OpenClaw"
|
||||
|
||||
**المشكلة:** تحتاج إلى مساعد الذكاء الاصطناعي في تطبيقات المراسلة، مجانًا تمامًا
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (unlimited free)
|
||||
2. if/minimax-m2.1 (unlimited free)
|
||||
3. if/kimi-k2-thinking (unlimited free)
|
||||
|
||||
Monthly cost: $0
|
||||
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 إعداد الموفر
|
||||
|
||||
### 🔐 مقدمي الاشتراكات
|
||||
|
||||
#### كلود كود (برو/ماكس)
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect Claude Code
|
||||
→ OAuth login → Auto token refresh
|
||||
→ 5-hour + weekly quota tracking
|
||||
|
||||
Models:
|
||||
cc/claude-opus-4-6
|
||||
cc/claude-sonnet-4-5-20250929
|
||||
cc/claude-haiku-4-5-20251001
|
||||
```
|
||||
|
||||
**نصيحة احترافية:** استخدم Opus للمهام المعقدة، وSonnet للسرعة. OmniRoute يتتبع الحصة لكل نموذج!
|
||||
|
||||
#### OpenAI Codex (Plus/Pro)
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect Codex
|
||||
→ OAuth login (port 1455)
|
||||
→ 5-hour + weekly reset
|
||||
|
||||
Models:
|
||||
cx/gpt-5.2-codex
|
||||
cx/gpt-5.1-codex-max
|
||||
```
|
||||
|
||||
#### Gemini CLI (180 ألفًا شهريًا مجانًا!)
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect Gemini CLI
|
||||
→ Google OAuth
|
||||
→ 180K completions/month + 1K/day
|
||||
|
||||
Models:
|
||||
gc/gemini-3-flash-preview
|
||||
gc/gemini-2.5-pro
|
||||
```
|
||||
|
||||
**أفضل قيمة:** طبقة مجانية ضخمة! استخدم هذا قبل المستويات المدفوعة.
|
||||
|
||||
#### مساعد جيثب
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect GitHub
|
||||
→ OAuth via GitHub
|
||||
→ Monthly reset (1st of month)
|
||||
|
||||
Models:
|
||||
gh/gpt-5
|
||||
gh/claude-4.5-sonnet
|
||||
gh/gemini-3-pro
|
||||
```
|
||||
|
||||
### 💰 مقدمو خدمات رخيصون
|
||||
|
||||
#### GLM-4.7 (إعادة التعيين اليومي، 0.6 دولار/1 مليون)
|
||||
|
||||
1. قم بالتسجيل: [Zhipu AI](https://open.bigmodel.cn/)
|
||||
2. احصل على مفتاح API من خطة الترميز
|
||||
3. لوحة المعلومات → إضافة مفتاح واجهة برمجة التطبيقات: الموفر: `glm`، مفتاح واجهة برمجة التطبيقات: `your-key`
|
||||
|
||||
**الاستخدام:** `glm/glm-4.7` — **نصيحة احترافية:** توفر خطة البرمجة حصة 3× بتكلفة 1/7! إعادة الضبط يوميًا الساعة 10:00 صباحًا.
|
||||
|
||||
#### MiniMax M2.1 (إعادة الضبط لمدة 5 ساعات، 0.20 دولار/1 مليون)
|
||||
|
||||
1. قم بالتسجيل: [MiniMax](https://www.minimax.io/)
|
||||
2. احصل على مفتاح API → لوحة المعلومات → إضافة مفتاح API
|
||||
|
||||
**الاستخدام:** `minimax/MiniMax-M2.1` — **نصيحة احترافية:** الخيار الأرخص للسياق الطويل (مليون رمز)!
|
||||
|
||||
#### كيمي K2 (شقة بقيمة 9 دولارات في الشهر)
|
||||
|
||||
1. الاشتراك: [Moonshot AI](https://platform.moonshot.ai/)
|
||||
2. احصل على مفتاح API → لوحة المعلومات → إضافة مفتاح API
|
||||
|
||||
**الاستخدام:** `kimi/kimi-latest` — **نصيحة احترافية:** سعر ثابت قدره 9 دولارات شهريًا مقابل 10 ملايين رمز مميز = 0.90 دولارًا أمريكيًا/التكلفة الفعلية لمليون واحد!
|
||||
|
||||
### 🆓 مقدمي الخدمة مجانًا
|
||||
|
||||
#### iFlow (8 نماذج مجانية)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect iFlow → OAuth login → Unlimited usage
|
||||
|
||||
Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1
|
||||
```
|
||||
|
||||
#### كوين (3 موديلات مجانية)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect Qwen → Device code auth → Unlimited usage
|
||||
|
||||
Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash
|
||||
```
|
||||
|
||||
#### كيرو (كلود فري)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited
|
||||
|
||||
Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 المجموعات
|
||||
|
||||
### مثال 1: زيادة الاشتراك إلى الحد الأقصى → النسخ الاحتياطي الرخيص
|
||||
|
||||
```
|
||||
Dashboard → Combos → Create New
|
||||
|
||||
Name: premium-coding
|
||||
Models:
|
||||
1. cc/claude-opus-4-6 (Subscription primary)
|
||||
2. glm/glm-4.7 (Cheap backup, $0.6/1M)
|
||||
3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M)
|
||||
|
||||
Use in CLI: premium-coding
|
||||
```
|
||||
|
||||
### المثال 2: مجاني فقط (بدون تكلفة)
|
||||
|
||||
```
|
||||
Name: free-combo
|
||||
Models:
|
||||
1. gc/gemini-3-flash-preview (180K free/month)
|
||||
2. if/kimi-k2-thinking (unlimited)
|
||||
3. qw/qwen3-coder-plus (unlimited)
|
||||
|
||||
Cost: $0 forever!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 تكامل CLI
|
||||
|
||||
### بيئة تطوير متكاملة للمؤشر
|
||||
|
||||
```
|
||||
Settings → Models → Advanced:
|
||||
OpenAI API Base URL: http://localhost:20128/v1
|
||||
OpenAI API Key: [from omniroute dashboard]
|
||||
Model: cc/claude-opus-4-6
|
||||
```
|
||||
|
||||
### كلود كود
|
||||
|
||||
تحرير `~/.claude/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"anthropic_api_base": "http://localhost:20128/v1",
|
||||
"anthropic_api_key": "your-omniroute-api-key"
|
||||
}
|
||||
```
|
||||
|
||||
### كوديكس سطر الأوامر
|
||||
|
||||
```bash
|
||||
export OPENAI_BASE_URL="http://localhost:20128"
|
||||
export OPENAI_API_KEY="your-omniroute-api-key"
|
||||
codex "your prompt"
|
||||
```
|
||||
|
||||
### OpenClaw
|
||||
|
||||
تحرير `~/.openclaw/openclaw.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": { "primary": "omniroute/if/glm-4.7" }
|
||||
}
|
||||
},
|
||||
"models": {
|
||||
"providers": {
|
||||
"omniroute": {
|
||||
"baseUrl": "http://localhost:20128/v1",
|
||||
"apiKey": "your-omniroute-api-key",
|
||||
"api": "openai-completions",
|
||||
"models": [{ "id": "if/glm-4.7", "name": "glm-4.7" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**أو استخدم لوحة المعلومات:** أدوات CLI → OpenClaw → التكوين التلقائي
|
||||
|
||||
### كلاين / متابعة / RooCode
|
||||
|
||||
```
|
||||
Provider: OpenAI Compatible
|
||||
Base URL: http://localhost:20128/v1
|
||||
API Key: [from dashboard]
|
||||
Model: cc/claude-opus-4-6
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 النشر
|
||||
|
||||
### نشر VPS
|
||||
|
||||
```bash
|
||||
git clone https://github.com/diegosouzapw/OmniRoute.git
|
||||
cd OmniRoute && npm install && npm run build
|
||||
|
||||
export JWT_SECRET="your-secure-secret-change-this"
|
||||
export INITIAL_PASSWORD="your-password"
|
||||
export DATA_DIR="/var/lib/omniroute"
|
||||
export PORT="20128"
|
||||
export HOSTNAME="0.0.0.0"
|
||||
export NODE_ENV="production"
|
||||
export NEXT_PUBLIC_BASE_URL="http://localhost:20128"
|
||||
export API_KEY_SECRET="endpoint-proxy-api-key-secret"
|
||||
|
||||
npm run start
|
||||
# Or: pm2 start npm --name omniroute -- start
|
||||
```
|
||||
|
||||
### عامل الميناء
|
||||
|
||||
```bash
|
||||
# Build image (default = runner-cli with codex/claude/droid preinstalled)
|
||||
docker build -t omniroute:cli .
|
||||
|
||||
# Portable mode (recommended)
|
||||
docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-data:/app/data omniroute:cli
|
||||
```
|
||||
|
||||
بالنسبة للوضع المدمج مع المضيف مع ثنائيات CLI، راجع قسم Docker في المستندات الرئيسية.
|
||||
|
||||
### متغيرات البيئة
|
||||
|
||||
| متغير | الافتراضي | الوصف |
|
||||
| --------------------- | ------------------------------------ | ---------------------------------------------------------------- |
|
||||
| `JWT_SECRET` | `omniroute-default-secret-change-me` | سر توقيع JWT (**تغيير في الإنتاج**) |
|
||||
| `INITIAL_PASSWORD` | `123456` | كلمة المرور الأولى لتسجيل الدخول |
|
||||
| `DATA_DIR` | `~/.omniroute` | دليل البيانات (ديسيبل، الاستخدام، السجلات) |
|
||||
| `PORT` | الإطار الافتراضي | منفذ الخدمة (`20128` في الأمثلة) |
|
||||
| `HOSTNAME` | الإطار الافتراضي | ربط المضيف (إعدادات Docker الافتراضية هي `0.0.0.0`) |
|
||||
| `NODE_ENV` | وقت التشغيل الافتراضي | قم بتعيين `production` للنشر |
|
||||
| `BASE_URL` | `http://localhost:20128` | عنوان URL الأساسي الداخلي من جانب الخادم |
|
||||
| `CLOUD_URL` | `https://omniroute.dev` | عنوان URL الأساسي لنقطة نهاية المزامنة السحابية |
|
||||
| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | سر HMAC لمفاتيح API التي تم إنشاؤها |
|
||||
| `REQUIRE_API_KEY` | `false` | فرض مفتاح Bearer API على `/v1/*` |
|
||||
| `ENABLE_REQUEST_LOGS` | `false` | تمكين سجلات الطلب/الاستجابة |
|
||||
| `AUTH_COOKIE_SECURE` | `false` | فرض ملف تعريف ارتباط المصادقة `Secure` (خلف الوكيل العكسي HTTPS) |
|
||||
|
||||
للحصول على مرجع متغير البيئة الكامل، راجع [README](../README.md).
|
||||
|
||||
---
|
||||
|
||||
## 📊 الموديلات المتوفرة
|
||||
|
||||
<details>
|
||||
<summary><b>عرض جميع الموديلات المتاحة</b></summary>
|
||||
|
||||
**كود كلود (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**المخطوطة (`cx/`)** — Plus/Pro: `cx/gpt-5.2-codex`، `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** — مجانًا: `gc/gemini-3-flash-preview`، `gc/gemini-2.5-pro`
|
||||
|
||||
**مساعد GitHub (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet`
|
||||
|
||||
**GLM (`glm/`)** — 0.6 دولار/1 مليون: `glm/glm-4.7`
|
||||
|
||||
**ميني ماكس (`minimax/`)** — 0.2 دولار/1 مليون: `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** — مجانًا: `if/kimi-k2-thinking`، `if/qwen3-coder-plus`، `if/deepseek-r1`
|
||||
|
||||
**كوين (`qw/`)** — مجانًا: `qw/qwen3-coder-plus`، `qw/qwen3-coder-flash`
|
||||
|
||||
**كيرو (`kr/`)** — مجانًا: `kr/claude-sonnet-4.5`، `kr/claude-haiku-4.5`
|
||||
|
||||
**DeepSeek (`ds/`)**: `ds/deepseek-chat`، `ds/deepseek-reasoner`
|
||||
|
||||
** جروك (`groq/`)**: `groq/llama-3.3-70b-versatile`، `groq/llama-4-maverick-17b-128e-instruct`
|
||||
|
||||
**xAI (`xai/`)**: `xai/grok-4`، `xai/grok-4-0709-fast-reasoning`، `xai/grok-code-mini`
|
||||
|
||||
**ميسترال (`mistral/`)**: `mistral/mistral-large-2501`، `mistral/codestral-2501`
|
||||
|
||||
**الحيرة (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar`
|
||||
|
||||
** معًا الذكاء الاصطناعي (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo`
|
||||
|
||||
**الذكاء الاصطناعي للألعاب النارية (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1`
|
||||
|
||||
** سيريبراس (`cerebras/`)**: `cerebras/llama-3.3-70b`
|
||||
|
||||
**الترابط (`cohere/`)**: `cohere/command-r-plus-08-2024`
|
||||
|
||||
** نفيديا نيم (`nvidia/`)**: `nvidia/nvidia/llama-3.3-70b-instruct`
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🧩 ميزات متقدمة
|
||||
|
||||
### نماذج مخصصة
|
||||
|
||||
أضف أي معرف نموذج إلى أي مزود دون انتظار تحديث التطبيق:
|
||||
|
||||
```bash
|
||||
# Via API
|
||||
curl -X POST http://localhost:20128/api/provider-models \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"provider": "openai", "modelId": "gpt-4.5-preview", "modelName": "GPT-4.5 Preview"}'
|
||||
|
||||
# List: curl http://localhost:20128/api/provider-models?provider=openai
|
||||
# Remove: curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview"
|
||||
```
|
||||
|
||||
أو استخدم لوحة المعلومات: **المزودون → [الموفر] → النماذج المخصصة**.
|
||||
|
||||
### مسارات موفر مخصصة
|
||||
|
||||
توجيه الطلبات مباشرة إلى موفر محدد مع التحقق من صحة النموذج:
|
||||
|
||||
```bash
|
||||
POST http://localhost:20128/v1/providers/openai/chat/completions
|
||||
POST http://localhost:20128/v1/providers/openai/embeddings
|
||||
POST http://localhost:20128/v1/providers/fireworks/images/generations
|
||||
```
|
||||
|
||||
تتم إضافة بادئة الموفر تلقائيًا في حالة فقدانها. تُرجع النماذج غير المتطابقة `400`.
|
||||
|
||||
### تكوين وكيل الشبكة
|
||||
|
||||
```bash
|
||||
# Set global proxy
|
||||
curl -X PUT http://localhost:20128/api/settings/proxy \
|
||||
-d '{"global": {"type":"http","host":"proxy.example.com","port":"8080"}}'
|
||||
|
||||
# Per-provider proxy
|
||||
curl -X PUT http://localhost:20128/api/settings/proxy \
|
||||
-d '{"providers": {"openai": {"type":"socks5","host":"proxy.example.com","port":"1080"}}}'
|
||||
|
||||
# Test proxy
|
||||
curl -X POST http://localhost:20128/api/settings/proxy/test \
|
||||
-d '{"proxy":{"type":"socks5","host":"proxy.example.com","port":"1080"}}'
|
||||
```
|
||||
|
||||
**الأسبقية:** خاص بالمفتاح ← خاص بالسرد والسرد ← خاص بالموفر ← عالمي ← البيئة.
|
||||
|
||||
### واجهة برمجة تطبيقات الكتالوج النموذجي
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/api/models/catalog
|
||||
```
|
||||
|
||||
إرجاع النماذج المجمعة حسب الموفر مع الأنواع (`chat`، `embedding`، `image`).
|
||||
|
||||
### المزامنة السحابية
|
||||
|
||||
- موفري المزامنة والمجموعات والإعدادات عبر الأجهزة
|
||||
- مزامنة الخلفية التلقائية مع انتهاء المهلة + الفشل السريع
|
||||
- تفضيل جانب الخادم `BASE_URL`/`CLOUD_URL` في الإنتاج
|
||||
|
||||
### LLM Gateway Intelligence (المرحلة 9)
|
||||
|
||||
- **ذاكرة التخزين المؤقت الدلالية** — ذاكرة تخزين مؤقت تلقائية غير متدفقة، درجة الحرارة = 0 استجابات (تجاوز باستخدام `X-OmniRoute-No-Cache: true`)
|
||||
- **صلاحية الطلب** — إلغاء تكرار الطلبات خلال 5 ثوانٍ عبر رأس `Idempotency-Key` أو `X-Request-Id`
|
||||
- **تتبع التقدم** — الاشتراك في أحداث SSE `event: progress` عبر رأس `X-OmniRoute-Progress: true`
|
||||
|
||||
---
|
||||
|
||||
### ملعب المترجم
|
||||
|
||||
الوصول عبر **لوحة المعلومات → المترجم**. تصحيح الأخطاء وتصور كيفية قيام OmniRoute بترجمة طلبات واجهة برمجة التطبيقات (API) بين مقدمي الخدمة.
|
||||
|
||||
| الوضع | الغرض |
|
||||
| -------------------- | ----------------------------------------------------------------------------- |
|
||||
| **ساحة اللعب** | حدد تنسيقات المصدر/الهدف، والصق طلبًا، وشاهد المخرجات المترجمة على الفور |
|
||||
| ** اختبار الدردشة ** | أرسل رسائل الدردشة المباشرة من خلال الوكيل وافحص دورة الطلب/الاستجابة الكاملة |
|
||||
| ** مقعد الاختبار ** | قم بإجراء اختبارات مجمعة عبر مجموعات تنسيقات متعددة للتحقق من صحة الترجمة |
|
||||
| **مراقبة حية** | شاهد الترجمات في الوقت الفعلي أثناء تدفق الطلبات عبر الوكيل |
|
||||
|
||||
**حالات الاستخدام:**
|
||||
|
||||
- تصحيح سبب فشل مجموعة محددة من العميل/الموفر
|
||||
- التحقق من ترجمة علامات التفكير واستدعاءات الأدوات ومطالبات النظام بشكل صحيح
|
||||
- مقارنة اختلافات التنسيق بين تنسيقات OpenAI وClaude وGemini وResponsions API
|
||||
|
||||
---
|
||||
|
||||
### استراتيجيات التوجيه
|
||||
|
||||
قم بالتكوين عبر **لوحة المعلومات → الإعدادات → التوجيه**.
|
||||
|
||||
| استراتيجية | الوصف |
|
||||
| ------------------------ | ---------------------------------------------------------------------------------------- |
|
||||
| ** املأ أولا ** | يستخدم الحسابات بترتيب الأولوية — يعالج الحساب الأساسي جميع الطلبات حتى تصبح غير متاحة |
|
||||
| ** راوند روبن ** | للتنقل عبر جميع الحسابات بحد ثابت قابل للتكوين (الافتراضي: 3 مكالمات لكل حساب) |
|
||||
| **P2C (قوة الاختيارين)** | يختار حسابين عشوائيين ويوجهك إلى الحساب الأكثر صحة - الأرصدة محملة بالوعي الصحي |
|
||||
| **عشوائي** | تحديد حساب عشوائيًا لكل طلب باستخدام خلط Fisher-Yates |
|
||||
| **الأقل استخدامًا** | التوجيهات إلى الحساب ذو الطابع الزمني الأقدم `lastUsedAt`، مع توزيع حركة المرور بالتساوي |
|
||||
| **التكلفة الأمثل** | التوجيهات إلى الحساب ذي أقل قيمة أولوية، مع تحسين موفري الخدمة الأقل تكلفة |
|
||||
|
||||
#### الأسماء المستعارة لنموذج البدل
|
||||
|
||||
قم بإنشاء أنماط أحرف البدل لإعادة تعيين أسماء النماذج:
|
||||
|
||||
```
|
||||
Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929
|
||||
Pattern: gpt-* → Target: gh/gpt-5.1-codex
|
||||
```
|
||||
|
||||
تدعم أحرف البدل `*` (أي أحرف) و`?` (حرف واحد).
|
||||
|
||||
#### سلاسل احتياطية
|
||||
|
||||
تحديد السلاسل الاحتياطية العالمية التي تنطبق على جميع الطلبات:
|
||||
|
||||
```
|
||||
Chain: production-fallback
|
||||
1. cc/claude-opus-4-6
|
||||
2. gh/gpt-5.1-codex
|
||||
3. glm/glm-4.7
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### المرونة وقواطع الدائرة
|
||||
|
||||
قم بالتكوين عبر **لوحة المعلومات → الإعدادات → المرونة**.
|
||||
|
||||
تطبق OmniRoute المرونة على مستوى المزود من خلال أربعة مكونات:
|
||||
|
||||
1. **ملفات تعريف الموفر** — التكوين لكل موفر لـ:
|
||||
- عتبة الفشل (كم عدد حالات الفشل قبل الفتح)
|
||||
- مدة التهدئة
|
||||
- حساسية الكشف عن حد المعدل
|
||||
- معلمات التراجع الأسي
|
||||
|
||||
2. **حدود المعدل القابلة للتحرير** — الإعدادات الافتراضية على مستوى النظام قابلة للتكوين في لوحة المعلومات:
|
||||
- **الطلبات في الدقيقة (RPM)** — الحد الأقصى للطلبات في الدقيقة لكل حساب
|
||||
- **الحد الأدنى للوقت بين الطلبات** — الحد الأدنى للفجوة بالمللي ثانية بين الطلبات
|
||||
- **الحد الأقصى للطلبات المتزامنة** — الحد الأقصى للطلبات المتزامنة لكل حساب
|
||||
- انقر **تحرير** للتعديل، ثم **حفظ** أو **إلغاء**. تستمر القيم عبر واجهة برمجة تطبيقات المرونة.
|
||||
|
||||
3. **قاطع الدائرة** — يتتبع حالات الفشل لكل مزود ويفتح الدائرة تلقائيًا عند الوصول إلى الحد الأدنى:
|
||||
- **مغلق** (صحي) — تتدفق الطلبات بشكل طبيعي
|
||||
- **مفتوح** — تم حظر الموفر مؤقتًا بعد الفشل المتكرر
|
||||
- **HALF_OPEN** — اختبار ما إذا كان الموفر قد استعاد عافيته
|
||||
|
||||
4. **السياسات والمعرفات المقفلة** — تعرض حالة قاطع الدائرة والمعرفات المقفلة مع إمكانية إلغاء القفل بالقوة.
|
||||
|
||||
5. **الاكتشاف التلقائي لحدود المعدل** — يراقب الرؤوس `429` و`Retry-After` لتجنب الوصول إلى حدود معدل الموفر بشكل استباقي.
|
||||
|
||||
**نصيحة احترافية:** استخدم زر **إعادة تعيين الكل** لمسح جميع قواطع الدائرة وفترات التباطؤ عندما يتعافى المزود من انقطاع الخدمة.
|
||||
|
||||
---
|
||||
|
||||
### تصدير / استيراد قاعدة البيانات
|
||||
|
||||
إدارة النسخ الاحتياطية لقاعدة البيانات في **لوحة المعلومات → الإعدادات → النظام والتخزين**.
|
||||
|
||||
| العمل | الوصف |
|
||||
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **تصدير قاعدة البيانات** | يقوم بتنزيل قاعدة بيانات SQLite الحالية كملف `.sqlite` |
|
||||
| **تصدير الكل (.tar.gz)** | تنزيل أرشيف نسخ احتياطي كامل بما في ذلك: قاعدة البيانات، والإعدادات، والمجموعات، واتصالات الموفر (بدون بيانات اعتماد)، وبيانات تعريف مفتاح API |
|
||||
| **استيراد قاعدة البيانات** | قم بتحميل ملف `.sqlite` لاستبدال قاعدة البيانات الحالية. يتم إنشاء نسخة احتياطية للاستيراد المسبق تلقائيًا |
|
||||
|
||||
```bash
|
||||
# API: Export database
|
||||
curl -o backup.sqlite http://localhost:20128/api/db-backups/export
|
||||
|
||||
# API: Export all (full archive)
|
||||
curl -o backup.tar.gz http://localhost:20128/api/db-backups/exportAll
|
||||
|
||||
# API: Import database
|
||||
curl -X POST http://localhost:20128/api/db-backups/import \
|
||||
-F "file=@backup.sqlite"
|
||||
```
|
||||
|
||||
**التحقق من صحة الاستيراد:** يتم التحقق من صحة الملف المستورد للتأكد من سلامته (فحص براغما SQLite)، والجداول المطلوبة (`provider_connections`، `provider_nodes`، `combos`، `api_keys`)، والحجم (100 ميجابايت كحد أقصى).
|
||||
|
||||
**حالات الاستخدام:**
|
||||
|
||||
- ترحيل OmniRoute بين الأجهزة
|
||||
- إنشاء نسخ احتياطية خارجية للتعافي من الكوارث
|
||||
- مشاركة التكوينات بين أعضاء الفريق (تصدير الكل → مشاركة الأرشيف)
|
||||
|
||||
---
|
||||
|
||||
### لوحة تحكم الإعدادات
|
||||
|
||||
يتم تنظيم صفحة الإعدادات في 5 علامات تبويب لسهولة التنقل:
|
||||
|
||||
| علامة التبويب | المحتويات |
|
||||
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **الأمن** | إعدادات تسجيل الدخول/كلمة المرور، والتحكم في الوصول إلى IP، ومصادقة API لـ `/models`، وحظر الموفر |
|
||||
| **التوجيه** | استراتيجية التوجيه العالمية (6 خيارات)، والأسماء المستعارة لنماذج أحرف البدل، والسلاسل الاحتياطية، وافتراضيات التحرير والسرد |
|
||||
| **المرونة** | ملفات تعريف الموفر، وحدود الأسعار القابلة للتحرير، وحالة قاطع الدائرة، والسياسات والمعرفات المقفلة |
|
||||
| **الذكاء الاصطناعي** | تكوين ميزانية التفكير، والحقن الفوري للنظام العالمي، وإحصائيات ذاكرة التخزين المؤقت السريعة |
|
||||
| **متقدم** | تكوين الوكيل العالمي (HTTP/SOCKS5) |
|
||||
|
||||
---
|
||||
|
||||
### إدارة التكاليف والميزانية
|
||||
|
||||
الوصول عبر **لوحة التحكم ← التكاليف**.
|
||||
|
||||
| علامة التبويب | الغرض |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| **الميزانية** | قم بتعيين حدود الإنفاق لكل مفتاح API باستخدام ميزانيات يومية/أسبوعية/شهرية وتتبع في الوقت الفعلي |
|
||||
| **التسعير** | عرض وتحرير إدخالات تسعير النموذج - التكلفة لكل ألف رمز إدخال/إخراج لكل مزود |
|
||||
|
||||
```bash
|
||||
# API: Set a budget
|
||||
curl -X POST http://localhost:20128/api/usage/budget \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"keyId": "key-123", "limit": 50.00, "period": "monthly"}'
|
||||
|
||||
# API: Get current budget status
|
||||
curl http://localhost:20128/api/usage/budget
|
||||
```
|
||||
|
||||
**تتبع التكلفة:** يقوم كل طلب بتسجيل استخدام الرمز المميز وحساب التكلفة باستخدام جدول التسعير. عرض التفاصيل في **لوحة المعلومات → الاستخدام** حسب الموفر والطراز ومفتاح واجهة برمجة التطبيقات.
|
||||
|
||||
---
|
||||
|
||||
### النسخ الصوتي
|
||||
|
||||
يدعم OmniRoute النسخ الصوتي عبر نقطة النهاية المتوافقة مع OpenAI:
|
||||
|
||||
```bash
|
||||
POST /v1/audio/transcriptions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
# Example with curl
|
||||
curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
-H "Authorization: Bearer your-api-key" \
|
||||
-F "file=@audio.mp3" \
|
||||
-F "model=deepgram/nova-3"
|
||||
```
|
||||
|
||||
الموفرون المتاحون: **Deepgram** (`deepgram/`)، **AssemblyAI** (`assemblyai/`).
|
||||
|
||||
تنسيقات الصوت المدعومة: `mp3`، `wav`، `m4a`، `flac`، `ogg`، `webm`.
|
||||
|
||||
---
|
||||
|
||||
### استراتيجيات موازنة التحرير والسرد
|
||||
|
||||
قم بتكوين التوازن لكل مجموعة في **لوحة المعلومات → المجموعات → إنشاء/تحرير → الإستراتيجية**.
|
||||
|
||||
| استراتيجية | الوصف |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------- |
|
||||
| **جولة روبن** | يدور عبر النماذج بالتتابع |
|
||||
| **الأولوية** | يحاول دائمًا النموذج الأول؛ لا يعود إلا على الخطأ |
|
||||
| **عشوائي** | يختار نموذجًا عشوائيًا من المجموعة لكل طلب |
|
||||
| **المرجح** | تعتمد المسارات بشكل متناسب على الأوزان المخصصة لكل نموذج |
|
||||
| **الأقل استخدامًا** | التوجيهات إلى النموذج الذي يحتوي على أقل عدد من الطلبات الأخيرة (يستخدم مقاييس التحرير والسرد) |
|
||||
| **التكلفة الأمثل** | الطرق إلى أرخص طراز متاح (يستخدم جدول التسعير) |
|
||||
|
||||
يمكن ضبط إعدادات التحرير والسرد العامة في **لوحة المعلومات → الإعدادات → التوجيه → إعدادات التحرير والسرد الافتراضية**.
|
||||
|
||||
---
|
||||
|
||||
### لوحة المعلومات الصحية
|
||||
|
||||
الوصول عبر **لوحة التحكم → الصحة**. نظرة عامة على صحة النظام في الوقت الحقيقي مع 6 بطاقات:
|
||||
|
||||
| بطاقة | ما يظهر |
|
||||
| ---------------------------------- | -------------------------------------------------------------- |
|
||||
| **حالة النظام** | وقت التشغيل، الإصدار، استخدام الذاكرة، دليل البيانات |
|
||||
| ** صحة المزود ** | حالة قاطع الدائرة الكهربائية لكل مزود (مغلق/مفتوح/نصف مفتوح) |
|
||||
| ** حدود المعدل ** | فترات تهدئة حد المعدل النشط لكل حساب مع الوقت المتبقي |
|
||||
| ** عمليات التأمين النشطة ** | تم حظر مقدمي الخدمة مؤقتًا بواسطة سياسة التأمين |
|
||||
| ** ذاكرة التخزين المؤقت للتوقيع ** | إحصائيات إلغاء البيانات المكررة (المفاتيح النشطة، معدل الدخول) |
|
||||
| ** قياس زمن الوصول ** | p50/p95/p99 تجميع زمن الوصول لكل مزود |
|
||||
|
||||
**نصيحة احترافية:** يتم تحديث صفحة الصحة تلقائيًا كل 10 ثوانٍ. استخدم بطاقة قاطع الدائرة لتحديد مقدمي الخدمة الذين يواجهون مشكلات.
|
||||
@@ -0,0 +1,441 @@
|
||||
# Справка за API
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](../es/API_REFERENCE.md) | 🇫🇷 [Français](../fr/API_REFERENCE.md) | 🇮🇹 [Italiano](../it/API_REFERENCE.md) | 🇷🇺 [Русский](../ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](../de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../in/API_REFERENCE.md) | 🇹🇭 [ไทย](../th/API_REFERENCE.md) | 🇺🇦 [Українська](../uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](../ar/API_REFERENCE.md) | 🇯🇵 [日本語](../ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../vi/API_REFERENCE.md) | 🇧🇬 [Български](../bg/API_REFERENCE.md) | 🇩🇰 [Dansk](../da/API_REFERENCE.md) | 🇫🇮 [Suomi](../fi/API_REFERENCE.md) | 🇮🇱 [עברית](../he/API_REFERENCE.md) | 🇭🇺 [Magyar](../hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../id/API_REFERENCE.md) | 🇰🇷 [한국어](../ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](../nl/API_REFERENCE.md) | 🇳🇴 [Norsk](../no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../pt/API_REFERENCE.md) | 🇷🇴 [Română](../ro/API_REFERENCE.md) | 🇵🇱 [Polski](../pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../sk/API_REFERENCE.md) | 🇸🇪 [Svenska](../sv/API_REFERENCE.md) | 🇵🇭 [Filipino](../phi/API_REFERENCE.md)
|
||||
|
||||
Пълна справка за всички крайни точки на OmniRoute API.
|
||||
|
||||
---
|
||||
|
||||
## Съдържание
|
||||
|
||||
- [Chat Completions](#chat-completions)
|
||||
- [Embeddings](#embeddings)
|
||||
- [Image Generation](#image-generation)
|
||||
- [List Models](#list-models)
|
||||
- [Compatibility Endpoints](#compatibility-endpoints)
|
||||
- [Semantic Cache](#semantic-cache)
|
||||
- [Dashboard & Management](#dashboard--management)
|
||||
- [Request Processing](#request-processing)
|
||||
- [Authentication](#authentication)
|
||||
|
||||
---
|
||||
|
||||
## Завършвания на чат
|
||||
|
||||
```bash
|
||||
POST /v1/chat/completions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "cc/claude-opus-4-6",
|
||||
"messages": [
|
||||
{"role": "user", "content": "Write a function to..."}
|
||||
],
|
||||
"stream": true
|
||||
}
|
||||
```
|
||||
|
||||
### Персонализирани заглавки
|
||||
|
||||
| Заглавка | Посока | Описание |
|
||||
| ------------------------ | ------- | ------------------------------------------ |
|
||||
| `X-OmniRoute-No-Cache` | Заявка | Задайте `true` за заобикаляне на кеша |
|
||||
| `X-OmniRoute-Progress` | Заявка | Задайте `true` за събития за прогрес |
|
||||
| `Idempotency-Key` | Заявка | Ключ за дедупиране (5s прозорец) |
|
||||
| `X-Request-Id` | Заявка | Алтернативен дедуп ключ |
|
||||
| `X-OmniRoute-Cache` | Отговор | `HIT` или `MISS` (без поточно предаване) |
|
||||
| `X-OmniRoute-Idempotent` | Отговор | `true` ако е дедупликиран |
|
||||
| `X-OmniRoute-Progress` | Отговор | `enabled` ако проследяване на напредъка на |
|
||||
|
||||
---
|
||||
|
||||
## Вграждания
|
||||
|
||||
```bash
|
||||
POST /v1/embeddings
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "nebius/Qwen/Qwen3-Embedding-8B",
|
||||
"input": "The food was delicious"
|
||||
}
|
||||
```
|
||||
|
||||
Налични доставчици: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.
|
||||
|
||||
```bash
|
||||
# List all embedding models
|
||||
GET /v1/embeddings
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Генериране на изображения
|
||||
|
||||
```bash
|
||||
POST /v1/images/generations
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "openai/dall-e-3",
|
||||
"prompt": "A beautiful sunset over mountains",
|
||||
"size": "1024x1024"
|
||||
}
|
||||
```
|
||||
|
||||
Налични доставчици: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.
|
||||
|
||||
```bash
|
||||
# List all image models
|
||||
GET /v1/images/generations
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Списък с модели
|
||||
|
||||
```bash
|
||||
GET /v1/models
|
||||
Authorization: Bearer your-api-key
|
||||
|
||||
→ Returns all chat, embedding, and image models + combos in OpenAI format
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Крайни точки за съвместимост
|
||||
|
||||
| Метод | Път | Формат |
|
||||
| ---------- | --------------------------- | -------------------------- |
|
||||
| ПУБЛИКАЦИЯ | `/v1/chat/completions` | OpenAI |
|
||||
| ПУБЛИКАЦИЯ | `/v1/messages` | Антропен |
|
||||
| ПУБЛИКАЦИЯ | `/v1/responses` | OpenAI отговори |
|
||||
| ПУБЛИКАЦИЯ | `/v1/embeddings` | OpenAI |
|
||||
| ПУБЛИКАЦИЯ | `/v1/images/generations` | OpenAI |
|
||||
| ВЗЕМЕТЕ | `/v1/models` | OpenAI |
|
||||
| ПУБЛИКАЦИЯ | `/v1/messages/count_tokens` | Антропен |
|
||||
| ВЗЕМЕТЕ | `/v1beta/models` | Близнаци |
|
||||
| ПУБЛИКАЦИЯ | `/v1beta/models/{...path}` | Gemini генерира съдържание |
|
||||
| ПУБЛИКАЦИЯ | `/v1/api/chat` | Олама |
|
||||
|
||||
### Специализирани маршрути на доставчик
|
||||
|
||||
```bash
|
||||
POST /v1/providers/{provider}/chat/completions
|
||||
POST /v1/providers/{provider}/embeddings
|
||||
POST /v1/providers/{provider}/images/generations
|
||||
```
|
||||
|
||||
Префиксът на доставчика се добавя автоматично, ако липсва. Несъответстващите модели връщат `400`.
|
||||
|
||||
---
|
||||
|
||||
## Семантичен кеш
|
||||
|
||||
```bash
|
||||
# Get cache stats
|
||||
GET /api/cache
|
||||
|
||||
# Clear all caches
|
||||
DELETE /api/cache
|
||||
```
|
||||
|
||||
Пример за отговор:
|
||||
|
||||
```json
|
||||
{
|
||||
"semanticCache": {
|
||||
"memorySize": 42,
|
||||
"memoryMaxSize": 500,
|
||||
"dbSize": 128,
|
||||
"hitRate": 0.65
|
||||
},
|
||||
"idempotency": {
|
||||
"activeKeys": 3,
|
||||
"windowMs": 5000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Табло за управление и управление
|
||||
|
||||
### Удостоверяване
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ----------------------------- | ------------- | ---------------------------------- |
|
||||
| `/api/auth/login` | ПУБЛИКАЦИЯ | Вход |
|
||||
| `/api/auth/logout` | ПУБЛИКАЦИЯ | Изход |
|
||||
| `/api/settings/require-login` | ВЗЕМИ/ПОСТАВИ | Изисква се превключване на влизане |
|
||||
|
||||
### Управление на доставчика
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ---------------------------- | -------------------------------- | ---------------------------------------- |
|
||||
| `/api/providers` | ВЗЕМЕТЕ/ПУБЛИКУВАЙТЕ | Списък / създаване на доставчици |
|
||||
| `/api/providers/[id]` | ПОЛУЧАВАНЕ/ПОСТАВЯНЕ/ИЗТРИВАНЕ | Управление на доставчик |
|
||||
| `/api/providers/[id]/test` | ПУБЛИКАЦИЯ | Тествайте връзката с доставчик |
|
||||
| `/api/providers/[id]/models` | ВЗЕМЕТЕ | Избройте модели на доставчици |
|
||||
| `/api/providers/validate` | ПУБЛИКАЦИЯ | Проверка на конфигурацията на доставчика |
|
||||
| `/api/provider-nodes*` | Различни | Управление на възел на доставчик |
|
||||
| `/api/provider-models` | ПОЛУЧАВАНЕ/ПУБЛИКУВАНЕ/ИЗТРИВАНЕ | Персонализирани модели |
|
||||
|
||||
### OAuth потоци
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| -------------------------------- | -------- | ------------------------------ |
|
||||
| `/api/oauth/[provider]/[action]` | Различни | Специфичен за доставчика OAuth |
|
||||
|
||||
### Маршрутизиране и конфигурация
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------------- | -------------------- | -------------------------------- |
|
||||
| `/api/models/alias` | ВЗЕМЕТЕ/ПУБЛИКУВАЙТЕ | Псевдоними на модели |
|
||||
| `/api/models/catalog` | ВЗЕМЕТЕ | Всички модели по доставчик + тип |
|
||||
| `/api/combos*` | Различни | Комбо управление |
|
||||
| `/api/keys*` | Различни | Управление на API ключове |
|
||||
| `/api/pricing` | ВЗЕМЕТЕ | Моделна цена |
|
||||
|
||||
### Използване и анализ
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------------------- | ------- | ----------------------- |
|
||||
| `/api/usage/history` | ВЗЕМЕТЕ | История на използването |
|
||||
| `/api/usage/logs` | ВЗЕМЕТЕ | Дневници за използване |
|
||||
| `/api/usage/request-logs` | ВЗЕМЕТЕ | Дневници на ниво заявка |
|
||||
| `/api/usage/[connectionId]` | ВЗЕМЕТЕ | Използване на връзка |
|
||||
|
||||
### Настройки
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ------------------------------- | ------------- | -------------------------------------- |
|
||||
| `/api/settings` | ВЗЕМИ/ПОСТАВИ | Общи настройки |
|
||||
| `/api/settings/proxy` | ВЗЕМИ/ПОСТАВИ | Конфигурация на мрежов прокси |
|
||||
| `/api/settings/proxy/test` | ПУБЛИКАЦИЯ | Тествайте прокси връзката |
|
||||
| `/api/settings/ip-filter` | ВЗЕМИ/ПОСТАВИ | Списък с разрешени/блокирани IP адреси |
|
||||
| `/api/settings/thinking-budget` | ВЗЕМИ/ПОСТАВИ | Бюджет на жетон за разсъждение |
|
||||
| `/api/settings/system-prompt` | ВЗЕМИ/ПОСТАВИ | Глобална системна подкана |
|
||||
|
||||
### Мониторинг
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ------------------------ | -------------------- | ----------------------------- |
|
||||
| `/api/sessions` | ВЗЕМЕТЕ | Проследяване на активна сесия |
|
||||
| `/api/rate-limits` | ВЗЕМЕТЕ | Лимити за лихви по сметка |
|
||||
| `/api/monitoring/health` | ВЗЕМЕТЕ | Здравна проверка |
|
||||
| `/api/cache` | ПОЛУЧАВАНЕ/ИЗТРИВАНЕ | Кеш статистики / изчистване |
|
||||
|
||||
### Архивиране и експортиране/импортиране
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------------------- | ---------- | ------------------------------------------------ |
|
||||
| `/api/db-backups` | ВЗЕМЕТЕ | Избройте наличните резервни копия |
|
||||
| `/api/db-backups` | ПОСТАВЕТЕ | Създайте ръчно архивиране |
|
||||
| `/api/db-backups` | ПУБЛИКАЦИЯ | Възстановяване от конкретен архив |
|
||||
| `/api/db-backups/export` | ВЗЕМЕТЕ | Изтегляне на база данни като .sqlite файл |
|
||||
| `/api/db-backups/import` | ПУБЛИКАЦИЯ | Качете .sqlite файл, за да замените базата данни |
|
||||
| `/api/db-backups/exportAll` | ВЗЕМЕТЕ | Изтеглете пълното архивиране като .tar.gz архив |
|
||||
|
||||
### Облачно синхронизиране
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ---------------------- | ---------- | ---------------------------------- |
|
||||
| `/api/sync/cloud` | Различни | Операции за синхронизиране в облак |
|
||||
| `/api/sync/initialize` | ПУБЛИКАЦИЯ | Инициализиране на синхронизиране |
|
||||
| `/api/cloud/*` | Различни | Облачно управление |
|
||||
|
||||
### CLI инструменти
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ---------------------------------- | ------- | ---------------------- |
|
||||
| `/api/cli-tools/claude-settings` | ВЗЕМЕТЕ | Клод CLI състояние |
|
||||
| `/api/cli-tools/codex-settings` | ВЗЕМЕТЕ | Codex CLI състояние |
|
||||
| `/api/cli-tools/droid-settings` | ВЗЕМЕТЕ | Droid CLI състояние |
|
||||
| `/api/cli-tools/openclaw-settings` | ВЗЕМЕТЕ | OpenClaw CLI състояние |
|
||||
| `/api/cli-tools/runtime/[toolId]` | ВЗЕМЕТЕ | Generic CLI runtime |
|
||||
|
||||
CLI отговорите включват: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
|
||||
|
||||
### Устойчивост и ограничения на скоростта
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ----------------------- | ------------- | --------------------------------------------- |
|
||||
| `/api/resilience` | ВЗЕМИ/ПОСТАВИ | Вземете/актуализирайте профили за устойчивост |
|
||||
| `/api/resilience/reset` | ПУБЛИКАЦИЯ | Нулиране на прекъсвачи |
|
||||
| `/api/rate-limits` | ВЗЕМЕТЕ | Състояние на ограничение на лимита по сметка |
|
||||
| `/api/rate-limit` | ВЗЕМЕТЕ | Конфигурация на глобален лимит на скоростта |
|
||||
|
||||
### Оценки
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ------------ | -------------------- | --------------------------------------- |
|
||||
| `/api/evals` | ВЗЕМЕТЕ/ПУБЛИКУВАЙТЕ | Избройте eval пакети / изпълнете оценка |
|
||||
|
||||
### Политики
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------- | -------------------------------- | ----------------------------------------- |
|
||||
| `/api/policies` | ПОЛУЧАВАНЕ/ПУБЛИКУВАНЕ/ИЗТРИВАНЕ | Управление на правилата за маршрутизиране |
|
||||
|
||||
### Съответствие
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------------------- | ------- | -------------------------------------------------- |
|
||||
| `/api/compliance/audit-log` | ВЗЕМЕТЕ | Дневник за проверка на съответствието (последно N) |
|
||||
|
||||
### v1beta (съвместим с Gemini)
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| -------------------------- | ---------- | ------------------------------------- |
|
||||
| `/v1beta/models` | ВЗЕМЕТЕ | Избройте модели във формат Gemini |
|
||||
| `/v1beta/models/{...path}` | ПУБЛИКАЦИЯ | Gemini `generateContent` крайна точка |
|
||||
|
||||
Тези крайни точки отразяват API формата на Gemini за клиенти, които очакват естествена съвместимост с Gemini SDK.
|
||||
|
||||
### Вътрешен/системен API
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------- | ---------- | ------------------------------------------------------------------------------ |
|
||||
| `/api/init` | ВЗЕМЕТЕ | Проверка за инициализация на приложението (използва се при първото стартиране) |
|
||||
| `/api/tags` | ВЗЕМЕТЕ | Тагове за модели, съвместими с Ollama (за клиенти на Ollama) |
|
||||
| `/api/restart` | ПУБЛИКАЦИЯ | Задейства грациозно рестартиране на сървъра |
|
||||
| `/api/shutdown` | ПУБЛИКАЦИЯ | Задействайте грациозно изключване на сървъра |
|
||||
|
||||
> **Забележка:** Тези крайни точки се използват вътрешно от системата или за съвместимост с клиента Ollama. Те обикновено не се извикват от крайните потребители.
|
||||
|
||||
---
|
||||
|
||||
## Аудио транскрипция
|
||||
|
||||
```bash
|
||||
POST /v1/audio/transcriptions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: multipart/form-data
|
||||
```
|
||||
|
||||
Транскрибирайте аудио файлове с помощта на Deepgram или AssemblyAI.
|
||||
|
||||
**Заявка:**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
-H "Authorization: Bearer your-api-key" \
|
||||
-F "file=@recording.mp3" \
|
||||
-F "model=deepgram/nova-3"
|
||||
```
|
||||
|
||||
**Отговор:**
|
||||
|
||||
```json
|
||||
{
|
||||
"text": "Hello, this is the transcribed audio content.",
|
||||
"task": "transcribe",
|
||||
"language": "en",
|
||||
"duration": 12.5
|
||||
}
|
||||
```
|
||||
|
||||
**Поддържани доставчици:** `deepgram/nova-3`, `assemblyai/best`.
|
||||
|
||||
**Поддържани формати:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
|
||||
---
|
||||
|
||||
## Съвместимост с Ollama
|
||||
|
||||
За клиенти, които използват API формат на Ollama:
|
||||
|
||||
```bash
|
||||
# Chat endpoint (Ollama format)
|
||||
POST /v1/api/chat
|
||||
|
||||
# Model listing (Ollama format)
|
||||
GET /api/tags
|
||||
```
|
||||
|
||||
Заявките се превеждат автоматично между Ollama и вътрешни формати.
|
||||
|
||||
---
|
||||
|
||||
## Телеметрия
|
||||
|
||||
```bash
|
||||
# Get latency telemetry summary (p50/p95/p99 per provider)
|
||||
GET /api/telemetry/summary
|
||||
```
|
||||
|
||||
**Отговор:**
|
||||
|
||||
```json
|
||||
{
|
||||
"providers": {
|
||||
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
|
||||
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Бюджет
|
||||
|
||||
```bash
|
||||
# Get budget status for all API keys
|
||||
GET /api/usage/budget
|
||||
|
||||
# Set or update a budget
|
||||
POST /api/usage/budget
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"keyId": "key-123",
|
||||
"limit": 50.00,
|
||||
"period": "monthly"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Наличност на модела
|
||||
|
||||
```bash
|
||||
# Get real-time model availability across all providers
|
||||
GET /api/models/availability
|
||||
|
||||
# Check availability for a specific model
|
||||
POST /api/models/availability
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "claude-sonnet-4-5-20250929"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Обработка на заявка
|
||||
|
||||
1. Клиентът изпраща заявка до `/v1/*`
|
||||
2. Обработчикът на маршрута извиква `handleChat`, `handleEmbedding`, `handleAudioTranscription` или `handleImageGeneration`
|
||||
3. Моделът е разрешен (директен доставчик/модел или псевдоним/комбо)
|
||||
4. Идентификационни данни, избрани от локална база данни с филтриране на наличността на акаунта
|
||||
5. За чат: `handleChatCore` — откриване на формат, превод, проверка на кеша, проверка на идемпотентност
|
||||
6. Изпълнителят на доставчика изпраща заявка нагоре по веригата
|
||||
7. Отговор, преведен обратно във формат на клиента (чат) или върнат такъв, какъвто е (вграждания/изображения/аудио)
|
||||
8. Записано използване/регистриране
|
||||
9. Резервният вариант се прилага при грешки според комбо правилата
|
||||
|
||||
Пълна справка за архитектурата: [link](ARCHITECTURE.md)
|
||||
|
||||
---
|
||||
|
||||
## Удостоверяване
|
||||
|
||||
- Маршрутите на таблото за управление (`/dashboard/*`) използват бисквитка `auth_token`
|
||||
- Входът използва запазен хеш на паролата; връщане към `INITIAL_PASSWORD`
|
||||
- `requireLogin` превключваем чрез `/api/settings/require-login`
|
||||
- `/v1/*` маршрутите по избор изискват Bearer API ключ, когато `REQUIRE_API_KEY=true`
|
||||
@@ -0,0 +1,781 @@
|
||||
# Архитектура OmniRoute
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](../es/ARCHITECTURE.md) | 🇫🇷 [Français](../fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](../it/ARCHITECTURE.md) | 🇷🇺 [Русский](../ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](../zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](../de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](../in/ARCHITECTURE.md) | 🇹🇭 [ไทย](../th/ARCHITECTURE.md) | 🇺🇦 [Українська](../uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](../ar/ARCHITECTURE.md) | 🇯🇵 [日本語](../ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](../vi/ARCHITECTURE.md) | 🇧🇬 [Български](../bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](../da/ARCHITECTURE.md) | 🇫🇮 [Suomi](../fi/ARCHITECTURE.md) | 🇮🇱 [עברית](../he/ARCHITECTURE.md) | 🇭🇺 [Magyar](../hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](../id/ARCHITECTURE.md) | 🇰🇷 [한국어](../ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](../ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](../nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](../no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](../pt/ARCHITECTURE.md) | 🇷🇴 [Română](../ro/ARCHITECTURE.md) | 🇵🇱 [Polski](../pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](../sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](../sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](../phi/ARCHITECTURE.md)
|
||||
|
||||
_Последна актуализация: 2026-02-18_
|
||||
|
||||
## Резюме
|
||||
|
||||
OmniRoute е локален AI маршрутизиращ шлюз и табло за управление, изградено на Next.js.
|
||||
Той осигурява една крайна точка, съвместима с OpenAI (`/v1/*`) и маршрутизира трафика през множество доставчици нагоре по веригата с превод, резервен вариант, опресняване на токени и проследяване на използването.
|
||||
|
||||
Основни възможности:
|
||||
|
||||
- OpenAI-съвместима API повърхност за CLI/инструменти (28 доставчици)
|
||||
- Превод на заявка/отговор във форматите на доставчика
|
||||
- Резервна комбинация от модели (последователност от няколко модела)
|
||||
- Резервен вариант на ниво акаунт (мулти акаунт на доставчик)
|
||||
- OAuth + API-ключ управление на връзката на доставчика
|
||||
- Генериране на вграждане чрез `/v1/embeddings` (6 доставчика, 9 модела)
|
||||
- Генериране на изображения чрез `/v1/images/generations` (4 доставчика, 9 модела)
|
||||
- Мислен синтактичен анализ на етикет (`<think>...</think>`) за модели на разсъждение
|
||||
- Дезинфекция на отговора за стриктна съвместимост с OpenAI SDK
|
||||
- Нормализиране на ролята (разработчик→система, система→потребител) за съвместимост между доставчици
|
||||
- Структурирано преобразуване на изход (json_schema → Gemini responseSchema)
|
||||
- Локална устойчивост за доставчици, ключове, псевдоними, комбинации, настройки, ценообразуване
|
||||
- Проследяване на използване/разходи и регистриране на заявки
|
||||
- Допълнителна облачна синхронизация за синхронизиране на множество устройства/състояние
|
||||
- Списък с разрешени/блокирани IP адреси за контрол на достъпа до API
|
||||
- Мислещо управление на бюджета (преминаване/автоматично/персонализирано/адаптивно)
|
||||
- Бързо инжектиране на глобалната система
|
||||
- Проследяване на сесии и пръстови отпечатъци
|
||||
- Подобрено ограничаване на скоростта за всеки акаунт със специфични за доставчика профили
|
||||
- Модел на прекъсвача за устойчивост на доставчика
|
||||
- Анти-гръмотевична стадна защита с mutex заключване
|
||||
- Кеш за дедупликация на заявки, базиран на подпис
|
||||
- Слой на домейна: наличност на модела, правила за разходите, резервна политика, политика за блокиране
|
||||
- Устойчивост на състоянието на домейна (кеш за запис на SQLite за резервни варианти, бюджети, блокировки, прекъсвачи на верига)
|
||||
- Механизъм за правила за централизирана оценка на заявката (заключване → бюджет → резервен)
|
||||
- Заявка за телеметрия с p50/p95/p99 агрегиране на латентност
|
||||
- ID на корелация (X-Request-Id) за проследяване от край до край
|
||||
- Регистриране на одит за съответствие с отказ за всеки API ключ
|
||||
- Eval framework за осигуряване на качеството на LLM
|
||||
- Resilience UI табло със статус на прекъсвача в реално време
|
||||
- Модулни OAuth доставчици (12 отделни модула под `src/lib/oauth/providers/`)
|
||||
|
||||
Основен модел на изпълнение:
|
||||
|
||||
- Маршрутите на приложението Next.js под `src/app/api/*` прилагат както API на таблото за управление, така и API за съвместимост
|
||||
- Споделено SSE/маршрутизиращо ядро в `src/sse/*` + `open-sse/*` обработва изпълнението на доставчика, превода, стрийминг, резервен вариант и използване
|
||||
|
||||
## Обхват и граници
|
||||
|
||||
### В обхват
|
||||
|
||||
- Време за изпълнение на локален шлюз
|
||||
- API за управление на таблото
|
||||
- Удостоверяване на доставчика и опресняване на токена
|
||||
- Заявка за превод и SSE стрийминг
|
||||
- Локално състояние + постоянство на използване
|
||||
- Допълнителна синхронизация в облака
|
||||
|
||||
### Извън обхвата
|
||||
|
||||
- Внедряване на облачна услуга зад `NEXT_PUBLIC_CLOUD_URL`
|
||||
- SLA/контролна равнина на доставчика извън локалния процес
|
||||
- Самите външни CLI двоични файлове (Claude CLI, Codex CLI и т.н.)
|
||||
|
||||
## Системен контекст на високо ниво
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Clients[Developer Clients]
|
||||
C1[Claude Code]
|
||||
C2[Codex CLI]
|
||||
C3[OpenClaw / Droid / Cline / Continue / Roo]
|
||||
C4[Custom OpenAI-compatible clients]
|
||||
BROWSER[Browser Dashboard]
|
||||
end
|
||||
|
||||
subgraph Router[OmniRoute Local Process]
|
||||
API[V1 Compatibility API\n/v1/*]
|
||||
DASH[Dashboard + Management API\n/api/*]
|
||||
CORE[SSE + Translation Core\nopen-sse + src/sse]
|
||||
DB[(db.json)]
|
||||
UDB[(usage.json + log.txt)]
|
||||
end
|
||||
|
||||
subgraph Upstreams[Upstream Providers]
|
||||
P1[OAuth Providers\nClaude/Codex/Gemini/Qwen/iFlow/GitHub/Kiro/Cursor/Antigravity]
|
||||
P2[API Key Providers\nOpenAI/Anthropic/OpenRouter/GLM/Kimi/MiniMax\nDeepSeek/Groq/xAI/Mistral/Perplexity\nTogether/Fireworks/Cerebras/Cohere/NVIDIA]
|
||||
P3[Compatible Nodes\nOpenAI-compatible / Anthropic-compatible]
|
||||
end
|
||||
|
||||
subgraph Cloud[Optional Cloud Sync]
|
||||
CLOUD[Cloud Sync Endpoint\nNEXT_PUBLIC_CLOUD_URL]
|
||||
end
|
||||
|
||||
C1 --> API
|
||||
C2 --> API
|
||||
C3 --> API
|
||||
C4 --> API
|
||||
BROWSER --> DASH
|
||||
|
||||
API --> CORE
|
||||
DASH --> DB
|
||||
CORE --> DB
|
||||
CORE --> UDB
|
||||
|
||||
CORE --> P1
|
||||
CORE --> P2
|
||||
CORE --> P3
|
||||
|
||||
DASH --> CLOUD
|
||||
```
|
||||
|
||||
## Основни компоненти по време на изпълнение
|
||||
|
||||
## 1) API и слой за маршрутизиране (Маршрути на приложението Next.js)
|
||||
|
||||
Основни директории:
|
||||
|
||||
- `src/app/api/v1/*` и `src/app/api/v1beta/*` за API за съвместимост
|
||||
- `src/app/api/*` за API за управление/конфигуриране
|
||||
- Следващото пренаписване в `next.config.mjs` преобразува `/v1/*` в `/api/v1/*`
|
||||
|
||||
Важни пътища за съвместимост:
|
||||
|
||||
- `src/app/api/v1/chat/completions/route.ts`
|
||||
- `src/app/api/v1/messages/route.ts`
|
||||
- `src/app/api/v1/responses/route.ts`
|
||||
- `src/app/api/v1/models/route.ts` — включва потребителски модели с `custom: true`
|
||||
- `src/app/api/v1/embeddings/route.ts` — генериране на вграждане (6 доставчика)
|
||||
- `src/app/api/v1/images/generations/route.ts` — генериране на изображения (4+ доставчици, вкл. Antigravity/Nebius)
|
||||
- `src/app/api/v1/messages/count_tokens/route.ts`
|
||||
- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — специален чат за всеки доставчик
|
||||
- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — специални вграждания за всеки доставчик
|
||||
- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — специални изображения за всеки доставчик
|
||||
- `src/app/api/v1beta/models/route.ts`
|
||||
- `src/app/api/v1beta/models/[...path]/route.ts`
|
||||
|
||||
Домейни за управление:
|
||||
|
||||
- Удостоверяване/настройки: `src/app/api/auth/*`, `src/app/api/settings/*`
|
||||
- Доставчици/връзки: `src/app/api/providers*`
|
||||
- Възли на доставчик: `src/app/api/provider-nodes*`
|
||||
- Персонализирани модели: `src/app/api/provider-models` (GET/POST/DELETE)
|
||||
- Каталог с модели: `src/app/api/models/catalog` (GET)
|
||||
- Прокси конфигурация: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST)
|
||||
- OAuth: `src/app/api/oauth/*`
|
||||
- Ключове/псевдоними/комбота/цени: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing`
|
||||
- Използване: `src/app/api/usage/*`
|
||||
- Синхронизиране/облак: `src/app/api/sync/*`, `src/app/api/cloud/*`
|
||||
- Помощни инструменти за CLI: `src/app/api/cli-tools/*`
|
||||
- IP филтър: `src/app/api/settings/ip-filter` (GET/PUT)
|
||||
- Бюджет за мислене: `src/app/api/settings/thinking-budget` (GET/PUT)
|
||||
- Системна подкана: `src/app/api/settings/system-prompt` (GET/PUT)
|
||||
- Сесии: `src/app/api/sessions` (GET)
|
||||
- Ограничения на скоростта: `src/app/api/rate-limits` (GET)
|
||||
- Устойчивост: `src/app/api/resilience` (GET/PATCH) — профили на доставчик, прекъсвач, състояние на ограничение на скоростта
|
||||
- Нулиране на устойчивостта: `src/app/api/resilience/reset` (POST) — нулиране на прекъсвачи + охлаждане
|
||||
- Кеш статистики: `src/app/api/cache/stats` (ПОЛУЧАВАНЕ/ИЗТРИВАНЕ)
|
||||
- Наличност на модела: `src/app/api/models/availability` (GET/POST)
|
||||
- Телеметрия: `src/app/api/telemetry/summary` (GET)
|
||||
- Бюджет: `src/app/api/usage/budget` (GET/POST)
|
||||
- Резервни вериги: `src/app/api/fallback/chains` (GET/POST/DELETE)
|
||||
- Одит за съответствие: `src/app/api/compliance/audit-log` (GET)
|
||||
- Стойности: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
|
||||
- Правила: `src/app/api/policies` (GET/POST)
|
||||
|
||||
## 2) SSE + ядро за превод
|
||||
|
||||
Основни модули на потока:
|
||||
|
||||
- Запис: `src/sse/handlers/chat.ts`
|
||||
- Основна оркестрация: `open-sse/handlers/chatCore.ts`
|
||||
- Адаптери за изпълнение на доставчика: `open-sse/executors/*`
|
||||
- Откриване на формат/конфигурация на доставчика: `open-sse/services/provider.ts`
|
||||
- Разбор/разрешаване на модела: `src/sse/services/model.ts`, `open-sse/services/model.ts`
|
||||
- Резервна логика на акаунта: `open-sse/services/accountFallback.ts`
|
||||
- Регистър на преводите: `open-sse/translator/index.ts`
|
||||
- Трансформации на потока: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts`
|
||||
- Извличане/нормализиране на използването: `open-sse/utils/usageTracking.ts`
|
||||
- Мислен анализатор на етикети: `open-sse/utils/thinkTagParser.ts`
|
||||
- Манипулатор за вграждане: `open-sse/handlers/embeddings.ts`
|
||||
- Регистър на доставчика на вграждане: `open-sse/config/embeddingRegistry.ts`
|
||||
- Манипулатор за генериране на изображения: `open-sse/handlers/imageGeneration.ts`
|
||||
- Регистър на доставчика на изображения: `open-sse/config/imageRegistry.ts`
|
||||
- Саниране на отговора: `open-sse/handlers/responseSanitizer.ts`
|
||||
- Нормализация на ролята: `open-sse/services/roleNormalizer.ts`
|
||||
|
||||
Услуги (бизнес логика):
|
||||
|
||||
- Избор/точкуване на акаунт: `open-sse/services/accountSelector.ts`
|
||||
- Управление на жизнения цикъл на контекста: `open-sse/services/contextManager.ts`
|
||||
- Налагане на IP филтър: `open-sse/services/ipFilter.ts`
|
||||
- Проследяване на сесии: `open-sse/services/sessionManager.ts`
|
||||
- Искане за дедупликация: `open-sse/services/signatureCache.ts`
|
||||
- Системно бързо инжектиране: `open-sse/services/systemPrompt.ts`
|
||||
- Мислещо управление на бюджета: `open-sse/services/thinkingBudget.ts`
|
||||
- Маршрутизиране на модела със заместващи знаци: `open-sse/services/wildcardRouter.ts`
|
||||
- Управление на лимита на скоростта: `open-sse/services/rateLimitManager.ts`
|
||||
- Прекъсвач: `open-sse/services/circuitBreaker.ts`
|
||||
|
||||
Модули на ниво домейн:
|
||||
|
||||
- Наличност на модела: `src/lib/domain/modelAvailability.ts`
|
||||
- Правила/бюджети за разходите: `src/lib/domain/costRules.ts`
|
||||
- Резервна политика: `src/lib/domain/fallbackPolicy.ts`
|
||||
- Комбо резолвер: `src/lib/domain/comboResolver.ts`
|
||||
- Правила за блокиране: `src/lib/domain/lockoutPolicy.ts`
|
||||
- Механизъм за правила: `src/domain/policyEngine.ts` — централизирано блокиране → бюджет → резервна оценка
|
||||
- Каталог с кодове за грешки: `src/lib/domain/errorCodes.ts`
|
||||
- ID на заявката: `src/lib/domain/requestId.ts`
|
||||
- Време за изчакване на извличане: `src/lib/domain/fetchTimeout.ts`
|
||||
- Заявка за телеметрия: `src/lib/domain/requestTelemetry.ts`
|
||||
- Съответствие/одит: `src/lib/domain/compliance/index.ts`
|
||||
- Евал бегач: `src/lib/domain/evalRunner.ts`
|
||||
- Устойчивост на състоянието на домейна: `src/lib/db/domainState.ts` — SQLite CRUD за резервни вериги, бюджети, история на разходите, състояние на блокиране, прекъсвачи
|
||||
|
||||
Модули за доставчик на OAuth (12 отделни файла под `src/lib/oauth/providers/`):
|
||||
|
||||
- Индекс на регистъра: `src/lib/oauth/providers/index.ts`
|
||||
- Индивидуални доставчици: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `iflow.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts`
|
||||
- Тънка обвивка: `src/lib/oauth/providers.ts` — повторно експортиране от отделни модули
|
||||
|
||||
## 3) Слой за устойчивост
|
||||
|
||||
Основно състояние DB:
|
||||
|
||||
- `src/lib/localDb.ts`
|
||||
- файл: `${DATA_DIR}/db.json` (или `$XDG_CONFIG_HOME/omniroute/db.json`, когато е зададено, в противен случай `~/.omniroute/db.json`)
|
||||
- обекти: providerConnections, providerNodes, modelAliases, комбинации, apiKeys, настройки, ценообразуване, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt**
|
||||
|
||||
DB за използване:
|
||||
|
||||
- `src/lib/usageDb.ts`
|
||||
- файлове: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`
|
||||
- следва същата основна политика за директория като `localDb` (`DATA_DIR`, след това `XDG_CONFIG_HOME/omniroute`, когато е зададено)
|
||||
- разложен на фокусирани подмодули: `migrations.ts`, `usageHistory.ts`, `costCalculator.ts`, `usageStats.ts`, `callLogs.ts`
|
||||
|
||||
DB на състоянието на домейна (SQLite):
|
||||
|
||||
- `src/lib/db/domainState.ts` — CRUD операции за състояние на домейна
|
||||
- Таблици (създадени в `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers`
|
||||
- Модел на кеша за запис: Картите в паметта са авторитетни по време на изпълнение; мутациите се записват синхронно в SQLite; състоянието се възстановява от DB при студен старт
|
||||
|
||||
## 4) Удостоверяване + повърхности за сигурност
|
||||
|
||||
- Удостоверяване на бисквитките на таблото за управление: `src/proxy.ts`, `src/app/api/auth/login/route.ts`
|
||||
- Генериране/проверка на API ключ: `src/shared/utils/apiKey.ts`
|
||||
- Тайните на доставчика се запазват в `providerConnections` записи
|
||||
- Поддръжка на изходящ прокси чрез `open-sse/utils/proxyFetch.ts` (env vars) и `open-sse/utils/networkProxy.ts` (конфигурируем за всеки доставчик или глобално)
|
||||
|
||||
## 5) Синхронизиране в облак
|
||||
|
||||
- Инициализация на планировчика: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`
|
||||
- Периодична задача: `src/shared/services/cloudSyncScheduler.ts`
|
||||
- Контролен маршрут: `src/app/api/sync/cloud/route.ts`
|
||||
|
||||
## Жизнен цикъл на заявка (`/v1/chat/completions`)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant Client as CLI/SDK Client
|
||||
participant Route as /api/v1/chat/completions
|
||||
participant Chat as src/sse/handlers/chat
|
||||
participant Core as open-sse/handlers/chatCore
|
||||
participant Model as Model Resolver
|
||||
participant Auth as Credential Selector
|
||||
participant Exec as Provider Executor
|
||||
participant Prov as Upstream Provider
|
||||
participant Stream as Stream Translator
|
||||
participant Usage as usageDb
|
||||
|
||||
Client->>Route: POST /v1/chat/completions
|
||||
Route->>Chat: handleChat(request)
|
||||
Chat->>Model: parse/resolve model or combo
|
||||
|
||||
alt Combo model
|
||||
Chat->>Chat: iterate combo models (handleComboChat)
|
||||
end
|
||||
|
||||
Chat->>Auth: getProviderCredentials(provider)
|
||||
Auth-->>Chat: active account + tokens/api key
|
||||
|
||||
Chat->>Core: handleChatCore(body, modelInfo, credentials)
|
||||
Core->>Core: detect source format
|
||||
Core->>Core: translate request to target format
|
||||
Core->>Exec: execute(provider, transformedBody)
|
||||
Exec->>Prov: upstream API call
|
||||
Prov-->>Exec: SSE/JSON response
|
||||
Exec-->>Core: response + metadata
|
||||
|
||||
alt 401/403
|
||||
Core->>Exec: refreshCredentials()
|
||||
Exec-->>Core: updated tokens
|
||||
Core->>Exec: retry request
|
||||
end
|
||||
|
||||
Core->>Stream: translate/normalize stream to client format
|
||||
Stream-->>Client: SSE chunks / JSON response
|
||||
|
||||
Stream->>Usage: extract usage + persist history/log
|
||||
```
|
||||
|
||||
## Комбо + Резервен поток на акаунт
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Incoming model string] --> B{Is combo name?}
|
||||
B -- Yes --> C[Load combo models sequence]
|
||||
B -- No --> D[Single model path]
|
||||
|
||||
C --> E[Try model N]
|
||||
E --> F[Resolve provider/model]
|
||||
D --> F
|
||||
|
||||
F --> G[Select account credentials]
|
||||
G --> H{Credentials available?}
|
||||
H -- No --> I[Return provider unavailable]
|
||||
H -- Yes --> J[Execute request]
|
||||
|
||||
J --> K{Success?}
|
||||
K -- Yes --> L[Return response]
|
||||
K -- No --> M{Fallback-eligible error?}
|
||||
|
||||
M -- No --> N[Return error]
|
||||
M -- Yes --> O[Mark account unavailable cooldown]
|
||||
O --> P{Another account for provider?}
|
||||
P -- Yes --> G
|
||||
P -- No --> Q{In combo with next model?}
|
||||
Q -- Yes --> E
|
||||
Q -- No --> R[Return all unavailable]
|
||||
```
|
||||
|
||||
Резервните решения се управляват от `open-sse/services/accountFallback.ts` с помощта на кодове за състояние и евристика за съобщения за грешка.
|
||||
|
||||
## Жизнен цикъл на внедряване на OAuth и опресняване на токени
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI as Dashboard UI
|
||||
participant OAuth as /api/oauth/[provider]/[action]
|
||||
participant ProvAuth as Provider Auth Server
|
||||
participant DB as localDb
|
||||
participant Test as /api/providers/[id]/test
|
||||
participant Exec as Provider Executor
|
||||
|
||||
UI->>OAuth: GET authorize or device-code
|
||||
OAuth->>ProvAuth: create auth/device flow
|
||||
ProvAuth-->>OAuth: auth URL or device code payload
|
||||
OAuth-->>UI: flow data
|
||||
|
||||
UI->>OAuth: POST exchange or poll
|
||||
OAuth->>ProvAuth: token exchange/poll
|
||||
ProvAuth-->>OAuth: access/refresh tokens
|
||||
OAuth->>DB: createProviderConnection(oauth data)
|
||||
OAuth-->>UI: success + connection id
|
||||
|
||||
UI->>Test: POST /api/providers/[id]/test
|
||||
Test->>Exec: validate credentials / optional refresh
|
||||
Exec-->>Test: valid or refreshed token info
|
||||
Test->>DB: update status/tokens/errors
|
||||
Test-->>UI: validation result
|
||||
```
|
||||
|
||||
Опресняването по време на трафик на живо се изпълнява вътре в `open-sse/handlers/chatCore.ts` чрез изпълнител `refreshCredentials()`.
|
||||
|
||||
## Жизнен цикъл на Cloud Sync (Активиране / Синхронизиране / Деактивиране)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI as Endpoint Page UI
|
||||
participant Sync as /api/sync/cloud
|
||||
participant DB as localDb
|
||||
participant Cloud as External Cloud Sync
|
||||
participant Claude as ~/.claude/settings.json
|
||||
|
||||
UI->>Sync: POST action=enable
|
||||
Sync->>DB: set cloudEnabled=true
|
||||
Sync->>DB: ensure API key exists
|
||||
Sync->>Cloud: POST /sync/{machineId} (providers/aliases/combos/keys)
|
||||
Cloud-->>Sync: sync result
|
||||
Sync->>Cloud: GET /{machineId}/v1/verify
|
||||
Sync-->>UI: enabled + verification status
|
||||
|
||||
UI->>Sync: POST action=sync
|
||||
Sync->>Cloud: POST /sync/{machineId}
|
||||
Cloud-->>Sync: remote data
|
||||
Sync->>DB: update newer local tokens/status
|
||||
Sync-->>UI: synced
|
||||
|
||||
UI->>Sync: POST action=disable
|
||||
Sync->>DB: set cloudEnabled=false
|
||||
Sync->>Cloud: DELETE /sync/{machineId}
|
||||
Sync->>Claude: switch ANTHROPIC_BASE_URL back to local (if needed)
|
||||
Sync-->>UI: disabled
|
||||
```
|
||||
|
||||
Периодичното синхронизиране се задейства от `CloudSyncScheduler`, когато облакът е активиран.
|
||||
|
||||
## Модел на данни и карта за съхранение
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
SETTINGS ||--o{ PROVIDER_CONNECTION : controls
|
||||
PROVIDER_NODE ||--o{ PROVIDER_CONNECTION : backs_compatible_provider
|
||||
PROVIDER_CONNECTION ||--o{ USAGE_ENTRY : emits_usage
|
||||
|
||||
SETTINGS {
|
||||
boolean cloudEnabled
|
||||
number stickyRoundRobinLimit
|
||||
boolean requireLogin
|
||||
string password_hash
|
||||
string fallbackStrategy
|
||||
json rateLimitDefaults
|
||||
json providerProfiles
|
||||
}
|
||||
|
||||
PROVIDER_CONNECTION {
|
||||
string id
|
||||
string provider
|
||||
string authType
|
||||
string name
|
||||
number priority
|
||||
boolean isActive
|
||||
string apiKey
|
||||
string accessToken
|
||||
string refreshToken
|
||||
string expiresAt
|
||||
string testStatus
|
||||
string lastError
|
||||
string rateLimitedUntil
|
||||
json providerSpecificData
|
||||
}
|
||||
|
||||
PROVIDER_NODE {
|
||||
string id
|
||||
string type
|
||||
string name
|
||||
string prefix
|
||||
string apiType
|
||||
string baseUrl
|
||||
}
|
||||
|
||||
MODEL_ALIAS {
|
||||
string alias
|
||||
string targetModel
|
||||
}
|
||||
|
||||
COMBO {
|
||||
string id
|
||||
string name
|
||||
string[] models
|
||||
}
|
||||
|
||||
API_KEY {
|
||||
string id
|
||||
string name
|
||||
string key
|
||||
string machineId
|
||||
}
|
||||
|
||||
USAGE_ENTRY {
|
||||
string provider
|
||||
string model
|
||||
number prompt_tokens
|
||||
number completion_tokens
|
||||
string connectionId
|
||||
string timestamp
|
||||
}
|
||||
|
||||
CUSTOM_MODEL {
|
||||
string id
|
||||
string name
|
||||
string providerId
|
||||
}
|
||||
|
||||
PROXY_CONFIG {
|
||||
string global
|
||||
json providers
|
||||
}
|
||||
|
||||
IP_FILTER {
|
||||
string mode
|
||||
string[] allowlist
|
||||
string[] blocklist
|
||||
}
|
||||
|
||||
THINKING_BUDGET {
|
||||
string mode
|
||||
number customBudget
|
||||
string effortLevel
|
||||
}
|
||||
|
||||
SYSTEM_PROMPT {
|
||||
boolean enabled
|
||||
string prompt
|
||||
string position
|
||||
}
|
||||
```
|
||||
|
||||
Файлове за физическо съхранение:
|
||||
|
||||
- основно състояние: `${DATA_DIR}/db.json` (или `$XDG_CONFIG_HOME/omniroute/db.json`, когато е зададено, в противен случай `~/.omniroute/db.json`)
|
||||
- статистика за използване: `${DATA_DIR}/usage.json`
|
||||
- Редове на заявката: `${DATA_DIR}/log.txt`
|
||||
- незадължителни сесии за преводач/заявка за отстраняване на грешки: `<repo>/logs/...`
|
||||
|
||||
## Топология на разполагане
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph LocalHost[Developer Host]
|
||||
CLI[CLI Tools]
|
||||
Browser[Dashboard Browser]
|
||||
end
|
||||
|
||||
subgraph ContainerOrProcess[OmniRoute Runtime]
|
||||
Next[Next.js Server\nPORT=20128]
|
||||
Core[SSE Core + Executors]
|
||||
MainDB[(db.json)]
|
||||
UsageDB[(usage.json/log.txt)]
|
||||
end
|
||||
|
||||
subgraph External[External Services]
|
||||
Providers[AI Providers]
|
||||
SyncCloud[Cloud Sync Service]
|
||||
end
|
||||
|
||||
CLI --> Next
|
||||
Browser --> Next
|
||||
Next --> Core
|
||||
Next --> MainDB
|
||||
Core --> MainDB
|
||||
Core --> UsageDB
|
||||
Core --> Providers
|
||||
Next --> SyncCloud
|
||||
```
|
||||
|
||||
## Съпоставяне на модул (критично за вземане на решения)
|
||||
|
||||
### Модули за маршрут и API
|
||||
|
||||
- `src/app/api/v1/*`, `src/app/api/v1beta/*`: API за съвместимост
|
||||
- `src/app/api/v1/providers/[provider]/*`: специални маршрути за всеки доставчик (чат, вграждания, изображения)
|
||||
- `src/app/api/providers*`: доставчик CRUD, валидиране, тестване
|
||||
- `src/app/api/provider-nodes*`: персонализирано съвместимо управление на възли
|
||||
- `src/app/api/provider-models`: персонализирано управление на модела (CRUD)
|
||||
- `src/app/api/models/catalog`: пълен модел каталог API (всички типове групирани по доставчик)
|
||||
- `src/app/api/oauth/*`: OAuth/код на устройство протича
|
||||
- `src/app/api/keys*`: жизнен цикъл на локален API ключ
|
||||
- `src/app/api/models/alias`: управление на псевдоними
|
||||
- `src/app/api/combos*`: резервно комбо управление
|
||||
- `src/app/api/pricing`: ценообразуване отменя за изчисляване на разходите
|
||||
- `src/app/api/settings/proxy`: конфигурация на прокси (GET/PUT/DELETE)
|
||||
- `src/app/api/settings/proxy/test`: тест за изходяща прокси връзка (POST)
|
||||
- `src/app/api/usage/*`: API за използване и регистрационни файлове
|
||||
- `src/app/api/sync/*` + `src/app/api/cloud/*`: облачно синхронизиране и помощници в облака
|
||||
- `src/app/api/cli-tools/*`: локални писатели/контролери на CLI конфигурация
|
||||
- `src/app/api/settings/ip-filter`: списък с разрешени/блокирани IP адреси (GET/PUT)
|
||||
- `src/app/api/settings/thinking-budget`: конфигурация на бюджета на мислещ токен (GET/PUT)
|
||||
- `src/app/api/settings/system-prompt`: глобална системна подкана (GET/PUT)
|
||||
- `src/app/api/sessions`: списък с активни сесии (GET)
|
||||
- `src/app/api/rate-limits`: състояние на ограничение на скоростта на сметка (GET)
|
||||
|
||||
### Ядро за маршрутизиране и изпълнение
|
||||
|
||||
- `src/sse/handlers/chat.ts`: анализ на заявка, комбо обработка, цикъл за избор на акаунт
|
||||
- `open-sse/handlers/chatCore.ts`: превод, изпращане на изпълнителя, обработка на повторен опит/опресняване, настройка на потока
|
||||
- `open-sse/executors/*`: специфично за доставчика поведение на мрежата и формата
|
||||
|
||||
### Регистър за преводи и конвертори на формати
|
||||
|
||||
- `open-sse/translator/index.ts`: регистър на преводача и оркестрация
|
||||
- Заявка за преводачи: `open-sse/translator/request/*`
|
||||
- Преводачи на отговори: `open-sse/translator/response/*`
|
||||
- Константи на формата: `open-sse/translator/formats.ts`
|
||||
|
||||
### Постоянство
|
||||
|
||||
- `src/lib/localDb.ts`: постоянна конфигурация/състояние
|
||||
- `src/lib/usageDb.ts`: хронология на използването и регистрационни файлове на текущи заявки
|
||||
|
||||
## Покритие на изпълнител на доставчик (стратегически модел)
|
||||
|
||||
Всеки доставчик има специализиран изпълнител, разширяващ `BaseExecutor` (в `open-sse/executors/base.ts`), който осигурява изграждане на URL адрес, изграждане на заглавка, повторен опит с експоненциално забавяне, кукички за опресняване на идентификационни данни и метода за оркестрация `execute()`.
|
||||
|
||||
| Изпълнител | Доставчик(и) | Специална обработка |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
|
||||
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Конфигурация на динамичен URL/заглавие за доставчик |
|
||||
| `AntigravityExecutor` | Google Антигравитация | Идентификационни номера на персонализирани проекти/сесии, повторен опит след анализ |
|
||||
| `CodexExecutor` | OpenAI Codex | Вкарва системни инструкции, налага усилие за разсъждение |
|
||||
| `CursorExecutor` | Курсор IDE | ConnectRPC протокол, Protobuf кодиране, подписване на заявка чрез контролна сума |
|
||||
| `GithubExecutor` | Копилот на GitHub | Опресняване на Copilot token, заглавки, имитиращи VSCode |
|
||||
| `KiroExecutor` | AWS CodeWhisperer/Киро | AWS EventStream двоичен формат → SSE конвертиране |
|
||||
| `GeminiCLIExecutor` | Gemini CLI | Цикъл на опресняване на Google OAuth токен |
|
||||
|
||||
Всички други доставчици (включително персонализирани съвместими възли) използват `DefaultExecutor`.
|
||||
|
||||
## Матрица за съвместимост на доставчика
|
||||
|
||||
| Доставчик | Формат | Удостоверяване | Поток | Непоточно | Опресняване на токена | API за използване |
|
||||
| ----------------- | --------------- | ------------------------------ | ---------------- | --------- | --------------------- | ---------------------------- |
|
||||
| Клод | Клод | API ключ / OAuth | ✅ | ✅ | ✅ | ⚠️ Само администратор |
|
||||
| Близнаци | близнаци | API ключ / OAuth | ✅ | ✅ | ✅ | ⚠️ Облачна конзола |
|
||||
| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Облачна конзола |
|
||||
| Антигравитация | антигравитация | OAuth | ✅ | ✅ | ✅ | ✅ API с пълна квота |
|
||||
| OpenAI | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Кодекс | openai-отговори | OAuth | ✅ принуден | ❌ | ✅ | ✅ Ограничения на скоростта |
|
||||
| Копилот на GitHub | openai | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Моментни снимки на квоти |
|
||||
| Курсор | курсор | Персонализирана контролна сума | ✅ | ✅ | ❌ | ❌ |
|
||||
| Киро | киро | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Ограничения за използване |
|
||||
| Куен | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ По заявка |
|
||||
| iFlow | openai | OAuth (основен) | ✅ | ✅ | ✅ | ⚠️ По заявка |
|
||||
| OpenRouter | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| GLM/Кими/МиниМакс | Клод | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| DeepSeek | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Groq | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| xAI (Grok) | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Мистрал | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Недоумение | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Заедно AI | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Фойерверки AI | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Мозъци | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Cohere | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| NVIDIA NIM | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
|
||||
## Обхват на превод на формат
|
||||
|
||||
Откритите изходни формати включват:
|
||||
|
||||
- `openai`
|
||||
- `openai-responses`
|
||||
- `claude`
|
||||
- `gemini`
|
||||
|
||||
Целевите формати включват:
|
||||
|
||||
- OpenAI чат/Отговори
|
||||
- Клод
|
||||
- Gemini/Gemini-CLI/Антигравитационен плик
|
||||
- Киро
|
||||
- Курсор
|
||||
|
||||
Преводите използват **OpenAI като хъб формат** — всички реализации преминават през OpenAI като междинен:
|
||||
|
||||
```
|
||||
Source Format → OpenAI (hub) → Target Format
|
||||
```
|
||||
|
||||
Преводите се избират динамично въз основа на формата на изходния полезен товар и целевия формат на доставчика.
|
||||
|
||||
Допълнителни слоеве за обработка в тръбопровода за превод:
|
||||
|
||||
- **Дефектификация на отговора** — Премахва нестандартните полета от отговорите във формат OpenAI (както стрийминг, така и без стрийминг), за да се гарантира стриктно съответствие с SDK
|
||||
- **Нормализиране на ролята** — Преобразува `developer` → `system` за цели, които не са OpenAI; обединява `system` → `user` за модели, които отхвърлят системната роля (GLM, ERNIE)
|
||||
- **Извличане на мислен етикет** — Анализира `<think>...</think>` блокове от съдържание в поле `reasoning_content`
|
||||
- **Структуриран изход** — Преобразува OpenAI `response_format.json_schema` в `responseMimeType` + `responseSchema` на Gemini
|
||||
|
||||
## Поддържани API крайни точки
|
||||
|
||||
| Крайна точка | Формат | Манипулатор |
|
||||
| -------------------------------------------------- | ------------------------- | ------------------------------------------------------------------ |
|
||||
| `POST /v1/chat/completions` | OpenAI чат | `src/sse/handlers/chat.ts` |
|
||||
| `POST /v1/messages` | Съобщения на Клод | Същият манипулатор (автоматично разпознат) |
|
||||
| `POST /v1/responses` | OpenAI отговори | `open-sse/handlers/responsesHandler.ts` |
|
||||
| `POST /v1/embeddings` | OpenAI вграждания | `open-sse/handlers/embeddings.ts` |
|
||||
| `GET /v1/embeddings` | Списък на модели | API маршрут |
|
||||
| `POST /v1/images/generations` | OpenAI изображения | `open-sse/handlers/imageGeneration.ts` |
|
||||
| `GET /v1/images/generations` | Списък на модели | API маршрут |
|
||||
| `POST /v1/providers/{provider}/chat/completions` | OpenAI чат | Специализиран за всеки доставчик с валидиране на модел |
|
||||
| `POST /v1/providers/{provider}/embeddings` | OpenAI вграждания | Специализиран за всеки доставчик с валидиране на модел |
|
||||
| `POST /v1/providers/{provider}/images/generations` | OpenAI изображения | Специализиран за всеки доставчик с валидиране на модел |
|
||||
| `POST /v1/messages/count_tokens` | Клод Токен Брой | API маршрут |
|
||||
| `GET /v1/models` | Списък с модели на OpenAI | API маршрут (чат + вграждане + изображение + потребителски модели) |
|
||||
| `GET /api/models/catalog` | Каталог | Всички модели, групирани по доставчик + тип |
|
||||
| `POST /v1beta/models/*:streamGenerateContent` | Родом от Близнаци | API маршрут |
|
||||
| `GET/PUT/DELETE /api/settings/proxy` | Прокси конфигурация | Конфигурация на мрежов прокси |
|
||||
| `POST /api/settings/proxy/test` | Прокси връзка | Крайна точка на прокси тест за изправност/свързаност |
|
||||
| `GET/POST/DELETE /api/provider-models` | Персонализирани модели | Персонализирано управление на модели за всеки доставчик |
|
||||
|
||||
## Обходен манипулатор
|
||||
|
||||
Обходният манипулатор (`open-sse/utils/bypassHandler.ts`) прихваща известни заявки за „изхвърляне“ от Claude CLI — пингове за загряване, извличане на заглавия и преброяване на токени — и връща **фалшив отговор**, без да консумира токени на доставчика нагоре по веригата. Това се задейства само когато `User-Agent` съдържа `claude-cli`.
|
||||
|
||||
## Тръбопровод за регистратор на заявки
|
||||
|
||||
Регистраторът на заявки (`open-sse/utils/requestLogger.ts`) осигурява 7-етапен конвейер за регистриране на грешки, деактивиран по подразбиране, активиран чрез `ENABLE_REQUEST_LOGS=true`:
|
||||
|
||||
```
|
||||
1_req_client.json → 2_req_source.json → 3_req_openai.json → 4_req_target.json
|
||||
→ 5_res_provider.txt → 6_res_openai.txt → 7_res_client.txt
|
||||
```
|
||||
|
||||
Файловете се записват в `<repo>/logs/<session>/` за всяка сесия на заявка.
|
||||
|
||||
## Режими на отказ и устойчивост
|
||||
|
||||
## 1) Наличност на акаунт/доставчик
|
||||
|
||||
- изчакване на акаунта на доставчика при преходни/скоростни/удостоверителни грешки
|
||||
- резервен акаунт преди неуспешна заявка
|
||||
- резервен комбиниран модел, когато пътят на текущия модел/доставчик е изчерпан
|
||||
|
||||
## 2) Изтичане на токена
|
||||
|
||||
- предварителна проверка и опресняване с повторен опит за опресняващи доставчици
|
||||
- 401/403 повторен опит след опит за опресняване в основния път
|
||||
|
||||
## 3) Безопасност на потока
|
||||
|
||||
- контролер на потоци, който се изключва
|
||||
- поток за превод с промиване в края на потока и обработка на `[DONE]`
|
||||
- резервна оценка на използването, когато липсват метаданни за използване на доставчика
|
||||
|
||||
## 4) Влошаване на облачната синхронизация
|
||||
|
||||
- появяват се грешки при синхронизиране, но локалното изпълнение продължава
|
||||
- планировчикът има логика с възможност за повторен опит, но периодичното изпълнение в момента извиква синхронизиране с един опит по подразбиране
|
||||
|
||||
## 5) Цялост на данните
|
||||
|
||||
- Миграция/поправка на DB форма за липсващи ключове
|
||||
- повредени предпазни мерки за нулиране на JSON за localDb и usageDb
|
||||
|
||||
## Наблюдаемост и оперативни сигнали
|
||||
|
||||
Източници на видимост по време на изпълнение:
|
||||
|
||||
- регистрационни файлове на конзолата от `src/sse/utils/logger.ts`
|
||||
- агрегати за използване на заявка в `usage.json`
|
||||
- влизане на състоянието на текстова заявка `log.txt`
|
||||
- незадължителни дълбоки регистрационни файлове за заявка/превод под `logs/`, когато `ENABLE_REQUEST_LOGS=true`
|
||||
- крайни точки за използване на таблото за управление (`/api/usage/*`) за потребление на UI
|
||||
|
||||
## Граници, чувствителни към сигурността
|
||||
|
||||
- JWT тайна (`JWT_SECRET`) защитава проверката/подписването на бисквитките на таблото за управление
|
||||
- Първоначалната резервна парола (`INITIAL_PASSWORD`, по подразбиране `123456`) трябва да бъде заменена при реални внедрявания
|
||||
- API ключ HMAC secret (`API_KEY_SECRET`) защитава генерирания локален формат на API ключ
|
||||
- Тайните на доставчика (API ключове/токени) се съхраняват в локалната база данни и трябва да бъдат защитени на ниво файлова система
|
||||
- Крайните точки за синхронизиране в облак разчитат на удостоверяване на API ключ + семантика на идентификатор на машина
|
||||
|
||||
## Околна среда и матрица за изпълнение
|
||||
|
||||
Променливите на средата, използвани активно от кода:
|
||||
|
||||
- Приложение/удостоверяване: `JWT_SECRET`, `INITIAL_PASSWORD`
|
||||
- Съхранение: `DATA_DIR`
|
||||
- Съвместимо поведение на възел: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE`
|
||||
- Допълнителна отмяна на базата за съхранение (Linux/macOS, когато `DATA_DIR` не е зададен): `XDG_CONFIG_HOME`
|
||||
- Хеширане на сигурността: `API_KEY_SECRET`, `MACHINE_ID_SALT`
|
||||
- Регистриране: `ENABLE_REQUEST_LOGS`
|
||||
- Синхронизиране/облачно URL адресиране: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL`
|
||||
- Изходящ прокси: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` и варианти с малки букви
|
||||
- Флагове за функция SOCKS5: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY`
|
||||
- Помощници за платформа/време на изпълнение (не специфична за приложението конфигурация): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME`
|
||||
|
||||
## Известни архитектурни бележки
|
||||
|
||||
1. `usageDb` и `localDb` сега споделят една и съща основна политика за директория (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) с мигриране на наследени файлове.
|
||||
2. `/api/v1/route.ts` връща списък със статичен модел и не е основният източник на модели, използван от `/v1/models`.
|
||||
3. Request logger записва пълни заглавки/тяло, когато е разрешено; третира регистрационната директория като чувствителна.
|
||||
4. Поведението в облака зависи от правилния `NEXT_PUBLIC_BASE_URL` и достижимостта на крайната точка на облака.
|
||||
5. Директорията `open-sse/` е публикувана като `@omniroute/open-sse` **npm workspace package**. Изходният код го импортира чрез `@omniroute/open-sse/...` (разрешено от Next.js `transpilePackages`). Пътищата на файловете в този документ все още използват името на директорията `open-sse/` за последователност.
|
||||
6. Диаграмите в таблото за управление използват **Recharts** (базирани на SVG) за достъпни, интерактивни аналитични визуализации (стълбовидни диаграми на използването на модела, таблици с разбивка на доставчиците с проценти на успех).
|
||||
7. E2E тестовете използват **Playwright** (`tests/e2e/`), изпълняват се чрез `npm run test:e2e`. Модулните тестове използват **Node.js test runner** (`tests/unit/`), изпълняват се чрез `npm run test:plan3`. Изходният код под `src/` е **TypeScript** (`.ts`/`.tsx`); работното пространство `open-sse/` остава JavaScript (`.js`).
|
||||
8. Страницата с настройки е организирана в 5 раздела: Сигурност, Маршрутизиране (6 глобални стратегии: първо попълване, кръгъл-робин, p2c, произволна, най-малко използвана, оптимизирана по отношение на разходите), Устойчивост (ограничения на скоростта за редактиране, прекъсвач, политики), AI (мислещ бюджет, системна подкана, кеш за подкана), Разширени (прокси).
|
||||
|
||||
## Контролен списък за оперативна проверка
|
||||
|
||||
- Създаване от източник: `npm run build`
|
||||
- Изграждане на Docker изображение: `docker build -t omniroute .`
|
||||
- Стартирайте услугата и проверете:
|
||||
- `GET /api/settings`
|
||||
- `GET /api/v1/models`
|
||||
- CLI целеви базов URL трябва да бъде `http://<host>:20128/v1`, когато `PORT=20128`
|
||||
@@ -0,0 +1,589 @@
|
||||
# omniroute — Документация на кодовата база
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](../pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](../es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](../fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](../it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](../ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](../zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](../de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](../in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](../th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](../uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](../ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](../ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](../vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](../bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](../da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](../fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](../he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](../hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](../id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](../ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](../ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](../nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](../no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](../pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](../ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](../pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](../sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](../sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](../phi/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
> Изчерпателно, удобно за начинаещи ръководство за **omniroute** прокси рутер с изкуствен интелект с множество доставчици.
|
||||
|
||||
---
|
||||
|
||||
## 1. Какво е omniroute?
|
||||
|
||||
omniroute е **прокси рутер**, който се намира между AI клиенти (Claude CLI, Codex, Cursor IDE и др.) и AI доставчици (Anthropic, Google, OpenAI, AWS, GitHub и др.). Решава един голям проблем:
|
||||
|
||||
> **Различните AI клиенти говорят различни „езици“ (API формати) и различните доставчици на AI също очакват различни „езици“.** omniroute превежда автоматично между тях.
|
||||
|
||||
Мислете за това като за универсален преводач в Обединените нации - всеки делегат може да говори всеки език и преводачът го преобразува за всеки друг делегат.
|
||||
|
||||
---
|
||||
|
||||
## 2. Преглед на архитектурата
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph Clients
|
||||
A[Claude CLI]
|
||||
B[Codex]
|
||||
C[Cursor IDE]
|
||||
D[OpenAI-compatible]
|
||||
end
|
||||
|
||||
subgraph omniroute
|
||||
E[Handler Layer]
|
||||
F[Translator Layer]
|
||||
G[Executor Layer]
|
||||
H[Services Layer]
|
||||
end
|
||||
|
||||
subgraph Providers
|
||||
I[Anthropic Claude]
|
||||
J[Google Gemini]
|
||||
K[OpenAI / Codex]
|
||||
L[GitHub Copilot]
|
||||
M[AWS Kiro]
|
||||
N[Antigravity]
|
||||
O[Cursor API]
|
||||
end
|
||||
|
||||
A --> E
|
||||
B --> E
|
||||
C --> E
|
||||
D --> E
|
||||
E --> F
|
||||
F --> G
|
||||
G --> I
|
||||
G --> J
|
||||
G --> K
|
||||
G --> L
|
||||
G --> M
|
||||
G --> N
|
||||
G --> O
|
||||
H -.-> E
|
||||
H -.-> G
|
||||
```
|
||||
|
||||
### Основен принцип: Превод на централно ниво
|
||||
|
||||
Всички преводи на формати преминават през **OpenAI формат като център**:
|
||||
|
||||
```
|
||||
Client Format → [OpenAI Hub] → Provider Format (request)
|
||||
Provider Format → [OpenAI Hub] → Client Format (response)
|
||||
```
|
||||
|
||||
Това означава, че имате нужда само от **N преводачи** (по един на формат) вместо от **N²** (всяка двойка).
|
||||
|
||||
---
|
||||
|
||||
## 3. Структура на проекта
|
||||
|
||||
```
|
||||
omniroute/
|
||||
├── open-sse/ ← Core proxy library (portable, framework-agnostic)
|
||||
│ ├── index.js ← Main entry point, exports everything
|
||||
│ ├── config/ ← Configuration & constants
|
||||
│ ├── executors/ ← Provider-specific request execution
|
||||
│ ├── handlers/ ← Request handling orchestration
|
||||
│ ├── services/ ← Business logic (auth, models, fallback, usage)
|
||||
│ ├── translator/ ← Format translation engine
|
||||
│ │ ├── request/ ← Request translators (8 files)
|
||||
│ │ ├── response/ ← Response translators (7 files)
|
||||
│ │ └── helpers/ ← Shared translation utilities (6 files)
|
||||
│ └── utils/ ← Utility functions
|
||||
├── src/ ← Application layer (Express/Worker runtime)
|
||||
│ ├── app/ ← Web UI, API routes, middleware
|
||||
│ ├── lib/ ← Database, auth, and shared library code
|
||||
│ ├── mitm/ ← Man-in-the-middle proxy utilities
|
||||
│ ├── models/ ← Database models
|
||||
│ ├── shared/ ← Shared utilities (wrappers around open-sse)
|
||||
│ ├── sse/ ← SSE endpoint handlers
|
||||
│ └── store/ ← State management
|
||||
├── data/ ← Runtime data (credentials, logs)
|
||||
│ └── provider-credentials.json (external credentials override, gitignored)
|
||||
└── tester/ ← Test utilities
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Разбивка модул по модул
|
||||
|
||||
### 4.1 Конфигурация (`open-sse/config/`)
|
||||
|
||||
**Единственият източник на истина** за всички конфигурации на доставчика.
|
||||
|
||||
| Файл | Цел |
|
||||
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `constants.ts` | `PROVIDERS` обект с основни URL адреси, идентификационни данни за OAuth (по подразбиране), заглавки и системни подкани по подразбиране за всеки доставчик. Също така дефинира `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG` и `SKIP_PATTERNS`. |
|
||||
| `credentialLoader.ts` | Зарежда външни идентификационни данни от `data/provider-credentials.json` и ги обединява върху твърдо кодираните настройки по подразбиране в `PROVIDERS`. Пази тайните извън контрола на източника, като същевременно поддържа обратна съвместимост. |
|
||||
| `providerModels.ts` | Централен регистър на моделите: псевдоними на доставчика на карти → ID на модела. Функции като `getModels()`, `getProviderByAlias()`. |
|
||||
| `codexInstructions.ts` | Системни инструкции, инжектирани в заявките на Codex (ограничения за редактиране, правила на пясъчника, правила за одобрение). |
|
||||
| `defaultThinkingSignature.ts` | „Мислещи“ подписи по подразбиране за модели Claude и Gemini. |
|
||||
| `ollamaModels.ts` | Дефиниция на схема за локални модели Ollama (име, размер, семейство, квантуване). |
|
||||
|
||||
#### Поток на зареждане на идентификационни данни
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["App starts"] --> B["constants.ts defines PROVIDERS\nwith hardcoded defaults"]
|
||||
B --> C{"data/provider-credentials.json\nexists?"}
|
||||
C -->|Yes| D["credentialLoader reads JSON"]
|
||||
C -->|No| E["Use hardcoded defaults"]
|
||||
D --> F{"For each provider in JSON"}
|
||||
F --> G{"Provider exists\nin PROVIDERS?"}
|
||||
G -->|No| H["Log warning, skip"]
|
||||
G -->|Yes| I{"Value is object?"}
|
||||
I -->|No| J["Log warning, skip"]
|
||||
I -->|Yes| K["Merge clientId, clientSecret,\ntokenUrl, authUrl, refreshUrl"]
|
||||
K --> F
|
||||
H --> F
|
||||
J --> F
|
||||
F -->|Done| L["PROVIDERS ready with\nmerged credentials"]
|
||||
E --> L
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Изпълнители (`open-sse/executors/`)
|
||||
|
||||
Изпълнителите капсулират **специфична за доставчика логика**, използвайки **стратегически модел**. Всеки изпълнител замества основните методи, ако е необходимо.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class BaseExecutor {
|
||||
+buildUrl(model, stream, options)
|
||||
+buildHeaders(credentials, stream, body)
|
||||
+transformRequest(body, model, stream, credentials)
|
||||
+execute(url, options)
|
||||
+shouldRetry(status, error)
|
||||
+refreshCredentials(credentials, log)
|
||||
}
|
||||
|
||||
class DefaultExecutor {
|
||||
+refreshCredentials()
|
||||
}
|
||||
|
||||
class AntigravityExecutor {
|
||||
+buildUrl()
|
||||
+buildHeaders()
|
||||
+transformRequest()
|
||||
+shouldRetry()
|
||||
+refreshCredentials()
|
||||
}
|
||||
|
||||
class CursorExecutor {
|
||||
+buildUrl()
|
||||
+buildHeaders()
|
||||
+transformRequest()
|
||||
+parseResponse()
|
||||
+generateChecksum()
|
||||
}
|
||||
|
||||
class KiroExecutor {
|
||||
+buildUrl()
|
||||
+buildHeaders()
|
||||
+transformRequest()
|
||||
+parseEventStream()
|
||||
+refreshCredentials()
|
||||
}
|
||||
|
||||
BaseExecutor <|-- DefaultExecutor
|
||||
BaseExecutor <|-- AntigravityExecutor
|
||||
BaseExecutor <|-- CursorExecutor
|
||||
BaseExecutor <|-- KiroExecutor
|
||||
BaseExecutor <|-- CodexExecutor
|
||||
BaseExecutor <|-- GeminiCLIExecutor
|
||||
BaseExecutor <|-- GithubExecutor
|
||||
```
|
||||
|
||||
| Изпълнител | Доставчик | Ключови специализации |
|
||||
| ---------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `base.ts` | — | Абстрактна база: изграждане на URL, заглавки, логика за повторен опит, опресняване на идентификационни данни |
|
||||
| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Генерично опресняване на OAuth токен за стандартни доставчици |
|
||||
| `antigravity.ts` | Google Cloud Code | Генериране на идентификатор на проект/сесия, резервен URL адрес с множество URL адреси, персонализирано анализиране на повторен опит от съобщения за грешка („нулиране след 2h7m23s“) |
|
||||
| `cursor.ts` | Курсор IDE | **Най-сложни**: SHA-256 контролна сума auth, Protobuf кодиране на заявка, двоичен EventStream → SSE отговор анализ |
|
||||
| `codex.ts` | OpenAI Codex | Вкарва системни инструкции, управлява нивата на мислене, премахва неподдържаните параметри |
|
||||
| `gemini-cli.ts` | Google Gemini CLI | Изграждане на персонализиран URL (`streamGenerateContent`), опресняване на Google OAuth токен |
|
||||
| `github.ts` | Копилот на GitHub | Система с двоен токен (GitHub OAuth + Copilot token), имитиране на заглавката на VSCode |
|
||||
| `kiro.ts` | AWS CodeWhisperer | Двоичен анализ на AWS EventStream, рамки за събития AMZN, оценка на токена |
|
||||
| `index.ts` | — | Фабрика: картографира името на доставчика → клас изпълнител, с резервен вариант по подразбиране |
|
||||
|
||||
---
|
||||
|
||||
### 4.3 Манипулатори (`open-sse/handlers/`)
|
||||
|
||||
**Слоят за оркестрация** — координира превода, изпълнението, поточното предаване и обработката на грешки.
|
||||
|
||||
| Файл | Цел |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `chatCore.ts` | **Централен оркестратор** (~600 реда). Обработва пълния жизнен цикъл на заявката: откриване на формат → превод → изпращане на изпълнител → стрийминг/не-стрийминг отговор → опресняване на токена → обработка на грешки → регистриране на използването. |
|
||||
| `responsesHandler.ts` | Адаптер за API за отговори на OpenAI: преобразува формата на отговорите → Завършвания на чат → изпраща до `chatCore` → конвертира SSE обратно във формат на отговорите. |
|
||||
| `embeddings.ts` | Манипулатор за генериране на вграждане: разрешава модел на вграждане → доставчик, изпраща до API на доставчика, връща съвместим с OpenAI отговор за вграждане. Поддържа 6+ доставчици. |
|
||||
| `imageGeneration.ts` | Манипулатор за генериране на изображения: разрешава модел на изображение → доставчик, поддържа режими, съвместими с OpenAI, Gemini-image (Антигравитация) и резервни (Nebius). Връща base64 или URL изображения. |
|
||||
|
||||
#### Жизнен цикъл на заявка (chatCore.ts)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client
|
||||
participant chatCore
|
||||
participant Translator
|
||||
participant Executor
|
||||
participant Provider
|
||||
|
||||
Client->>chatCore: Request (any format)
|
||||
chatCore->>chatCore: Detect source format
|
||||
chatCore->>chatCore: Check bypass patterns
|
||||
chatCore->>chatCore: Resolve model & provider
|
||||
chatCore->>Translator: Translate request (source → OpenAI → target)
|
||||
chatCore->>Executor: Get executor for provider
|
||||
Executor->>Executor: Build URL, headers, transform request
|
||||
Executor->>Executor: Refresh credentials if needed
|
||||
Executor->>Provider: HTTP fetch (streaming or non-streaming)
|
||||
|
||||
alt Streaming
|
||||
Provider-->>chatCore: SSE stream
|
||||
chatCore->>chatCore: Pipe through SSE transform stream
|
||||
Note over chatCore: Transform stream translates<br/>each chunk: target → OpenAI → source
|
||||
chatCore-->>Client: Translated SSE stream
|
||||
else Non-streaming
|
||||
Provider-->>chatCore: JSON response
|
||||
chatCore->>Translator: Translate response
|
||||
chatCore-->>Client: Translated JSON
|
||||
end
|
||||
|
||||
alt Error (401, 429, 500...)
|
||||
chatCore->>Executor: Retry with credential refresh
|
||||
chatCore->>chatCore: Account fallback logic
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.4 Услуги (`open-sse/services/`)
|
||||
|
||||
Бизнес логика, която поддържа манипулаторите и изпълнителите.
|
||||
|
||||
| Файл | Цел |
|
||||
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `provider.ts` | **Откриване на формат** (`detectFormat`): анализира структурата на тялото на заявката, за да идентифицира форматите Claude/OpenAI/Gemini/Antigravity/Responses (включва `max_tokens` евристика за Claude). Също така: изграждане на URL адреси, изграждане на заглавки, нормализиране на конфигурацията на мислене. Поддържа `openai-compatible-*` и `anthropic-compatible-*` динамични доставчици. |
|
||||
| `model.ts` | Разбор на низ на модел (`claude/model-name` → `{provider: "claude", model: "model-name"}`), разрешаване на псевдоними с откриване на сблъсък, дезинфекция на входа (отхвърля преминаване на пътя/контролни знаци) и разрешаване на информация за модела с поддръжка на асинхронно получаване на псевдоними. |
|
||||
| `accountFallback.ts` | Обработка на ограничение на скоростта: експоненциално забавяне (1s → 2s → 4s → макс. 2min), управление на изчакване на акаунта, класификация на грешките (кои грешки задействат резервно или не). |
|
||||
| `tokenRefresh.ts` | Опресняване на OAuth токена за **всеки доставчик**: Google (Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). Включва кеш за дедупликация на обещание по време на полет и повторен опит с експоненциално забавяне. |
|
||||
| `combo.ts` | **Комбинирани модели**: вериги от резервни модели. Ако модел A се провали с допустима грешка за резервен вариант, опитайте модел B, след това C и т.н. Връща действителните кодове за състояние нагоре по веригата. |
|
||||
| `usage.ts` | Извлича данни за квоти/използване от API на доставчика (квоти на GitHub Copilot, квоти на модела на Antigravity, ограничения на скоростта на Codex, разбивки на използването на Kiro, настройки на Claude). |
|
||||
| `accountSelector.ts` | Интелигентен избор на акаунт с алгоритъм за точкуване: взема предвид приоритет, здравословно състояние, кръгова позиция и състояние на изчакване, за да избере оптималния акаунт за всяка заявка. |
|
||||
| `contextManager.ts` | Управление на жизнения цикъл на контекста на заявката: създава и проследява контекстни обекти на заявка с метаданни (идентификатор на заявка, времеви клейма, информация за доставчика) за отстраняване на грешки и регистриране. |
|
||||
| `ipFilter.ts` | IP-базиран контрол на достъпа: поддържа разрешени и блокирани режими. Валидира клиентския IP адрес спрямо конфигурирани правила, преди да обработи API заявки. |
|
||||
| `sessionManager.ts` | Проследяване на сесии с пръстов отпечатък на клиента: проследява активни сесии с помощта на хеширани клиентски идентификатори, следи броя на заявките и предоставя показатели за сесиите. |
|
||||
| `signatureCache.ts` | Кеш за дедупликация, базиран на подписи на заявки: предотвратява дублиране на заявки чрез кеширане на подписи на скорошни заявки и връщане на кеширани отговори за идентични заявки в рамките на времеви прозорец. |
|
||||
| `systemPrompt.ts` | Инжектиране на глобална системна подкана: добавя пред или добавя конфигурируема системна подкана към всички заявки, с обработка на съвместимостта за всеки доставчик. |
|
||||
| `thinkingBudget.ts` | Управление на бюджета на токените за разсъждение: поддържа режими за преминаване, автоматичен (конфигурация на лентово мислене), персонализиран (фиксиран бюджет) и адаптивен (мащабиран според сложността) режими за контролиране на токени за мислене/разсъждение. |
|
||||
| `wildcardRouter.ts` | Маршрутизиране на модела със заместващи знаци: разрешава шаблони със заместващи знаци (напр. `*/claude-*`) до конкретни двойки доставчик/модел въз основа на наличност и приоритет. |
|
||||
|
||||
#### Дедупликация на опресняване на токени
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant R1 as Request 1
|
||||
participant R2 as Request 2
|
||||
participant Cache as refreshPromiseCache
|
||||
participant OAuth as OAuth Provider
|
||||
|
||||
R1->>Cache: getAccessToken("gemini", token)
|
||||
Cache->>Cache: No in-flight promise
|
||||
Cache->>OAuth: Start refresh
|
||||
R2->>Cache: getAccessToken("gemini", token)
|
||||
Cache->>Cache: Found in-flight promise
|
||||
Cache-->>R2: Return existing promise
|
||||
OAuth-->>Cache: New access token
|
||||
Cache-->>R1: New access token
|
||||
Cache-->>R2: Same access token (shared)
|
||||
Cache->>Cache: Delete cache entry
|
||||
```
|
||||
|
||||
#### Резервна държавна машина на акаунта
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Active
|
||||
Active --> Error: Request fails (401/429/500)
|
||||
Error --> Cooldown: Apply backoff
|
||||
Cooldown --> Active: Cooldown expires
|
||||
Active --> Active: Request succeeds (reset backoff)
|
||||
|
||||
state Error {
|
||||
[*] --> ClassifyError
|
||||
ClassifyError --> ShouldFallback: Rate limit / Auth / Transient
|
||||
ClassifyError --> NoFallback: 400 Bad Request
|
||||
}
|
||||
|
||||
state Cooldown {
|
||||
[*] --> ExponentialBackoff
|
||||
ExponentialBackoff: Level 0 = 1s
|
||||
ExponentialBackoff: Level 1 = 2s
|
||||
ExponentialBackoff: Level 2 = 4s
|
||||
ExponentialBackoff: Max = 2min
|
||||
}
|
||||
```
|
||||
|
||||
#### Комбиниран модел верига
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Request with\ncombo model"] --> B["Model A"]
|
||||
B -->|"2xx Success"| C["Return response"]
|
||||
B -->|"429/401/500"| D{"Fallback\neligible?"}
|
||||
D -->|Yes| E["Model B"]
|
||||
D -->|No| F["Return error"]
|
||||
E -->|"2xx Success"| C
|
||||
E -->|"429/401/500"| G{"Fallback\neligible?"}
|
||||
G -->|Yes| H["Model C"]
|
||||
G -->|No| F
|
||||
H -->|"2xx Success"| C
|
||||
H -->|"Fail"| I["All failed →\nReturn last status"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.5 Преводач (`open-sse/translator/`)
|
||||
|
||||
**Машината за превод на формати**, използваща саморегистрираща се плъгин система.
|
||||
|
||||
#### Архитектура
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "Request Translation"
|
||||
A["Claude → OpenAI"]
|
||||
B["Gemini → OpenAI"]
|
||||
C["Antigravity → OpenAI"]
|
||||
D["OpenAI Responses → OpenAI"]
|
||||
E["OpenAI → Claude"]
|
||||
F["OpenAI → Gemini"]
|
||||
G["OpenAI → Kiro"]
|
||||
H["OpenAI → Cursor"]
|
||||
end
|
||||
|
||||
subgraph "Response Translation"
|
||||
I["Claude → OpenAI"]
|
||||
J["Gemini → OpenAI"]
|
||||
K["Kiro → OpenAI"]
|
||||
L["Cursor → OpenAI"]
|
||||
M["OpenAI → Claude"]
|
||||
N["OpenAI → Antigravity"]
|
||||
O["OpenAI → Responses"]
|
||||
end
|
||||
```
|
||||
|
||||
| Указател | Файлове | Описание |
|
||||
| ------------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `request/` | 8 преводачи | Преобразувайте тела на заявки между формати. Всеки файл се саморегистрира чрез `register(from, to, fn)` при импортиране. |
|
||||
| `response/` | 7 преводачи | Преобразувайте поточно предавани отговори между формати. Обработва SSE типове събития, мисловни блокове, извиквания на инструменти. |
|
||||
| `helpers/` | 6 помощника | Споделени помощни програми: `claudeHelper` (извличане на системни подкани, мислеща конфигурация), `geminiHelper` (съпоставяне на части/съдържание), `openaiHelper` (филтриране на формат), `toolCallHelper` (генериране на ID, инжектиране на липсващ отговор), `maxTokensHelper`, `responsesApiHelper`. |
|
||||
| `index.ts` | — | Механизъм за превод: `translateRequest()`, `translateResponse()`, управление на състоянието, регистър. |
|
||||
| `formats.ts` | — | Константи на формата: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. |
|
||||
|
||||
#### Ключов дизайн: Саморегистриращи се добавки
|
||||
|
||||
```javascript
|
||||
// Each translator file calls register() on import:
|
||||
import { register } from "../index.js";
|
||||
register("claude", "openai", translateClaudeToOpenAI);
|
||||
|
||||
// The index.js imports all translator files, triggering registration:
|
||||
import "./request/claude-to-openai.js"; // ← self-registers
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.6 Помощни средства (`open-sse/utils/`)
|
||||
|
||||
| Файл | Цел |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `error.ts` | Изграждане на отговор при грешка (съвместим с OpenAI формат), анализиране на грешка нагоре по веригата, извличане на времето за повторен опит на Antigravity от съобщения за грешка, поточно предаване на грешка на SSE. |
|
||||
| `stream.ts` | **SSE Transform Stream** — основният тръбопровод за стрийминг. Два режима: `TRANSLATE` (превод в пълен формат) и `PASSTHROUGH` (нормализиране + извличане на използването). Управлява буфериране на парчета, оценка на използването, проследяване на дължината на съдържанието. Екземплярите на енкодер/декодер на поток избягват споделено състояние. |
|
||||
| `streamHelpers.ts` | Помощни програми за SSE на ниско ниво: `parseSSELine` (толерантни към бели интервали), `hasValuableContent` (филтрира празни парчета за OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (сериализация на SSE, съобразена с формата с `perf_metrics` почистване). |
|
||||
| `usageTracking.ts` | Извличане на използване на токени от всеки формат (Claude/OpenAI/Gemini/Responses), оценка с отделни съотношения на инструмент/съобщение char-per-token, добавяне на буфер (марж за безопасност от 2000 токена), филтриране на специфично за формат поле, конзолно регистриране с ANSI цветове. |
|
||||
| `requestLogger.ts` | Регистриране на искания на базата на файл (включване чрез `ENABLE_REQUEST_LOGS=true`). Създава сесийни папки с номерирани файлове: `1_req_client.json` → `7_res_client.txt`. Всички I/O са асинхронни (задействай и забрави). Маскира чувствителните заглавки. |
|
||||
| `bypassHandler.ts` | Прихваща специфични модели от Claude CLI (извличане на заглавие, загряване, броене) и връща фалшиви отговори, без да се обажда на доставчик. Поддържа както стрийминг, така и не стрийминг. Умишлено ограничен до Claude CLI обхват. |
|
||||
| `networkProxy.ts` | Разрешава URL адрес на изходящ прокси за даден доставчик с приоритет: специфична за доставчика конфигурация → глобална конфигурация → променливи на средата (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Поддържа `NO_PROXY` изключения. Кешира конфигурацията за 30s. |
|
||||
|
||||
#### SSE Streaming Pipeline
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"]
|
||||
B --> C["Buffer lines\n(split on newline)"]
|
||||
C --> D["parseSSELine()\n(trim whitespace, parse JSON)"]
|
||||
D --> E{"Mode?"}
|
||||
E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"]
|
||||
E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"]
|
||||
F --> H["hasValuableContent()\nfilter empty chunks"]
|
||||
G --> H
|
||||
H -->|"Has content"| I["extractUsage()\ntrack token counts"]
|
||||
H -->|"Empty"| J["Skip chunk"]
|
||||
I --> K["formatSSE()\nserialize + clean perf_metrics"]
|
||||
K --> L["TextEncoder\n(per-stream instance)"]
|
||||
L --> M["Enqueue to\nclient stream"]
|
||||
|
||||
style A fill:#f9f,stroke:#333
|
||||
style M fill:#9f9,stroke:#333
|
||||
```
|
||||
|
||||
#### Структура на сесията на регистратора на заявка
|
||||
|
||||
```
|
||||
logs/
|
||||
└── claude_gemini_claude-sonnet_20260208_143045/
|
||||
├── 1_req_client.json ← Raw client request
|
||||
├── 2_req_source.json ← After initial conversion
|
||||
├── 3_req_openai.json ← OpenAI intermediate format
|
||||
├── 4_req_target.json ← Final target format
|
||||
├── 5_res_provider.txt ← Provider SSE chunks (streaming)
|
||||
├── 5_res_provider.json ← Provider response (non-streaming)
|
||||
├── 6_res_openai.txt ← OpenAI intermediate chunks
|
||||
├── 7_res_client.txt ← Client-facing SSE chunks
|
||||
└── 6_error.json ← Error details (if any)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.7 Приложен слой (`src/`)
|
||||
|
||||
| Указател | Цел |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| `src/app/` | Уеб потребителски интерфейс, API маршрути, Express междинен софтуер, манипулатори за обратно извикване OAuth |
|
||||
| `src/lib/` | Достъп до база данни (`localDb.ts`, `usageDb.ts`), удостоверяване, споделено |
|
||||
| `src/mitm/` | Прокси помощни програми Man-in-the-middle за прихващане на трафик на доставчик |
|
||||
| `src/models/` | Дефиниции на модел на база данни |
|
||||
| `src/shared/` | Обвивки около open-sse функции (доставчик, поток, грешка и др.) |
|
||||
| `src/sse/` | SSE манипулатори на крайни точки, които свързват библиотеката open-sse към експресни маршрути |
|
||||
| `src/store/` | Управление на състоянието на приложението |
|
||||
|
||||
#### Известни API маршрути
|
||||
|
||||
| Маршрут | Методи | Цел |
|
||||
| --------------------------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
||||
| `/api/provider-models` | ПОЛУЧАВАНЕ/ПУБЛИКУВАНЕ/ИЗТРИВАНЕ | CRUD за потребителски модели на доставчик |
|
||||
| `/api/models/catalog` | ВЗЕМЕТЕ | Обобщен каталог на всички модели (чат, вграждане, изображение, персонализирани), групирани по доставчик |
|
||||
| `/api/settings/proxy` | ПОЛУЧАВАНЕ/ПОСТАВЯНЕ/ИЗТРИВАНЕ | Конфигурация на йерархичен изходящ прокси (`global/providers/combos/keys`) |
|
||||
| `/api/settings/proxy/test` | ПУБЛИКАЦИЯ | Потвърждава прокси свързаността и връща публичен IP/латентност |
|
||||
| `/v1/providers/[provider]/chat/completions` | ПУБЛИКАЦИЯ | Специализирани завършвания на чат за всеки доставчик с валидиране на модел |
|
||||
| `/v1/providers/[provider]/embeddings` | ПУБЛИКАЦИЯ | Специализирани вграждания за всеки доставчик с валидиране на модел |
|
||||
| `/v1/providers/[provider]/images/generations` | ПУБЛИКАЦИЯ | Специално генериране на изображения за всеки доставчик с валидиране на модел |
|
||||
| `/api/settings/ip-filter` | ВЗЕМИ/ПОСТАВИ | Управление на списък с разрешени/блокирани IP |
|
||||
| `/api/settings/thinking-budget` | ВЗЕМИ/ПОСТАВИ | Конфигурация на бюджета на токена за разсъждение (пропускане/автоматично/персонализирано/адаптивно) |
|
||||
| `/api/settings/system-prompt` | ВЗЕМИ/ПОСТАВИ | Бързо инжектиране на глобална система за всички заявки |
|
||||
| `/api/sessions` | ВЗЕМЕТЕ | Проследяване на активна сесия и показатели |
|
||||
| `/api/rate-limits` | ВЗЕМЕТЕ | Състояние на ограничение на лимита по сметка |
|
||||
|
||||
---
|
||||
|
||||
## 5. Ключови модели на дизайн
|
||||
|
||||
### 5.1 Hub-and-Spoke превод
|
||||
|
||||
Всички формати се превеждат през **OpenAI формат като център**. Добавянето на нов доставчик изисква само писане на **една двойка** преводачи (към/от OpenAI), а не на N двойки.
|
||||
|
||||
### 5.2 Модел на стратегия за изпълнител
|
||||
|
||||
Всеки доставчик има специален клас изпълнител, наследен от `BaseExecutor`. Фабриката в `executors/index.ts` избира правилния по време на изпълнение.
|
||||
|
||||
### 5.3 Саморегистрираща се плъгин система
|
||||
|
||||
Модулите за преводач се регистрират при импортиране чрез `register()`. Добавянето на нов преводач е просто създаване на файл и импортирането му.
|
||||
|
||||
### 5.4 Резервен акаунт с експоненциално отстъпление
|
||||
|
||||
Когато доставчикът върне 429/401/500, системата може да превключи към следващия акаунт, прилагайки експоненциално охлаждане (1s → 2s → 4s → max 2min).
|
||||
|
||||
### Комбинирани вериги за модели 5.5
|
||||
|
||||
„Комбо“ групира множество низове `provider/model`. Ако първият не успее, автоматично се върнете към следващия.
|
||||
|
||||
### 5.6 Поточен превод с пълно състояние
|
||||
|
||||
Преводът на отговор поддържа състоянието в SSE блокове (проследяване на мислещ блок, натрупване на извикване на инструмент, индексиране на блок съдържание) чрез механизма `initState()`.
|
||||
|
||||
### 5.7 Буфер за безопасност при използване
|
||||
|
||||
Добавя се буфер от 2000 токена към отчетеното използване, за да се предотврати достигането на ограниченията на контекстните прозорци на клиентите поради натоварване от системни подкани и превод на формати.
|
||||
|
||||
---
|
||||
|
||||
## 6. Поддържани формати
|
||||
|
||||
| Формат | Посока | Идентификатор |
|
||||
| ------------------------- | -------------- | ------------------ |
|
||||
| Завършвания на OpenAI чат | източник + цел | `openai` |
|
||||
| OpenAI Responses API | източник + цел | `openai-responses` |
|
||||
| Антропичен Клод | източник + цел | `claude` |
|
||||
| Google Gemini | източник + цел | `gemini` |
|
||||
| Google Gemini CLI | само цел | `gemini-cli` |
|
||||
| Антигравитация | източник + цел | `antigravity` |
|
||||
| AWS Киро | само цел | `kiro` |
|
||||
| Курсор | само цел | `cursor` |
|
||||
|
||||
---
|
||||
|
||||
## 7. Поддържани доставчици
|
||||
|
||||
| Доставчик | Метод за удостоверяване | Изпълнител | Основни бележки |
|
||||
| ------------------------ | -------------------------------- | --------------- | -------------------------------------------------- |
|
||||
| Антропичен Клод | API ключ или OAuth | По подразбиране | Използва `x-api-key` заглавка |
|
||||
| Google Gemini | API ключ или OAuth | По подразбиране | Използва `x-goog-api-key` заглавка |
|
||||
| Google Gemini CLI | OAuth | GeminiCLI | Използва `streamGenerateContent` крайна точка |
|
||||
| Антигравитация | OAuth | Антигравитация | Multi-URL резервен, персонализиран повторен анализ |
|
||||
| OpenAI | API ключ | По подразбиране | Удостоверяване на стандартен носител |
|
||||
| Кодекс | OAuth | Кодекс | Инжектира системни инструкции, управлява мисленето |
|
||||
| Копилот на GitHub | OAuth + Copilot token | Github | Двоен токен, имитираща заглавка на VSCode |
|
||||
| Киро (AWS) | AWS SSO OIDC или социални | Киро | Парсинг на двоичен EventStream |
|
||||
| Курсор IDE | Контролна сума за удостоверяване | Курсор | Protobuf кодиране, SHA-256 контролни суми |
|
||||
| Куен | OAuth | По подразбиране | Стандартно удостоверяване |
|
||||
| iFlow | OAuth (основен + носител) | По подразбиране | Заглавка за двойно удостоверяване |
|
||||
| OpenRouter | API ключ | По подразбиране | Удостоверяване на стандартен носител |
|
||||
| GLM, Kimi, MiniMax | API ключ | По подразбиране | Съвместим с Claude, използвайте `x-api-key` |
|
||||
| `openai-compatible-*` | API ключ | По подразбиране | Динамично: всяка крайна точка, съвместима с OpenAI |
|
||||
| `anthropic-compatible-*` | API ключ | По подразбиране | Динамично: всяка крайна точка, съвместима с Claude |
|
||||
|
||||
---
|
||||
|
||||
## 8. Резюме на потока от данни
|
||||
|
||||
### Заявка за поточно предаване
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Client"] --> B["detectFormat()"]
|
||||
B --> C["translateRequest()\nsource → OpenAI → target"]
|
||||
C --> D["Executor\nbuildUrl + buildHeaders"]
|
||||
D --> E["fetch(providerURL)"]
|
||||
E --> F["createSSEStream()\nTRANSLATE mode"]
|
||||
F --> G["parseSSELine()"]
|
||||
G --> H["translateResponse()\ntarget → OpenAI → source"]
|
||||
H --> I["extractUsage()\n+ addBuffer"]
|
||||
I --> J["formatSSE()"]
|
||||
J --> K["Client receives\ntranslated SSE"]
|
||||
K --> L["logUsage()\nsaveRequestUsage()"]
|
||||
```
|
||||
|
||||
### Заявка без поточно предаване
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Client"] --> B["detectFormat()"]
|
||||
B --> C["translateRequest()\nsource → OpenAI → target"]
|
||||
C --> D["Executor.execute()"]
|
||||
D --> E["translateResponse()\ntarget → OpenAI → source"]
|
||||
E --> F["Return JSON\nresponse"]
|
||||
```
|
||||
|
||||
### Байпасен поток (Claude CLI)
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Claude CLI request"] --> B{"Match bypass\npattern?"}
|
||||
B -->|"Title/Warmup/Count"| C["Generate fake\nOpenAI response"]
|
||||
B -->|"No match"| D["Normal flow"]
|
||||
C --> E["Translate to\nsource format"]
|
||||
E --> F["Return without\ncalling provider"]
|
||||
```
|
||||
@@ -0,0 +1,77 @@
|
||||
# OmniRoute — Галерия с функции на таблото
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../FEATURES.md) | 🇧🇷 [Português (Brasil)](../pt-BR/FEATURES.md) | 🇪🇸 [Español](../es/FEATURES.md) | 🇫🇷 [Français](../fr/FEATURES.md) | 🇮🇹 [Italiano](../it/FEATURES.md) | 🇷🇺 [Русский](../ru/FEATURES.md) | 🇨🇳 [中文 (简体)](../zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](../de/FEATURES.md) | 🇮🇳 [हिन्दी](../in/FEATURES.md) | 🇹🇭 [ไทย](../th/FEATURES.md) | 🇺🇦 [Українська](../uk-UA/FEATURES.md) | 🇸🇦 [العربية](../ar/FEATURES.md) | 🇯🇵 [日本語](../ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](../vi/FEATURES.md) | 🇧🇬 [Български](../bg/FEATURES.md) | 🇩🇰 [Dansk](../da/FEATURES.md) | 🇫🇮 [Suomi](../fi/FEATURES.md) | 🇮🇱 [עברית](../he/FEATURES.md) | 🇭🇺 [Magyar](../hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](../id/FEATURES.md) | 🇰🇷 [한국어](../ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](../ms/FEATURES.md) | 🇳🇱 [Nederlands](../nl/FEATURES.md) | 🇳🇴 [Norsk](../no/FEATURES.md) | 🇵🇹 [Português (Portugal)](../pt/FEATURES.md) | 🇷🇴 [Română](../ro/FEATURES.md) | 🇵🇱 [Polski](../pl/FEATURES.md) | 🇸🇰 [Slovenčina](../sk/FEATURES.md) | 🇸🇪 [Svenska](../sv/FEATURES.md) | 🇵🇭 [Filipino](../phi/FEATURES.md)
|
||||
|
||||
Визуално ръководство за всеки раздел на таблото за управление OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## 🔌 Доставчици
|
||||
|
||||
Управлявайте връзките на доставчици на AI: OAuth доставчици (Claude Code, Codex, Gemini CLI), доставчици на API ключове (Groq, DeepSeek, OpenRouter) и безплатни доставчици (iFlow, Qwen, Kiro).
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🎨 Комбота
|
||||
|
||||
Създавайте комбинации за маршрутизиране на модели с 6 стратегии: първо попълване, кръгъл робин, мощност от два избора, произволна, най-малко използвана и оптимизирана по отношение на разходите. Всяка комбинация свързва няколко модела с автоматичен резервен вариант.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 📊 Анализ
|
||||
|
||||
Изчерпателни анализи на използването с потребление на токени, оценки на разходите, топлинни карти на активността, седмични диаграми на разпределение и разбивки по доставчик.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🏥 Здраве на системата
|
||||
|
||||
Мониторинг в реално време: време на работа, памет, версия, процентили на латентност (p50/p95/p99), статистика на кеша и състояния на прекъсвача на доставчика.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🔧 Площадка за преводачи
|
||||
|
||||
Четири режима за отстраняване на грешки в API преводи: **Playground** (конвертор на формати), **Chat Tester** (заявки на живо), **Test Bench** (пакетни тестове) и **Live Monitor** (поток в реално време).
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Настройки
|
||||
|
||||
Общи настройки, системно съхранение, управление на архивиране (база данни за експортиране/импортиране), външен вид (тъмен/светъл режим), сигурност (включва защита на крайна точка на API и блокиране на потребителски доставчик), маршрутизиране, устойчивост и разширена конфигурация.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🔧 CLI инструменти
|
||||
|
||||
Конфигурация с едно щракване за инструменти за кодиране на AI: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code и Antigravity.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 📝 Регистри за заявки
|
||||
|
||||
Регистриране на заявки в реално време с филтриране по доставчик, модел, акаунт и API ключ. Показва кодове за състояние, използване на токени, латентност и подробности за отговора.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🌐 Крайна точка на API
|
||||
|
||||
Вашата унифицирана крайна точка на API с разбивка на възможностите: завършвания на чат, вграждания, генериране на изображения, прекласиране, аудио транскрипция и регистрирани ключове за API.
|
||||
|
||||

|
||||
@@ -0,0 +1,219 @@
|
||||
# Отстраняване на неизправности
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](../es/TROUBLESHOOTING.md) | 🇫🇷 [Français](../fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](../bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](../ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../phi/TROUBLESHOOTING.md)
|
||||
|
||||
Често срещани проблеми и решения за OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## Бързи поправки
|
||||
|
||||
| Проблем | Решение |
|
||||
| ------------------------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| Първото влизане не работи | Проверете `INITIAL_PASSWORD` в `.env` (по подразбиране: `123456`) |
|
||||
| Таблото се отваря на грешен порт | Задайте `PORT=20128` и `NEXT_PUBLIC_BASE_URL=http://localhost:20128` |
|
||||
| Няма регистрационни файлове за заявки под `logs/` | Задайте `ENABLE_REQUEST_LOGS=true` |
|
||||
| EACCES: разрешението е отказано | Задайте `DATA_DIR=/path/to/writable/dir` да замени `~/.omniroute` |
|
||||
| Стратегията за маршрутизиране не се запазва | Актуализация до v1.4.11+ (корекция на Zod схема за постоянство на настройките) |
|
||||
|
||||
---
|
||||
|
||||
## Проблеми с доставчика
|
||||
|
||||
### „Езиковият модел не предостави съобщения“
|
||||
|
||||
**Причина:** Квотата на доставчика е изчерпана.
|
||||
|
||||
**Коригиране:**
|
||||
|
||||
1. Проверете инструмента за проследяване на квоти на таблото за управление
|
||||
2. Използвайте комбо с резервни нива
|
||||
3. Преминете към по-евтино/безплатно ниво
|
||||
|
||||
### Ограничаване на скоростта
|
||||
|
||||
**Причина:** Абонаментната квота е изчерпана.
|
||||
|
||||
**Коригиране:**
|
||||
|
||||
- Добавете резервен вариант: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
|
||||
- Използвайте GLM/MiniMax като евтино резервно копие
|
||||
|
||||
### OAuth Token е изтекъл
|
||||
|
||||
OmniRoute автоматично опреснява токените. Ако проблемите продължават:
|
||||
|
||||
1. Табло → Доставчик → Свързване отново
|
||||
2. Изтрийте и добавете отново връзката с доставчика
|
||||
|
||||
---
|
||||
|
||||
## Проблеми с облака
|
||||
|
||||
### Грешки при синхронизиране в облак
|
||||
|
||||
1. Проверете дали `BASE_URL` сочи към вашия работещ екземпляр (напр. `http://localhost:20128`)
|
||||
2. Проверете `CLOUD_URL` точки към вашата крайна точка в облака (напр. `https://omniroute.dev`)
|
||||
3. Поддържайте стойностите на `NEXT_PUBLIC_*` в съответствие със стойностите от страна на сървъра
|
||||
|
||||
### Cloud `stream=false` Връща 500
|
||||
|
||||
**Симптом:** `Unexpected token 'd'...` в крайна точка на облака за обаждания без поточно предаване.
|
||||
|
||||
**Причина:** Upstream връща SSE полезен товар, докато клиентът очаква JSON.
|
||||
|
||||
**Заобиколно решение:** Използвайте `stream=true` за директни обаждания в облака. Локалното време на изпълнение включва резервен SSE→JSON.
|
||||
|
||||
### Облакът казва Свързан, но „Невалиден API ключ“
|
||||
|
||||
1. Създайте нов ключ от локалното табло за управление (`/api/keys`)
|
||||
2. Стартирайте облачна синхронизация: Активирайте Облак → Синхронизирай сега
|
||||
3. Старите/несинхронизирани ключове все още могат да връщат `401` в облака
|
||||
|
||||
---
|
||||
|
||||
## Проблеми с Docker
|
||||
|
||||
### CLI инструментът показва, че не е инсталиран
|
||||
|
||||
1. Проверете полетата по време на изпълнение: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq`
|
||||
2. За преносим режим: използвайте целево изображение `runner-cli` (пакетни CLI)
|
||||
3. За режим на монтиране на хост: задайте `CLI_EXTRA_PATHS` и монтирайте директорията bin на хоста като само за четене
|
||||
4. Ако `installed=true` и `runnable=false`: двоичен файл е намерен, но проверката на състоянието е неуспешна
|
||||
|
||||
### Бързо валидиране по време на изпълнение
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Проблеми с разходите
|
||||
|
||||
### Високи разходи
|
||||
|
||||
1. Проверете статистическите данни за употреба в Табло → Използване
|
||||
2. Превключете основния модел на GLM/MiniMax
|
||||
3. Използвайте безплатно ниво (Gemini CLI, iFlow) за некритични задачи
|
||||
4. Задайте бюджети за разходи за API ключ: Табло за управление → API ключове → Бюджет
|
||||
|
||||
---
|
||||
|
||||
## Отстраняване на грешки
|
||||
|
||||
### Активиране на регистрационните файлове на заявките
|
||||
|
||||
Задайте `ENABLE_REQUEST_LOGS=true` във вашия `.env` файл. Дневниците се появяват в директорията `logs/`.
|
||||
|
||||
### Проверете здравето на доставчика
|
||||
|
||||
```bash
|
||||
# Health dashboard
|
||||
http://localhost:20128/dashboard/health
|
||||
|
||||
# API health check
|
||||
curl http://localhost:20128/api/monitoring/health
|
||||
```
|
||||
|
||||
### Съхранение по време на изпълнение
|
||||
|
||||
- Основно състояние: `${DATA_DIR}/db.json` (доставчици, комбинации, псевдоними, ключове, настройки)
|
||||
- Използване: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`
|
||||
- Регистрации за заявки: `<repo>/logs/...` (когато `ENABLE_REQUEST_LOGS=true`)
|
||||
|
||||
---
|
||||
|
||||
## Проблеми с прекъсвача
|
||||
|
||||
### Доставчикът остана в ОТВОРЕНО състояние
|
||||
|
||||
Когато прекъсвачът на доставчика е ОТВОРЕЕН, заявките се блокират, докато изтече времето за охлаждане.
|
||||
|
||||
**Коригиране:**
|
||||
|
||||
1. Отидете на **Табло → Настройки → Устойчивост**
|
||||
2. Проверете картата на прекъсвача на засегнатия доставчик
|
||||
3. Щракнете върху **Нулиране на всички**, за да изчистите всички прекъсвачи, или изчакайте времето за охлаждане да изтече
|
||||
4. Уверете се, че доставчикът действително е наличен, преди да нулирате
|
||||
|
||||
### Доставчикът продължава да изключва прекъсвача
|
||||
|
||||
Ако доставчик многократно влиза в ОТВОРЕНО състояние:
|
||||
|
||||
1. Проверете **Табло → Здраве → Здраве на доставчика** за модела на повреда
|
||||
2. Отидете на **Настройки → Устойчивост → Профили на доставчици** и увеличете прага на отказ
|
||||
3. Проверете дали доставчикът е променил ограниченията на API или изисква повторно удостоверяване
|
||||
4. Прегледайте телеметрията за латентност — високата латентност може да причини грешки, базирани на изчакване
|
||||
|
||||
---
|
||||
|
||||
## Проблеми с аудио транскрипцията
|
||||
|
||||
### Грешка „Неподдържан модел“.
|
||||
|
||||
- Уверете се, че използвате правилния префикс: `deepgram/nova-3` или `assemblyai/best`
|
||||
- Проверете дали доставчикът е свързан в **Табло → Доставчици**
|
||||
|
||||
### Транскрипцията се връща празна или е неуспешна
|
||||
|
||||
- Проверете поддържаните аудио формати: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`
|
||||
- Уверете се, че размерът на файла е в границите на доставчика (обикновено < 25MB)
|
||||
- Проверете валидността на API ключа на доставчика в картата на доставчика
|
||||
|
||||
---
|
||||
|
||||
## Отстраняване на грешки на преводача
|
||||
|
||||
Използвайте **Табло за управление → Преводач** за отстраняване на грешки при проблеми с превода на формат:
|
||||
|
||||
| Режим | Кога да използвате |
|
||||
| ------------------- | --------------------------------------------------------------------------------------------------------- |
|
||||
| **Детска площадка** | Сравнете входно/изходните формати един до друг — поставете неуспешна заявка, за да видите как се превежда |
|
||||
| **Чат тестер** | Изпращайте съобщения на живо и проверявайте пълния полезен товар на заявка/отговор, включително заглавки |
|
||||
| **Тестова стенда** | Изпълнете пакетни тестове в комбинации от формати, за да откриете кои преводи са нарушени |
|
||||
| **Монитор на живо** | Гледайте потока на заявките в реално време, за да уловите периодични проблеми с превода |
|
||||
|
||||
### Често срещани проблеми с формата
|
||||
|
||||
- **Мислещите етикети не се появяват** — Проверете дали целевият доставчик поддържа мисленето и настройката на бюджета за мислене
|
||||
- **Отпадане на извикванията на инструменти** — Някои преводи на формати може да премахнат неподдържаните полета; потвърдете в режим Playground
|
||||
- **Липсва системна подкана** — Клод и Джемини обработват системните подкани по различен начин; проверка на резултата за превод
|
||||
- **SDK връща необработен низ вместо обект** — Коригирано във v1.1.0: дезинфекциращото средство за отговор вече премахва нестандартните полета (`x_groq`, `usage_breakdown` и т.н.), които причиняват неуспешно валидиране на OpenAI SDK Pydantic
|
||||
- **GLM/ERNIE отхвърля `system` роля** — Коригирано във v1.1.0: нормализаторът на роли автоматично обединява системни съобщения в потребителски съобщения за несъвместими модели
|
||||
- **`developer` ролята не е разпозната** — Коригирано във v1.1.0: автоматично преобразувано в `system` за доставчици, които не са OpenAI
|
||||
- **`json_schema` не работи с Gemini** — Коригирано във v1.1.0: `response_format` сега се преобразува в `responseMimeType` + `responseSchema` на Gemini
|
||||
|
||||
---
|
||||
|
||||
## Настройки за устойчивост
|
||||
|
||||
### Автоматичното ограничение на скоростта не се задейства
|
||||
|
||||
- Автоматичното ограничение на скоростта се прилага само за доставчици на API ключове (не OAuth/абонамент)
|
||||
- Уверете се, че **Настройки → Устойчивост → Профили на доставчици** има активиран автоматичен лимит на скоростта
|
||||
- Проверете дали доставчикът връща `429` кодове за състояние или `Retry-After` заглавки
|
||||
|
||||
### Настройване на експоненциално забавяне
|
||||
|
||||
Профилите на доставчика поддържат тези настройки:
|
||||
|
||||
- **Базово забавяне** — Първоначално време на изчакване след първата повреда (по подразбиране: 1s)
|
||||
- **Максимално забавяне** — Максимално ограничение на времето за изчакване (по подразбиране: 30 секунди)
|
||||
- **Множител** — Колко да се увеличи закъснението за последователен отказ (по подразбиране: 2x)
|
||||
|
||||
### Анти-гръмотевично стадо
|
||||
|
||||
Когато много едновременни заявки попаднат на доставчик с ограничена скорост, OmniRoute използва mutex + автоматично ограничаване на скоростта, за да сериализира заявките и да предотврати каскадни грешки. Това е автоматично за доставчиците на API ключове.
|
||||
|
||||
---
|
||||
|
||||
## Все още сте заседнали?
|
||||
|
||||
- **Проблеми с GitHub**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **Архитектура**: Вижте [link](ARCHITECTURE.md) за вътрешни подробности
|
||||
- **API Reference**: Вижте [link](API_REFERENCE.md) за всички крайни точки
|
||||
- **Табло за управление на здравето**: Проверете **Табло за управление → Здраве** за състоянието на системата в реално време
|
||||
- **Преводач**: Използвайте **Табло за управление → Преводач** за отстраняване на грешки при проблеми с формата
|
||||
@@ -0,0 +1,698 @@
|
||||
# Ръководство за потребителя
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](../es/USER_GUIDE.md) | 🇫🇷 [Français](../fr/USER_GUIDE.md) | 🇮🇹 [Italiano](../it/USER_GUIDE.md) | 🇷🇺 [Русский](../ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](../de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](../in/USER_GUIDE.md) | 🇹🇭 [ไทย](../th/USER_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](../ar/USER_GUIDE.md) | 🇯🇵 [日本語](../ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/USER_GUIDE.md) | 🇧🇬 [Български](../bg/USER_GUIDE.md) | 🇩🇰 [Dansk](../da/USER_GUIDE.md) | 🇫🇮 [Suomi](../fi/USER_GUIDE.md) | 🇮🇱 [עברית](../he/USER_GUIDE.md) | 🇭🇺 [Magyar](../hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/USER_GUIDE.md) | 🇰🇷 [한국어](../ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](../nl/USER_GUIDE.md) | 🇳🇴 [Norsk](../no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/USER_GUIDE.md) | 🇷🇴 [Română](../ro/USER_GUIDE.md) | 🇵🇱 [Polski](../pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/USER_GUIDE.md) | 🇸🇪 [Svenska](../sv/USER_GUIDE.md) | 🇵🇭 [Filipino](../phi/USER_GUIDE.md)
|
||||
|
||||
Пълно ръководство за конфигуриране на доставчици, създаване на комбинации, интегриране на CLI инструменти и внедряване на OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## Съдържание
|
||||
|
||||
- [Pricing at a Glance](#-pricing-at-a-glance)
|
||||
- [Use Cases](#-use-cases)
|
||||
- [Provider Setup](#-provider-setup)
|
||||
- [CLI Integration](#-cli-integration)
|
||||
- [Deployment](#-deployment)
|
||||
- [Available Models](#-available-models)
|
||||
- [Advanced Features](#-advanced-features)
|
||||
|
||||
---
|
||||
|
||||
## 💰 Ценообразуването с един поглед
|
||||
|
||||
| Ниво | Доставчик | Цена | Нулиране на квота | Най-добро за |
|
||||
| ------------------ | ----------------- | --------------------- | ----------------------- | ------------------------- |
|
||||
| **💳 АБОНАМЕНТ** | Claude Code (Pro) | $20/месец | 5 часа + седмично | Вече сте абонирани |
|
||||
| | Codex (Plus/Pro) | $20-200/месец | 5 часа + седмично | Потребители на OpenAI |
|
||||
| | Gemini CLI | **БЕЗПЛАТНО** | 180K/месец + 1K/ден | всички! |
|
||||
| | Копилот на GitHub | $10-19/месец | Месечно | Потребители на GitHub |
|
||||
| **🔑 КЛЮЧ ЗА API** | DeepSeek | Плащане за използване | Няма | Евтини разсъждения |
|
||||
| | Groq | Плащане за използване | Няма | Свръхбърз извод |
|
||||
| | xAI (Grok) | Плащане за използване | Няма | Грок 4 разсъждения |
|
||||
| | Мистрал | Плащане за използване | Няма | Хоствани в ЕС модели |
|
||||
| | Недоумение | Плащане за използване | Няма | Разширено търсене |
|
||||
| | Заедно AI | Плащане за използване | Няма | Модели с отворен код |
|
||||
| | Фойерверки AI | Плащане за използване | Няма | Бързи FLUX изображения |
|
||||
| | Мозъци | Плащане за използване | Няма | Скорост на вафла |
|
||||
| | Cohere | Плащане за използване | Няма | Команда R+ RAG |
|
||||
| | NVIDIA NIM | Плащане за използване | Няма | Корпоративни модели |
|
||||
| **💰 ЕВТИНО** | GLM-4.7 | $0,6/1 милион | Ежедневно 10 сутринта | Резервно копие на бюджета |
|
||||
| | MiniMax M2.1 | $0,2/1 милион | 5-часово търкаляне | Най-евтиният вариант |
|
||||
| | Кими К2 | $9/месец апартамент | 10 милиона токена/месец | Предвидими разходи |
|
||||
| **🆓 БЕЗПЛАТНО** | iFlow | $0 | Неограничен | 8 модела безплатно |
|
||||
| | Куен | $0 | Неограничен | 3 модела безплатно |
|
||||
| | Киро | $0 | Неограничен | Клод безплатно |
|
||||
|
||||
**💡 Професионален съвет:** Започнете с Gemini CLI (180K безплатно/месец) + iFlow (неограничено безплатно) комбинация = $0 цена!
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Случаи на употреба
|
||||
|
||||
### Случай 1: „Имам абонамент за Claude Pro“
|
||||
|
||||
**Проблем:** Квотата изтича неизползвана, ограничения на скоростта по време на тежко кодиране
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (use subscription fully)
|
||||
2. glm/glm-4.7 (cheap backup when quota out)
|
||||
3. if/kimi-k2-thinking (free emergency fallback)
|
||||
|
||||
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
|
||||
vs. $20 + hitting limits = frustration
|
||||
```
|
||||
|
||||
### Случай 2: „Искам нулеви разходи“
|
||||
|
||||
**Проблем:** Не мога да си позволя абонаменти, имам нужда от надеждно AI кодиране
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K free/month)
|
||||
2. if/kimi-k2-thinking (unlimited free)
|
||||
3. qw/qwen3-coder-plus (unlimited free)
|
||||
|
||||
Monthly cost: $0
|
||||
Quality: Production-ready models
|
||||
```
|
||||
|
||||
### Случай 3: „Имам нужда от кодиране 24/7, без прекъсвания“
|
||||
|
||||
**Проблем:** Крайни срокове, не мога да си позволя престой
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (best quality)
|
||||
2. cx/gpt-5.2-codex (second subscription)
|
||||
3. glm/glm-4.7 (cheap, resets daily)
|
||||
4. minimax/MiniMax-M2.1 (cheapest, 5h reset)
|
||||
5. if/kimi-k2-thinking (free unlimited)
|
||||
|
||||
Result: 5 layers of fallback = zero downtime
|
||||
Monthly cost: $20-200 (subscriptions) + $10-20 (backup)
|
||||
```
|
||||
|
||||
### Случай 4: „Искам БЕЗПЛАТЕН AI в OpenClaw“
|
||||
|
||||
**Проблем:** Имате нужда от AI асистент в приложенията за съобщения, напълно безплатно
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (unlimited free)
|
||||
2. if/minimax-m2.1 (unlimited free)
|
||||
3. if/kimi-k2-thinking (unlimited free)
|
||||
|
||||
Monthly cost: $0
|
||||
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Настройка на доставчик
|
||||
|
||||
### 🔐 Доставчици на абонаменти
|
||||
|
||||
#### Claude Code (Pro/Max)
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect Claude Code
|
||||
→ OAuth login → Auto token refresh
|
||||
→ 5-hour + weekly quota tracking
|
||||
|
||||
Models:
|
||||
cc/claude-opus-4-6
|
||||
cc/claude-sonnet-4-5-20250929
|
||||
cc/claude-haiku-4-5-20251001
|
||||
```
|
||||
|
||||
**Професионален съвет:** Използвайте Opus за сложни задачи, Sonnet за скорост. OmniRoute проследява квота за модел!
|
||||
|
||||
#### OpenAI Codex (Plus/Pro)
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect Codex
|
||||
→ OAuth login (port 1455)
|
||||
→ 5-hour + weekly reset
|
||||
|
||||
Models:
|
||||
cx/gpt-5.2-codex
|
||||
cx/gpt-5.1-codex-max
|
||||
```
|
||||
|
||||
#### Gemini CLI (БЕЗПЛАТНО 180K/месец!)
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect Gemini CLI
|
||||
→ Google OAuth
|
||||
→ 180K completions/month + 1K/day
|
||||
|
||||
Models:
|
||||
gc/gemini-3-flash-preview
|
||||
gc/gemini-2.5-pro
|
||||
```
|
||||
|
||||
**Най-добра стойност:** Огромно безплатно ниво! Използвайте това преди платените нива.
|
||||
|
||||
#### Копилот на GitHub
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect GitHub
|
||||
→ OAuth via GitHub
|
||||
→ Monthly reset (1st of month)
|
||||
|
||||
Models:
|
||||
gh/gpt-5
|
||||
gh/claude-4.5-sonnet
|
||||
gh/gemini-3-pro
|
||||
```
|
||||
|
||||
### 💰 Евтини доставчици
|
||||
|
||||
#### GLM-4.7 (Ежедневно нулиране, $0,6/1 млн.)
|
||||
|
||||
1. Регистрирайте се: [Zhipu AI](https://open.bigmodel.cn/)
|
||||
2. Вземете API ключ от Coding Plan
|
||||
3. Табло → Добавяне на API ключ: Доставчик: `glm`, API ключ: `your-key`
|
||||
|
||||
**Използване:** `glm/glm-4.7` — **Професионален съвет:** Планът за кодиране предлага 3× квота на цена 1/7! Нулирайте всеки ден в 10:00 ч.
|
||||
|
||||
#### MiniMax M2.1 (5 часа нулиране, $0,20/1 млн.)
|
||||
|
||||
1. Регистрирайте се: [MiniMax](https://www.minimax.io/)
|
||||
2. Вземете API ключ → Табло → Добавете API ключ
|
||||
|
||||
**Използване:** `minimax/MiniMax-M2.1` — **Професионален съвет:** Най-евтината опция за дълъг контекст (1M токени)!
|
||||
|
||||
#### Kimi K2 ($9/месец фиксиран)
|
||||
|
||||
1. Абонирайте се: [Moonshot AI](https://platform.moonshot.ai/)
|
||||
2. Вземете API ключ → Табло → Добавете API ключ
|
||||
|
||||
**Използване:** `kimi/kimi-latest` — **Професионален съвет:** Фиксирани $9/месец за 10 милиона токена = $0,90/1 милион ефективна цена!
|
||||
|
||||
### 🆓 БЕЗПЛАТНИ доставчици
|
||||
|
||||
#### iFlow (8 БЕЗПЛАТНИ модела)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect iFlow → OAuth login → Unlimited usage
|
||||
|
||||
Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1
|
||||
```
|
||||
|
||||
#### Qwen (3 БЕЗПЛАТНИ модела)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect Qwen → Device code auth → Unlimited usage
|
||||
|
||||
Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash
|
||||
```
|
||||
|
||||
#### Киро (Клод БЕЗПЛАТНО)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited
|
||||
|
||||
Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Комбота
|
||||
|
||||
### Пример 1: Увеличаване на абонамента → Евтино архивиране
|
||||
|
||||
```
|
||||
Dashboard → Combos → Create New
|
||||
|
||||
Name: premium-coding
|
||||
Models:
|
||||
1. cc/claude-opus-4-6 (Subscription primary)
|
||||
2. glm/glm-4.7 (Cheap backup, $0.6/1M)
|
||||
3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M)
|
||||
|
||||
Use in CLI: premium-coding
|
||||
```
|
||||
|
||||
### Пример 2: Само безплатно (нулева цена)
|
||||
|
||||
```
|
||||
Name: free-combo
|
||||
Models:
|
||||
1. gc/gemini-3-flash-preview (180K free/month)
|
||||
2. if/kimi-k2-thinking (unlimited)
|
||||
3. qw/qwen3-coder-plus (unlimited)
|
||||
|
||||
Cost: $0 forever!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 CLI интеграция
|
||||
|
||||
### Курсор IDE
|
||||
|
||||
```
|
||||
Settings → Models → Advanced:
|
||||
OpenAI API Base URL: http://localhost:20128/v1
|
||||
OpenAI API Key: [from omniroute dashboard]
|
||||
Model: cc/claude-opus-4-6
|
||||
```
|
||||
|
||||
### Клод Код
|
||||
|
||||
Редактиране на `~/.claude/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"anthropic_api_base": "http://localhost:20128/v1",
|
||||
"anthropic_api_key": "your-omniroute-api-key"
|
||||
}
|
||||
```
|
||||
|
||||
### Codex CLI
|
||||
|
||||
```bash
|
||||
export OPENAI_BASE_URL="http://localhost:20128"
|
||||
export OPENAI_API_KEY="your-omniroute-api-key"
|
||||
codex "your prompt"
|
||||
```
|
||||
|
||||
### OpenClaw
|
||||
|
||||
Редактиране на `~/.openclaw/openclaw.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": { "primary": "omniroute/if/glm-4.7" }
|
||||
}
|
||||
},
|
||||
"models": {
|
||||
"providers": {
|
||||
"omniroute": {
|
||||
"baseUrl": "http://localhost:20128/v1",
|
||||
"apiKey": "your-omniroute-api-key",
|
||||
"api": "openai-completions",
|
||||
"models": [{ "id": "if/glm-4.7", "name": "glm-4.7" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Или използвайте таблото за управление:** CLI инструменти → OpenClaw → Автоматично конфигуриране
|
||||
|
||||
### Cline / Продължи / RooCode
|
||||
|
||||
```
|
||||
Provider: OpenAI Compatible
|
||||
Base URL: http://localhost:20128/v1
|
||||
API Key: [from dashboard]
|
||||
Model: cc/claude-opus-4-6
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Внедряване
|
||||
|
||||
### Внедряване на VPS
|
||||
|
||||
```bash
|
||||
git clone https://github.com/diegosouzapw/OmniRoute.git
|
||||
cd OmniRoute && npm install && npm run build
|
||||
|
||||
export JWT_SECRET="your-secure-secret-change-this"
|
||||
export INITIAL_PASSWORD="your-password"
|
||||
export DATA_DIR="/var/lib/omniroute"
|
||||
export PORT="20128"
|
||||
export HOSTNAME="0.0.0.0"
|
||||
export NODE_ENV="production"
|
||||
export NEXT_PUBLIC_BASE_URL="http://localhost:20128"
|
||||
export API_KEY_SECRET="endpoint-proxy-api-key-secret"
|
||||
|
||||
npm run start
|
||||
# Or: pm2 start npm --name omniroute -- start
|
||||
```
|
||||
|
||||
### Докер
|
||||
|
||||
```bash
|
||||
# Build image (default = runner-cli with codex/claude/droid preinstalled)
|
||||
docker build -t omniroute:cli .
|
||||
|
||||
# Portable mode (recommended)
|
||||
docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-data:/app/data omniroute:cli
|
||||
```
|
||||
|
||||
За интегриран в хост режим с двоични файлове на CLI вижте раздела Docker в основните документи.
|
||||
|
||||
### Променливи на средата
|
||||
|
||||
| Променлива | По подразбиране | Описание |
|
||||
| --------------------- | -------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| `JWT_SECRET` | `omniroute-default-secret-change-me` | Тайна за подписване на JWT (**промяна в производството**) |
|
||||
| `INITIAL_PASSWORD` | `123456` | Първа парола за влизане |
|
||||
| `DATA_DIR` | `~/.omniroute` | Директория с данни (db, използване, регистрационни файлове) |
|
||||
| `PORT` | рамка по подразбиране | Сервизен порт (`20128` в примерите) |
|
||||
| `HOSTNAME` | рамка по подразбиране | Свързване на хост (Docker по подразбиране е `0.0.0.0`) |
|
||||
| `NODE_ENV` | по подразбиране по време на изпълнение | Задайте `production` за внедряване |
|
||||
| `BASE_URL` | `http://localhost:20128` | Вътрешен основен URL адрес от страната на сървъра |
|
||||
| `CLOUD_URL` | `https://omniroute.dev` | Основен URL адрес на крайна точка за синхронизиране в облак |
|
||||
| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC тайна за генерирани API ключове |
|
||||
| `REQUIRE_API_KEY` | `false` | Прилагане на API ключ на носител на `/v1/*` |
|
||||
| `ENABLE_REQUEST_LOGS` | `false` | Разрешава регистрационни файлове за заявки/отговори |
|
||||
| `AUTH_COOKIE_SECURE` | `false` | Принудително `Secure` бисквитка за удостоверяване (зад HTTPS обратен прокси) |
|
||||
|
||||
За пълната справка за променливите на средата вижте [README](../README.md).
|
||||
|
||||
---
|
||||
|
||||
## 📊 Налични модели
|
||||
|
||||
<details>
|
||||
<summary><b>Вижте всички налични модели</b></summary>
|
||||
|
||||
**Claude Code (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**Codex (`cx/`)** — Plus/Pro: `cx/gpt-5.2-codex`, `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** — БЕЗПЛАТНО: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro`
|
||||
|
||||
**GitHub Copilot (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet`
|
||||
|
||||
**GLM (`glm/`)** — $0,6/1 млн.: `glm/glm-4.7`
|
||||
|
||||
**MiniMax (`minimax/`)** — $0,2/1 млн.: `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** — БЕЗПЛАТНО: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1`
|
||||
|
||||
**Qwen (`qw/`)** — БЕЗПЛАТНО: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash`
|
||||
|
||||
**Киро (`kr/`)** — БЕЗПЛАТНО: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5`
|
||||
|
||||
**DeepSeek (`ds/`)**: `ds/deepseek-chat`, `ds/deepseek-reasoner`
|
||||
|
||||
**Groq (`groq/`)**: `groq/llama-3.3-70b-versatile`, `groq/llama-4-maverick-17b-128e-instruct`
|
||||
|
||||
**xAI (`xai/`)**: `xai/grok-4`, `xai/grok-4-0709-fast-reasoning`, `xai/grok-code-mini`
|
||||
|
||||
**Мистрал (`mistral/`)**: `mistral/mistral-large-2501`, `mistral/codestral-2501`
|
||||
|
||||
**Недоумение (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar`
|
||||
|
||||
**Заедно AI (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo`
|
||||
|
||||
**Фойерверки AI (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1`
|
||||
|
||||
**Cerebras (`cerebras/`)**: `cerebras/llama-3.3-70b`
|
||||
|
||||
**Cohere (`cohere/`)**: `cohere/command-r-plus-08-2024`
|
||||
|
||||
**NVIDIA NIM (`nvidia/`)**: `nvidia/nvidia/llama-3.3-70b-instruct`
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🧩 Разширени функции
|
||||
|
||||
### Персонализирани модели
|
||||
|
||||
Добавете всеки ID на модел към всеки доставчик, без да чакате актуализация на приложението:
|
||||
|
||||
```bash
|
||||
# Via API
|
||||
curl -X POST http://localhost:20128/api/provider-models \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"provider": "openai", "modelId": "gpt-4.5-preview", "modelName": "GPT-4.5 Preview"}'
|
||||
|
||||
# List: curl http://localhost:20128/api/provider-models?provider=openai
|
||||
# Remove: curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview"
|
||||
```
|
||||
|
||||
Или използвайте таблото за управление: **Доставчици → [Доставчик] → Персонализирани модели**.
|
||||
|
||||
### Специализирани маршрути на доставчик
|
||||
|
||||
Насочвайте заявките директно към конкретен доставчик с валидиране на модела:
|
||||
|
||||
```bash
|
||||
POST http://localhost:20128/v1/providers/openai/chat/completions
|
||||
POST http://localhost:20128/v1/providers/openai/embeddings
|
||||
POST http://localhost:20128/v1/providers/fireworks/images/generations
|
||||
```
|
||||
|
||||
Префиксът на доставчика се добавя автоматично, ако липсва. Несъответстващите модели връщат `400`.
|
||||
|
||||
### Конфигурация на мрежов прокси
|
||||
|
||||
```bash
|
||||
# Set global proxy
|
||||
curl -X PUT http://localhost:20128/api/settings/proxy \
|
||||
-d '{"global": {"type":"http","host":"proxy.example.com","port":"8080"}}'
|
||||
|
||||
# Per-provider proxy
|
||||
curl -X PUT http://localhost:20128/api/settings/proxy \
|
||||
-d '{"providers": {"openai": {"type":"socks5","host":"proxy.example.com","port":"1080"}}}'
|
||||
|
||||
# Test proxy
|
||||
curl -X POST http://localhost:20128/api/settings/proxy/test \
|
||||
-d '{"proxy":{"type":"socks5","host":"proxy.example.com","port":"1080"}}'
|
||||
```
|
||||
|
||||
**Приоритет:** Специфичен за ключ → Специфичен за комбинация → Специфичен за доставчик → Глобален → Среда.
|
||||
|
||||
### API за каталог на модели
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/api/models/catalog
|
||||
```
|
||||
|
||||
Връща модели, групирани по доставчик с типове (`chat`, `embedding`, `image`).
|
||||
|
||||
### Облачно синхронизиране
|
||||
|
||||
- Синхронизиране на доставчици, комбинации и настройки на всички устройства
|
||||
- Автоматична фонова синхронизация с изчакване + бързо отказване
|
||||
- Предпочитане на сървъра `BASE_URL`/`CLOUD_URL` в производството
|
||||
|
||||
### LLM Gateway Intelligence (Фаза 9)
|
||||
|
||||
- **Семантичен кеш** — Автоматично кешира нестрийминг, температура=0 отговори (заобикаляне с `X-OmniRoute-No-Cache: true`)
|
||||
- **Request Idempotency** — Дедупликира заявките в рамките на 5s чрез `Idempotency-Key` или `X-Request-Id` заглавка
|
||||
- **Проследяване на напредъка** — Включване на SSE `event: progress` събития чрез `X-OmniRoute-Progress: true` заглавка
|
||||
|
||||
---
|
||||
|
||||
### Площадка за преводачи
|
||||
|
||||
Достъп чрез **Табло → Преводач**. Отстранете грешки и визуализирайте как OmniRoute превежда API заявки между доставчици.
|
||||
|
||||
| Режим | Цел |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------------- |
|
||||
| **Детска площадка** | Изберете изходни/целеви формати, поставете заявка и незабавно вижте преведения резултат |
|
||||
| **Чат тестер** | Изпращайте чат съобщения на живо през проксито и проверявайте пълния цикъл на заявка/отговор |
|
||||
| **Тестова стенда** | Изпълнете групови тестове в множество комбинации от формати, за да проверите правилността на превода |
|
||||
| **Монитор на живо** | Гледайте преводи в реално време, докато заявките преминават през проксито |
|
||||
|
||||
**Случаи на употреба:**
|
||||
|
||||
- Отстраняване на грешки защо конкретна комбинация клиент/доставчик е неуспешна
|
||||
- Проверете дали мислещите тагове, извикванията на инструменти и системните подкани се превеждат правилно
|
||||
- Сравнете разликите във форматите между форматите OpenAI, Claude, Gemini и Responses API
|
||||
|
||||
---
|
||||
|
||||
### Стратегии за маршрутизиране
|
||||
|
||||
Конфигурирайте чрез **Табло → Настройки → Маршрутизация**.
|
||||
|
||||
| Стратегия | Описание |
|
||||
| ---------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| **Първо попълване** | Използва акаунти в приоритетен ред — основният акаунт обработва всички заявки, докато стане недостъпен |
|
||||
| **Round Robin** | Преминава през всички акаунти с конфигурируем лепкав лимит (по подразбиране: 3 обаждания на акаунт) |
|
||||
| **P2C (Сила на два избора)** | Избира 2 произволни акаунта и маршрути към по-здравословния — балансира натоварването с осъзнаване на здравето |
|
||||
| **Произволно** | Произволно избира акаунт за всяка заявка чрез разбъркване на Fisher-Yates |
|
||||
| **Най-малко използвани** | Насочва към акаунта с най-стария `lastUsedAt` времеви печат, разпределяйки трафика равномерно |
|
||||
| **Оптимизирани разходи** | Маршрути към акаунта с най-ниска стойност на приоритет, оптимизиране за доставчици с най-ниска цена |
|
||||
|
||||
#### Псевдоними на модели със заместващи символи
|
||||
|
||||
Създайте шаблони със заместващи знаци, за да пренасочите имената на моделите:
|
||||
|
||||
```
|
||||
Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929
|
||||
Pattern: gpt-* → Target: gh/gpt-5.1-codex
|
||||
```
|
||||
|
||||
Заместващите знаци поддържат `*` (всякакви знаци) и `?` (единичен знак).
|
||||
|
||||
#### Резервни вериги
|
||||
|
||||
Дефинирайте глобални резервни вериги, които се прилагат за всички заявки:
|
||||
|
||||
```
|
||||
Chain: production-fallback
|
||||
1. cc/claude-opus-4-6
|
||||
2. gh/gpt-5.1-codex
|
||||
3. glm/glm-4.7
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Устойчивост и прекъсвачи
|
||||
|
||||
Конфигурирайте чрез **Табло → Настройки → Устойчивост**.
|
||||
|
||||
OmniRoute прилага устойчивост на ниво доставчик с четири компонента:
|
||||
|
||||
1. **Профили на доставчици** — Конфигурация за всеки доставчик за:
|
||||
- Праг на повреда (колко повреда преди отваряне)
|
||||
- Продължителност на изчакване
|
||||
- Чувствителност на откриване на ограничение на скоростта
|
||||
- Параметри на експоненциално забавяне
|
||||
|
||||
2. **Редактируеми ограничения на скоростта** — Настройки по подразбиране на системно ниво, които могат да се конфигурират в таблото за управление:
|
||||
- **Заявки в минута (RPM)** — Максимален брой заявки в минута за акаунт
|
||||
- **Минимално време между заявките** — Минимална разлика в милисекунди между заявките
|
||||
- **Максимални едновременни заявки** — Максимални едновременни заявки за акаунт
|
||||
- Щракнете върху **Редактиране**, за да промените, след това върху **Запазване** или **Отказ**. Стойностите се запазват чрез API за устойчивост.
|
||||
|
||||
3. **Прекъсвач на веригата** — Проследява повреди на доставчик и автоматично отваря веригата при достигане на праг:
|
||||
- **ЗАТВОРЕНО** (здравословно) — Заявките протичат нормално
|
||||
- **OPEN** — Доставчикът е временно блокиран след повтарящи се повреди
|
||||
- **HALF_OPEN** — Тестване дали доставчикът се е възстановил
|
||||
|
||||
4. **Правила и заключени идентификатори** — Показва състоянието на прекъсвача и заключените идентификатори с възможност за принудително отключване.
|
||||
|
||||
5. **Автоматично откриване на ограничение на скоростта** — Наблюдава заглавките `429` и `Retry-After`, за да избегне проактивно достигане на ограниченията на скоростта на доставчика.
|
||||
|
||||
**Професионален съвет:** Използвайте бутона **Нулиране на всички**, за да изчистите всички прекъсвачи и изчаквания, когато доставчикът се възстанови от прекъсване.
|
||||
|
||||
---
|
||||
|
||||
### Експорт/импорт на база данни
|
||||
|
||||
Управлявайте резервни копия на бази данни в **Табло → Настройки → Система и съхранение**.
|
||||
|
||||
| Действие | Описание |
|
||||
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Експортиране на база данни** | Изтегля текущата база данни SQLite като `.sqlite` файл |
|
||||
| **Експортиране на всички (.tar.gz)** | Изтегля пълен резервен архив, включително: база данни, настройки, комбинации, връзки с доставчик (без идентификационни данни), API ключ метаданни |
|
||||
| **Импортиране на база данни** | Качете файл `.sqlite`, за да замените текущата база данни. Автоматично се създава резервно копие преди импортиране |
|
||||
|
||||
```bash
|
||||
# API: Export database
|
||||
curl -o backup.sqlite http://localhost:20128/api/db-backups/export
|
||||
|
||||
# API: Export all (full archive)
|
||||
curl -o backup.tar.gz http://localhost:20128/api/db-backups/exportAll
|
||||
|
||||
# API: Import database
|
||||
curl -X POST http://localhost:20128/api/db-backups/import \
|
||||
-F "file=@backup.sqlite"
|
||||
```
|
||||
|
||||
**Проверка на импортиране:** Импортираният файл се валидира за цялост (проверка на SQLite pragma), необходими таблици (`provider_connections`, `provider_nodes`, `combos`, `api_keys`) и размер (макс. 100MB).
|
||||
|
||||
**Случаи на употреба:**
|
||||
|
||||
- Мигрирайте OmniRoute между машини
|
||||
- Създаване на външни резервни копия за възстановяване след бедствие
|
||||
- Споделяне на конфигурации между членовете на екипа (експортиране на всички → споделяне на архив)
|
||||
|
||||
---
|
||||
|
||||
### Табло за управление на настройките
|
||||
|
||||
Страницата с настройки е организирана в 5 раздела за лесна навигация:
|
||||
|
||||
| Раздел | Съдържание |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Сигурност** | Настройки за вход/парола, IP контрол на достъпа, API удостоверяване за `/models` и блокиране на доставчик |
|
||||
| **Маршрутизиране** | Стратегия за глобално маршрутизиране (6 опции), псевдоними на модели със заместващи символи, резервни вериги, комбинирани настройки по подразбиране |
|
||||
| **Устойчивост** | Профили на доставчици, редактируеми лимити на скоростта, състояние на прекъсвача, политики и заключени идентификатори |
|
||||
| **AI** | Обмисляне на конфигурация на бюджета, инжектиране на глобална система, статистика на бързия кеш |
|
||||
| **Разширено** | Глобална прокси конфигурация (HTTP/SOCKS5) |
|
||||
|
||||
---
|
||||
|
||||
### Управление на разходите и бюджета
|
||||
|
||||
Достъп чрез **Табло → Разходи**.
|
||||
|
||||
| Раздел | Цел |
|
||||
| ---------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| **Бюджет** | Задайте лимити на разходите за API ключ с дневни/седмични/месечни бюджети и проследяване в реално време |
|
||||
| **Цени** | Преглеждайте и редактирайте записи за ценообразуване на модела — цена за 1K входно/изходни токени на доставчик |
|
||||
|
||||
```bash
|
||||
# API: Set a budget
|
||||
curl -X POST http://localhost:20128/api/usage/budget \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"keyId": "key-123", "limit": 50.00, "period": "monthly"}'
|
||||
|
||||
# API: Get current budget status
|
||||
curl http://localhost:20128/api/usage/budget
|
||||
```
|
||||
|
||||
**Проследяване на разходите:** Всяка заявка регистрира използването на токени и изчислява разходите с помощта на таблицата с цените. Вижте разбивки в **Табло за управление → Използване** по доставчик, модел и API ключ.
|
||||
|
||||
---
|
||||
|
||||
### Аудио транскрипция
|
||||
|
||||
OmniRoute поддържа аудио транскрипция чрез OpenAI-съвместима крайна точка:
|
||||
|
||||
```bash
|
||||
POST /v1/audio/transcriptions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
# Example with curl
|
||||
curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
-H "Authorization: Bearer your-api-key" \
|
||||
-F "file=@audio.mp3" \
|
||||
-F "model=deepgram/nova-3"
|
||||
```
|
||||
|
||||
Налични доставчици: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`).
|
||||
|
||||
Поддържани аудио формати: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
|
||||
---
|
||||
|
||||
### Комбинирани стратегии за балансиране
|
||||
|
||||
Конфигурирайте балансирането за комбо в **Табло за управление → Комбота → Създаване/Редактиране → Стратегия**.
|
||||
|
||||
| Стратегия | Описание |
|
||||
| ---------------------------- | -------------------------------------------------------------------------------- |
|
||||
| **Round-Robin** | Върти се през моделите последователно |
|
||||
| **Приоритет** | Винаги пробва първия модел; връща се само при грешка |
|
||||
| **Произволно** | Избира произволен модел от комбинацията за всяка заявка |
|
||||
| **Претеглено** | Маршрути пропорционално въз основа на зададени тегла за модел |
|
||||
| **Най-малко използвани** | Насочва към модела с най-малко скорошни заявки (използва комбинирани показатели) |
|
||||
| **Оптимизиран за разходите** | Маршрути до най-евтиния наличен модел (използва ценова таблица) |
|
||||
|
||||
Глобалните настройки по подразбиране на комбинацията могат да бъдат зададени в **Табло → Настройки → Маршрут → Настройки по подразбиране на комбинация**.
|
||||
|
||||
---
|
||||
|
||||
### Здравно табло
|
||||
|
||||
Достъп чрез **Табло → Здраве**. Преглед на здравето на системата в реално време с 6 карти:
|
||||
|
||||
| Карта | Какво показва |
|
||||
| ---------------------------- | -------------------------------------------------------------------------- |
|
||||
| **Състояние на системата** | Време на работа, версия, използване на паметта, директория с данни |
|
||||
| **Здраве на доставчика** | Състояние на прекъсвача за всеки доставчик (затворен/отворен/полуотворен) |
|
||||
| **Ограничения на скоростта** | Активен лимит на изчакване за акаунт с оставащо време |
|
||||
| **Активни блокировки** | Доставчици, временно блокирани от политиката за блокиране |
|
||||
| **Кеш на подписа** | Статистика на кеша за дедупликация (активни ключове, процент на попадения) |
|
||||
| **Телеметрия за забавяне** | p50/p95/p99 агрегиране на латентност за доставчик |
|
||||
|
||||
**Професионален съвет:** Страницата Health се опреснява автоматично на всеки 10 секунди. Използвайте картата на прекъсвача, за да идентифицирате кои доставчици имат проблеми.
|
||||
@@ -0,0 +1,441 @@
|
||||
# API-reference
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](../es/API_REFERENCE.md) | 🇫🇷 [Français](../fr/API_REFERENCE.md) | 🇮🇹 [Italiano](../it/API_REFERENCE.md) | 🇷🇺 [Русский](../ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](../de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../in/API_REFERENCE.md) | 🇹🇭 [ไทย](../th/API_REFERENCE.md) | 🇺🇦 [Українська](../uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](../ar/API_REFERENCE.md) | 🇯🇵 [日本語](../ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../vi/API_REFERENCE.md) | 🇧🇬 [Български](../bg/API_REFERENCE.md) | 🇩🇰 [Dansk](../da/API_REFERENCE.md) | 🇫🇮 [Suomi](../fi/API_REFERENCE.md) | 🇮🇱 [עברית](../he/API_REFERENCE.md) | 🇭🇺 [Magyar](../hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../id/API_REFERENCE.md) | 🇰🇷 [한국어](../ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](../nl/API_REFERENCE.md) | 🇳🇴 [Norsk](../no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../pt/API_REFERENCE.md) | 🇷🇴 [Română](../ro/API_REFERENCE.md) | 🇵🇱 [Polski](../pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../sk/API_REFERENCE.md) | 🇸🇪 [Svenska](../sv/API_REFERENCE.md) | 🇵🇭 [Filipino](../phi/API_REFERENCE.md)
|
||||
|
||||
Komplet reference for alle OmniRoute API-slutpunkter.
|
||||
|
||||
---
|
||||
|
||||
## Indholdsfortegnelse
|
||||
|
||||
- [Chat Completions](#chat-completions)
|
||||
- [Embeddings](#embeddings)
|
||||
- [Image Generation](#image-generation)
|
||||
- [List Models](#list-models)
|
||||
- [Compatibility Endpoints](#compatibility-endpoints)
|
||||
- [Semantic Cache](#semantic-cache)
|
||||
- [Dashboard & Management](#dashboard--management)
|
||||
- [Request Processing](#request-processing)
|
||||
- [Authentication](#authentication)
|
||||
|
||||
---
|
||||
|
||||
## Chatafslutninger
|
||||
|
||||
```bash
|
||||
POST /v1/chat/completions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "cc/claude-opus-4-6",
|
||||
"messages": [
|
||||
{"role": "user", "content": "Write a function to..."}
|
||||
],
|
||||
"stream": true
|
||||
}
|
||||
```
|
||||
|
||||
### Brugerdefinerede overskrifter
|
||||
|
||||
| Overskrift | Retning | Beskrivelse |
|
||||
| ------------------------ | --------- | ---------------------------------------------- |
|
||||
| `X-OmniRoute-No-Cache` | Anmodning | Indstil til `true` for at omgå cache |
|
||||
| `X-OmniRoute-Progress` | Anmodning | Indstil til `true` for fremskridtsbegivenheder |
|
||||
| `Idempotency-Key` | Anmodning | Dedup nøgle (5s vindue) |
|
||||
| `X-Request-Id` | Anmodning | Alternativ dedup nøgle |
|
||||
| `X-OmniRoute-Cache` | Svar | `HIT` eller `MISS` (ikke-streaming) |
|
||||
| `X-OmniRoute-Idempotent` | Svar | `true` hvis deduplikeret |
|
||||
| `X-OmniRoute-Progress` | Svar | `enabled` hvis statussporing på |
|
||||
|
||||
---
|
||||
|
||||
## Indlejringer
|
||||
|
||||
```bash
|
||||
POST /v1/embeddings
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "nebius/Qwen/Qwen3-Embedding-8B",
|
||||
"input": "The food was delicious"
|
||||
}
|
||||
```
|
||||
|
||||
Tilgængelige udbydere: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.
|
||||
|
||||
```bash
|
||||
# List all embedding models
|
||||
GET /v1/embeddings
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Billedgenerering
|
||||
|
||||
```bash
|
||||
POST /v1/images/generations
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "openai/dall-e-3",
|
||||
"prompt": "A beautiful sunset over mountains",
|
||||
"size": "1024x1024"
|
||||
}
|
||||
```
|
||||
|
||||
Tilgængelige udbydere: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.
|
||||
|
||||
```bash
|
||||
# List all image models
|
||||
GET /v1/images/generations
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Liste over modeller
|
||||
|
||||
```bash
|
||||
GET /v1/models
|
||||
Authorization: Bearer your-api-key
|
||||
|
||||
→ Returns all chat, embedding, and image models + combos in OpenAI format
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Kompatibilitetsslutpunkter
|
||||
|
||||
| Metode | Sti | Format |
|
||||
| ------ | --------------------------- | ---------------------- |
|
||||
| POST | `/v1/chat/completions` | OpenAI |
|
||||
| POST | `/v1/messages` | Antropisk |
|
||||
| POST | `/v1/responses` | OpenAI-svar |
|
||||
| POST | `/v1/embeddings` | OpenAI |
|
||||
| POST | `/v1/images/generations` | OpenAI |
|
||||
| FÅ | `/v1/models` | OpenAI |
|
||||
| POST | `/v1/messages/count_tokens` | Antropisk |
|
||||
| FÅ | `/v1beta/models` | Tvillingerne |
|
||||
| POST | `/v1beta/models/{...path}` | Gemini generer indhold |
|
||||
| POST | `/v1/api/chat` | Ollama |
|
||||
|
||||
### Dedikerede udbyderruter
|
||||
|
||||
```bash
|
||||
POST /v1/providers/{provider}/chat/completions
|
||||
POST /v1/providers/{provider}/embeddings
|
||||
POST /v1/providers/{provider}/images/generations
|
||||
```
|
||||
|
||||
Udbyderpræfikset tilføjes automatisk, hvis det mangler. Umatchede modeller returnerer `400`.
|
||||
|
||||
---
|
||||
|
||||
## Semantisk cache
|
||||
|
||||
```bash
|
||||
# Get cache stats
|
||||
GET /api/cache
|
||||
|
||||
# Clear all caches
|
||||
DELETE /api/cache
|
||||
```
|
||||
|
||||
Eksempel på svar:
|
||||
|
||||
```json
|
||||
{
|
||||
"semanticCache": {
|
||||
"memorySize": 42,
|
||||
"memoryMaxSize": 500,
|
||||
"dbSize": 128,
|
||||
"hitRate": 0.65
|
||||
},
|
||||
"idempotency": {
|
||||
"activeKeys": 3,
|
||||
"windowMs": 5000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dashboard & Management
|
||||
|
||||
### Godkendelse
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| ----------------------------- | ------- | -------------------- |
|
||||
| `/api/auth/login` | POST | Log ind |
|
||||
| `/api/auth/logout` | POST | Log ud |
|
||||
| `/api/settings/require-login` | GET/PUT | Skift login påkrævet |
|
||||
|
||||
### Udbyderstyring
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| ---------------------------- | ------------- | ---------------------------- |
|
||||
| `/api/providers` | GET/POST | Liste/opret udbydere |
|
||||
| `/api/providers/[id]` | GET/SETT/SLET | Administrer en udbyder |
|
||||
| `/api/providers/[id]/test` | POST | Test udbyderforbindelse |
|
||||
| `/api/providers/[id]/models` | FÅ | Liste udbydermodeller |
|
||||
| `/api/providers/validate` | POST | Valider udbyderkonfiguration |
|
||||
| `/api/provider-nodes*` | Forskellige | Udbyder node management |
|
||||
| `/api/provider-models` | GET/POST/SLET | Brugerdefinerede modeller |
|
||||
|
||||
### OAuth-flows
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| -------------------------------- | ----------- | --------------------- |
|
||||
| `/api/oauth/[provider]/[action]` | Forskellige | Udbyderspecifik OAuth |
|
||||
|
||||
### Routing & Config
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| --------------------- | ----------- | ---------------------------------- |
|
||||
| `/api/models/alias` | GET/POST | Modelaliaser |
|
||||
| `/api/models/catalog` | FÅ | Alle modeller efter udbyder + type |
|
||||
| `/api/combos*` | Forskellige | Combo management |
|
||||
| `/api/keys*` | Forskellige | API nøglestyring |
|
||||
| `/api/pricing` | FÅ | Modelpriser |
|
||||
|
||||
### Brug og analyse
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| --------------------------- | ------ | ---------------------------- |
|
||||
| `/api/usage/history` | FÅ | Brugshistorik |
|
||||
| `/api/usage/logs` | FÅ | Brugslogs |
|
||||
| `/api/usage/request-logs` | FÅ | Logfiler på anmodningsniveau |
|
||||
| `/api/usage/[connectionId]` | FÅ | Brug pr. forbindelse |
|
||||
|
||||
### Indstillinger
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| ------------------------------- | ------- | ----------------------------------- |
|
||||
| `/api/settings` | GET/PUT | Generelle indstillinger |
|
||||
| `/api/settings/proxy` | GET/PUT | Netværk proxy-konfiguration |
|
||||
| `/api/settings/proxy/test` | POST | Test proxyforbindelse |
|
||||
| `/api/settings/ip-filter` | GET/PUT | IP-tilladelsesliste/blokeringsliste |
|
||||
| `/api/settings/thinking-budget` | GET/PUT | Begrundelse token budget |
|
||||
| `/api/settings/system-prompt` | GET/PUT | Global systemprompt |
|
||||
|
||||
### Overvågning
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| ------------------------ | ------- | --------------------- |
|
||||
| `/api/sessions` | FÅ | Aktiv sessionssporing |
|
||||
| `/api/rate-limits` | FÅ | Satsgrænser pr. konto |
|
||||
| `/api/monitoring/health` | FÅ | Sundhedstjek |
|
||||
| `/api/cache` | FÅ/SLET | Cache-statistik/ryd |
|
||||
|
||||
### Sikkerhedskopiering og eksport/import
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| --------------------------- | ------ | -------------------------------------------- |
|
||||
| `/api/db-backups` | FÅ | Liste over tilgængelige sikkerhedskopier |
|
||||
| `/api/db-backups` | SÆT | Opret en manuel backup |
|
||||
| `/api/db-backups` | POST | Gendan fra en specifik sikkerhedskopi |
|
||||
| `/api/db-backups/export` | FÅ | Download database som .sqlite-fil |
|
||||
| `/api/db-backups/import` | POST | Upload .sqlite-fil for at erstatte databasen |
|
||||
| `/api/db-backups/exportAll` | FÅ | Download fuld backup som .tar.gz-arkiv |
|
||||
|
||||
### Cloud Sync
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| ---------------------- | ----------- | -------------------------------- |
|
||||
| `/api/sync/cloud` | Forskellige | Cloud-synkroniseringsoperationer |
|
||||
| `/api/sync/initialize` | POST | Initialiser synkronisering |
|
||||
| `/api/cloud/*` | Forskellige | Cloud management |
|
||||
|
||||
### CLI-værktøjer
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| ---------------------------------- | ------ | -------------------- |
|
||||
| `/api/cli-tools/claude-settings` | FÅ | Claude CLI status |
|
||||
| `/api/cli-tools/codex-settings` | FÅ | Codex CLI-status |
|
||||
| `/api/cli-tools/droid-settings` | FÅ | Droid CLI status |
|
||||
| `/api/cli-tools/openclaw-settings` | FÅ | OpenClaw CLI status |
|
||||
| `/api/cli-tools/runtime/[toolId]` | FÅ | Generisk CLI runtime |
|
||||
|
||||
CLI-svar inkluderer: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
|
||||
|
||||
### Modstandsdygtighed og satsgrænser
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| ----------------------- | ------- | ------------------------------------ |
|
||||
| `/api/resilience` | GET/PUT | Få/opdater resiliensprofiler |
|
||||
| `/api/resilience/reset` | POST | Nulstil afbrydere |
|
||||
| `/api/rate-limits` | FÅ | Satsgrænsestatus pr. konto |
|
||||
| `/api/rate-limit` | FÅ | Global hastighedsgrænsekonfiguration |
|
||||
|
||||
### Evals
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| ------------ | -------- | ----------------------------------- |
|
||||
| `/api/evals` | GET/POST | Liste eval suiter / køre evaluering |
|
||||
|
||||
### Politikker
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| --------------- | ------------- | ----------------------------- |
|
||||
| `/api/policies` | GET/POST/SLET | Administrer routingpolitikker |
|
||||
|
||||
### Overholdelse
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| --------------------------- | ------ | ------------------------------------ |
|
||||
| `/api/compliance/audit-log` | FÅ | Overholdelsesrevisionslog (sidste N) |
|
||||
|
||||
### v1beta (Gemini-kompatibel)
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| -------------------------- | ------ | ---------------------------------- |
|
||||
| `/v1beta/models` | FÅ | Vis modeller i Gemini-format |
|
||||
| `/v1beta/models/{...path}` | POST | Gemini `generateContent` slutpunkt |
|
||||
|
||||
Disse endepunkter afspejler Geminis API-format for klienter, der forventer indbygget Gemini SDK-kompatibilitet.
|
||||
|
||||
### Interne / System API'er
|
||||
|
||||
| Slutpunkt | Metode | Beskrivelse |
|
||||
| --------------- | ------ | --------------------------------------------------------- |
|
||||
| `/api/init` | FÅ | Applikationsinitieringskontrol (bruges ved første kørsel) |
|
||||
| `/api/tags` | FÅ | Ollama-kompatible modelmærker (til Ollama-kunder) |
|
||||
| `/api/restart` | POST | Udløs yndefuld servergenstart |
|
||||
| `/api/shutdown` | POST | Udløs yndefuld serverlukning |
|
||||
|
||||
> **Bemærk:** Disse endepunkter bruges internt af systemet eller til Ollama-klientkompatibilitet. De kaldes typisk ikke af slutbrugere.
|
||||
|
||||
---
|
||||
|
||||
## Lydtransskription
|
||||
|
||||
```bash
|
||||
POST /v1/audio/transcriptions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: multipart/form-data
|
||||
```
|
||||
|
||||
Transskriber lydfiler ved hjælp af Deepgram eller AssemblyAI.
|
||||
|
||||
**Forespørgsel:**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
-H "Authorization: Bearer your-api-key" \
|
||||
-F "file=@recording.mp3" \
|
||||
-F "model=deepgram/nova-3"
|
||||
```
|
||||
|
||||
**Svar:**
|
||||
|
||||
```json
|
||||
{
|
||||
"text": "Hello, this is the transcribed audio content.",
|
||||
"task": "transcribe",
|
||||
"language": "en",
|
||||
"duration": 12.5
|
||||
}
|
||||
```
|
||||
|
||||
**Understøttede udbydere:** `deepgram/nova-3`, `assemblyai/best`.
|
||||
|
||||
**Understøttede formater:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
|
||||
---
|
||||
|
||||
## Ollama-kompatibilitet
|
||||
|
||||
For klienter, der bruger Ollamas API-format:
|
||||
|
||||
```bash
|
||||
# Chat endpoint (Ollama format)
|
||||
POST /v1/api/chat
|
||||
|
||||
# Model listing (Ollama format)
|
||||
GET /api/tags
|
||||
```
|
||||
|
||||
Forespørgsler oversættes automatisk mellem Ollama og interne formater.
|
||||
|
||||
---
|
||||
|
||||
## Telemetri
|
||||
|
||||
```bash
|
||||
# Get latency telemetry summary (p50/p95/p99 per provider)
|
||||
GET /api/telemetry/summary
|
||||
```
|
||||
|
||||
**Svar:**
|
||||
|
||||
```json
|
||||
{
|
||||
"providers": {
|
||||
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
|
||||
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Budget
|
||||
|
||||
```bash
|
||||
# Get budget status for all API keys
|
||||
GET /api/usage/budget
|
||||
|
||||
# Set or update a budget
|
||||
POST /api/usage/budget
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"keyId": "key-123",
|
||||
"limit": 50.00,
|
||||
"period": "monthly"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modeltilgængelighed
|
||||
|
||||
```bash
|
||||
# Get real-time model availability across all providers
|
||||
GET /api/models/availability
|
||||
|
||||
# Check availability for a specific model
|
||||
POST /api/models/availability
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "claude-sonnet-4-5-20250929"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Anmodningsbehandling
|
||||
|
||||
1. Klient sender anmodning til `/v1/*`
|
||||
2. Rutehandler kalder `handleChat`, `handleEmbedding`, `handleAudioTranscription` eller `handleImageGeneration`
|
||||
3. Modellen er løst (direkte udbyder/model eller alias/kombination)
|
||||
4. Oplysninger valgt fra lokal DB med filtrering af kontotilgængelighed
|
||||
5. Til chat: `handleChatCore` — formatdetektion, oversættelse, cachecheck, idempotenstjek
|
||||
6. Udbyder eksekutør sender upstream anmodning
|
||||
7. Svar oversat tilbage til klientformat (chat) eller returneret som det er (indlejringer/billeder/lyd)
|
||||
8. Brug/logning registreret
|
||||
9. Fallback gælder for fejl i henhold til combo regler
|
||||
|
||||
Fuld arkitekturreference: [link](ARCHITECTURE.md)
|
||||
|
||||
---
|
||||
|
||||
## Godkendelse
|
||||
|
||||
- Dashboard-ruter (`/dashboard/*`) bruger `auth_token`-cookie
|
||||
- Login bruger gemt adgangskode-hash; tilbagefald til `INITIAL_PASSWORD`
|
||||
- `requireLogin` kan skiftes via `/api/settings/require-login`
|
||||
- `/v1/*`-ruter kræver valgfrit Bearer API-nøgle, når `REQUIRE_API_KEY=true`
|
||||
@@ -0,0 +1,781 @@
|
||||
# OmniRoute-arkitektur
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](../es/ARCHITECTURE.md) | 🇫🇷 [Français](../fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](../it/ARCHITECTURE.md) | 🇷🇺 [Русский](../ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](../zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](../de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](../in/ARCHITECTURE.md) | 🇹🇭 [ไทย](../th/ARCHITECTURE.md) | 🇺🇦 [Українська](../uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](../ar/ARCHITECTURE.md) | 🇯🇵 [日本語](../ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](../vi/ARCHITECTURE.md) | 🇧🇬 [Български](../bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](../da/ARCHITECTURE.md) | 🇫🇮 [Suomi](../fi/ARCHITECTURE.md) | 🇮🇱 [עברית](../he/ARCHITECTURE.md) | 🇭🇺 [Magyar](../hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](../id/ARCHITECTURE.md) | 🇰🇷 [한국어](../ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](../ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](../nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](../no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](../pt/ARCHITECTURE.md) | 🇷🇴 [Română](../ro/ARCHITECTURE.md) | 🇵🇱 [Polski](../pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](../sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](../sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](../phi/ARCHITECTURE.md)
|
||||
|
||||
_Sidst opdateret: 2026-02-18_
|
||||
|
||||
## Resumé
|
||||
|
||||
OmniRoute er en lokal AI-routinggateway og dashboard bygget på Next.js.
|
||||
Det giver et enkelt OpenAI-kompatibelt slutpunkt (`/v1/*`) og dirigerer trafik på tværs af flere upstream-udbydere med oversættelse, fallback, token-opdatering og brugssporing.
|
||||
|
||||
Kerneegenskaber:
|
||||
|
||||
- OpenAI-kompatibel API-overflade til CLI/værktøjer (28 udbydere)
|
||||
- Anmodning/svar oversættelse på tværs af udbyderformater
|
||||
- Model combo fallback (multi-model sekvens)
|
||||
- Fallback på kontoniveau (multi-konto pr. udbyder)
|
||||
- Administration af forbindelse til OAuth + API-nøgleudbyder
|
||||
- Indlejringsgenerering via `/v1/embeddings` (6 udbydere, 9 modeller)
|
||||
- Billedgenerering via `/v1/images/generations` (4 udbydere, 9 modeller)
|
||||
- Tænk tag-parsing (`<think>...</think>`) for ræsonneringsmodeller
|
||||
- Response sanitization for streng OpenAI SDK-kompatibilitet
|
||||
- Rollenormalisering (udvikler→system, system→bruger) for kompatibilitet på tværs af udbydere
|
||||
- Struktureret outputkonvertering (json_schema → Gemini responseSchema)
|
||||
- Lokal persistens for udbydere, nøgler, aliaser, kombinationer, indstillinger, priser
|
||||
- Brug/omkostningssporing og anmodningslogning
|
||||
- Valgfri skysynkronisering til synkronisering af flere enheder/tilstande
|
||||
- IP-tilladelsesliste/blokeringsliste til API-adgangskontrol
|
||||
- Tænkende budgetstyring (passthrough/auto/custom/adaptive)
|
||||
- Global system prompt injektion
|
||||
- Sessionssporing og fingeraftryk
|
||||
- Forbedret prisbegrænsning pr. konto med udbyderspecifikke profiler
|
||||
- Circuit breaker mønster for udbyderens modstandsdygtighed
|
||||
- Anti-tordenbeskyttelse med mutex-låsning
|
||||
- Signaturbaseret anmodnings deduplikeringscache
|
||||
- Domænelag: modeltilgængelighed, omkostningsregler, fallback-politik, lockout-politik
|
||||
- Vedvarende domænetilstand (SQLite-gennemskrivningscache til fallbacks, budgetter, lockouts, strømafbrydere)
|
||||
- Politikmotor til centraliseret anmodningsevaluering (lockout → budget → fallback)
|
||||
- Anmod om telemetri med p50/p95/p99 latency aggregering
|
||||
- Korrelations-ID (X-Request-Id) til ende-til-ende-sporing
|
||||
- Overholdelsesrevisionslogning med opt-out pr. API-nøgle
|
||||
- Evalueringsramme for LLM kvalitetssikring
|
||||
- Resilience UI-dashboard med strømafbryderstatus i realtid
|
||||
- Modulære OAuth-udbydere (12 individuelle moduler under `src/lib/oauth/providers/`)
|
||||
|
||||
Primær runtime model:
|
||||
|
||||
- Next.js app-ruter under `src/app/api/*` implementerer både dashboard-API'er og kompatibilitets-API'er
|
||||
- En delt SSE/routingkerne i `src/sse/*` + `open-sse/*` håndterer udbyderens udførelse, oversættelse, streaming, fallback og brug
|
||||
|
||||
## Omfang og grænser
|
||||
|
||||
### I omfang
|
||||
|
||||
- Lokal gateway køretid
|
||||
- Dashboard management API'er
|
||||
- Udbydergodkendelse og tokenopdatering
|
||||
- Anmod om oversættelse og SSE-streaming
|
||||
- Lokal stat + vedvarende brug
|
||||
- Valgfri skysynkroniseringsorkestrering
|
||||
|
||||
### Uden for anvendelsesområde
|
||||
|
||||
- Cloud-tjenesteimplementering bag `NEXT_PUBLIC_CLOUD_URL`
|
||||
- Udbyder SLA/kontrolplan uden for lokal proces
|
||||
- Eksterne CLI-binære filer selv (Claude CLI, Codex CLI osv.)
|
||||
|
||||
## Systemkontekst på højt niveau
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Clients[Developer Clients]
|
||||
C1[Claude Code]
|
||||
C2[Codex CLI]
|
||||
C3[OpenClaw / Droid / Cline / Continue / Roo]
|
||||
C4[Custom OpenAI-compatible clients]
|
||||
BROWSER[Browser Dashboard]
|
||||
end
|
||||
|
||||
subgraph Router[OmniRoute Local Process]
|
||||
API[V1 Compatibility API\n/v1/*]
|
||||
DASH[Dashboard + Management API\n/api/*]
|
||||
CORE[SSE + Translation Core\nopen-sse + src/sse]
|
||||
DB[(db.json)]
|
||||
UDB[(usage.json + log.txt)]
|
||||
end
|
||||
|
||||
subgraph Upstreams[Upstream Providers]
|
||||
P1[OAuth Providers\nClaude/Codex/Gemini/Qwen/iFlow/GitHub/Kiro/Cursor/Antigravity]
|
||||
P2[API Key Providers\nOpenAI/Anthropic/OpenRouter/GLM/Kimi/MiniMax\nDeepSeek/Groq/xAI/Mistral/Perplexity\nTogether/Fireworks/Cerebras/Cohere/NVIDIA]
|
||||
P3[Compatible Nodes\nOpenAI-compatible / Anthropic-compatible]
|
||||
end
|
||||
|
||||
subgraph Cloud[Optional Cloud Sync]
|
||||
CLOUD[Cloud Sync Endpoint\nNEXT_PUBLIC_CLOUD_URL]
|
||||
end
|
||||
|
||||
C1 --> API
|
||||
C2 --> API
|
||||
C3 --> API
|
||||
C4 --> API
|
||||
BROWSER --> DASH
|
||||
|
||||
API --> CORE
|
||||
DASH --> DB
|
||||
CORE --> DB
|
||||
CORE --> UDB
|
||||
|
||||
CORE --> P1
|
||||
CORE --> P2
|
||||
CORE --> P3
|
||||
|
||||
DASH --> CLOUD
|
||||
```
|
||||
|
||||
## Core Runtime Components
|
||||
|
||||
## 1) API og Routing Layer (Next.js App Routes)
|
||||
|
||||
Hovedmapper:
|
||||
|
||||
- `src/app/api/v1/*` og `src/app/api/v1beta/*` for kompatibilitets-API'er
|
||||
- `src/app/api/*` til administrations-/konfigurations-API'er
|
||||
- Næste omskrivninger i `next.config.mjs` kort `/v1/*` til `/api/v1/*`
|
||||
|
||||
Vigtige kompatibilitetsruter:
|
||||
|
||||
- `src/app/api/v1/chat/completions/route.ts`
|
||||
- `src/app/api/v1/messages/route.ts`
|
||||
- `src/app/api/v1/responses/route.ts`
|
||||
- `src/app/api/v1/models/route.ts` — inkluderer brugerdefinerede modeller med `custom: true`
|
||||
- `src/app/api/v1/embeddings/route.ts` — indlejringsgenerering (6 udbydere)
|
||||
- `src/app/api/v1/images/generations/route.ts` — billedgenerering (4+ udbydere inkl. Antigravity/Nebius)
|
||||
- `src/app/api/v1/messages/count_tokens/route.ts`
|
||||
- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — dedikeret chat pr. udbyder
|
||||
- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — dedikerede indlejringer pr. udbyder
|
||||
- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — dedikerede billeder pr. udbyder
|
||||
- `src/app/api/v1beta/models/route.ts`
|
||||
- `src/app/api/v1beta/models/[...path]/route.ts`
|
||||
|
||||
Ledelsesdomæner:
|
||||
|
||||
- Godkendelse/indstillinger: `src/app/api/auth/*`, `src/app/api/settings/*`
|
||||
- Udbydere/forbindelser: `src/app/api/providers*`
|
||||
- Udbyder noder: `src/app/api/provider-nodes*`
|
||||
- Brugerdefinerede modeller: `src/app/api/provider-models` (GET/POST/DELETE)
|
||||
- Modelkatalog: `src/app/api/models/catalog` (GET)
|
||||
- Proxy-konfiguration: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST)
|
||||
- OAuth: `src/app/api/oauth/*`
|
||||
- Nøgler/aliaser/kombinationer/priser: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing`
|
||||
- Anvendelse: `src/app/api/usage/*`
|
||||
- Synkroniser/sky: `src/app/api/sync/*`, `src/app/api/cloud/*`
|
||||
- CLI-værktøjshjælpere: `src/app/api/cli-tools/*`
|
||||
- IP-filter: `src/app/api/settings/ip-filter` (GET/PUT)
|
||||
- Tænkende budget: `src/app/api/settings/thinking-budget` (GET/PUT)
|
||||
- Systemprompt: `src/app/api/settings/system-prompt` (GET/PUT)
|
||||
- Sessioner: `src/app/api/sessions` (GET)
|
||||
- Satsgrænser: `src/app/api/rate-limits` (GET)
|
||||
- Modstandsdygtighed: `src/app/api/resilience` (GET/PATCH) — udbyderprofiler, strømafbryder, hastighedsgrænsetilstand
|
||||
- Resilience reset: `src/app/api/resilience/reset` (POST) — nulstil breakers + cooldowns
|
||||
- Cachestatistik: `src/app/api/cache/stats` (GET/DELETE)
|
||||
- Modeltilgængelighed: `src/app/api/models/availability` (GET/POST)
|
||||
- Telemetri: `src/app/api/telemetry/summary` (GET)
|
||||
- Budget: `src/app/api/usage/budget` (GET/POST)
|
||||
- Fallback-kæder: `src/app/api/fallback/chains` (GET/POST/DELETE)
|
||||
- Overholdelsesrevision: `src/app/api/compliance/audit-log` (GET)
|
||||
- Evaler: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
|
||||
- Politikker: `src/app/api/policies` (GET/POST)
|
||||
|
||||
## 2) SSE + Oversættelseskerne
|
||||
|
||||
Hovedflowmoduler:
|
||||
|
||||
- Indgang: `src/sse/handlers/chat.ts`
|
||||
- Kerneorkestrering: `open-sse/handlers/chatCore.ts`
|
||||
- Leverandørudførelsesadaptere: `open-sse/executors/*`
|
||||
- Formatdetektion/udbyderkonfiguration: `open-sse/services/provider.ts`
|
||||
- Modelparse/opløsning: `src/sse/services/model.ts`, `open-sse/services/model.ts`
|
||||
- Konto fallback logik: `open-sse/services/accountFallback.ts`
|
||||
- Oversættelsesregister: `open-sse/translator/index.ts`
|
||||
- Strømtransformationer: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts`
|
||||
- Brugsekstraktion/normalisering: `open-sse/utils/usageTracking.ts`
|
||||
- Tænk tag-parser: `open-sse/utils/thinkTagParser.ts`
|
||||
- Indlejringshåndtering: `open-sse/handlers/embeddings.ts`
|
||||
- Indlejring af udbyderregistrering: `open-sse/config/embeddingRegistry.ts`
|
||||
- Billedgenereringsbehandler: `open-sse/handlers/imageGeneration.ts`
|
||||
- Billedudbyderregistrering: `open-sse/config/imageRegistry.ts`
|
||||
- Reaktionssanering: `open-sse/handlers/responseSanitizer.ts`
|
||||
- Rollenormalisering: `open-sse/services/roleNormalizer.ts`
|
||||
|
||||
Tjenester (forretningslogik):
|
||||
|
||||
- Kontovalg/score: `open-sse/services/accountSelector.ts`
|
||||
- Kontekstlivscyklusstyring: `open-sse/services/contextManager.ts`
|
||||
- Håndhævelse af IP-filter: `open-sse/services/ipFilter.ts`
|
||||
- Sessionssporing: `open-sse/services/sessionManager.ts`
|
||||
- Anmod om deduplikering: `open-sse/services/signatureCache.ts`
|
||||
- Systemprompt indsprøjtning: `open-sse/services/systemPrompt.ts`
|
||||
- Tænkende budgetstyring: `open-sse/services/thinkingBudget.ts`
|
||||
- Wildcard model routing: `open-sse/services/wildcardRouter.ts`
|
||||
- Satsgrænsestyring: `open-sse/services/rateLimitManager.ts`
|
||||
- Afbryder: `open-sse/services/circuitBreaker.ts`
|
||||
|
||||
Domænelagsmoduler:
|
||||
|
||||
- Modeltilgængelighed: `src/lib/domain/modelAvailability.ts`
|
||||
- Omkostningsregler/budgetter: `src/lib/domain/costRules.ts`
|
||||
- Fallback-politik: `src/lib/domain/fallbackPolicy.ts`
|
||||
- Combo resolver: `src/lib/domain/comboResolver.ts`
|
||||
- Lockout-politik: `src/lib/domain/lockoutPolicy.ts`
|
||||
- Politikmotor: `src/domain/policyEngine.ts` — centraliseret lockout → budget → fallback-evaluering
|
||||
- Fejlkodekatalog: `src/lib/domain/errorCodes.ts`
|
||||
- Anmodnings-id: `src/lib/domain/requestId.ts`
|
||||
- Hente timeout: `src/lib/domain/fetchTimeout.ts`
|
||||
- Anmod om telemetri: `src/lib/domain/requestTelemetry.ts`
|
||||
- Overholdelse/revision: `src/lib/domain/compliance/index.ts`
|
||||
- Evalløber: `src/lib/domain/evalRunner.ts`
|
||||
- Vedvarende domænetilstand: `src/lib/db/domainState.ts` — SQLite CRUD til reservekæder, budgetter, omkostningshistorik, lockouttilstand, afbrydere
|
||||
|
||||
OAuth-udbydermoduler (12 individuelle filer under `src/lib/oauth/providers/`):
|
||||
|
||||
- Registerindeks: `src/lib/oauth/providers/index.ts`
|
||||
- Individuelle udbydere: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `iflow.ts`, `qwen.ts`, , , `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts`
|
||||
- Tyndt omslag: `src/lib/oauth/providers.ts` — reeksport fra individuelle moduler
|
||||
|
||||
## 3) Persistens-lag
|
||||
|
||||
Primær tilstand DB:
|
||||
|
||||
- `src/lib/localDb.ts`
|
||||
- fil: `${DATA_DIR}/db.json` (eller `$XDG_CONFIG_HOME/omniroute/db.json` når indstillet, ellers `~/.omniroute/db.json`)
|
||||
- enheder: providerConnections, providerNodes, modelAliaser, combos, apiKeys, indstillinger, prissætning, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt**
|
||||
|
||||
Brug DB:
|
||||
|
||||
- `src/lib/usageDb.ts`
|
||||
- filer: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`
|
||||
- følger den samme grundlæggende bibliotekspolitik som `localDb` (`DATA_DIR`, derefter `XDG_CONFIG_HOME/omniroute`, når den er indstillet)
|
||||
- opdelt i fokuserede undermoduler: `migrations.ts`, `usageHistory.ts`, `costCalculator.ts`, `usageStats.ts`, `callLogs.ts`
|
||||
|
||||
Domain State DB (SQLite):
|
||||
|
||||
- `src/lib/db/domainState.ts` — CRUD-operationer for domænetilstand
|
||||
- Tabeller (oprettet i `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers`
|
||||
- Gennemskrivningscachemønster: Kort i hukommelsen er autoritative under kørsel; mutationer skrives synkront til SQLite; tilstand gendannes fra DB ved koldstart
|
||||
|
||||
## 4) Auth + Sikkerhedsoverflader
|
||||
|
||||
- Dashboard-cookiegodkendelse: `src/proxy.ts`, `src/app/api/auth/login/route.ts`
|
||||
- Generering/bekræftelse af API-nøgler: `src/shared/utils/apiKey.ts`
|
||||
- Udbyderhemmeligheder bestod i `providerConnections` poster
|
||||
- Udgående proxy-understøttelse via `open-sse/utils/proxyFetch.ts` (env vars) og `open-sse/utils/networkProxy.ts` (konfigurerbar pr. udbyder eller global)
|
||||
|
||||
## 5) Cloud Sync
|
||||
|
||||
- Planlægger init: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`
|
||||
- Periodisk opgave: `src/shared/services/cloudSyncScheduler.ts`
|
||||
- Kontrolrute: `src/app/api/sync/cloud/route.ts`
|
||||
|
||||
## Anmod om livscyklus (`/v1/chat/completions`)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant Client as CLI/SDK Client
|
||||
participant Route as /api/v1/chat/completions
|
||||
participant Chat as src/sse/handlers/chat
|
||||
participant Core as open-sse/handlers/chatCore
|
||||
participant Model as Model Resolver
|
||||
participant Auth as Credential Selector
|
||||
participant Exec as Provider Executor
|
||||
participant Prov as Upstream Provider
|
||||
participant Stream as Stream Translator
|
||||
participant Usage as usageDb
|
||||
|
||||
Client->>Route: POST /v1/chat/completions
|
||||
Route->>Chat: handleChat(request)
|
||||
Chat->>Model: parse/resolve model or combo
|
||||
|
||||
alt Combo model
|
||||
Chat->>Chat: iterate combo models (handleComboChat)
|
||||
end
|
||||
|
||||
Chat->>Auth: getProviderCredentials(provider)
|
||||
Auth-->>Chat: active account + tokens/api key
|
||||
|
||||
Chat->>Core: handleChatCore(body, modelInfo, credentials)
|
||||
Core->>Core: detect source format
|
||||
Core->>Core: translate request to target format
|
||||
Core->>Exec: execute(provider, transformedBody)
|
||||
Exec->>Prov: upstream API call
|
||||
Prov-->>Exec: SSE/JSON response
|
||||
Exec-->>Core: response + metadata
|
||||
|
||||
alt 401/403
|
||||
Core->>Exec: refreshCredentials()
|
||||
Exec-->>Core: updated tokens
|
||||
Core->>Exec: retry request
|
||||
end
|
||||
|
||||
Core->>Stream: translate/normalize stream to client format
|
||||
Stream-->>Client: SSE chunks / JSON response
|
||||
|
||||
Stream->>Usage: extract usage + persist history/log
|
||||
```
|
||||
|
||||
## Combo + Account Fallback Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Incoming model string] --> B{Is combo name?}
|
||||
B -- Yes --> C[Load combo models sequence]
|
||||
B -- No --> D[Single model path]
|
||||
|
||||
C --> E[Try model N]
|
||||
E --> F[Resolve provider/model]
|
||||
D --> F
|
||||
|
||||
F --> G[Select account credentials]
|
||||
G --> H{Credentials available?}
|
||||
H -- No --> I[Return provider unavailable]
|
||||
H -- Yes --> J[Execute request]
|
||||
|
||||
J --> K{Success?}
|
||||
K -- Yes --> L[Return response]
|
||||
K -- No --> M{Fallback-eligible error?}
|
||||
|
||||
M -- No --> N[Return error]
|
||||
M -- Yes --> O[Mark account unavailable cooldown]
|
||||
O --> P{Another account for provider?}
|
||||
P -- Yes --> G
|
||||
P -- No --> Q{In combo with next model?}
|
||||
Q -- Yes --> E
|
||||
Q -- No --> R[Return all unavailable]
|
||||
```
|
||||
|
||||
Fallback-beslutninger er drevet af `open-sse/services/accountFallback.ts` ved hjælp af statuskoder og fejlmeddelelsesheuristik.
|
||||
|
||||
## OAuth Onboarding og Token Refresh Lifecycle
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI as Dashboard UI
|
||||
participant OAuth as /api/oauth/[provider]/[action]
|
||||
participant ProvAuth as Provider Auth Server
|
||||
participant DB as localDb
|
||||
participant Test as /api/providers/[id]/test
|
||||
participant Exec as Provider Executor
|
||||
|
||||
UI->>OAuth: GET authorize or device-code
|
||||
OAuth->>ProvAuth: create auth/device flow
|
||||
ProvAuth-->>OAuth: auth URL or device code payload
|
||||
OAuth-->>UI: flow data
|
||||
|
||||
UI->>OAuth: POST exchange or poll
|
||||
OAuth->>ProvAuth: token exchange/poll
|
||||
ProvAuth-->>OAuth: access/refresh tokens
|
||||
OAuth->>DB: createProviderConnection(oauth data)
|
||||
OAuth-->>UI: success + connection id
|
||||
|
||||
UI->>Test: POST /api/providers/[id]/test
|
||||
Test->>Exec: validate credentials / optional refresh
|
||||
Exec-->>Test: valid or refreshed token info
|
||||
Test->>DB: update status/tokens/errors
|
||||
Test-->>UI: validation result
|
||||
```
|
||||
|
||||
Opdatering under live-trafik udføres inde i `open-sse/handlers/chatCore.ts` via executor `refreshCredentials()`.
|
||||
|
||||
## Cloud Sync Lifecycle (Aktiver / Synkroniser / Deaktiver)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI as Endpoint Page UI
|
||||
participant Sync as /api/sync/cloud
|
||||
participant DB as localDb
|
||||
participant Cloud as External Cloud Sync
|
||||
participant Claude as ~/.claude/settings.json
|
||||
|
||||
UI->>Sync: POST action=enable
|
||||
Sync->>DB: set cloudEnabled=true
|
||||
Sync->>DB: ensure API key exists
|
||||
Sync->>Cloud: POST /sync/{machineId} (providers/aliases/combos/keys)
|
||||
Cloud-->>Sync: sync result
|
||||
Sync->>Cloud: GET /{machineId}/v1/verify
|
||||
Sync-->>UI: enabled + verification status
|
||||
|
||||
UI->>Sync: POST action=sync
|
||||
Sync->>Cloud: POST /sync/{machineId}
|
||||
Cloud-->>Sync: remote data
|
||||
Sync->>DB: update newer local tokens/status
|
||||
Sync-->>UI: synced
|
||||
|
||||
UI->>Sync: POST action=disable
|
||||
Sync->>DB: set cloudEnabled=false
|
||||
Sync->>Cloud: DELETE /sync/{machineId}
|
||||
Sync->>Claude: switch ANTHROPIC_BASE_URL back to local (if needed)
|
||||
Sync-->>UI: disabled
|
||||
```
|
||||
|
||||
Periodisk synkronisering udløses af `CloudSyncScheduler`, når skyen er aktiveret.
|
||||
|
||||
## Datamodel og lagerkort
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
SETTINGS ||--o{ PROVIDER_CONNECTION : controls
|
||||
PROVIDER_NODE ||--o{ PROVIDER_CONNECTION : backs_compatible_provider
|
||||
PROVIDER_CONNECTION ||--o{ USAGE_ENTRY : emits_usage
|
||||
|
||||
SETTINGS {
|
||||
boolean cloudEnabled
|
||||
number stickyRoundRobinLimit
|
||||
boolean requireLogin
|
||||
string password_hash
|
||||
string fallbackStrategy
|
||||
json rateLimitDefaults
|
||||
json providerProfiles
|
||||
}
|
||||
|
||||
PROVIDER_CONNECTION {
|
||||
string id
|
||||
string provider
|
||||
string authType
|
||||
string name
|
||||
number priority
|
||||
boolean isActive
|
||||
string apiKey
|
||||
string accessToken
|
||||
string refreshToken
|
||||
string expiresAt
|
||||
string testStatus
|
||||
string lastError
|
||||
string rateLimitedUntil
|
||||
json providerSpecificData
|
||||
}
|
||||
|
||||
PROVIDER_NODE {
|
||||
string id
|
||||
string type
|
||||
string name
|
||||
string prefix
|
||||
string apiType
|
||||
string baseUrl
|
||||
}
|
||||
|
||||
MODEL_ALIAS {
|
||||
string alias
|
||||
string targetModel
|
||||
}
|
||||
|
||||
COMBO {
|
||||
string id
|
||||
string name
|
||||
string[] models
|
||||
}
|
||||
|
||||
API_KEY {
|
||||
string id
|
||||
string name
|
||||
string key
|
||||
string machineId
|
||||
}
|
||||
|
||||
USAGE_ENTRY {
|
||||
string provider
|
||||
string model
|
||||
number prompt_tokens
|
||||
number completion_tokens
|
||||
string connectionId
|
||||
string timestamp
|
||||
}
|
||||
|
||||
CUSTOM_MODEL {
|
||||
string id
|
||||
string name
|
||||
string providerId
|
||||
}
|
||||
|
||||
PROXY_CONFIG {
|
||||
string global
|
||||
json providers
|
||||
}
|
||||
|
||||
IP_FILTER {
|
||||
string mode
|
||||
string[] allowlist
|
||||
string[] blocklist
|
||||
}
|
||||
|
||||
THINKING_BUDGET {
|
||||
string mode
|
||||
number customBudget
|
||||
string effortLevel
|
||||
}
|
||||
|
||||
SYSTEM_PROMPT {
|
||||
boolean enabled
|
||||
string prompt
|
||||
string position
|
||||
}
|
||||
```
|
||||
|
||||
Fysiske lagerfiler:
|
||||
|
||||
- hovedtilstand: `${DATA_DIR}/db.json` (eller `$XDG_CONFIG_HOME/omniroute/db.json` når indstillet, ellers `~/.omniroute/db.json`)
|
||||
- brugsstatistik: `${DATA_DIR}/usage.json`
|
||||
- anmod om log linjer: `${DATA_DIR}/log.txt`
|
||||
- valgfri oversætter/anmodningsfejlfindingssessioner: `<repo>/logs/...`
|
||||
|
||||
## Implementeringstopologi
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph LocalHost[Developer Host]
|
||||
CLI[CLI Tools]
|
||||
Browser[Dashboard Browser]
|
||||
end
|
||||
|
||||
subgraph ContainerOrProcess[OmniRoute Runtime]
|
||||
Next[Next.js Server\nPORT=20128]
|
||||
Core[SSE Core + Executors]
|
||||
MainDB[(db.json)]
|
||||
UsageDB[(usage.json/log.txt)]
|
||||
end
|
||||
|
||||
subgraph External[External Services]
|
||||
Providers[AI Providers]
|
||||
SyncCloud[Cloud Sync Service]
|
||||
end
|
||||
|
||||
CLI --> Next
|
||||
Browser --> Next
|
||||
Next --> Core
|
||||
Next --> MainDB
|
||||
Core --> MainDB
|
||||
Core --> UsageDB
|
||||
Core --> Providers
|
||||
Next --> SyncCloud
|
||||
```
|
||||
|
||||
## Modulkortlægning (beslutningskritisk)
|
||||
|
||||
### Rute- og API-moduler
|
||||
|
||||
- `src/app/api/v1/*`, `src/app/api/v1beta/*`: kompatibilitets-API'er
|
||||
- `src/app/api/v1/providers/[provider]/*`: dedikerede ruter pr. udbyder (chat, indlejringer, billeder)
|
||||
- `src/app/api/providers*`: udbyder CRUD, validering, test
|
||||
- `src/app/api/provider-nodes*`: brugerdefineret kompatibel nodestyring
|
||||
- `src/app/api/provider-models`: brugerdefineret modelstyring (CRUD)
|
||||
- `src/app/api/models/catalog`: komplet modelkatalog API (alle typer grupperet efter udbyder)
|
||||
- `src/app/api/oauth/*`: OAuth/enhedskode-flows
|
||||
- `src/app/api/keys*`: lokal API nøgle livscyklus
|
||||
- `src/app/api/models/alias`: alias management
|
||||
- `src/app/api/combos*`: fallback combo management
|
||||
- `src/app/api/pricing`: pristilsidesættelser til omkostningsberegning
|
||||
- `src/app/api/settings/proxy`: proxy-konfiguration (GET/PUT/DELETE)
|
||||
- `src/app/api/settings/proxy/test`: test af udgående proxyforbindelse (POST)
|
||||
- `src/app/api/usage/*`: brugs- og log-API'er
|
||||
- `src/app/api/sync/*` + `src/app/api/cloud/*`: skysynkronisering og skyvendte hjælpere
|
||||
- `src/app/api/cli-tools/*`: lokale CLI-konfigurationsskrivere/-brikker
|
||||
- `src/app/api/settings/ip-filter`: IP-tilladelsesliste/blokeringsliste (GET/PUT)
|
||||
- `src/app/api/settings/thinking-budget`: Tænkende token-budgetkonfiguration (GET/PUT)
|
||||
- `src/app/api/settings/system-prompt`: global systemprompt (GET/PUT)
|
||||
- `src/app/api/sessions`: aktiv sessionsfortegnelse (GET)
|
||||
- `src/app/api/rate-limits`: satsgrænsestatus pr. konto (GET)
|
||||
|
||||
### Routing og udførelseskerne
|
||||
|
||||
- `src/sse/handlers/chat.ts`: anmodning om parse, kombinationshåndtering, kontovalgsløkke
|
||||
- `open-sse/handlers/chatCore.ts`: oversættelse, eksekutorafsendelse, genforsøg/opdateringshåndtering, stream-opsætning
|
||||
- `open-sse/executors/*`: udbyderspecifik netværks- og formatadfærd
|
||||
|
||||
### Oversættelsesregister og formatkonvertere
|
||||
|
||||
- `open-sse/translator/index.ts`: oversætterregister og orkestrering
|
||||
- Anmod om oversættere: `open-sse/translator/request/*`
|
||||
- Svaroversættere: `open-sse/translator/response/*`
|
||||
- Formatkonstanter: `open-sse/translator/formats.ts`
|
||||
|
||||
### Vedholdenhed
|
||||
|
||||
- `src/lib/localDb.ts`: vedvarende konfiguration/tilstand
|
||||
- `src/lib/usageDb.ts`: brugshistorik og rullende anmodningslogfiler
|
||||
|
||||
## Udbyder Eksekutør Dækning (Strategimønster)
|
||||
|
||||
Hver udbyder har en specialiseret udfører, der udvider `BaseExecutor` (i `open-sse/executors/base.ts`), som giver URL-opbygning, header-konstruktion, genforsøg med eksponentiel backoff, legitimationsopdateringshook og `execute()` orkestreringsmetoden.
|
||||
|
||||
| Eksekutør | Udbyder(e) | Særlig håndtering |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
||||
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fyrværkeri, Cerebras, Cohere, NVIDIA | Dynamisk URL/header-konfiguration pr. udbyder |
|
||||
| `AntigravityExecutor` | Google Antigravity | Brugerdefinerede projekt-/sessions-id'er, forsøg igen - efter parsing |
|
||||
| `CodexExecutor` | OpenAI Codex | Injicerer systeminstruktioner, fremtvinger ræsonnement indsats |
|
||||
| `CursorExecutor` | Markør IDE | ConnectRPC-protokol, Protobuf-kodning, anmodningssignering via checksum |
|
||||
| `GithubExecutor` | GitHub Copilot | Copilot token opdatering, VSCode-mimicing headers |
|
||||
| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream binært format → SSE-konvertering |
|
||||
| `GeminiCLIExecutor` | Gemini CLI | Opdateringscyklus for Google OAuth-token |
|
||||
|
||||
Alle andre udbydere (inklusive brugerdefinerede kompatible noder) bruger `DefaultExecutor`.
|
||||
|
||||
## Udbyderkompatibilitetsmatrix
|
||||
|
||||
| Udbyder | Format | Auth | Stream | Ikke-stream | Token Opdater | Brug API |
|
||||
| ---------------- | --------------- | --------------------- | ---------------- | ----------- | ------------- | -------------------- |
|
||||
| Claude | claude | API-nøgle / OAuth | ✅ | ✅ | ✅ | ⚠️ Kun administrator |
|
||||
| Tvillingerne | gemini | API-nøgle / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
|
||||
| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
|
||||
| Antigravitation | antityngdekraft | OAuth | ✅ | ✅ | ✅ | ✅ Fuld kvote API |
|
||||
| OpenAI | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
| Codex | openai-svar | OAuth | ✅ tvunget | ❌ | ✅ | ✅ Satsgrænser |
|
||||
| GitHub Copilot | åbne | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Kvote snapshots |
|
||||
| Markør | markør | Tilpasset kontrolsum | ✅ | ✅ | ❌ | ❌ |
|
||||
| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Brugsgrænser |
|
||||
| Qwen | åbne | OAuth | ✅ | ✅ | ✅ | ⚠️ Efter anmodning |
|
||||
| iFlow | åbne | OAuth (Grundlæggende) | ✅ | ✅ | ✅ | ⚠️ Efter anmodning |
|
||||
| OpenRouter | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
| GLM/Kimi/MiniMax | claude | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
| DeepSeek | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
| Groq | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
| xAI (Grok) | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
| Mistral | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
| Forvirring | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
| Sammen AI | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
| Fyrværkeri AI | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
| Cerebras | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
| Sammenhæng | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
| NVIDIA NIM | åbne | API-nøgle | ✅ | ✅ | ❌ | ❌ |
|
||||
|
||||
## Format oversættelsesdækning
|
||||
|
||||
Detekterede kildeformater omfatter:
|
||||
|
||||
- `openai`
|
||||
- `openai-responses`
|
||||
- `claude`
|
||||
- `gemini`
|
||||
|
||||
Målformater omfatter:
|
||||
|
||||
- OpenAI chat/svar
|
||||
- Claude
|
||||
- Gemini/Gemini-CLI/Antigravity kuvert
|
||||
- Kiro
|
||||
- Markør
|
||||
|
||||
Oversættelser bruger **OpenAI som hub-format** - alle konverteringer går gennem OpenAI som mellemliggende:
|
||||
|
||||
```
|
||||
Source Format → OpenAI (hub) → Target Format
|
||||
```
|
||||
|
||||
Oversættelser vælges dynamisk baseret på kildens nyttelastform og udbyderens målformat.
|
||||
|
||||
Yderligere behandlingslag i oversættelsespipelinen:
|
||||
|
||||
- **Responssanering** — Fjerner ikke-standardfelter fra OpenAI-formatsvar (både streaming og ikke-streaming) for at sikre streng SDK-overholdelse
|
||||
- **Rollenormalisering** — Konverterer `developer` → `system` til ikke-OpenAI-mål; fusionerer `system` → `user` for modeller, der afviser systemrollen (GLM, ERNIE)
|
||||
- **Tænk tag-udtrækning** — Parser `<think>...</think>` blokke fra indhold til feltet `reasoning_content`
|
||||
- **Struktureret output** — Konverterer OpenAI `response_format.json_schema` til Gemini's `responseMimeType` + `responseSchema`
|
||||
|
||||
## Understøttede API-endepunkter
|
||||
|
||||
| Slutpunkt | Format | Behandler |
|
||||
| -------------------------------------------------- | ------------------------- | ------------------------------------------------------------------ |
|
||||
| `POST /v1/chat/completions` | OpenAI Chat | `src/sse/handlers/chat.ts` |
|
||||
| `POST /v1/messages` | Claude Beskeder | Samme handler (auto-detekteret) |
|
||||
| `POST /v1/responses` | OpenAI-svar | `open-sse/handlers/responsesHandler.ts` |
|
||||
| `POST /v1/embeddings` | OpenAI-indlejringer | `open-sse/handlers/embeddings.ts` |
|
||||
| `GET /v1/embeddings` | Modelliste | API-rute |
|
||||
| `POST /v1/images/generations` | OpenAI Billeder | `open-sse/handlers/imageGeneration.ts` |
|
||||
| `GET /v1/images/generations` | Modelliste | API-rute |
|
||||
| `POST /v1/providers/{provider}/chat/completions` | OpenAI Chat | Dedikeret per udbyder med modelvalidering |
|
||||
| `POST /v1/providers/{provider}/embeddings` | OpenAI-indlejringer | Dedikeret per udbyder med modelvalidering |
|
||||
| `POST /v1/providers/{provider}/images/generations` | OpenAI Billeder | Dedikeret per udbyder med modelvalidering |
|
||||
| `POST /v1/messages/count_tokens` | Claude Token Count | API-rute |
|
||||
| `GET /v1/models` | OpenAI Models liste | API-rute (chat + indlejring + billede + brugerdefinerede modeller) |
|
||||
| `GET /api/models/catalog` | Katalog | Alle modeller grupperet efter udbyder + type |
|
||||
| `POST /v1beta/models/*:streamGenerateContent` | Tvilling hjemmehørende | API-rute |
|
||||
| `GET/PUT/DELETE /api/settings/proxy` | Proxy-konfiguration | Netværk proxy-konfiguration |
|
||||
| `POST /api/settings/proxy/test` | Proxy-forbindelse | Proxy-sundheds-/forbindelsestestslutpunkt |
|
||||
| `GET/POST/DELETE /api/provider-models` | Brugerdefinerede modeller | Brugerdefineret modelstyring pr. udbyder |
|
||||
|
||||
## Bypass Handler
|
||||
|
||||
Bypass-handleren (`open-sse/utils/bypassHandler.ts`) opsnapper kendte "smid-anmodninger" fra Claude CLI - opvarmningsping, titeludtræk og tokentællinger - og returnerer et **falsk svar** uden at forbruge upstream-udbydertokens. Dette udløses kun, når `User-Agent` indeholder `claude-cli`.
|
||||
|
||||
## Anmod om Logger Pipeline
|
||||
|
||||
Anmodningsloggeren (`open-sse/utils/requestLogger.ts`) giver en 7-trins debug-logningspipeline, deaktiveret som standard, aktiveret via `ENABLE_REQUEST_LOGS=true`:
|
||||
|
||||
```
|
||||
1_req_client.json → 2_req_source.json → 3_req_openai.json → 4_req_target.json
|
||||
→ 5_res_provider.txt → 6_res_openai.txt → 7_res_client.txt
|
||||
```
|
||||
|
||||
Filer skrives til `<repo>/logs/<session>/` for hver anmodningssession.
|
||||
|
||||
## Fejltilstande og modstandsdygtighed
|
||||
|
||||
## 1) Konto/udbyder tilgængelighed
|
||||
|
||||
- Nedkøling af udbyderkonto på forbigående/rate/godkendelsesfejl
|
||||
- konto fallback før mislykket anmodning
|
||||
- combo model fallback, når den nuværende model/udbydersti er udtømt
|
||||
|
||||
## 2) Tokens udløb
|
||||
|
||||
- Forhåndstjek og opdater med genforsøg for udbydere, der kan opdateres
|
||||
- 401/403 forsøg igen efter opdateringsforsøg i kernestien
|
||||
|
||||
## 3) Strømsikkerhed
|
||||
|
||||
- afbrydelsesbevidst streamcontroller
|
||||
- translationsstream med end-of-stream flush og `[DONE]` håndtering
|
||||
- forbrugsestimeret fallback, når udbyderens brugsmetadata mangler
|
||||
|
||||
## 4) Cloud Sync-forringelse
|
||||
|
||||
- Synkroniseringsfejl dukker op, men lokal kørsel fortsætter
|
||||
- Scheduler har logik, der kan genforsøge, men periodisk udførelse kalder i øjeblikket enkelt-forsøgssynkronisering som standard
|
||||
|
||||
## 5) Dataintegritet
|
||||
|
||||
- DB shape migration/reparation for manglende nøgler
|
||||
- korrupte JSON-nulstillingsbeskyttelsesforanstaltninger for localDb og usageDb
|
||||
|
||||
## Observerbarhed og operationelle signaler
|
||||
|
||||
Kilder til synlighed ved kørsel:
|
||||
|
||||
- konsollogfiler fra `src/sse/utils/logger.ts`
|
||||
- brugsaggregater pr. anmodning i `usage.json`
|
||||
- log på status for tekstanmodning `log.txt`
|
||||
- valgfri dybe anmodnings-/oversættelseslogfiler under `logs/` når `ENABLE_REQUEST_LOGS=true`
|
||||
- dashboardbrugsendepunkter (`/api/usage/*`) for brugergrænsefladeforbrug
|
||||
|
||||
## Sikkerhedsfølsomme grænser
|
||||
|
||||
- JWT-hemmelighed (`JWT_SECRET`) sikrer bekræftelse/signering af dashboard-sessionscookie
|
||||
- Indledende adgangskode fallback (`INITIAL_PASSWORD`, standard `123456`) skal tilsidesættes i rigtige implementeringer
|
||||
- API-nøgle HMAC-hemmelighed (`API_KEY_SECRET`) sikrer genereret lokalt API-nøgleformat
|
||||
- Udbyderhemmeligheder (API-nøgler/tokens) bevares i lokal DB og bør beskyttes på filsystemniveau
|
||||
- Slutpunkter for skysynkronisering er afhængige af API-nøglegodkendelse + maskin-id-semantik
|
||||
|
||||
## Miljø og Runtime Matrix
|
||||
|
||||
Miljøvariabler aktivt brugt af kode:
|
||||
|
||||
- App/godkendelse: `JWT_SECRET`, `INITIAL_PASSWORD`
|
||||
- Opbevaring: `DATA_DIR`
|
||||
- Kompatibel nodeadfærd: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE`
|
||||
- Valgfri lagerbasetilsidesættelse (Linux/macOS, når `DATA_DIR` ikke er indstillet): `XDG_CONFIG_HOME`
|
||||
- Sikkerhedshashing: `API_KEY_SECRET`, `MACHINE_ID_SALT`
|
||||
- Logning: `ENABLE_REQUEST_LOGS`
|
||||
- Synkronisering/cloud URLing: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL`
|
||||
- Udgående proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` og varianter med små bogstaver
|
||||
- SOCKS5-funktionsflag: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY`
|
||||
- Platform-/runtime-hjælpere (ikke app-specifik konfiguration): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME`
|
||||
|
||||
## Kendte arkitektoniske noter
|
||||
|
||||
1. `usageDb` og `localDb` deler nu den samme grundlæggende bibliotekspolitik (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) med ældre filmigrering.
|
||||
2. `/api/v1/route.ts` returnerer en statisk modelliste og er ikke den primære modelkilde, der bruges af `/v1/models`.
|
||||
3. Anmodningslogger skriver hele headers/body, når den er aktiveret; behandle logbiblioteket som følsomt.
|
||||
4. Cloudadfærd afhænger af korrekt `NEXT_PUBLIC_BASE_URL` og cloud-endepunkters tilgængelighed.
|
||||
5. `open-sse/` biblioteket udgives som `@omniroute/open-sse` **npm workspace-pakken**. Kildekoden importerer det via `@omniroute/open-sse/...` (løst af Next.js `transpilePackages`). Filstier i dette dokument bruger stadig mappenavnet `open-sse/` for at opnå konsistens.
|
||||
6. Diagrammer i dashboardet bruger **Recharts** (SVG-baseret) til tilgængelige, interaktive analysevisualiseringer (søjlediagrammer for modelbrug, udbyderopdelingstabeller med succesrater).
|
||||
7. E2E-tests bruger **Playwright** (`tests/e2e/`), køres via `npm run test:e2e`. Enhedstests bruger **Node.js testløber** (`tests/unit/`), køres via `npm run test:plan3`. Kildekoden under `src/` er **TypeScript** (`.ts`/`.tsx`); `open-sse/`-arbejdsområdet forbliver JavaScript (`.js`).
|
||||
8. Siden Indstillinger er organiseret i 5 faner: Sikkerhed, Routing (6 globale strategier: fill-first, round-robin, p2c, random, mindst brugt, omkostningsoptimeret), Resiliens (redigerbare hastighedsgrænser, strømafbryder, politikker), AI (tænkebudget, systemprompt, promptcache), Avanceret (proxy).
|
||||
|
||||
## Tjekliste for operationel verifikation
|
||||
|
||||
- Byg fra kilde: `npm run build`
|
||||
- Byg Docker-billede: `docker build -t omniroute .`
|
||||
- Start service og bekræft:
|
||||
- `GET /api/settings`
|
||||
- `GET /api/v1/models`
|
||||
- CLI-målbasis-URL skal være `http://<host>:20128/v1`, når `PORT=20128`
|
||||
@@ -0,0 +1,589 @@
|
||||
# omniroute — Kodebasedokumentation
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](../pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](../es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](../fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](../it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](../ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](../zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](../de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](../in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](../th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](../uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](../ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](../ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](../vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](../bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](../da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](../fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](../he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](../hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](../id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](../ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](../ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](../nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](../no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](../pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](../ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](../pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](../sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](../sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](../phi/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
> En omfattende, begyndervenlig guide til **omniroute** multi-udbyder AI proxy-routeren.
|
||||
|
||||
---
|
||||
|
||||
## 1. Hvad er omniroute?
|
||||
|
||||
omniroute er en **proxy-router**, der sidder mellem AI-klienter (Claude CLI, Codex, Cursor IDE osv.) og AI-udbydere (Anthropic, Google, OpenAI, AWS, GitHub osv.). Det løser et stort problem:
|
||||
|
||||
> **Forskellige AI-klienter taler forskellige "sprog" (API-formater), og forskellige AI-udbydere forventer også forskellige "sprog".** omniroute oversætter mellem dem automatisk.
|
||||
|
||||
Tænk på det som en universel oversætter i FN - enhver delegeret kan tale et hvilket som helst sprog, og oversætteren konverterer det til enhver anden delegeret.
|
||||
|
||||
---
|
||||
|
||||
## 2. Arkitekturoversigt
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph Clients
|
||||
A[Claude CLI]
|
||||
B[Codex]
|
||||
C[Cursor IDE]
|
||||
D[OpenAI-compatible]
|
||||
end
|
||||
|
||||
subgraph omniroute
|
||||
E[Handler Layer]
|
||||
F[Translator Layer]
|
||||
G[Executor Layer]
|
||||
H[Services Layer]
|
||||
end
|
||||
|
||||
subgraph Providers
|
||||
I[Anthropic Claude]
|
||||
J[Google Gemini]
|
||||
K[OpenAI / Codex]
|
||||
L[GitHub Copilot]
|
||||
M[AWS Kiro]
|
||||
N[Antigravity]
|
||||
O[Cursor API]
|
||||
end
|
||||
|
||||
A --> E
|
||||
B --> E
|
||||
C --> E
|
||||
D --> E
|
||||
E --> F
|
||||
F --> G
|
||||
G --> I
|
||||
G --> J
|
||||
G --> K
|
||||
G --> L
|
||||
G --> M
|
||||
G --> N
|
||||
G --> O
|
||||
H -.-> E
|
||||
H -.-> G
|
||||
```
|
||||
|
||||
### Kerneprincip: Hub-and-Speake-oversættelse
|
||||
|
||||
Al formatoversættelse passerer gennem **OpenAI-formatet som hub**:
|
||||
|
||||
```
|
||||
Client Format → [OpenAI Hub] → Provider Format (request)
|
||||
Provider Format → [OpenAI Hub] → Client Format (response)
|
||||
```
|
||||
|
||||
Det betyder, at du kun behøver **N oversættere** (én pr. format) i stedet for **N²** (hvert par).
|
||||
|
||||
---
|
||||
|
||||
## 3. Projektstruktur
|
||||
|
||||
```
|
||||
omniroute/
|
||||
├── open-sse/ ← Core proxy library (portable, framework-agnostic)
|
||||
│ ├── index.js ← Main entry point, exports everything
|
||||
│ ├── config/ ← Configuration & constants
|
||||
│ ├── executors/ ← Provider-specific request execution
|
||||
│ ├── handlers/ ← Request handling orchestration
|
||||
│ ├── services/ ← Business logic (auth, models, fallback, usage)
|
||||
│ ├── translator/ ← Format translation engine
|
||||
│ │ ├── request/ ← Request translators (8 files)
|
||||
│ │ ├── response/ ← Response translators (7 files)
|
||||
│ │ └── helpers/ ← Shared translation utilities (6 files)
|
||||
│ └── utils/ ← Utility functions
|
||||
├── src/ ← Application layer (Express/Worker runtime)
|
||||
│ ├── app/ ← Web UI, API routes, middleware
|
||||
│ ├── lib/ ← Database, auth, and shared library code
|
||||
│ ├── mitm/ ← Man-in-the-middle proxy utilities
|
||||
│ ├── models/ ← Database models
|
||||
│ ├── shared/ ← Shared utilities (wrappers around open-sse)
|
||||
│ ├── sse/ ← SSE endpoint handlers
|
||||
│ └── store/ ← State management
|
||||
├── data/ ← Runtime data (credentials, logs)
|
||||
│ └── provider-credentials.json (external credentials override, gitignored)
|
||||
└── tester/ ← Test utilities
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Modul-for-modul-opdeling
|
||||
|
||||
### 4.1 Config (`open-sse/config/`)
|
||||
|
||||
Den **enkelte kilde til sandhed** for alle udbyderkonfigurationer.
|
||||
|
||||
| Fil | Formål |
|
||||
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `constants.ts` | `PROVIDERS` objekt med basis-URL'er, OAuth-legitimationsoplysninger (standarder), headere og standardsystemprompter for hver udbyder. Definerer også `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG` og `SKIP_PATTERNS`. |
|
||||
| `credentialLoader.ts` | Indlæser eksterne legitimationsoplysninger fra `data/provider-credentials.json` og fletter dem over de hårdkodede standardindstillinger i `PROVIDERS`. Holder hemmeligheder uden for kildekontrol og bevarer bagudkompatibilitet. |
|
||||
| `providerModels.ts` | Central modelregistrering: kortudbyderaliasser → model-id'er. Funktioner som `getModels()`, `getProviderByAlias()`. |
|
||||
| `codexInstructions.ts` | Systeminstruktioner indsat i Codex-anmodninger (redigeringsbegrænsninger, sandkasseregler, godkendelsespolitikker). |
|
||||
| `defaultThinkingSignature.ts` | Standard "tænkende" signaturer for Claude og Gemini modeller. |
|
||||
| `ollamaModels.ts` | Skemadefinition for lokale Ollama-modeller (navn, størrelse, familie, kvantisering). |
|
||||
|
||||
#### Credential Loading Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["App starts"] --> B["constants.ts defines PROVIDERS\nwith hardcoded defaults"]
|
||||
B --> C{"data/provider-credentials.json\nexists?"}
|
||||
C -->|Yes| D["credentialLoader reads JSON"]
|
||||
C -->|No| E["Use hardcoded defaults"]
|
||||
D --> F{"For each provider in JSON"}
|
||||
F --> G{"Provider exists\nin PROVIDERS?"}
|
||||
G -->|No| H["Log warning, skip"]
|
||||
G -->|Yes| I{"Value is object?"}
|
||||
I -->|No| J["Log warning, skip"]
|
||||
I -->|Yes| K["Merge clientId, clientSecret,\ntokenUrl, authUrl, refreshUrl"]
|
||||
K --> F
|
||||
H --> F
|
||||
J --> F
|
||||
F -->|Done| L["PROVIDERS ready with\nmerged credentials"]
|
||||
E --> L
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Eksekutører (`open-sse/executors/`)
|
||||
|
||||
Eksekutører indkapsler **udbyderspecifik logik** ved hjælp af **Strategy Pattern**. Hver executor tilsidesætter basismetoder efter behov.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class BaseExecutor {
|
||||
+buildUrl(model, stream, options)
|
||||
+buildHeaders(credentials, stream, body)
|
||||
+transformRequest(body, model, stream, credentials)
|
||||
+execute(url, options)
|
||||
+shouldRetry(status, error)
|
||||
+refreshCredentials(credentials, log)
|
||||
}
|
||||
|
||||
class DefaultExecutor {
|
||||
+refreshCredentials()
|
||||
}
|
||||
|
||||
class AntigravityExecutor {
|
||||
+buildUrl()
|
||||
+buildHeaders()
|
||||
+transformRequest()
|
||||
+shouldRetry()
|
||||
+refreshCredentials()
|
||||
}
|
||||
|
||||
class CursorExecutor {
|
||||
+buildUrl()
|
||||
+buildHeaders()
|
||||
+transformRequest()
|
||||
+parseResponse()
|
||||
+generateChecksum()
|
||||
}
|
||||
|
||||
class KiroExecutor {
|
||||
+buildUrl()
|
||||
+buildHeaders()
|
||||
+transformRequest()
|
||||
+parseEventStream()
|
||||
+refreshCredentials()
|
||||
}
|
||||
|
||||
BaseExecutor <|-- DefaultExecutor
|
||||
BaseExecutor <|-- AntigravityExecutor
|
||||
BaseExecutor <|-- CursorExecutor
|
||||
BaseExecutor <|-- KiroExecutor
|
||||
BaseExecutor <|-- CodexExecutor
|
||||
BaseExecutor <|-- GeminiCLIExecutor
|
||||
BaseExecutor <|-- GithubExecutor
|
||||
```
|
||||
|
||||
| Eksekutør | Udbyder | Nøglespecialiseringer |
|
||||
| ---------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `base.ts` | — | Abstrakt base: URL-opbygning, overskrifter, genforsøgslogik, opdatering af legitimationsoplysninger |
|
||||
| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Generisk OAuth-tokenopdatering til standardudbydere |
|
||||
| `antigravity.ts` | Google Cloud-kode | Generering af projekt-/sessions-id, multi-URL fallback, brugerdefineret genforsøg at parse fra fejlmeddelelser ("nulstil efter 2t7m23s") |
|
||||
| `cursor.ts` | Markør IDE | **Mest kompleks**: SHA-256 checksum auth, Protobuf request encoding, binær EventStream → SSE respons parsing |
|
||||
| `codex.ts` | OpenAI Codex | Injicerer systeminstruktioner, styrer tankeniveauer, fjerner ikke-understøttede parametre |
|
||||
| `gemini-cli.ts` | Google Gemini CLI | Opbygning af tilpasset URL (`streamGenerateContent`), opdatering af Google OAuth-token |
|
||||
| `github.ts` | GitHub Copilot | Dobbelt token-system (GitHub OAuth + Copilot-token), VSCode-header-efterligning |
|
||||
| `kiro.ts` | AWS CodeWhisperer | AWS EventStream binær parsing, AMZN hændelsesrammer, token estimering |
|
||||
| `index.ts` | — | Fabrik: navn på kortudbyder → eksekveringsklasse, med standard fallback |
|
||||
|
||||
---
|
||||
|
||||
### 4.3 Håndtere (`open-sse/handlers/`)
|
||||
|
||||
**Orkestreringslaget** — koordinerer oversættelse, udførelse, streaming og fejlhåndtering.
|
||||
|
||||
| Fil | Formål |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `chatCore.ts` | **Central orkestrator** (~600 linjer). Håndterer hele forespørgselslivscyklussen: formatdetektion → oversættelse → eksekutørafsendelse → streaming/ikke-streamingsvar → token-opdatering → fejlhåndtering → logføring af brug. |
|
||||
| `responsesHandler.ts` | Adapter til OpenAI's Responses API: konverterer svarformat → Chatfuldførelser → sender til `chatCore` → konverterer SSE tilbage til svarformat. |
|
||||
| `embeddings.ts` | Indlejringsgenereringshåndtering: løser indlejringsmodel → udbyder, sender til udbyder API, returnerer OpenAI-kompatibelt indlejringssvar. Understøtter 6+ udbydere. |
|
||||
| `imageGeneration.ts` | Billedgenereringshåndtering: løser billedmodel → udbyder, understøtter OpenAI-kompatibel, Gemini-image (Antigravity) og fallback (Nebius) tilstande. Returnerer base64- eller URL-billeder. |
|
||||
|
||||
#### Anmod om livscyklus (chatCore.ts)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client
|
||||
participant chatCore
|
||||
participant Translator
|
||||
participant Executor
|
||||
participant Provider
|
||||
|
||||
Client->>chatCore: Request (any format)
|
||||
chatCore->>chatCore: Detect source format
|
||||
chatCore->>chatCore: Check bypass patterns
|
||||
chatCore->>chatCore: Resolve model & provider
|
||||
chatCore->>Translator: Translate request (source → OpenAI → target)
|
||||
chatCore->>Executor: Get executor for provider
|
||||
Executor->>Executor: Build URL, headers, transform request
|
||||
Executor->>Executor: Refresh credentials if needed
|
||||
Executor->>Provider: HTTP fetch (streaming or non-streaming)
|
||||
|
||||
alt Streaming
|
||||
Provider-->>chatCore: SSE stream
|
||||
chatCore->>chatCore: Pipe through SSE transform stream
|
||||
Note over chatCore: Transform stream translates<br/>each chunk: target → OpenAI → source
|
||||
chatCore-->>Client: Translated SSE stream
|
||||
else Non-streaming
|
||||
Provider-->>chatCore: JSON response
|
||||
chatCore->>Translator: Translate response
|
||||
chatCore-->>Client: Translated JSON
|
||||
end
|
||||
|
||||
alt Error (401, 429, 500...)
|
||||
chatCore->>Executor: Retry with credential refresh
|
||||
chatCore->>chatCore: Account fallback logic
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.4 Tjenester (`open-sse/services/`)
|
||||
|
||||
Forretningslogik, der understøtter behandlerne og udførerne.
|
||||
|
||||
| Fil | Formål |
|
||||
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `provider.ts` | **Formatregistrering** (`detectFormat`): analyser anmoder om kropsstruktur for at identificere Claude/OpenAI/Gemini/Antigravity/Responses-formater (inkluderer `max_tokens` heuristik for Claude). Også: URL-opbygning, header-opbygning, normalisering af tænkekonfig. Understøtter `openai-compatible-*` og `anthropic-compatible-*` dynamiske udbydere. |
|
||||
| `model.ts` | Modelstrengparsing (`claude/model-name` → `{provider: "claude", model: "model-name"}`), alias-opløsning med kollisionsdetektion, input-sanering (afviser stigennemgang/kontroltegn) og modelinformationsopløsning med understøttelse af async alias getter. |
|
||||
| `accountFallback.ts` | Håndtering af hastighedsgrænser: eksponentiel backoff (1s → 2s → 4s → max 2min), kontoafkølingsstyring, fejlklassificering (hvilke fejl udløser fallback vs. ikke). |
|
||||
| `tokenRefresh.ts` | Opdatering af OAuth-token for **alle udbydere**: Google (Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). Inkluderer under flyvning lover deduplikation cache og forsøg igen med eksponentiel backoff. |
|
||||
| `combo.ts` | **Combo-modeller**: kæder af reservemodeller. Hvis model A fejler med en fallback-kvalificeret fejl, prøv model B, derefter C osv. Returnerer faktiske upstream-statuskoder. |
|
||||
| `usage.ts` | Henter kvote-/brugsdata fra udbyder-API'er (GitHub Copilot-kvoter, Antigravity-modelkvoter, Codex-hastighedsgrænser, Kiro-brugsopdelinger, Claude-indstillinger). |
|
||||
| `accountSelector.ts` | Smart kontovalg med scoringsalgoritme: overvejer prioritet, sundhedsstatus, round-robin-position og nedkølingstilstand for at vælge den optimale konto for hver anmodning. |
|
||||
| `contextManager.ts` | Anmodningskontekstlivscyklusstyring: opretter og sporer kontekstobjekter pr. anmodning med metadata (anmodnings-id, tidsstempler, udbyderoplysninger) til fejlretning og logning. |
|
||||
| `ipFilter.ts` | IP-baseret adgangskontrol: understøtter tilladelsesliste og bloklistetilstande. Validerer klient-IP mod konfigurerede regler, før API-anmodninger behandles. |
|
||||
| `sessionManager.ts` | Sessionssporing med klientfingeraftryk: sporer aktive sessioner ved hjælp af hashed klient-id'er, overvåger antallet af anmodninger og leverer sessionsmetrics. |
|
||||
| `signatureCache.ts` | Anmod om signaturbaseret deduplikeringscache: forhindrer duplikerede anmodninger ved at cache de seneste anmodningssignaturer og returnere cachelagrede svar for identiske anmodninger inden for et tidsvindue. |
|
||||
| `systemPrompt.ts` | Global systemprompt-injektion: forudsætter eller tilføjer en konfigurerbar systemprompt til alle anmodninger med kompatibilitetshåndtering pr. udbyder. |
|
||||
| `thinkingBudget.ts` | Reasoning token budget management: understøtter passthrough, auto (strip thinking config), brugerdefineret (fast budget) og adaptive (kompleksitetsskaleret) tilstande til at kontrollere tanke/ræsonnement tokens. |
|
||||
| `wildcardRouter.ts` | Routing af jokertegnmodelmønster: løser jokertegnmønstre (f.eks. `*/claude-*`) til konkrete udbyder/modelpar baseret på tilgængelighed og prioritet. |
|
||||
|
||||
#### Token Refresh Deduplication
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant R1 as Request 1
|
||||
participant R2 as Request 2
|
||||
participant Cache as refreshPromiseCache
|
||||
participant OAuth as OAuth Provider
|
||||
|
||||
R1->>Cache: getAccessToken("gemini", token)
|
||||
Cache->>Cache: No in-flight promise
|
||||
Cache->>OAuth: Start refresh
|
||||
R2->>Cache: getAccessToken("gemini", token)
|
||||
Cache->>Cache: Found in-flight promise
|
||||
Cache-->>R2: Return existing promise
|
||||
OAuth-->>Cache: New access token
|
||||
Cache-->>R1: New access token
|
||||
Cache-->>R2: Same access token (shared)
|
||||
Cache->>Cache: Delete cache entry
|
||||
```
|
||||
|
||||
#### Account Fallback State Machine
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Active
|
||||
Active --> Error: Request fails (401/429/500)
|
||||
Error --> Cooldown: Apply backoff
|
||||
Cooldown --> Active: Cooldown expires
|
||||
Active --> Active: Request succeeds (reset backoff)
|
||||
|
||||
state Error {
|
||||
[*] --> ClassifyError
|
||||
ClassifyError --> ShouldFallback: Rate limit / Auth / Transient
|
||||
ClassifyError --> NoFallback: 400 Bad Request
|
||||
}
|
||||
|
||||
state Cooldown {
|
||||
[*] --> ExponentialBackoff
|
||||
ExponentialBackoff: Level 0 = 1s
|
||||
ExponentialBackoff: Level 1 = 2s
|
||||
ExponentialBackoff: Level 2 = 4s
|
||||
ExponentialBackoff: Max = 2min
|
||||
}
|
||||
```
|
||||
|
||||
#### Kombi-modelkæde
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Request with\ncombo model"] --> B["Model A"]
|
||||
B -->|"2xx Success"| C["Return response"]
|
||||
B -->|"429/401/500"| D{"Fallback\neligible?"}
|
||||
D -->|Yes| E["Model B"]
|
||||
D -->|No| F["Return error"]
|
||||
E -->|"2xx Success"| C
|
||||
E -->|"429/401/500"| G{"Fallback\neligible?"}
|
||||
G -->|Yes| H["Model C"]
|
||||
G -->|No| F
|
||||
H -->|"2xx Success"| C
|
||||
H -->|"Fail"| I["All failed →\nReturn last status"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.5 Oversætter (`open-sse/translator/`)
|
||||
|
||||
**formatoversættelsesmotoren** ved hjælp af et selvregistrerende plugin-system.
|
||||
|
||||
#### Arkitektur
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "Request Translation"
|
||||
A["Claude → OpenAI"]
|
||||
B["Gemini → OpenAI"]
|
||||
C["Antigravity → OpenAI"]
|
||||
D["OpenAI Responses → OpenAI"]
|
||||
E["OpenAI → Claude"]
|
||||
F["OpenAI → Gemini"]
|
||||
G["OpenAI → Kiro"]
|
||||
H["OpenAI → Cursor"]
|
||||
end
|
||||
|
||||
subgraph "Response Translation"
|
||||
I["Claude → OpenAI"]
|
||||
J["Gemini → OpenAI"]
|
||||
K["Kiro → OpenAI"]
|
||||
L["Cursor → OpenAI"]
|
||||
M["OpenAI → Claude"]
|
||||
N["OpenAI → Antigravity"]
|
||||
O["OpenAI → Responses"]
|
||||
end
|
||||
```
|
||||
|
||||
| Katalog | Filer | Beskrivelse |
|
||||
| ------------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `request/` | 8 oversættere | Konverter anmodningstekster mellem formater. Hver fil selvregistreres via `register(from, to, fn)` ved import. |
|
||||
| `response/` | 7 oversættere | Konverter streamingsvarstykker mellem formater. Håndterer SSE-hændelsestyper, tænkeblokke, værktøjskald. |
|
||||
| `helpers/` | 6 hjælpere | Delte hjælpeprogrammer: `claudeHelper` (udtræk af systemprompt, tænkekonfiguration), `geminiHelper` (kortlægning af dele/indhold), `openaiHelper` (formatfiltrering), `toolCallHelper` (ID-generering, manglende svarindsprøjtning), `maxTokensHelper`, `responsesApiHelper`. |
|
||||
| `index.ts` | — | Oversættelsesmaskine: `translateRequest()`, `translateResponse()`, statsledelse, register. |
|
||||
| `formats.ts` | — | Formatkonstanter: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. |
|
||||
|
||||
#### Nøgledesign: Selvregistrerende plugins
|
||||
|
||||
```javascript
|
||||
// Each translator file calls register() on import:
|
||||
import { register } from "../index.js";
|
||||
register("claude", "openai", translateClaudeToOpenAI);
|
||||
|
||||
// The index.js imports all translator files, triggering registration:
|
||||
import "./request/claude-to-openai.js"; // ← self-registers
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.6 Utils (`open-sse/utils/`)
|
||||
|
||||
| Fil | Formål |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `error.ts` | Opbygning af fejlsvar (OpenAI-kompatibelt format), upstream fejlparsing, Antigravity genforsøgstidsudtrækning fra fejlmeddelelser, SSE fejlstreaming. |
|
||||
| `stream.ts` | **SSE Transform Stream** — den centrale streamingpipeline. To tilstande: `TRANSLATE` (fuldformatoversættelse) og `PASSTHROUGH` (normalisering + ekstraktionsbrug). Håndterer chunk-buffring, brugsestimering, indholdslængdesporing. Per-stream encoder/decoder-instanser undgår delt tilstand. |
|
||||
| `streamHelpers.ts` | SSE-værktøjer på lavt niveau: `parseSSELine` (whitespace-tolerant), `hasValuableContent` (filtrerer tomme bidder til OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (format-bevidst SSETOKEN_101\*\* oprydning med oprydning med ). |
|
||||
| `usageTracking.ts` | Udtræk af tokenbrug fra ethvert format (Claude/OpenAI/Gemini/Responses), estimering med separate værktøj/meddelelse-char-per-token-forhold, buffertilsætning (2000 tokens sikkerhedsmargen), formatspecifik feltfiltrering, konsollogning med ANSI-farver. |
|
||||
| `requestLogger.ts` | Filbaseret anmodningslogning (tilmelding via `ENABLE_REQUEST_LOGS=true`). Opretter sessionsmapper med nummererede filer: `1_req_client.json` → `7_res_client.txt`. Alle I/O er asynkrone (fire-and-forget). Masker følsomme overskrifter. |
|
||||
| `bypassHandler.ts` | Opsnapper specifikke mønstre fra Claude CLI (titeludtræk, opvarmning, optælling) og returnerer falske svar uden at ringe til nogen udbyder. Understøtter både streaming og ikke-streaming. Med vilje begrænset til Claude CLI-omfang. |
|
||||
| `networkProxy.ts` | Løser udgående proxy-URL for en given udbyder med forrang: udbyderspecifik konfiguration → global konfiguration → miljøvariabler (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Understøtter `NO_PROXY` ekskluderinger. Caches konfiguration for 30'erne. |
|
||||
|
||||
#### SSE Streaming Pipeline
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"]
|
||||
B --> C["Buffer lines\n(split on newline)"]
|
||||
C --> D["parseSSELine()\n(trim whitespace, parse JSON)"]
|
||||
D --> E{"Mode?"}
|
||||
E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"]
|
||||
E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"]
|
||||
F --> H["hasValuableContent()\nfilter empty chunks"]
|
||||
G --> H
|
||||
H -->|"Has content"| I["extractUsage()\ntrack token counts"]
|
||||
H -->|"Empty"| J["Skip chunk"]
|
||||
I --> K["formatSSE()\nserialize + clean perf_metrics"]
|
||||
K --> L["TextEncoder\n(per-stream instance)"]
|
||||
L --> M["Enqueue to\nclient stream"]
|
||||
|
||||
style A fill:#f9f,stroke:#333
|
||||
style M fill:#9f9,stroke:#333
|
||||
```
|
||||
|
||||
#### Anmod om loggersessionsstruktur
|
||||
|
||||
```
|
||||
logs/
|
||||
└── claude_gemini_claude-sonnet_20260208_143045/
|
||||
├── 1_req_client.json ← Raw client request
|
||||
├── 2_req_source.json ← After initial conversion
|
||||
├── 3_req_openai.json ← OpenAI intermediate format
|
||||
├── 4_req_target.json ← Final target format
|
||||
├── 5_res_provider.txt ← Provider SSE chunks (streaming)
|
||||
├── 5_res_provider.json ← Provider response (non-streaming)
|
||||
├── 6_res_openai.txt ← OpenAI intermediate chunks
|
||||
├── 7_res_client.txt ← Client-facing SSE chunks
|
||||
└── 6_error.json ← Error details (if any)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.7 applikationslag (`src/`)
|
||||
|
||||
| Katalog | Formål |
|
||||
| ------------- | ---------------------------------------------------------------------------- |
|
||||
| `src/app/` | Web-UI, API-ruter, Express-middleware, OAuth-tilbagekaldsbehandlere |
|
||||
| `src/lib/` | Databaseadgang (`localDb.ts`, `usageDb.ts`), godkendelse, delt |
|
||||
| `src/mitm/` | Man-in-the-middle proxy-værktøjer til at opsnappe udbydertrafik |
|
||||
| `src/models/` | Databasemodeldefinitioner |
|
||||
| `src/shared/` | Indpakninger omkring åben-sse-funktioner (udbyder, stream, fejl osv.) |
|
||||
| `src/sse/` | SSE-slutpunktshandlere, der forbinder open-sse-biblioteket til Express-ruter |
|
||||
| `src/store/` | Administration af applikationstilstand |
|
||||
|
||||
#### Bemærkelsesværdige API-ruter
|
||||
|
||||
| Rute | Metoder | Formål |
|
||||
| --------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| `/api/provider-models` | GET/POST/SLET | CRUD til brugerdefinerede modeller pr. udbyder |
|
||||
| `/api/models/catalog` | FÅ | Samlet katalog over alle modeller (chat, indlejring, billede, brugerdefineret) grupperet efter udbyder |
|
||||
| `/api/settings/proxy` | GET/SETT/SLET | Hierarkisk udgående proxy-konfiguration (`global/providers/combos/keys`) |
|
||||
| `/api/settings/proxy/test` | POST | Validerer proxy-forbindelse og returnerer offentlig IP/latency |
|
||||
| `/v1/providers/[provider]/chat/completions` | POST | Dedikerede chat-afslutninger pr. udbyder med modelvalidering |
|
||||
| `/v1/providers/[provider]/embeddings` | POST | Dedikerede indlejringer pr. udbyder med modelvalidering |
|
||||
| `/v1/providers/[provider]/images/generations` | POST | Dedikeret billedgenerering pr. udbyder med modelvalidering |
|
||||
| `/api/settings/ip-filter` | GET/PUT | Administration af IP-tilladelsesliste/blokeringsliste |
|
||||
| `/api/settings/thinking-budget` | GET/PUT | Begrundelsestokens budgetkonfiguration (passthrough/auto/custom/adaptive) |
|
||||
| `/api/settings/system-prompt` | GET/PUT | Global systemprompt-injektion for alle anmodninger |
|
||||
| `/api/sessions` | FÅ | Aktiv sessionssporing og metrics |
|
||||
| `/api/rate-limits` | FÅ | Satsgrænsestatus pr. konto |
|
||||
|
||||
---
|
||||
|
||||
## 5. Nøgledesignmønstre
|
||||
|
||||
### 5.1 Hub-and-Speake-oversættelse
|
||||
|
||||
Alle formater oversættes gennem **OpenAI-format som hub**. Tilføjelse af en ny udbyder kræver kun at skrive **et par** af oversættere (til/fra OpenAI), ikke N par.
|
||||
|
||||
### 5.2 Eksekutørstrategimønster
|
||||
|
||||
Hver udbyder har en dedikeret eksekveringsklasse, der arver fra `BaseExecutor`. Fabrikken i `executors/index.ts` vælger den rigtige ved kørsel.
|
||||
|
||||
### 5.3 Selvregistrerende plugin-system
|
||||
|
||||
Oversættermoduler registrerer sig selv ved import via `register()`. Tilføjelse af en ny oversætter er blot at oprette en fil og importere den.
|
||||
|
||||
### 5.4 Account Fallback med eksponentiel backoff
|
||||
|
||||
Når en udbyder returnerer 429/401/500, kan systemet skifte til den næste konto ved at anvende eksponentielle nedkøling (1s → 2s → 4s → max 2min).
|
||||
|
||||
### 5.5 Combo modelkæder
|
||||
|
||||
En "combo" grupperer flere `provider/model` strenge. Hvis den første fejler, går du automatisk tilbage til den næste.
|
||||
|
||||
### 5.6 Stateful streaming-oversættelse
|
||||
|
||||
Svaroversættelse opretholder tilstand på tværs af SSE-chunks (tænkebloksporing, akkumulering af værktøjsopkald, indholdsblokindeksering) via `initState()`-mekanismen.
|
||||
|
||||
### 5.7 Sikkerhedsbuffer for brug
|
||||
|
||||
En 2000-token buffer tilføjes til rapporteret brug for at forhindre klienter i at ramme kontekstvinduegrænser på grund af overhead fra systemprompter og formatoversættelse.
|
||||
|
||||
---
|
||||
|
||||
## 6. Understøttede formater
|
||||
|
||||
| Format | Retning | Identifikator |
|
||||
| ------------------------ | ----------- | ------------------ |
|
||||
| OpenAI Chat fuldførelser | kilde + mål | `openai` |
|
||||
| OpenAI Responses API | kilde + mål | `openai-responses` |
|
||||
| Antropiske Claude | kilde + mål | `claude` |
|
||||
| Google Gemini | kilde + mål | `gemini` |
|
||||
| Google Gemini CLI | kun mål | `gemini-cli` |
|
||||
| Antigravitation | kilde + mål | `antigravity` |
|
||||
| AWS Kiro | kun mål | `kiro` |
|
||||
| Markør | kun mål | `cursor` |
|
||||
|
||||
---
|
||||
|
||||
## 7. Understøttede udbydere
|
||||
|
||||
| Udbyder | Auth metode | Eksekutør | Nøglebemærkninger |
|
||||
| ------------------------ | ----------------------------- | --------------- | ----------------------------------------------- |
|
||||
| Antropiske Claude | API-nøgle eller OAuth | Standard | Bruger `x-api-key` header |
|
||||
| Google Gemini | API-nøgle eller OAuth | Standard | Bruger `x-goog-api-key` header |
|
||||
| Google Gemini CLI | OAuth | GeminiCLI | Bruger `streamGenerateContent` slutpunkt |
|
||||
| Antigravitation | OAuth | Antigravitation | Multi-URL fallback, tilpasset genforsøg parsing |
|
||||
| OpenAI | API nøgle | Standard | Standard bærer auth |
|
||||
| Codex | OAuth | Codex | Injicerer systeminstruktioner, styrer tænkning |
|
||||
| GitHub Copilot | OAuth + Copilot-token | Github | Dobbelt token, VSCode-header-efterligning |
|
||||
| Kiro (AWS) | AWS SSO OIDC eller Social | Kiro | Binær EventStream-parsing |
|
||||
| Markør IDE | Kontrolsum auth | Markør | Protobuf-kodning, SHA-256 kontrolsummer |
|
||||
| Qwen | OAuth | Standard | Standard auth |
|
||||
| iFlow | OAuth (grundlæggende + bærer) | Standard | Dobbelt godkendelseshoved |
|
||||
| OpenRouter | API nøgle | Standard | Standard bærer auth |
|
||||
| GLM, Kimi, MiniMax | API nøgle | Standard | Claude-kompatibel, brug `x-api-key` |
|
||||
| `openai-compatible-*` | API nøgle | Standard | Dynamisk: ethvert OpenAI-kompatibelt slutpunkt |
|
||||
| `anthropic-compatible-*` | API nøgle | Standard | Dynamisk: ethvert Claude-kompatibelt slutpunkt |
|
||||
|
||||
---
|
||||
|
||||
## 8. Oversigt over dataflow
|
||||
|
||||
### Streaminganmodning
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Client"] --> B["detectFormat()"]
|
||||
B --> C["translateRequest()\nsource → OpenAI → target"]
|
||||
C --> D["Executor\nbuildUrl + buildHeaders"]
|
||||
D --> E["fetch(providerURL)"]
|
||||
E --> F["createSSEStream()\nTRANSLATE mode"]
|
||||
F --> G["parseSSELine()"]
|
||||
G --> H["translateResponse()\ntarget → OpenAI → source"]
|
||||
H --> I["extractUsage()\n+ addBuffer"]
|
||||
I --> J["formatSSE()"]
|
||||
J --> K["Client receives\ntranslated SSE"]
|
||||
K --> L["logUsage()\nsaveRequestUsage()"]
|
||||
```
|
||||
|
||||
### Ikke-streamende anmodning
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Client"] --> B["detectFormat()"]
|
||||
B --> C["translateRequest()\nsource → OpenAI → target"]
|
||||
C --> D["Executor.execute()"]
|
||||
D --> E["translateResponse()\ntarget → OpenAI → source"]
|
||||
E --> F["Return JSON\nresponse"]
|
||||
```
|
||||
|
||||
### Bypass Flow (Claude CLI)
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Claude CLI request"] --> B{"Match bypass\npattern?"}
|
||||
B -->|"Title/Warmup/Count"| C["Generate fake\nOpenAI response"]
|
||||
B -->|"No match"| D["Normal flow"]
|
||||
C --> E["Translate to\nsource format"]
|
||||
E --> F["Return without\ncalling provider"]
|
||||
```
|
||||
@@ -0,0 +1,77 @@
|
||||
# OmniRoute — Dashboard Feature Gallery
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../FEATURES.md) | 🇧🇷 [Português (Brasil)](../pt-BR/FEATURES.md) | 🇪🇸 [Español](../es/FEATURES.md) | 🇫🇷 [Français](../fr/FEATURES.md) | 🇮🇹 [Italiano](../it/FEATURES.md) | 🇷🇺 [Русский](../ru/FEATURES.md) | 🇨🇳 [中文 (简体)](../zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](../de/FEATURES.md) | 🇮🇳 [हिन्दी](../in/FEATURES.md) | 🇹🇭 [ไทย](../th/FEATURES.md) | 🇺🇦 [Українська](../uk-UA/FEATURES.md) | 🇸🇦 [العربية](../ar/FEATURES.md) | 🇯🇵 [日本語](../ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](../vi/FEATURES.md) | 🇧🇬 [Български](../bg/FEATURES.md) | 🇩🇰 [Dansk](../da/FEATURES.md) | 🇫🇮 [Suomi](../fi/FEATURES.md) | 🇮🇱 [עברית](../he/FEATURES.md) | 🇭🇺 [Magyar](../hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](../id/FEATURES.md) | 🇰🇷 [한국어](../ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](../ms/FEATURES.md) | 🇳🇱 [Nederlands](../nl/FEATURES.md) | 🇳🇴 [Norsk](../no/FEATURES.md) | 🇵🇹 [Português (Portugal)](../pt/FEATURES.md) | 🇷🇴 [Română](../ro/FEATURES.md) | 🇵🇱 [Polski](../pl/FEATURES.md) | 🇸🇰 [Slovenčina](../sk/FEATURES.md) | 🇸🇪 [Svenska](../sv/FEATURES.md) | 🇵🇭 [Filipino](../phi/FEATURES.md)
|
||||
|
||||
Visuel guide til hver sektion af OmniRoute-dashboardet.
|
||||
|
||||
---
|
||||
|
||||
## 🔌 Udbydere
|
||||
|
||||
Administrer AI-udbyderforbindelser: OAuth-udbydere (Claude Code, Codex, Gemini CLI), API-nøgleudbydere (Groq, DeepSeek, OpenRouter) og gratis udbydere (iFlow, Qwen, Kiro).
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🎨 Kombinationer
|
||||
|
||||
Opret modelrouting-kombinationer med 6 strategier: Fyld-først, round-robin, power-of-to-choices, tilfældig, mindst brugt og omkostningsoptimeret. Hver combo kæder flere modeller med automatisk fallback.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 📊 Analyse
|
||||
|
||||
Omfattende brugsanalyse med token-forbrug, omkostningsestimater, aktivitetsvarmekort, ugentlige distributionsdiagrammer og opdelinger pr. udbyder.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🏥 Systemsundhed
|
||||
|
||||
Overvågning i realtid: oppetid, hukommelse, version, latency percentiler (p50/p95/p99), cache-statistik og udbyderens afbrydertilstande.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🔧 Oversætterlegeplads
|
||||
|
||||
Fire tilstande til fejlfinding af API-oversættelser: **Playground** (formatkonverter), **Chat Tester** (live-anmodninger), **Test Bench** (batchtest) og **Live Monitor** (streaming i realtid).
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Indstillinger
|
||||
|
||||
Generelle indstillinger, systemlagring, backup-styring (eksport/import-database), udseende (mørk/lys-tilstand), sikkerhed (inkluderer API-endepunktsbeskyttelse og blokering af tilpasset udbyder), routing, modstandsdygtighed og avanceret konfiguration.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🔧 CLI-værktøjer
|
||||
|
||||
Et-klik-konfiguration til AI-kodningsværktøjer: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code og Antigravity.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 📝 Anmodningslogs
|
||||
|
||||
Logning af anmodninger i realtid med filtrering efter udbyder, model, konto og API-nøgle. Viser statuskoder, tokenbrug, latenstid og svardetaljer.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🌐 API-endepunkt
|
||||
|
||||
Dit forenede API-slutpunkt med kapacitetsopdeling: Chatfuldførelser, indlejringer, billedgenerering, omrangering, lydtransskription og registrerede API-nøgler.
|
||||
|
||||

|
||||
@@ -0,0 +1,219 @@
|
||||
# Fejlfinding
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](../es/TROUBLESHOOTING.md) | 🇫🇷 [Français](../fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](../bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](../ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../phi/TROUBLESHOOTING.md)
|
||||
|
||||
Almindelige problemer og løsninger til OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## Hurtige rettelser
|
||||
|
||||
| Problem | Løsning |
|
||||
| -------------------------------------- | --------------------------------------------------------------------------- |
|
||||
| Første login virker ikke | Tjek `INITIAL_PASSWORD` i `.env` (standard: `123456`) |
|
||||
| Dashboard åbner ved forkert port | Sæt `PORT=20128` og `NEXT_PUBLIC_BASE_URL=http://localhost:20128` |
|
||||
| Ingen anmodningslogfiler under `logs/` | Sæt `ENABLE_REQUEST_LOGS=true` |
|
||||
| EACCES: tilladelse nægtet | Indstil `DATA_DIR=/path/to/writable/dir` til at tilsidesætte `~/.omniroute` |
|
||||
| Routingstrategi gemmer ikke | Opdatering til v1.4.11+ (Zod-skemafix for indstillinger persistens) |
|
||||
|
||||
---
|
||||
|
||||
## Udbyderproblemer
|
||||
|
||||
### "Sprogmodellen leverede ikke beskeder"
|
||||
|
||||
**Årsag:** Udbyderkvoten er opbrugt.
|
||||
|
||||
**Ret:**
|
||||
|
||||
1. Tjek dashboard kvotesporing
|
||||
2. Brug en kombination med reserveniveauer
|
||||
3. Skift til billigere/gratis niveau
|
||||
|
||||
### Satsbegrænsende
|
||||
|
||||
**Årsag:** Abonnementskvoten er opbrugt.
|
||||
|
||||
**Ret:**
|
||||
|
||||
- Tilføj reserve: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
|
||||
- Brug GLM/MiniMax som billig backup
|
||||
|
||||
### OAuth-token er udløbet
|
||||
|
||||
OmniRoute opdaterer automatisk tokens. Hvis problemerne fortsætter:
|
||||
|
||||
1. Dashboard → Udbyder → Genopret forbindelse
|
||||
2. Slet og tilføj udbyderforbindelsen igen
|
||||
|
||||
---
|
||||
|
||||
## Skyproblemer
|
||||
|
||||
### Cloud Sync-fejl
|
||||
|
||||
1. Bekræft `BASE_URL` point til din løbeforekomst (f.eks. `http://localhost:20128`)
|
||||
2. Bekræft `CLOUD_URL` punkter til dit cloud-endepunkt (f.eks. `https://omniroute.dev`)
|
||||
3. Hold `NEXT_PUBLIC_*` værdier på linje med værdier på serversiden
|
||||
|
||||
### Cloud `stream=false` Returnerer 500
|
||||
|
||||
**Symptom:** `Unexpected token 'd'...` på cloud-endepunkt til ikke-streamingopkald.
|
||||
|
||||
**Årsag:** Upstream returnerer SSE-nyttelast, mens klienten forventer JSON.
|
||||
|
||||
**Løsning:** Brug `stream=true` til direkte skyopkald. Lokal kørselstid inkluderer SSE→JSON fallback.
|
||||
|
||||
### Cloud siger tilsluttet, men "Ugyldig API-nøgle"
|
||||
|
||||
1. Opret en ny nøgle fra det lokale dashboard (`/api/keys`)
|
||||
2. Kør skysynkronisering: Aktiver sky → Synkroniser nu
|
||||
3. Gamle/ikke-synkroniserede nøgler kan stadig returnere `401` på skyen
|
||||
|
||||
---
|
||||
|
||||
## Docker-problemer
|
||||
|
||||
### CLI-værktøj viser ikke installeret
|
||||
|
||||
1. Tjek runtime-felter: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq`
|
||||
2. For bærbar tilstand: brug billedmål `runner-cli` (bundtede CLI'er)
|
||||
3. For værtsmonteringstilstand: Indstil `CLI_EXTRA_PATHS` og monter værtsbin-mappen som skrivebeskyttet
|
||||
4. Hvis `installed=true` og `runnable=false`: binær blev fundet, men helbredstjekket mislykkedes
|
||||
|
||||
### Hurtig runtime-validering
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Omkostningsproblemer
|
||||
|
||||
### Høje omkostninger
|
||||
|
||||
1. Tjek brugsstatistik i Dashboard → Brug
|
||||
2. Skift primær model til GLM/MiniMax
|
||||
3. Brug gratis niveau (Gemini CLI, iFlow) til ikke-kritiske opgaver
|
||||
4. Indstil omkostningsbudgetter pr. API-nøgle: Dashboard → API-nøgler → Budget
|
||||
|
||||
---
|
||||
|
||||
## Fejlretning
|
||||
|
||||
### Aktiver anmodningslogfiler
|
||||
|
||||
Indstil `ENABLE_REQUEST_LOGS=true` i din `.env` fil. Logfiler vises under biblioteket `logs/`.
|
||||
|
||||
### Tjek udbyderens helbred
|
||||
|
||||
```bash
|
||||
# Health dashboard
|
||||
http://localhost:20128/dashboard/health
|
||||
|
||||
# API health check
|
||||
curl http://localhost:20128/api/monitoring/health
|
||||
```
|
||||
|
||||
### Runtime Storage
|
||||
|
||||
- Hovedtilstand: `${DATA_DIR}/db.json` (udbydere, kombinationer, aliaser, nøgler, indstillinger)
|
||||
- Anvendelse: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`
|
||||
- Anmodningslogfiler: `<repo>/logs/...` (når `ENABLE_REQUEST_LOGS=true`)
|
||||
|
||||
---
|
||||
|
||||
## Circuit Breaker Problemer
|
||||
|
||||
### Udbyder sidder fast i ÅBEN tilstand
|
||||
|
||||
Når en udbyders afbryder er ÅBEN, blokeres anmodninger, indtil nedkølingen udløber.
|
||||
|
||||
**Ret:**
|
||||
|
||||
1. Gå til **Dashboard → Indstillinger → Resiliens**
|
||||
2. Tjek afbryderkortet for den berørte udbyder
|
||||
3. Klik på **Nulstil alle** for at rydde alle afbrydere, eller vent på, at nedkølingen udløber
|
||||
4. Bekræft, at udbyderen faktisk er tilgængelig, før du nulstiller
|
||||
|
||||
### Udbyderen bliver ved med at udløse strømafbryderen
|
||||
|
||||
Hvis en udbyder gentagne gange går i ÅBEN tilstand:
|
||||
|
||||
1. Tjek **Dashboard → Health → Provider Health** for fejlmønsteret
|
||||
2. Gå til **Indstillinger → Resiliens → Udbyderprofiler** og øg fejltærsklen
|
||||
3. Tjek, om udbyderen har ændret API-grænser eller kræver gengodkendelse
|
||||
4. Gennemgå latency-telemetri — høj latenstid kan forårsage timeout-baserede fejl
|
||||
|
||||
---
|
||||
|
||||
## Problemer med lydtransskription
|
||||
|
||||
### "Ikke-understøttet model" fejl
|
||||
|
||||
- Sørg for, at du bruger det korrekte præfiks: `deepgram/nova-3` eller `assemblyai/best`
|
||||
- Bekræft, at udbyderen er tilsluttet i **Dashboard → Udbydere**
|
||||
|
||||
### Transskription returnerer tom eller mislykkes
|
||||
|
||||
- Tjek understøttede lydformater: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`
|
||||
- Bekræft filstørrelsen er inden for udbyderens grænser (typisk < 25 MB)
|
||||
- Tjek gyldigheden af udbyderens API-nøgle på udbyderkortet
|
||||
|
||||
---
|
||||
|
||||
## Oversætter-fejlretning
|
||||
|
||||
Brug **Dashboard → Oversætter** til at fejlfinde problemer med formatoversættelse:
|
||||
|
||||
| Tilstand | Hvornår skal man bruge |
|
||||
| ---------------- | --------------------------------------------------------------------------------------------------------------- |
|
||||
| **Legeplads** | Sammenlign input/output-formater side om side — indsæt en mislykket anmodning for at se, hvordan den oversættes |
|
||||
| **Chattester** | Send livebeskeder og inspicer den fulde anmodnings-/svarnyttelast inklusive overskrifter |
|
||||
| **Testbænk** | Kør batchtest på tværs af formatkombinationer for at finde ud af, hvilke oversættelser der er brudte |
|
||||
| **Live Monitor** | Se anmodningsflow i realtid for at fange periodiske oversættelsesproblemer |
|
||||
|
||||
### Almindelige formatproblemer
|
||||
|
||||
- **Tænke-tags vises ikke** — Tjek, om måludbyderen understøtter tænkning og indstilling af tænkebudget
|
||||
- **Værktøjsopkald falder** — Nogle formatoversættelser kan fjerne ikke-understøttede felter; verificere i Playground-tilstand
|
||||
- **Systemprompt mangler** — Claude og Gemini håndterer systemprompts forskelligt; kontrollere oversættelsesoutput
|
||||
- **SDK returnerer rå streng i stedet for objekt** — Rettet i v1.1.0: Response Sanizer fjerner nu ikke-standardfelter (`x_groq`, `usage_breakdown` osv.), der forårsager OpenAI SDK Pydantic valideringsfejl
|
||||
- **GLM/ERNIE afviser `system` rolle** — Rettet i v1.1.0: Rollenormalisering flettes automatisk systemmeddelelser ind i brugermeddelelser for inkompatible modeller
|
||||
- **`developer` rolle ikke genkendt** — Rettet i v1.1.0: automatisk konverteret til `system` for ikke-OpenAI-udbydere
|
||||
- **`json_schema` virker ikke med Gemini** — Rettet i v1.1.0: `response_format` er nu konverteret til Gemini's `responseMimeType` + `responseSchema`
|
||||
|
||||
---
|
||||
|
||||
## Resiliensindstillinger
|
||||
|
||||
### Automatisk hastighedsgrænse udløses ikke
|
||||
|
||||
- Automatisk hastighedsgrænse gælder kun for API-nøgleudbydere (ikke OAuth/abonnement)
|
||||
- Bekræft, at **Indstillinger → Modstandsdygtighed → Udbyderprofiler** har aktiveret automatisk satsgrænse
|
||||
- Tjek, om udbyderen returnerer `429` statuskoder eller `Retry-After` overskrifter
|
||||
|
||||
### Tuning eksponentiel backoff
|
||||
|
||||
Udbyderprofiler understøtter disse indstillinger:
|
||||
|
||||
- **Base delay** — Indledende ventetid efter første fejl (standard: 1s)
|
||||
- **Maksimal forsinkelse** — Maksimal ventetid (standard: 30s)
|
||||
- **Multiplikator** — Hvor meget skal forsinkelsen øges pr. på hinanden følgende fejl (standard: 2x)
|
||||
|
||||
### Anti-tordenbesætning
|
||||
|
||||
Når mange samtidige anmodninger rammer en hastighedsbegrænset udbyder, bruger OmniRoute mutex + automatisk hastighedsbegrænsning til at serialisere anmodninger og forhindre kaskadefejl. Dette er automatisk for API-nøgleudbydere.
|
||||
|
||||
---
|
||||
|
||||
## Stadig fast?
|
||||
|
||||
- **GitHub-problemer**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **Arkitektur**: Se [link](ARCHITECTURE.md) for interne detaljer
|
||||
- **API-reference**: Se [link](API_REFERENCE.md) for alle endepunkter
|
||||
- **Health Dashboard**: Tjek **Dashboard → Health** for systemstatus i realtid
|
||||
- **Oversætter**: Brug **Dashboard → Oversætter** til at fejlsøge formatproblemer
|
||||
@@ -0,0 +1,698 @@
|
||||
# Brugervejledning
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](../es/USER_GUIDE.md) | 🇫🇷 [Français](../fr/USER_GUIDE.md) | 🇮🇹 [Italiano](../it/USER_GUIDE.md) | 🇷🇺 [Русский](../ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](../de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](../in/USER_GUIDE.md) | 🇹🇭 [ไทย](../th/USER_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](../ar/USER_GUIDE.md) | 🇯🇵 [日本語](../ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/USER_GUIDE.md) | 🇧🇬 [Български](../bg/USER_GUIDE.md) | 🇩🇰 [Dansk](../da/USER_GUIDE.md) | 🇫🇮 [Suomi](../fi/USER_GUIDE.md) | 🇮🇱 [עברית](../he/USER_GUIDE.md) | 🇭🇺 [Magyar](../hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/USER_GUIDE.md) | 🇰🇷 [한국어](../ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](../nl/USER_GUIDE.md) | 🇳🇴 [Norsk](../no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/USER_GUIDE.md) | 🇷🇴 [Română](../ro/USER_GUIDE.md) | 🇵🇱 [Polski](../pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/USER_GUIDE.md) | 🇸🇪 [Svenska](../sv/USER_GUIDE.md) | 🇵🇭 [Filipino](../phi/USER_GUIDE.md)
|
||||
|
||||
Komplet guide til konfiguration af udbydere, oprettelse af kombinationer, integration af CLI-værktøjer og implementering af OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## Indholdsfortegnelse
|
||||
|
||||
- [Pricing at a Glance](#-pricing-at-a-glance)
|
||||
- [Use Cases](#-use-cases)
|
||||
- [Provider Setup](#-provider-setup)
|
||||
- [CLI Integration](#-cli-integration)
|
||||
- [Deployment](#-deployment)
|
||||
- [Available Models](#-available-models)
|
||||
- [Advanced Features](#-advanced-features)
|
||||
|
||||
---
|
||||
|
||||
## 💰 Prissætning på et øjeblik
|
||||
|
||||
| Tier | Udbyder | Omkostninger | Kvote nulstilling | Bedst til |
|
||||
| ----------------- | ----------------- | ------------------- | ------------------ | -------------------------- |
|
||||
| **💳 ABONNEMENT** | Claude Code (Pro) | 20 USD/md. | 5 timer + ugentlig | Allerede abonneret |
|
||||
| | Codex (Plus/Pro) | $20-200/md. | 5 timer + ugentlig | OpenAI-brugere |
|
||||
| | Gemini CLI | **GRATIS** | 180K/md + 1K/dag | Alle sammen! |
|
||||
| | GitHub Copilot | $10-19/md. | Månedlig | GitHub-brugere |
|
||||
| **🔑 API NØGLE** | DeepSeek | Betal pr. brug | Ingen | Billig ræsonnement |
|
||||
| | Groq | Betal pr. brug | Ingen | Ultrahurtig slutning |
|
||||
| | xAI (Grok) | Betal pr. brug | Ingen | Grok 4 ræsonnement |
|
||||
| | Mistral | Betal pr. brug | Ingen | EU-hostede modeller |
|
||||
| | Forvirring | Betal pr. brug | Ingen | Søgeforøget |
|
||||
| | Sammen AI | Betal pr. brug | Ingen | Open source-modeller |
|
||||
| | Fyrværkeri AI | Betal pr. brug | Ingen | Fast FLUX billeder |
|
||||
| | Cerebras | Betal pr. brug | Ingen | Wafer-skala hastighed |
|
||||
| | Sammenhæng | Betal pr. brug | Ingen | Kommando R+ RAG |
|
||||
| | NVIDIA NIM | Betal pr. brug | Ingen | Virksomhedsmodeller |
|
||||
| **💰 BILLIG** | GLM-4.7 | 0,6 USD/1 mio. | Dagligt 10:00 | Budget backup |
|
||||
| | MiniMax M2.1 | $0,2/1 mio. | 5-timers rullende | Billigste mulighed |
|
||||
| | Kimi K2 | 9 USD/md. lejlighed | 10M tokens/md. | Forudsigelige omkostninger |
|
||||
| **🆓 GRATIS** | iFlow | $0 | Ubegrænset | 8 modeller gratis |
|
||||
| | Qwen | $0 | Ubegrænset | 3 modeller gratis |
|
||||
| | Kiro | $0 | Ubegrænset | Claude gratis |
|
||||
|
||||
**💡 Pro-tip:** Start med Gemini CLI (180K gratis/måned) + iFlow (ubegrænset gratis) combo = $0 omkostninger!
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Use Cases
|
||||
|
||||
### Case 1: "Jeg har Claude Pro-abonnement"
|
||||
|
||||
**Problem:** Kvoten udløber ubrugt, satsgrænser under tung kodning
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
1. cc/claude-opus-4-6 (use subscription fully)
|
||||
2. glm/glm-4.7 (cheap backup when quota out)
|
||||
3. if/kimi-k2-thinking (free emergency fallback)
|
||||
|
||||
Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
|
||||
vs. $20 + hitting limits = frustration
|
||||
```
|
||||
|
||||
### Case 2: "Jeg vil have nul omkostninger"
|
||||
|
||||
**Problem:** Har ikke råd til abonnementer, har brug for pålidelig AI-kodning
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
1. gc/gemini-3-flash (180K free/month)
|
||||
2. if/kimi-k2-thinking (unlimited free)
|
||||
3. qw/qwen3-coder-plus (unlimited free)
|
||||
|
||||
Monthly cost: $0
|
||||
Quality: Production-ready models
|
||||
```
|
||||
|
||||
### Case 3: "Jeg har brug for 24/7 kodning, ingen afbrydelser"
|
||||
|
||||
**Problem:** Deadlines, har ikke råd til nedetid
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
1. cc/claude-opus-4-6 (best quality)
|
||||
2. cx/gpt-5.2-codex (second subscription)
|
||||
3. glm/glm-4.7 (cheap, resets daily)
|
||||
4. minimax/MiniMax-M2.1 (cheapest, 5h reset)
|
||||
5. if/kimi-k2-thinking (free unlimited)
|
||||
|
||||
Result: 5 layers of fallback = zero downtime
|
||||
Monthly cost: $20-200 (subscriptions) + $10-20 (backup)
|
||||
```
|
||||
|
||||
### Case 4: "Jeg vil have GRATIS AI i OpenClaw"
|
||||
|
||||
**Problem:** Har brug for AI-assistent i beskedapps, helt gratis
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
1. if/glm-4.7 (unlimited free)
|
||||
2. if/minimax-m2.1 (unlimited free)
|
||||
3. if/kimi-k2-thinking (unlimited free)
|
||||
|
||||
Monthly cost: $0
|
||||
Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Udbyderopsætning
|
||||
|
||||
### 🔐 Abonnementsudbydere
|
||||
|
||||
#### Claude Code (Pro/Max)
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect Claude Code
|
||||
→ OAuth login → Auto token refresh
|
||||
→ 5-hour + weekly quota tracking
|
||||
|
||||
Models:
|
||||
cc/claude-opus-4-6
|
||||
cc/claude-sonnet-4-5-20250929
|
||||
cc/claude-haiku-4-5-20251001
|
||||
```
|
||||
|
||||
**Prof tip:** Brug Opus til komplekse opgaver, Sonnet for hurtighed. OmniRoute sporer kvote pr. model!
|
||||
|
||||
#### OpenAI Codex (Plus/Pro)
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect Codex
|
||||
→ OAuth login (port 1455)
|
||||
→ 5-hour + weekly reset
|
||||
|
||||
Models:
|
||||
cx/gpt-5.2-codex
|
||||
cx/gpt-5.1-codex-max
|
||||
```
|
||||
|
||||
#### Gemini CLI (GRATIS 180K/måned!)
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect Gemini CLI
|
||||
→ Google OAuth
|
||||
→ 180K completions/month + 1K/day
|
||||
|
||||
Models:
|
||||
gc/gemini-3-flash-preview
|
||||
gc/gemini-2.5-pro
|
||||
```
|
||||
|
||||
**Bedste værdi:** Kæmpe gratis niveau! Brug dette før betalte niveauer.
|
||||
|
||||
#### GitHub Copilot
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect GitHub
|
||||
→ OAuth via GitHub
|
||||
→ Monthly reset (1st of month)
|
||||
|
||||
Models:
|
||||
gh/gpt-5
|
||||
gh/claude-4.5-sonnet
|
||||
gh/gemini-3-pro
|
||||
```
|
||||
|
||||
### 💰 Billige udbydere
|
||||
|
||||
#### GLM-4.7 (Daglig nulstilling, $0,6/1 mio.)
|
||||
|
||||
1. Tilmeld dig: [Zhipu AI](https://open.bigmodel.cn/)
|
||||
2. Hent API-nøgle fra Coding Plan
|
||||
3. Dashboard → Tilføj API-nøgle: Udbyder: `glm`, API-nøgle: `your-key`
|
||||
|
||||
**Brug:** `glm/glm-4.7` — **Prof tip:** Kodningsplan tilbyder 3× kvote til 1/7 pris! Nulstil dagligt 10:00.
|
||||
|
||||
#### MiniMax M2.1 (5 timers nulstilling, $0,20/1 mio.)
|
||||
|
||||
1. Tilmeld dig: [MiniMax](https://www.minimax.io/)
|
||||
2. Hent API-nøgle → Dashboard → Tilføj API-nøgle
|
||||
|
||||
**Brug:** `minimax/MiniMax-M2.1` — **Prof tip:** Billigste mulighed for lang sammenhæng (1M tokens)!
|
||||
|
||||
#### Kimi K2 ($9/måned lejlighed)
|
||||
|
||||
1. Abonner: [Moonshot AI](https://platform.moonshot.ai/)
|
||||
2. Hent API-nøgle → Dashboard → Tilføj API-nøgle
|
||||
|
||||
**Brug:** `kimi/kimi-latest` — **Prof tip:** Fast $9/måned for 10M tokens = $0,90/1M effektive omkostninger!
|
||||
|
||||
### 🆓 GRATIS udbydere
|
||||
|
||||
#### iFlow (8 GRATIS modeller)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect iFlow → OAuth login → Unlimited usage
|
||||
|
||||
Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1
|
||||
```
|
||||
|
||||
#### Qwen (3 GRATIS modeller)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect Qwen → Device code auth → Unlimited usage
|
||||
|
||||
Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash
|
||||
```
|
||||
|
||||
#### Kiro (Claude GRATIS)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited
|
||||
|
||||
Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Kombinationer
|
||||
|
||||
### Eksempel 1: Maksimer abonnement → Billig backup
|
||||
|
||||
```
|
||||
Dashboard → Combos → Create New
|
||||
|
||||
Name: premium-coding
|
||||
Models:
|
||||
1. cc/claude-opus-4-6 (Subscription primary)
|
||||
2. glm/glm-4.7 (Cheap backup, $0.6/1M)
|
||||
3. minimax/MiniMax-M2.1 (Cheapest fallback, $0.20/1M)
|
||||
|
||||
Use in CLI: premium-coding
|
||||
```
|
||||
|
||||
### Eksempel 2: Kun gratis (nul omkostninger)
|
||||
|
||||
```
|
||||
Name: free-combo
|
||||
Models:
|
||||
1. gc/gemini-3-flash-preview (180K free/month)
|
||||
2. if/kimi-k2-thinking (unlimited)
|
||||
3. qw/qwen3-coder-plus (unlimited)
|
||||
|
||||
Cost: $0 forever!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 CLI-integration
|
||||
|
||||
### Markør IDE
|
||||
|
||||
```
|
||||
Settings → Models → Advanced:
|
||||
OpenAI API Base URL: http://localhost:20128/v1
|
||||
OpenAI API Key: [from omniroute dashboard]
|
||||
Model: cc/claude-opus-4-6
|
||||
```
|
||||
|
||||
### Claude Code
|
||||
|
||||
Rediger `~/.claude/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"anthropic_api_base": "http://localhost:20128/v1",
|
||||
"anthropic_api_key": "your-omniroute-api-key"
|
||||
}
|
||||
```
|
||||
|
||||
### Codex CLI
|
||||
|
||||
```bash
|
||||
export OPENAI_BASE_URL="http://localhost:20128"
|
||||
export OPENAI_API_KEY="your-omniroute-api-key"
|
||||
codex "your prompt"
|
||||
```
|
||||
|
||||
### OpenClaw
|
||||
|
||||
Rediger `~/.openclaw/openclaw.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": { "primary": "omniroute/if/glm-4.7" }
|
||||
}
|
||||
},
|
||||
"models": {
|
||||
"providers": {
|
||||
"omniroute": {
|
||||
"baseUrl": "http://localhost:20128/v1",
|
||||
"apiKey": "your-omniroute-api-key",
|
||||
"api": "openai-completions",
|
||||
"models": [{ "id": "if/glm-4.7", "name": "glm-4.7" }]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Eller brug Dashboard:** CLI Tools → OpenClaw → Auto-config
|
||||
|
||||
### Cline / Fortsæt / RooCode
|
||||
|
||||
```
|
||||
Provider: OpenAI Compatible
|
||||
Base URL: http://localhost:20128/v1
|
||||
API Key: [from dashboard]
|
||||
Model: cc/claude-opus-4-6
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Implementering
|
||||
|
||||
### VPS-implementering
|
||||
|
||||
```bash
|
||||
git clone https://github.com/diegosouzapw/OmniRoute.git
|
||||
cd OmniRoute && npm install && npm run build
|
||||
|
||||
export JWT_SECRET="your-secure-secret-change-this"
|
||||
export INITIAL_PASSWORD="your-password"
|
||||
export DATA_DIR="/var/lib/omniroute"
|
||||
export PORT="20128"
|
||||
export HOSTNAME="0.0.0.0"
|
||||
export NODE_ENV="production"
|
||||
export NEXT_PUBLIC_BASE_URL="http://localhost:20128"
|
||||
export API_KEY_SECRET="endpoint-proxy-api-key-secret"
|
||||
|
||||
npm run start
|
||||
# Or: pm2 start npm --name omniroute -- start
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
# Build image (default = runner-cli with codex/claude/droid preinstalled)
|
||||
docker build -t omniroute:cli .
|
||||
|
||||
# Portable mode (recommended)
|
||||
docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-data:/app/data omniroute:cli
|
||||
```
|
||||
|
||||
For værtsintegreret tilstand med CLI-binære filer, se Docker-sektionen i hoveddokumenterne.
|
||||
|
||||
### Miljøvariabler
|
||||
|
||||
| Variabel | Standard | Beskrivelse |
|
||||
| --------------------- | ------------------------------------ | ---------------------------------------------------- |
|
||||
| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT signeringshemmelighed (**ændring i produktion**) |
|
||||
| `INITIAL_PASSWORD` | `123456` | Første login-adgangskode |
|
||||
| `DATA_DIR` | `~/.omniroute` | Datamappe (db, forbrug, logfiler) |
|
||||
| `PORT` | ramme standard | Serviceport (`20128` i eksempler) |
|
||||
| `HOSTNAME` | ramme standard | Bind vært (Docker er som standard `0.0.0.0`) |
|
||||
| `NODE_ENV` | runtime default | Indstil `production` til implementering |
|
||||
| `BASE_URL` | `http://localhost:20128` | Intern basis-URL på serversiden |
|
||||
| `CLOUD_URL` | `https://omniroute.dev` | Base URL for slutpunkt for skysynkronisering |
|
||||
| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC-hemmelighed for genererede API-nøgler |
|
||||
| `REQUIRE_API_KEY` | `false` | Gennemtving Bearer API-nøgle på `/v1/*` |
|
||||
| `ENABLE_REQUEST_LOGS` | `false` | Aktiverer anmodnings-/svarlogs |
|
||||
| `AUTH_COOKIE_SECURE` | `false` | Tving `Secure` auth-cookie (bag HTTPS omvendt proxy) |
|
||||
|
||||
For den fulde reference til miljøvariablen, se [README](../README.md).
|
||||
|
||||
---
|
||||
|
||||
## 📊 Tilgængelige modeller
|
||||
|
||||
<details>
|
||||
<summary><b>Se alle tilgængelige modeller</b></summary>
|
||||
|
||||
**Claude Code (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**Codex (`cx/`)** — Plus/Pro: `cx/gpt-5.2-codex`, `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** — GRATIS: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro`
|
||||
|
||||
**GitHub Copilot (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet`
|
||||
|
||||
**GLM (`glm/`)** — 0,6 USD/1 mio.: `glm/glm-4.7`
|
||||
|
||||
**MiniMax (`minimax/`)** — $0,2/1 mio.: `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** — GRATIS: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1`
|
||||
|
||||
**Qwen (`qw/`)** — GRATIS: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash`
|
||||
|
||||
**Kiro (`kr/`)** — GRATIS: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5`
|
||||
|
||||
**DeepSeek (`ds/`)**: `ds/deepseek-chat`, `ds/deepseek-reasoner`
|
||||
|
||||
**Groq (`groq/`)**: `groq/llama-3.3-70b-versatile`, `groq/llama-4-maverick-17b-128e-instruct`
|
||||
|
||||
**xAI (`xai/`)**: `xai/grok-4`, `xai/grok-4-0709-fast-reasoning`, `xai/grok-code-mini`
|
||||
|
||||
**Mistral (`mistral/`)**: `mistral/mistral-large-2501`, `mistral/codestral-2501`
|
||||
|
||||
**Forvirring (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar`
|
||||
|
||||
**Together AI (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo`
|
||||
|
||||
**Fireworks AI (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1`
|
||||
|
||||
**Cerebras (`cerebras/`)**: `cerebras/llama-3.3-70b`
|
||||
|
||||
**Kohere (`cohere/`)**: `cohere/command-r-plus-08-2024`
|
||||
|
||||
**NVIDIA NIM (`nvidia/`)**: `nvidia/nvidia/llama-3.3-70b-instruct`
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🧩 Avancerede funktioner
|
||||
|
||||
### Brugerdefinerede modeller
|
||||
|
||||
Tilføj ethvert model-id til enhver udbyder uden at vente på en appopdatering:
|
||||
|
||||
```bash
|
||||
# Via API
|
||||
curl -X POST http://localhost:20128/api/provider-models \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"provider": "openai", "modelId": "gpt-4.5-preview", "modelName": "GPT-4.5 Preview"}'
|
||||
|
||||
# List: curl http://localhost:20128/api/provider-models?provider=openai
|
||||
# Remove: curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview"
|
||||
```
|
||||
|
||||
Eller brug Dashboard: **Udbydere → [Udbyder] → Brugerdefinerede modeller**.
|
||||
|
||||
### Dedikerede udbyderruter
|
||||
|
||||
Rut anmodninger direkte til en specifik udbyder med modelvalidering:
|
||||
|
||||
```bash
|
||||
POST http://localhost:20128/v1/providers/openai/chat/completions
|
||||
POST http://localhost:20128/v1/providers/openai/embeddings
|
||||
POST http://localhost:20128/v1/providers/fireworks/images/generations
|
||||
```
|
||||
|
||||
Udbyderpræfikset tilføjes automatisk, hvis det mangler. Umatchede modeller returnerer `400`.
|
||||
|
||||
### Konfiguration af netværksproxy
|
||||
|
||||
```bash
|
||||
# Set global proxy
|
||||
curl -X PUT http://localhost:20128/api/settings/proxy \
|
||||
-d '{"global": {"type":"http","host":"proxy.example.com","port":"8080"}}'
|
||||
|
||||
# Per-provider proxy
|
||||
curl -X PUT http://localhost:20128/api/settings/proxy \
|
||||
-d '{"providers": {"openai": {"type":"socks5","host":"proxy.example.com","port":"1080"}}}'
|
||||
|
||||
# Test proxy
|
||||
curl -X POST http://localhost:20128/api/settings/proxy/test \
|
||||
-d '{"proxy":{"type":"socks5","host":"proxy.example.com","port":"1080"}}'
|
||||
```
|
||||
|
||||
**Forrang:** Nøglespecifik → Kombinationsspecifik → Udbyderspecifik → Global → Miljø.
|
||||
|
||||
### Model Catalog API
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/api/models/catalog
|
||||
```
|
||||
|
||||
Returnerer modeller grupperet efter udbyder med typer (`chat`, `embedding`, `image`).
|
||||
|
||||
### Cloud Sync
|
||||
|
||||
- Synkroniser udbydere, kombinationer og indstillinger på tværs af enheder
|
||||
- Automatisk baggrundssynkronisering med timeout + fejl-hurtig
|
||||
- Foretrækker server-side `BASE_URL`/`CLOUD_URL` i produktion
|
||||
|
||||
### LLM Gateway Intelligence (fase 9)
|
||||
|
||||
- **Semantisk cache** — Auto-cacher ikke-streaming, temperatur=0 svar (omgå med `X-OmniRoute-No-Cache: true`)
|
||||
- **Anmod om idempotens** — Deduplikerer anmodninger inden for 5 sekunder via `Idempotency-Key` eller `X-Request-Id` header
|
||||
- **Progress Tracking** — Tilmeld SSE `event: progress` begivenheder via `X-OmniRoute-Progress: true` header
|
||||
|
||||
---
|
||||
|
||||
### Oversætter Legeplads
|
||||
|
||||
Adgang via **Dashboard → Oversætter**. Fejlfind og visualiser, hvordan OmniRoute oversætter API-anmodninger mellem udbydere.
|
||||
|
||||
| Tilstand | Formål |
|
||||
| ---------------- | --------------------------------------------------------------------------------------------- |
|
||||
| **Legeplads** | Vælg kilde-/målformater, indsæt en anmodning, og se det oversatte output med det samme |
|
||||
| **Chattester** | Send live chatbeskeder gennem proxyen og inspicer den fulde anmodning/svar-cyklus |
|
||||
| **Testbænk** | Kør batchtest på tværs af flere formatkombinationer for at bekræfte oversættelsens korrekthed |
|
||||
| **Live Monitor** | Se oversættelser i realtid, mens anmodninger strømmer gennem proxyen |
|
||||
|
||||
**Brugstilfælde:**
|
||||
|
||||
- Fejlfinding af, hvorfor en specifik klient/udbyder-kombination mislykkes
|
||||
- Bekræft, at tankemærker, værktøjsopkald og systembeskeder oversættes korrekt
|
||||
- Sammenlign formatforskelle mellem OpenAI, Claude, Gemini og Responses API-formater
|
||||
|
||||
---
|
||||
|
||||
### Routingstrategier
|
||||
|
||||
Konfigurer via **Dashboard → Indstillinger → Routing**.
|
||||
|
||||
| Strategi | Beskrivelse |
|
||||
| ------------------------------ | --------------------------------------------------------------------------------------------------------------- |
|
||||
| **Fyld først** | Bruger konti i prioriteret rækkefølge — primær konto håndterer alle anmodninger, indtil de ikke er tilgængelige |
|
||||
| **Round Robin** | Går gennem alle konti med en konfigurerbar sticky-grænse (standard: 3 opkald pr. konto) |
|
||||
| **P2C (Power of Two Choices)** | Vælger 2 tilfældige konti og ruter til den sundere — balancerer belastning med bevidsthed om sundhed |
|
||||
| **Tilfældig** | Vælger tilfældigt en konto for hver anmodning ved hjælp af Fisher-Yates shuffle |
|
||||
| **Mindst brugt** | Ruter til kontoen med det ældste `lastUsedAt` tidsstempel, der fordeler trafikken jævnt |
|
||||
| **Omkostningsoptimeret** | Ruter til kontoen med den laveste prioritetsværdi, optimerer til udbydere med laveste omkostninger |
|
||||
|
||||
#### Wildcard-modelaliaser
|
||||
|
||||
Opret jokertegnmønstre for at omdanne modelnavne:
|
||||
|
||||
```
|
||||
Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929
|
||||
Pattern: gpt-* → Target: gh/gpt-5.1-codex
|
||||
```
|
||||
|
||||
Jokertegn understøtter `*` (alle tegn) og `?` (enkelt tegn).
|
||||
|
||||
#### Fallback-kæder
|
||||
|
||||
Definer globale reservekæder, der gælder på tværs af alle anmodninger:
|
||||
|
||||
```
|
||||
Chain: production-fallback
|
||||
1. cc/claude-opus-4-6
|
||||
2. gh/gpt-5.1-codex
|
||||
3. glm/glm-4.7
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Modstandsdygtighed og strømafbrydere
|
||||
|
||||
Konfigurer via **Dashboard → Indstillinger → Resiliens**.
|
||||
|
||||
OmniRoute implementerer modstandsdygtighed på udbyderniveau med fire komponenter:
|
||||
|
||||
1. **Udbyderprofiler** — Konfiguration pr. udbyder for:
|
||||
- Fejltærskel (hvor mange fejl før åbning)
|
||||
- Nedkølingsvarighed
|
||||
- Følsomhed for registrering af hastighedsgrænse
|
||||
- Eksponentielle backoff-parametre
|
||||
|
||||
2. **Redigerbare hastighedsgrænser** — Standardindstillinger på systemniveau, der kan konfigureres i dashboardet:
|
||||
- **Requests Per Minute (RPM)** — Maksimale anmodninger pr. minut pr. konto
|
||||
- **Min Time Between Requests** — Minimumsafstand i millisekunder mellem anmodninger
|
||||
- **Maksimal samtidige anmodninger** — Maksimalt antal samtidige anmodninger pr. konto
|
||||
- Klik på **Rediger** for at ændre, og klik derefter på **Gem** eller **Annuller**. Værdier bevarer via resilience API.
|
||||
|
||||
3. **Circuit Breaker** — Sporer fejl pr. udbyder og åbner automatisk kredsløbet, når en tærskel er nået:
|
||||
- **LUKKET** (Sund) — Anmodninger flyder normalt
|
||||
- **ÅBEN** — Udbyderen er midlertidigt blokeret efter gentagne fejl
|
||||
- **HALF_OPEN** — Tester, om udbyderen er genoprettet
|
||||
|
||||
4. **Politik og låste identifikatorer** — Viser strømafbryderstatus og låste identifikatorer med tvangsoplåsningsfunktion.
|
||||
|
||||
5. **Automatisk registrering af hastighedsgrænse** — Overvåger `429` og `Retry-After` overskrifter for proaktivt at undgå at ramme udbyderens satsgrænser.
|
||||
|
||||
**Prof tip:** Brug knappen **Nulstil alle** til at rydde alle strømafbrydere og nedkøling, når en udbyder kommer sig efter en fejl.
|
||||
|
||||
---
|
||||
|
||||
### Databaseeksport/import
|
||||
|
||||
Administrer databasesikkerhedskopier i **Dashboard → Indstillinger → System og lager**.
|
||||
|
||||
| Handling | Beskrivelse |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Eksporter database** | Downloader den aktuelle SQLite-database som en `.sqlite`-fil |
|
||||
| **Eksporter alle (.tar.gz)** | Downloader et komplet backup-arkiv inklusive: database, indstillinger, kombinationer, udbyderforbindelser (ingen legitimationsoplysninger), API-nøglemetadata |
|
||||
| **Importer database** | Upload en `.sqlite` fil for at erstatte den aktuelle database. Der oprettes automatisk en pre-import backup |
|
||||
|
||||
```bash
|
||||
# API: Export database
|
||||
curl -o backup.sqlite http://localhost:20128/api/db-backups/export
|
||||
|
||||
# API: Export all (full archive)
|
||||
curl -o backup.tar.gz http://localhost:20128/api/db-backups/exportAll
|
||||
|
||||
# API: Import database
|
||||
curl -X POST http://localhost:20128/api/db-backups/import \
|
||||
-F "file=@backup.sqlite"
|
||||
```
|
||||
|
||||
**Importvalidering:** Den importerede fil er valideret for integritet (SQLite pragmatjek), påkrævede tabeller (`provider_connections`, `provider_nodes`, `combos`, `api_keys`) og størrelse (maks. 100 MB).
|
||||
|
||||
**Brugstilfælde:**
|
||||
|
||||
- Migrer OmniRoute mellem maskiner
|
||||
- Opret eksterne sikkerhedskopier til katastrofegendannelse
|
||||
- Del konfigurationer mellem teammedlemmer (eksporter alle → del arkiv)
|
||||
|
||||
---
|
||||
|
||||
### Indstillinger Dashboard
|
||||
|
||||
Indstillingssiden er organiseret i 5 faner for nem navigation:
|
||||
|
||||
| Faneblad | Indhold |
|
||||
| ------------- | --------------------------------------------------------------------------------------------------------- |
|
||||
| **Sikkerhed** | Indstillinger for login/adgangskode, IP-adgangskontrol, API-godkendelse for `/models` og udbyderblokering |
|
||||
| **Routing** | Global routingstrategi (6 muligheder), jokertegn-modelaliaser, reservekæder, combo-standarder |
|
||||
| **Resiliens** | Udbyderprofiler, redigerbare hastighedsgrænser, strømafbryderstatus, politikker og låste identifikatorer |
|
||||
| **AI** | Tænkende budgetkonfiguration, global systemprompt-injektion, prompt-cache-statistik |
|
||||
| **Avanceret** | Global proxy-konfiguration (HTTP/SOCKS5) |
|
||||
|
||||
---
|
||||
|
||||
### Omkostninger og budgetstyring
|
||||
|
||||
Adgang via **Dashboard → Omkostninger**.
|
||||
|
||||
| Faneblad | Formål |
|
||||
| ---------- | -------------------------------------------------------------------------------------------------- |
|
||||
| **Budget** | Indstil forbrugsgrænser pr. API-nøgle med daglige/ugentlige/månedlige budgetter og realtidssporing |
|
||||
| **Priser** | Se og rediger modelprissætninger — pris pr. 1K input/output-tokens pr. udbyder |
|
||||
|
||||
```bash
|
||||
# API: Set a budget
|
||||
curl -X POST http://localhost:20128/api/usage/budget \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"keyId": "key-123", "limit": 50.00, "period": "monthly"}'
|
||||
|
||||
# API: Get current budget status
|
||||
curl http://localhost:20128/api/usage/budget
|
||||
```
|
||||
|
||||
**Omkostningssporing:** Hver anmodning logger tokenbrug og beregner omkostninger ved hjælp af pristabellen. Se opdelinger i **Dashboard → Brug** efter udbyder, model og API-nøgle.
|
||||
|
||||
---
|
||||
|
||||
### Lydtransskription
|
||||
|
||||
OmniRoute understøtter lydtransskription via det OpenAI-kompatible slutpunkt:
|
||||
|
||||
```bash
|
||||
POST /v1/audio/transcriptions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
# Example with curl
|
||||
curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
-H "Authorization: Bearer your-api-key" \
|
||||
-F "file=@audio.mp3" \
|
||||
-F "model=deepgram/nova-3"
|
||||
```
|
||||
|
||||
Tilgængelige udbydere: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`).
|
||||
|
||||
Understøttede lydformater: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
|
||||
---
|
||||
|
||||
### Kombinationsbalanceringsstrategier
|
||||
|
||||
Konfigurer balancering pr. kombination i **Dashboard → Combos → Opret/Rediger → Strategi**.
|
||||
|
||||
| Strategi | Beskrivelse |
|
||||
| ------------------------ | ----------------------------------------------------------------------------- |
|
||||
| **Round-Robin** | Roterer sekventielt gennem modeller |
|
||||
| **Prioritet** | Prøver altid den første model; falder kun tilbage på fejl |
|
||||
| **Tilfældig** | Vælger en tilfældig model fra kombinationen for hver anmodning |
|
||||
| **Vægtet** | Ruter proportionalt baseret på tildelte vægte pr. model |
|
||||
| **Mindst brugt** | Ruter til modellen med de færreste seneste anmodninger (bruger combo-metrics) |
|
||||
| **Omkostningsoptimeret** | Ruter til den billigste tilgængelige model (bruger pristabel) |
|
||||
|
||||
Globale kombinationsstandarder kan indstilles i **Dashboard → Indstillinger → Routing → Combo-standarder**.
|
||||
|
||||
---
|
||||
|
||||
### Sundhedsdashboard
|
||||
|
||||
Adgang via **Dashboard → Health**. Oversigt over systemets tilstand i realtid med 6 kort:
|
||||
|
||||
| Kort | Hvad det viser |
|
||||
| --------------------- | --------------------------------------------------------- |
|
||||
| **Systemstatus** | Oppetid, version, hukommelsesforbrug, datakatalog |
|
||||
| **Udbydersundhed** | Per-leverandør afbrydertilstand (Lukket/Åben/Halv-Åben) |
|
||||
| **Satsgrænser** | Aktive nedkølingsgrænser pr. konto med resterende tid |
|
||||
| **Aktive lockouts** | Udbydere midlertidigt blokeret af lockout-politikken |
|
||||
| **Signatur Cache** | Deduplikeringscache-statistikker (aktive nøgler, hitrate) |
|
||||
| **Latency Telemetri** | p50/p95/p99 latenssammenlægning pr. udbyder |
|
||||
|
||||
**Prof tip:** Sundhedssiden opdateres automatisk hvert 10. sekund. Brug afbryderkortet til at identificere, hvilke udbydere der oplever problemer.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user